intranet-core 1.0.2 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 16bba6e4fbd42e10c7c782d5171b4092f5d116a0
4
- data.tar.gz: ac817457c107a692555ae55af7bd98337094c778
3
+ metadata.gz: bf5a56e43b31aff50e2987cb337fdca3308f5444
4
+ data.tar.gz: c319c8fa7398563f469bb403edb7fff1923c126c
5
5
  SHA512:
6
- metadata.gz: 4446887c3d60d16dbacea6820f17f4679490ee0bb83b20cbd5c12d2c9c5e5f98d60e21df0126632539d6789f92a9723bec7ff6a8b7c34d32197ed07e73c9cea4
7
- data.tar.gz: 6708f510f4beeb3dc7bb2d981dd2ce49292f602b23489bf9a6c177829ef04040f5f3fe0dba129c9480723f7131dbee754dafa82d9d76e8c496b345450f1f7304
6
+ metadata.gz: 0cd16c07120e3a5f3996a9b186d69c40a5816ad58b3852b988d334a82a18637bf2f130dc098ce7d465976a4148b412cbb1955e001cad546ccf5c77d2d23b7599
7
+ data.tar.gz: a280390146e29d0fa3be5c44faebdc6f72b54d4c7e4599dd81ae94bde5c15e4481ece613c236d777522433beae0c9cb16dd92842488318a109b712f7ef2b9a8d
@@ -3,6 +3,18 @@
3
3
  module Intranet
4
4
  # The default implementation and interface of an Intranet module.
5
5
  class AbstractResponder
6
+ # Returns the name of the module.
7
+ # @return [String] The name of the module
8
+ def self.module_name; end
9
+
10
+ # The version of the module, according to semantic versionning.
11
+ # @return [String] The version of the module
12
+ def self.module_version; end
13
+
14
+ # The homepage of the module, if any.
15
+ # @return [String/Nil] The homepage URL of the module, or nil if no homepage is available.
16
+ def self.module_homepage; end
17
+
6
18
  # Destroys the responder instance.
7
19
  # This method gets called when server is shut down.
8
20
  def finalize
@@ -16,11 +16,16 @@ module Intranet
16
16
  # @return [CoreExtensions::Tree]
17
17
  attr_reader :responders
18
18
 
19
+ # The metadata concerning all registered modules (for Haml)
20
+ # @return [Hash]
21
+ attr_reader :modules
22
+
19
23
  # Initializes a new builder.
20
24
  # @param logger [Object] The logger.
21
25
  def initialize(logger)
22
26
  @logger = logger
23
27
  @responders = CoreExtensions::Tree.new
28
+ @modules = { NAME => { version: VERSION, homepage: HOMEPAGE_URL } }
24
29
  end
25
30
 
26
31
  # Finalizes the builder. Each registered responder is called for +finalize+.
@@ -63,17 +68,14 @@ module Intranet
63
68
  # directory. If empty, the responder will be registered as Home responder
64
69
  # (to serve /index.html in particular). Subdirectories are allowed using
65
70
  # an array element for each directory level.
71
+ # @raise [ArgumentError] If the +responder+ is not a valid responder instance.
66
72
  # @raise [ArgumentError] If one of the element of the +path+ contains invalid characters.
67
73
  def register(responder, path = [])
74
+ raise ArgumentError unless responder.class.superclass.to_s == 'Intranet::AbstractResponder'
68
75
  raise ArgumentError unless path.all?(&:urlized?)
69
76
 
70
- current_node = @responders
71
- path.each do |part|
72
- next if part.empty? || part == '.'
73
-
74
- current_node = current_node.add_child_node(part)
75
- end
76
- current_node.value = responder
77
+ insert_responder(responder, path)
78
+ store_module_metadata(responder)
77
79
  end
78
80
 
79
81
  private
@@ -93,6 +95,29 @@ module Intranet
93
95
 
94
96
  [current_treenode.value, '/' + relative_path.join('/')]
95
97
  end
