intranet-core 2.1.4 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/core_extensions.rb +2 -0
- data/lib/core_extensions/hash.rb +15 -0
- data/lib/core_extensions/string.rb +0 -1
- data/lib/intranet/core/builder.rb +13 -3
- data/lib/intranet/core/version.rb +1 -1
- data/spec/core_extensions/hash_spec.rb +22 -0
- data/spec/intranet/core_spec.rb +241 -244
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6860141eca0145a6d51787a137641ead4978b69d2f7b2d28ce5dcf1a5193f42
|
4
|
+
data.tar.gz: 6f43415cdf7334c81466b1205a838b92762c15dff3fb8ca3e096ccb71ebecfa2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84eeb50385f879656140e5b385a98a50c3149fa7b6cb8d31fd49b97ce73d5f69eda2e3e33789876196c0eaccaa47721b089e7870a0b90880392f03aedb279600
|
7
|
+
data.tar.gz: 07e5122a4279dc99efe881651637e932ec36601b3007529e545b13b7ccaef2297ca05b7f6184f02a6693d61ad1147b162961c508992ce57ce09ce56a0a8de32e
|
data/lib/core_extensions.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'core_extensions/hash'
|
3
4
|
require_relative 'core_extensions/string'
|
4
5
|
require_relative 'core_extensions/tree'
|
5
6
|
require_relative 'core_extensions/webrick/httpresponse'
|
6
7
|
|
8
|
+
Hash.include CoreExtensions::Hash
|
7
9
|
String.include CoreExtensions::String
|
8
10
|
WEBrick::HTTPResponse.include CoreExtensions::WEBrick::HTTPResponse
|
9
11
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CoreExtensions
|
4
|
+
# Extension of Ruby's standard library +Hash+ class.
|
5
|
+
module Hash
|
6
|
+
# Returns a copy of a hash with +keys+ excluded. Original hash is not
|
7
|
+
# modified.
|
8
|
+
# @return [Hash]
|
9
|
+
def except(*keys)
|
10
|
+
h = dup
|
11
|
+
keys.each { |key| h.delete(key) }
|
12
|
+
h
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -57,12 +57,12 @@ module Intranet
|
|
57
57
|
|
58
58
|
# Generate header and footer when partial content is returned by the responder
|
59
59
|
if status == 206 && mime_type == 'text/html'
|
60
|
-
body =
|
61
|
-
js: responder.js_dependencies, current_path: parsed_path)
|
60
|
+
body = add_header_and_footer(body, responder, parsed_path)
|
62
61
|
status = 200
|
63
62
|
end
|
64
63
|
[status, mime_type, body]
|
65
|
-
rescue KeyError, NoMethodError
|
64
|
+
rescue KeyError, NoMethodError => e
|
65
|
+
@logger.debug(e)
|
66
66
|
[404, '', '']
|
67
67
|
end
|
68
68
|
|
@@ -111,6 +111,16 @@ module Intranet
|
|
111
111
|
[current_treenode.value, '/' + parsed_path.join('/'), '/' + unparsed_path.join('/')]
|
112
112
|
end
|
113
113
|
|
114
|
+
# Encapsulate the given body in the default page skeleton, effectively
|
115
|
+
# adding page header and footer.
|
116
|
+
# @param body [String] The body of the page
|
117
|
+
# @param responder [Intranet::AbstractResponder] The responder that produced the body
|
118
|
+
# @param path [String] The path to the responder
|
119
|
+
def add_header_and_footer(body, responder, path)
|
120
|
+
to_markup('skeleton', body: body, css: responder.css_dependencies,
|
121
|
+
js: responder.js_dependencies, current_path: path)
|
122
|
+
end
|
123
|
+
|
114
124
|
# Check whether a path is valid.
|
115
125
|
# @param path [Array] The path to test.
|
116
126
|
# @return [Boolean] True if the path is valid, False otherwise.
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'core_extensions/hash'
|
4
|
+
|
5
|
+
RSpec.describe CoreExtensions::Hash do
|
6
|
+
before do
|
7
|
+
Hash.include described_class
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#except' do
|
11
|
+
it 'should return a copy of the original hash with the given keys removed' do
|
12
|
+
tested_hash = { a: true, b: false, c: nil }
|
13
|
+
expect(tested_hash.except(:c)).to eql({ a: true, b: false })
|
14
|
+
expect(tested_hash).to eql({ a: true, b: false, c: nil })
|
15
|
+
|
16
|
+
tested_hash = { a: 100, b: 200, c: 300 }
|
17
|
+
expect(tested_hash.except(:a)).to eql({ b: 200, c: 300 })
|
18
|
+
expect(tested_hash.except(:a, :c)).to eql({ b: 200 })
|
19
|
+
expect(tested_hash).to eql({ a: 100, b: 200, c: 300 })
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/spec/intranet/core_spec.rb
CHANGED
@@ -15,71 +15,67 @@ RSpec.describe Intranet::Core do
|
|
15
15
|
|
16
16
|
describe '#start' do
|
17
17
|
it 'should start an HTTP server on an available port' do
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
# Wait for the server on port 8080 to be running
|
25
|
-
while @intranet8080.instance_variable_get(:@server).status != :Running
|
26
|
-
end
|
18
|
+
# make sure port 80 & 8080 are not available
|
19
|
+
@intranet8080 = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
20
|
+
thread8080 = Thread.new { @intranet8080.start }
|
21
|
+
while @intranet8080.instance_variable_get(:@server).status != :Running
|
22
|
+
end
|
23
|
+
expect(@intranet8080.port).to be >= 8080
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
)
|
32
|
-
expect(intranet.port).not_to eql(8080)
|
33
|
-
ensure
|
34
|
-
intranet.stop if intranet.respond_to?(:stop)
|
35
|
-
Thread.kill(thread)
|
36
|
-
thread.join
|
25
|
+
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
26
|
+
thread = Thread.new { @intranet.start }
|
27
|
+
while @intranet.instance_variable_get(:@server).status != :Running
|
37
28
|
end
|
29
|
+
expect(@intranet.port).to be > 8080
|
30
|
+
|
31
|
+
@intranet.stop
|
32
|
+
thread&.join
|
33
|
+
@intranet8080.stop
|
34
|
+
thread8080&.join
|
38
35
|
end
|
39
36
|
|
40
37
|
it 'should start searching for an available port at the given +preferred_port+' do
|
41
|
-
intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL), 9090)
|
42
|
-
|
38
|
+
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL), 9090)
|
39
|
+
thread = Thread.new { @intranet.start }
|
40
|
+
while @intranet.instance_variable_get(:@server).status != :Running
|
41
|
+
end
|
42
|
+
|
43
|
+
expect(@intranet.port).to be >= 9090
|
44
|
+
|
45
|
+
@intranet.stop
|
46
|
+
thread&.join
|
43
47
|
end
|
44
48
|
|
45
49
|
it 'should serve the /design directory' do
|
46
|
-
|
50
|
+
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
51
|
+
thread = Thread.new { @intranet.start }
|
52
|
+
while @intranet.instance_variable_get(:@server).status != :Running
|
53
|
+
end
|
54
|
+
|
55
|
+
socket = TCPSocket.new('localhost', @intranet.port)
|
56
|
+
socket.puts("GET /design/favicon.ico HTTP/1.1\r\nHost: localhost:#{@intranet.port}\r\n\r\n")
|
57
|
+
expect(socket.gets).to include('HTTP/1.1 200 OK')
|
58
|
+
socket.close
|
59
|
+
|
60
|
+
@intranet.stop
|
61
|
+
thread&.join
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when no module is registered' do
|
65
|
+
it 'should return HTTP error 404 when requested for /index.html' do
|
47
66
|
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
48
|
-
thread = Thread.new
|
49
|
-
@intranet.start
|
50
|
-
end
|
67
|
+
thread = Thread.new { @intranet.start }
|
51
68
|
while @intranet.instance_variable_get(:@server).status != :Running
|
52
69
|
end
|
53
70
|
|
54
71
|
socket = TCPSocket.new('localhost', @intranet.port)
|
55
|
-
socket.puts("GET /
|
56
|
-
|
57
|
-
|
72
|
+
socket.puts("GET /index.html HTTP/1.1\r\n" \
|
73
|
+
"Host: localhost:#{@intranet.port}\r\n\r\n")
|
74
|
+
expect(socket.gets).to include('HTTP/1.1 404 Not Found')
|
58
75
|
socket.close
|
59
|
-
Thread.kill(thread)
|
60
|
-
thread.join
|
61
|
-
end
|
62
|
-
end
|
63
76
|
|
64
|
-
|
65
|
-
|
66
|
-
begin
|
67
|
-
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
68
|
-
thread = Thread.new do
|
69
|
-
@intranet.start
|
70
|
-
end
|
71
|
-
while @intranet.instance_variable_get(:@server).status != :Running
|
72
|
-
end
|
73
|
-
|
74
|
-
socket = TCPSocket.new('localhost', @intranet.port)
|
75
|
-
socket.puts("GET /index.html HTTP/1.1\r\n" \
|
76
|
-
"Host: localhost:#{@intranet.port}\r\n\r\n")
|
77
|
-
expect(socket.gets).to include('HTTP/1.1 404 Not Found')
|
78
|
-
ensure
|
79
|
-
socket.close
|
80
|
-
Thread.kill(thread)
|
81
|
-
thread.join
|
82
|
-
end
|
77
|
+
@intranet.stop
|
78
|
+
thread&.join
|
83
79
|
end
|
84
80
|
end
|
85
81
|
end
|
@@ -87,59 +83,71 @@ RSpec.describe Intranet::Core do
|
|
87
83
|
describe '#register_module' do
|
88
84
|
context 'registering a module when the server is running' do
|
89
85
|
it 'should fail' do
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
thread = Thread.new do
|
94
|
-
@intranet.start
|
95
|
-
end
|
96
|
-
while @intranet.instance_variable_get(:@server).status != :Running
|
97
|
-
end
|
98
|
-
|
99
|
-
expect { @intranet.register_module(r, ['path'], '') }.to raise_error Errno::EALREADY
|
100
|
-
ensure
|
101
|
-
Thread.kill(thread)
|
102
|
-
thread.join
|
86
|
+
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
87
|
+
thread = Thread.new { @intranet.start }
|
88
|
+
while @intranet.instance_variable_get(:@server).status != :Running
|
103
89
|
end
|
90
|
+
|
91
|
+
r = Intranet::TestResponder.new('/index.html' => [200, 'text/html', ''])
|
92
|
+
expect { @intranet.register_module(r, ['path'], '') }.to raise_error Errno::EALREADY
|
93
|
+
|
94
|
+
@intranet.stop
|
95
|
+
thread&.join
|
104
96
|
end
|
105
97
|
end
|
106
98
|
|
107
99
|
context 'registering a module with an invalid path' do
|
108
100
|
it 'should fail' do
|
109
101
|
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
102
|
+
|
110
103
|
r = Intranet::TestResponder.new('/index.html' => [200, 'text/html', ''])
|
111
104
|
expect { @intranet.register_module(r, [], '') }.to raise_error ArgumentError
|
112
105
|
expect { @intranet.register_module(r, %w[1 2 3], '') }.to raise_error ArgumentError
|
113
106
|
expect { @intranet.register_module(r, ['', 'valid'], '') }.to raise_error ArgumentError
|
114
107
|
expect { @intranet.register_module(r, ['Invalid'], '') }.to raise_error ArgumentError
|
115
108
|
expect { @intranet.register_module(r, 'fo', '') }.to raise_error ArgumentError
|
109
|
+
|
110
|
+
thread = Thread.new { @intranet.start }
|
111
|
+
while @intranet.instance_variable_get(:@server).status != :Running
|
112
|
+
end
|
113
|
+
|
114
|
+
@intranet.stop
|
115
|
+
thread&.join
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
119
|
context 'registering an invalid module' do
|
120
120
|
it 'should fail' do
|
121
121
|
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
122
|
+
|
122
123
|
expect { @intranet.register_module(nil, ['path'], '') }.to raise_error ArgumentError
|
124
|
+
|
125
|
+
thread = Thread.new { @intranet.start }
|
126
|
+
while @intranet.instance_variable_get(:@server).status != :Running
|
127
|
+
end
|
128
|
+
|
129
|
+
@intranet.stop
|
130
|
+
thread&.join
|
123
131
|
end
|
124
132
|
end
|
125
133
|
|
126
134
|
context 'when a valid module is registered' do
|
127
135
|
before(:each) do
|
128
136
|
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
137
|
+
|
129
138
|
responder = Intranet::TestResponder.new('/index.html' => [200, 'text/html', ''])
|
130
139
|
# Third argument of register_module() is optional, so we test both cases.
|
131
140
|
@intranet.register_module(responder, %w[responder], responder.resources_dir)
|
132
141
|
@intranet.register_module(responder, %w[resp onder])
|
133
|
-
|
134
|
-
|
135
|
-
end
|
142
|
+
|
143
|
+
@thread = Thread.new { @intranet.start }
|
136
144
|
while @intranet.instance_variable_get(:@server).status != :Running
|
137
145
|
end
|
138
146
|
end
|
139
147
|
|
140
148
|
after(:each) do
|
141
|
-
|
142
|
-
@thread
|
149
|
+
@intranet.stop
|
150
|
+
@thread&.join
|
143
151
|
end
|
144
152
|
|
145
153
|
it 'should be used to serve URI relative to the module root' do
|
@@ -179,148 +187,142 @@ RSpec.describe Intranet::Core do
|
|
179
187
|
|
180
188
|
context 'given a valid and registered module' do
|
181
189
|
it 'should be called with the decoded URL path and query in UTF-8 encoding' do
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
break if line.empty?
|
198
|
-
end
|
199
|
-
line = socket.gets.chomp
|
200
|
-
expect(line).to eql(
|
201
|
-
'PATH=/query t (UTF-8), ' \
|
202
|
-
'QUERY={var1 (UTF-8) => value1 (UTF-8),var2 (UTF-8) => value2 (UTF-8)}'
|
203
|
-
)
|
204
|
-
ensure
|
205
|
-
socket.close
|
206
|
-
Thread.kill(thread)
|
207
|
-
thread.join
|
190
|
+
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
191
|
+
|
192
|
+
responder = Intranet::TestResponder.new('/index.html' => [200, 'text/html', ''])
|
193
|
+
@intranet.register_module(responder, ['responder'], responder.resources_dir)
|
194
|
+
|
195
|
+
thread = Thread.new { @intranet.start }
|
196
|
+
while @intranet.instance_variable_get(:@server).status != :Running
|
197
|
+
end
|
198
|
+
|
199
|
+
socket = TCPSocket.new('localhost', @intranet.port)
|
200
|
+
socket.puts("GET /responder/query%20t?var1=value1&var2=value2 HTTP/1.1\r\n" \
|
201
|
+
"Host: localhost:#{@intranet.port}\r\n\r\n")
|
202
|
+
expect(socket.gets).to include('HTTP/1.1 200 OK')
|
203
|
+
while (line = socket.gets.chomp) # consume HTTP response headers
|
204
|
+
break if line.empty?
|
208
205
|
end
|
206
|
+
line = socket.gets.chomp
|
207
|
+
expect(line).to eql(
|
208
|
+
'PATH=/query t (UTF-8), ' \
|
209
|
+
'QUERY={var1 (UTF-8) => value1 (UTF-8),var2 (UTF-8) => value2 (UTF-8)}'
|
210
|
+
)
|
211
|
+
socket.close
|
212
|
+
|
213
|
+
@intranet.stop
|
214
|
+
thread&.join
|
209
215
|
end
|
210
216
|
end
|
211
217
|
|
212
218
|
context 'given a module returning partial HTML content' do
|
213
219
|
it 'should be called to retrieve the body of the page' do
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
while @intranet.instance_variable_get(:@server).status != :Running
|
228
|
-
end
|
229
|
-
|
230
|
-
socket = TCPSocket.new('localhost', @intranet.port)
|
231
|
-
socket.puts("GET /r/index.html HTTP/1.1\r\nHost: localhost:#{@intranet.port}\r\n\r\n")
|
232
|
-
|
233
|
-
# Return code: HTTP error 200
|
234
|
-
expect(socket.gets).to include('HTTP/1.1 200 OK')
|
235
|
-
|
236
|
-
while (line = socket.gets.chomp) # consume HTTP response headers
|
237
|
-
break if line.empty?
|
238
|
-
end
|
239
|
-
html = socket.readpartial(4096) # read rest of data
|
240
|
-
|
241
|
-
# Returned HTML document: includes the partial content and the title
|
242
|
-
expect(html).to match(%r{<main>.*PARTIAL_CONTENT.*</main>}m)
|
243
|
-
expect(html).to match(%r{<head>.*<title>.*MyTitle.*</title>.*</head>}m)
|
244
|
-
|
245
|
-
# Returned HTML document: includes the hostname in title, h1-title and footer
|
246
|
-
hostname = Socket.gethostname
|
247
|
-
expect(html).to match(%r{<head>.*<title>.*#{hostname.capitalize}.*</title>.*</head>}m)
|
248
|
-
expect(html).to match(%r{<body>.*<h1>.*#{hostname.capitalize}.*</h1>.*</body>}m)
|
249
|
-
expect(html).to match(%r{<footer>.*#{hostname}.*</footer>}m)
|
250
|
-
|
251
|
-
# Returned HTML document: includes all CSS dependencies, relative or absolute path
|
252
|
-
expect(html).to match(%r{<link href='/responder.css' rel='stylesheet' type='text/css'})
|
253
|
-
expect(html).to match(%r{<link href='/r/nav.css' rel='stylesheet' type='text/css'})
|
254
|
-
|
255
|
-
# Returned HTML document: includes all JS dependencies
|
256
|
-
expect(html).to match(%r{<script defer='defer' src='/r/module.js'></script>})
|
257
|
-
expect(html).to match(%r{<script defer='defer' src='/js/interactive.js'></script>})
|
258
|
-
|
259
|
-
# Returned HTML document: includes Intranet Core name, version and URL
|
260
|
-
expect(html).to match(
|
261
|
-
%r{<footer>.*<a href='#{Intranet::Core::HOMEPAGE_URL}'.*>#{Intranet::Core::NAME}</a>.*#{Intranet::Core::VERSION}.*</footer>}m # rubocop:disable Layout/LineLength
|
262
|
-
)
|
263
|
-
|
264
|
-
# Returned HTML document: includes all registered modules version name, version and URL
|
265
|
-
expect(html).to match(
|
266
|
-
%r{<footer>.*<a href='http://nil/'.*>test-responder</a>.*0.0.0.*</footer>}m
|
267
|
-
)
|
268
|
-
ensure
|
269
|
-
socket.close
|
270
|
-
Thread.kill(thread)
|
271
|
-
thread.join
|
220
|
+
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
221
|
+
|
222
|
+
responder = Intranet::TestResponder.new(
|
223
|
+
{
|
224
|
+
'/index.html' => [206, 'text/html', { content: 'PARTIAL_CONTENT', title: 'MyTitle' }]
|
225
|
+
},
|
226
|
+
['/responder.css', 'nav.css'],
|
227
|
+
['module.js', '/js/interactive.js']
|
228
|
+
)
|
229
|
+
@intranet.register_module(responder, ['r'], responder.resources_dir)
|
230
|
+
|
231
|
+
thread = Thread.new { @intranet.start }
|
232
|
+
while @intranet.instance_variable_get(:@server).status != :Running
|
272
233
|
end
|
234
|
+
|
235
|
+
socket = TCPSocket.new('localhost', @intranet.port)
|
236
|
+
socket.puts("GET /r/index.html HTTP/1.1\r\nHost: localhost:#{@intranet.port}\r\n\r\n")
|
237
|
+
|
238
|
+
# Return code: HTTP error 200
|
239
|
+
expect(socket.gets).to include('HTTP/1.1 200 OK')
|
240
|
+
|
241
|
+
while (line = socket.gets.chomp) # consume HTTP response headers
|
242
|
+
break if line.empty?
|
243
|
+
end
|
244
|
+
html = socket.readpartial(4096) # read rest of data
|
245
|
+
socket.close
|
246
|
+
|
247
|
+
# Returned HTML document: includes the partial content and the title
|
248
|
+
expect(html).to match(%r{<main>.*PARTIAL_CONTENT.*</main>}m)
|
249
|
+
expect(html).to match(%r{<head>.*<title>.*MyTitle.*</title>.*</head>}m)
|
250
|
+
|
251
|
+
# Returned HTML document: includes the hostname in title, h1-title and footer
|
252
|
+
hostname = Socket.gethostname
|
253
|
+
expect(html).to match(%r{<head>.*<title>.*#{hostname.capitalize}.*</title>.*</head>}m)
|
254
|
+
expect(html).to match(%r{<body>.*<h1>.*#{hostname.capitalize}.*</h1>.*</body>}m)
|
255
|
+
expect(html).to match(%r{<footer>.*#{hostname}.*</footer>}m)
|
256
|
+
|
257
|
+
# Returned HTML document: includes all CSS dependencies, relative or absolute path
|
258
|
+
expect(html).to match(%r{<link href='/responder.css' rel='stylesheet' type='text/css'})
|
259
|
+
expect(html).to match(%r{<link href='/r/nav.css' rel='stylesheet' type='text/css'})
|
260
|
+
|
261
|
+
# Returned HTML document: includes all JS dependencies
|
262
|
+
expect(html).to match(%r{<script defer='defer' src='/r/module.js'></script>})
|
263
|
+
expect(html).to match(%r{<script defer='defer' src='/js/interactive.js'></script>})
|
264
|
+
|
265
|
+
# Returned HTML document: includes Intranet Core name, version and URL
|
266
|
+
expect(html).to match(
|
267
|
+
%r{<footer>.*<a href='#{Intranet::Core::HOMEPAGE_URL}'.*>#{Intranet::Core::NAME}</a>.*#{Intranet::Core::VERSION}.*</footer>}m # rubocop:disable Layout/LineLength
|
268
|
+
)
|
269
|
+
|
270
|
+
# Returned HTML document: includes all registered modules version name, version and URL
|
271
|
+
expect(html).to match(
|
272
|
+
%r{<footer>.*<a href='http://nil/'.*>test-responder</a>.*0.0.0.*</footer>}m
|
273
|
+
)
|
274
|
+
|
275
|
+
@intranet.stop
|
276
|
+
thread&.join
|
273
277
|
end
|
274
278
|
it 'should be called to update the main navigation menu' do
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
while @intranet.instance_variable_get(:@server).status != :Running
|
293
|
-
end
|
294
|
-
|
295
|
-
socket = TCPSocket.new('localhost', @intranet.port)
|
296
|
-
socket.puts("GET /r/index.html HTTP/1.1\r\nHost: localhost:#{@intranet.port}\r\n\r\n")
|
297
|
-
|
298
|
-
# Return code: HTTP error 200
|
299
|
-
expect(socket.gets).to include('HTTP/1.1 200 OK')
|
300
|
-
|
301
|
-
while (line = socket.gets.chomp)
|
302
|
-
break if line.empty?
|
303
|
-
end
|
304
|
-
html = socket.readpartial(4096) # read rest of data
|
305
|
-
|
306
|
-
# Returned HTML document main menu
|
307
|
-
expect(html).to match(%r{<a href='/dep_th1/index.html'>.*Dep Th1.*</a>})
|
308
|
-
expect(html).not_to match(%r{<a href='/other1/index.html'>})
|
309
|
-
expect(html).to match(
|
310
|
-
%r{<a>.*Depth2.*</a>.*<ul>.*<a href='/depth2/res_p1/index.html'>.*Res P1.*</a>.*</ul>}m
|
311
|
-
)
|
312
|
-
expect(html).to match(
|
313
|
-
%r{<a>.*Depth2.*</a>.*<ul>.*<a href='/depth2/resp2/index.html'>.*Resp2.*</a>.*</ul>}m
|
314
|
-
)
|
315
|
-
expect(html).not_to match(%r{<a href='/depth2/resp/index.html'>})
|
316
|
-
expect(html).not_to match(%r{<a>.*Other2.*</a>}m)
|
317
|
-
expect(html).not_to match(%r{<a href='/other2/res1/index.html'>})
|
318
|
-
expect(html).not_to match(%r{<a href='/other2/res2/index.html'>})
|
319
|
-
ensure
|
320
|
-
socket.close
|
321
|
-
Thread.kill(thread)
|
322
|
-
thread.join
|
279
|
+
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
280
|
+
|
281
|
+
responder = Intranet::TestResponder.new(
|
282
|
+
'/index.html' => [206, 'text/html', { content: 'PARTIAL_CONTENT', title: 'MyTitle' }]
|
283
|
+
)
|
284
|
+
other_responder = Intranet::TestResponder.new({}, [], [], true)
|
285
|
+
@intranet.register_module(responder, %w[r], responder.resources_dir)
|
286
|
+
@intranet.register_module(responder, %w[dep_th1], responder.resources_dir)
|
287
|
+
@intranet.register_module(responder, %w[depth2 res_p1], responder.resources_dir)
|
288
|
+
@intranet.register_module(responder, %w[depth2 resp2], responder.resources_dir)
|
289
|
+
@intranet.register_module(other_responder, %w[depth2 resp], other_responder.resources_dir)
|
290
|
+
@intranet.register_module(other_responder, %w[other1], other_responder.resources_dir)
|
291
|
+
@intranet.register_module(other_responder, %w[other2 res1], other_responder.resources_dir)
|
292
|
+
@intranet.register_module(other_responder, %w[other2 res2], other_responder.resources_dir)
|
293
|
+
|
294
|
+
thread = Thread.new { @intranet.start }
|
295
|
+
while @intranet.instance_variable_get(:@server).status != :Running
|
323
296
|
end
|
297
|
+
|
298
|
+
socket = TCPSocket.new('localhost', @intranet.port)
|
299
|
+
socket.puts("GET /r/index.html HTTP/1.1\r\nHost: localhost:#{@intranet.port}\r\n\r\n")
|
300
|
+
|
301
|
+
# Return code: HTTP error 200
|
302
|
+
expect(socket.gets).to include('HTTP/1.1 200 OK')
|
303
|
+
|
304
|
+
while (line = socket.gets.chomp)
|
305
|
+
break if line.empty?
|
306
|
+
end
|
307
|
+
html = socket.readpartial(4096) # read rest of data
|
308
|
+
socket.close
|
309
|
+
|
310
|
+
# Returned HTML document main menu
|
311
|
+
expect(html).to match(%r{<a href='/dep_th1/index.html'>.*Dep Th1.*</a>})
|
312
|
+
expect(html).not_to match(%r{<a href='/other1/index.html'>})
|
313
|
+
expect(html).to match(
|
314
|
+
%r{<a>.*Depth2.*</a>.*<ul>.*<a href='/depth2/res_p1/index.html'>.*Res P1.*</a>.*</ul>}m
|
315
|
+
)
|
316
|
+
expect(html).to match(
|
317
|
+
%r{<a>.*Depth2.*</a>.*<ul>.*<a href='/depth2/resp2/index.html'>.*Resp2.*</a>.*</ul>}m
|
318
|
+
)
|
319
|
+
expect(html).not_to match(%r{<a href='/depth2/resp/index.html'>})
|
320
|
+
expect(html).not_to match(%r{<a>.*Other2.*</a>}m)
|
321
|
+
expect(html).not_to match(%r{<a href='/other2/res1/index.html'>})
|
322
|
+
expect(html).not_to match(%r{<a href='/other2/res2/index.html'>})
|
323
|
+
|
324
|
+
@intranet.stop
|
325
|
+
thread&.join
|
324
326
|
end
|
325
327
|
end
|
326
328
|
end
|
@@ -329,66 +331,61 @@ RSpec.describe Intranet::Core do
|
|
329
331
|
context 'given a relative URL' do
|
330
332
|
it 'should fail' do
|
331
333
|
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
334
|
+
|
332
335
|
expect { @intranet.home_url = 'foo/index.html' }.to raise_error ArgumentError
|
333
|
-
end
|
334
|
-
end
|
335
336
|
|
336
|
-
|
337
|
-
|
338
|
-
begin
|
339
|
-
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
340
|
-
@intranet.home_url = '/responder/index.html'
|
341
|
-
thread = Thread.new do
|
342
|
-
@intranet.start
|
343
|
-
end
|
344
|
-
while @intranet.instance_variable_get(:@server).status != :Running
|
345
|
-
end
|
346
|
-
|
347
|
-
socket = TCPSocket.new('localhost', @intranet.port)
|
348
|
-
socket.puts("GET /index.html HTTP/1.1\r\nHost: localhost:#{@intranet.port}\r\n\r\n")
|
349
|
-
expect(socket.gets).to include('HTTP/1.1 307 Temporary Redirect')
|
350
|
-
while (line = socket.gets.chomp) # search the HTTP response for the 'Location' header
|
351
|
-
break if line.start_with?('Location:')
|
352
|
-
end
|
353
|
-
expect(line).to include("http://localhost:#{@intranet.port}/responder/index.html")
|
354
|
-
ensure
|
355
|
-
socket.close
|
356
|
-
Thread.kill(thread)
|
357
|
-
thread.join
|
337
|
+
thread = Thread.new { @intranet.start }
|
338
|
+
while @intranet.instance_variable_get(:@server).status != :Running
|
358
339
|
end
|
340
|
+
|
341
|
+
@intranet.stop
|
342
|
+
thread&.join
|
359
343
|
end
|
360
344
|
end
|
361
|
-
end
|
362
345
|
|
363
|
-
|
364
|
-
|
365
|
-
begin
|
346
|
+
context 'given an absolute URL' do
|
347
|
+
it 'should set up a redirection from /index.html to the provided URL' do
|
366
348
|
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
367
|
-
|
368
|
-
@intranet.
|
369
|
-
thread = Thread.new do
|
370
|
-
@intranet.start
|
371
|
-
end
|
349
|
+
@intranet.home_url = '/responder/index.html'
|
350
|
+
thread = Thread.new { @intranet.start }
|
372
351
|
while @intranet.instance_variable_get(:@server).status != :Running
|
373
352
|
end
|
374
353
|
|
375
354
|
socket = TCPSocket.new('localhost', @intranet.port)
|
376
|
-
socket.puts("GET /
|
377
|
-
expect(socket.gets).to include('HTTP/1.1
|
378
|
-
|
355
|
+
socket.puts("GET /index.html HTTP/1.1\r\nHost: localhost:#{@intranet.port}\r\n\r\n")
|
356
|
+
expect(socket.gets).to include('HTTP/1.1 307 Temporary Redirect')
|
357
|
+
while (line = socket.gets.chomp) # search the HTTP response for the 'Location' header
|
358
|
+
break if line.start_with?('Location:')
|
359
|
+
end
|
360
|
+
expect(line).to include("http://localhost:#{@intranet.port}/responder/index.html")
|
379
361
|
socket.close
|
380
362
|
|
381
363
|
@intranet.stop
|
382
|
-
|
383
|
-
|
364
|
+
thread&.join
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
384
368
|
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
369
|
+
describe '#stop' do
|
370
|
+
it 'should stop the web server and finalize all registered responders' do
|
371
|
+
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
372
|
+
responder = Intranet::TestResponder.new('/index.html' => [200, 'text/html', 'CONTENT'])
|
373
|
+
@intranet.register_module(responder, %w[r], responder.resources_dir)
|
374
|
+
thread = Thread.new { @intranet.start }
|
375
|
+
while @intranet.instance_variable_get(:@server).status != :Running
|
391
376
|
end
|
377
|
+
|
378
|
+
socket = TCPSocket.new('localhost', @intranet.port)
|
379
|
+
socket.puts("GET /r/index.html HTTP/1.1\r\nHost: localhost:#{@intranet.port}\r\n\r\n")
|
380
|
+
expect(socket.gets).to include('HTTP/1.1 200 OK')
|
381
|
+
expect(responder.finalized).to be false
|
382
|
+
socket.close
|
383
|
+
|
384
|
+
@intranet.stop
|
385
|
+
thread&.join
|
386
|
+
|
387
|
+
expect { TCPSocket.new('localhost', @intranet.port) }.to raise_error(Errno::ECONNREFUSED)
|
388
|
+
expect(responder.finalized).to be true
|
392
389
|
end
|
393
390
|
end
|
394
391
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: intranet-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ebling Mis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: haml
|
@@ -158,6 +158,7 @@ extra_rdoc_files: []
|
|
158
158
|
files:
|
159
159
|
- README.md
|
160
160
|
- lib/core_extensions.rb
|
161
|
+
- lib/core_extensions/hash.rb
|
161
162
|
- lib/core_extensions/string.rb
|
162
163
|
- lib/core_extensions/tree.rb
|
163
164
|
- lib/core_extensions/webrick/httpresponse.rb
|
@@ -179,6 +180,7 @@ files:
|
|
179
180
|
- lib/intranet/resources/www/fonts/SourceSansPro.woff2
|
180
181
|
- lib/intranet/resources/www/nav.js
|
181
182
|
- lib/intranet/resources/www/style.css
|
183
|
+
- spec/core_extensions/hash_spec.rb
|
182
184
|
- spec/core_extensions/string_spec.rb
|
183
185
|
- spec/core_extensions/tree_spec.rb
|
184
186
|
- spec/core_extensions/webrick/httpresponse_spec.rb
|