98
+
99
+ # Inserts a responder instance in the appropriate Tree node according the given +path+.
100
+ # Missing Tree nodes are created.
101
+ # @param responder [Intranet::AbstractResponder] The responder instance of the module.
102
+ # @param path [Array] See Intranet::Builder::register().
103
+ def insert_responder(responder, path)
104
+ current_node = @responders
105
+ path.each do |part|
106
+ next if part.empty? || part == '.'
107
+
108
+ current_node = current_node.add_child_node(part)
109
+ end
110
+ current_node.value = responder
111
+ end
112
+
113
+ # Stores the module name, version and homepage URL. These information are used to display the
114
+ # 'about' modal window when partial content is returned by a module. The hash structure
115
+ # ensures that each module metadata are stored once only.
116
+ # @param responder [Intranet::AbstractResponder] The responder instance of the module.
117
+ def store_module_metadata(responder)
118
+ @modules[responder.class.module_name] = { version: responder.class.module_version,
119
+ homepage: responder.class.module_homepage }
120
+ end
96
121
  end
97
122
  end
98
123
  end
@@ -2,7 +2,16 @@
2
2
 
3
3
  module Intranet
4
4
  class Core
5
- # The version of the Intranet core, according to semantic versionning.
6
- VERSION = '1.0.2'
5
+ # The name of the gem.
6
+ NAME = 'intranet-core'
7
+
8
+ # The version of the gem, according to semantic versionning.
9
+ VERSION = '1.1.1'
10
+
11
+ # The URL of the gem homepage.
12
+ HOMEPAGE_URL = 'https://rubygems.org/gems/intranet-core'
13
+
14
+ # The URL of the gem source code.
15
+ SOURCES_URL = 'https://bitbucket.org/ebling-mis/intranet-core'
7
16
  end
8
17
  end
@@ -45,8 +45,11 @@
45
45
  %aside#modal
46
46
  %div#modal-content
47
47
  %h2= 'Intranet'
48
- %p
49
- %strong
50
- %a{href: 'https://rubygems.org/gems/intranet-core', target: '_blank'}= 'core'
51
- = '  '
52
- = Intranet::Core::VERSION
48
+ %dl
49
+ - modules.each do |name, metadata|
50
+ %dt
51
+ - if metadata[:homepage].nil?
52
+ = name
53
+ - else
54
+ %a{href: metadata[:homepage], target: '_blank'}= name
55
+ %dd= metadata[:version]
@@ -3,7 +3,7 @@
3
3
  * Design for the IntraNet core.
4
4
  */
5
5
 
6
- /******************************* External Fonts *******************************/
6
+ /***************************************** External Fonts *****************************************/
7
7
 
8
8
  @font-face {
9
9
  font-family: "Source Sans Pro";
@@ -13,7 +13,7 @@
13
13
  unicode-range: U+0-FF, U+131, U+152-153, U+2C6, U+2DA, U+2DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
14
14
  }
15
15
 
16
- /******************************* General design *******************************/
16
+ /***************************************** General design *****************************************/
17
17
 
18
18
  body, html {
19
19
  padding: 0px;
@@ -21,7 +21,7 @@ body, html {
21
21
  height: 100%;
22
22
  }
23
23
  body {
24
- background: #1e262b url('background.jpg') fixed top right no-repeat;
24
+ background: #1e262b;
25
25
  font-family: "Source Sans Pro", Cantarell, sans-serif;
26
26
  color: black;
27
27
  }
@@ -38,7 +38,7 @@ a {
38
38
  cursor: pointer;
39
39
  }
40
40
 
41
- /********************************* Navigation *********************************/
41
+ /******************************************* Navigation *******************************************/
42
42
 
43
43
  header {
44
44
  position: fixed;
@@ -193,6 +193,7 @@ ul.breadcrumb li a, main article a {
193
193
  /******************************** Main content *******************************/
194
194
 
195
195
  body > aside {
196
+ background: url('background.jpg') fixed top right no-repeat;
196
197
  height: 45%;
197
198
  min-height: 350px;
198
199
  max-height: 500px; /* less than height of background.jpg */
@@ -280,6 +281,19 @@ body > footer aside#modal #modal-content { /* modal box */
280
281
  width: 400px;
281
282
  font-size: 125%;
282
283
  }
284
+ body > footer aside#modal #modal-content dl {
285
+ display: grid;
286
+ grid-template-columns: repeat(2, 50%);
287
+ grid-gap: 5px 25px;
288
+ }
289
+ body > footer aside#modal #modal-content dl dt {
290
+ font-weight: bold;
291
+ text-align: right;
292
+ }
293
+ body > footer aside#modal #modal-content dl dd {
294
+ text-align: left;
295
+ margin-left: 0;
296
+ }
283
297
  /* Mobile devices only */
284
298
  @media only screen and (max-width: 600px), only screen and (max-device-width: 600px) {
285
299
  body > footer {
@@ -288,7 +302,7 @@ body > footer aside#modal #modal-content { /* modal box */
288
302
  }
289
303
 
290
304
 
291
- /********************************* Error pages *********************************/
305
+ /******************************************* Error pages ******************************************/
292
306
 
293
307
  section#error h2 {
294
308
  color: #ff3333;
@@ -109,26 +109,9 @@ RSpec.describe Intranet::Core do
109
109
  end
110
110
 
111
111
  context 'registering an invalid module' do
112
- it 'should succeed but accesses to the module URL should return HTTP error 404' do
113
- begin
114
- @intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
115
- @intranet.register_module(nil, [], '')
116
- thread = Thread.new do
117
- @intranet.start
118
- end
119
- while @intranet.instance_variable_get(:@server).status != :Running
120
- end
121
-
122
- socket = TCPSocket.new('localhost', @intranet.port)
123
- socket.puts("GET /index.html HTTP/1.1\r\n" \
124
- "Host: localhost:#{@intranet.port}\r\n\r\n")
125
- expect(socket.gets).to include('HTTP/1.1 404 Not Found')
126
- socket.close
127
- ensure
128
- socket.close
129
- Thread.kill(thread)
130
- thread.join
131
- end
112
+ it 'should fail' do
113
+ @intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
114
+ expect { @intranet.register_module(nil, [], '') }.to raise_error ArgumentError
132
115
  end
133
116
  end
134
117
 
@@ -315,9 +298,15 @@ RSpec.describe Intranet::Core do
315
298
  expect(html).to match(%r{<script defer='defer' src='module.js'></script>})
316
299
  expect(html).to match(%r{<script defer='defer' src='/js/interactive.js'></script>})
317
300
 
318
- # Returned HTML document: includes Intranet Core Version
319
- expect(html).to match(%r{<footer>.*#{Intranet::Core::VERSION}.*</footer>}m)
320
- expect(html).to match(%r{<footer>.*https://rubygems.org/gems/intranet-core.*</footer>}m)
301
+ # Returned HTML document: includes Intranet Core name, version and URL
302
+ expect(html).to match(
303
+ %r{<footer>.*<a href='#{Intranet::Core::HOMEPAGE_URL}'.*>#{Intranet::Core::NAME}</a>.*#{Intranet::Core::VERSION}.*</footer>}m # rubocop:disable Metrics/LineLength
304
+ )
305
+
306
+ # Returned HTML document: includes all registered modules version name, version and URL
307
+ expect(html).to match(
308
+ %r{<footer>.*<a href='http://nil/'.*>test-responder</a>.*0.0.0.*</footer>}m
309
+ )
321
310
  ensure
322
311
  socket.close
323
312
  Thread.kill(thread)
@@ -15,6 +15,19 @@ module Intranet
15
15
 
16
16
  def finalize
17
17
  @finalized = true
18
+ super
19
+ end
20
+
21
+ def self.module_name
22
+ 'test-responder'
23
+ end
24
+
25
+ def self.module_version
26
+ '0.0.0'
27
+ end
28
+
29
+ def self.module_homepage
30
+ 'http://nil/'
18
31
  end
19
32
 
20
33
  def resources_dir
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: 1.0.2
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ebling Mis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-24 00:00:00.000000000 Z
11
+ date: 2019-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: haml
@@ -191,10 +191,11 @@ files:
191
191
  - spec/spec_helper.rb
192
192
  - spec/test_responder/responder.rb
193
193
  - spec/test_responder/www/style.css
194
- homepage: https://bitbucket.org/ebling-mis/intranet-core
194
+ homepage: https://rubygems.org/gems/intranet-core
195
195
  licenses:
196
196
  - MIT
197
- metadata: {}
197
+ metadata:
198
+ source_code_uri: https://bitbucket.org/ebling-mis/intranet-core
198
199
  post_install_message:
199
200
  rdoc_options: []
200
201
  require_paths: