sitehub 0.4.2 → 0.4.3

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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +17 -0
  3. data/Gemfile +0 -2
  4. data/Gemfile.lock +15 -1
  5. data/README.md +23 -0
  6. data/Rakefile +3 -9
  7. data/circle.yml +6 -0
  8. data/lib/sitehub/builder.rb +19 -19
  9. data/lib/sitehub/collection/route_collection.rb +7 -9
  10. data/lib/sitehub/collection/split_route_collection/split.rb +7 -5
  11. data/lib/sitehub/collection/split_route_collection.rb +13 -10
  12. data/lib/sitehub/collection.rb +26 -21
  13. data/lib/sitehub/constants/http_header_keys.rb +2 -6
  14. data/lib/sitehub/constants/rack_http_header_keys.rb +2 -2
  15. data/lib/sitehub/constants.rb +3 -3
  16. data/lib/sitehub/cookie/attribute.rb +4 -4
  17. data/lib/sitehub/cookie/flag.rb +4 -5
  18. data/lib/sitehub/cookie.rb +10 -14
  19. data/lib/sitehub/cookie_rewriting.rb +11 -13
  20. data/lib/sitehub/forward_proxies.rb +12 -13
  21. data/lib/sitehub/forward_proxy.rb +38 -24
  22. data/lib/sitehub/forward_proxy_builder.rb +38 -21
  23. data/lib/sitehub/http_headers.rb +39 -26
  24. data/lib/sitehub/logging/access_logger.rb +39 -35
  25. data/lib/sitehub/logging/error_logger.rb +7 -7
  26. data/lib/sitehub/logging/log_entry.rb +6 -5
  27. data/lib/sitehub/logging/log_stash.rb +2 -2
  28. data/lib/sitehub/logging/log_wrapper.rb +5 -5
  29. data/lib/sitehub/logging.rb +1 -1
  30. data/lib/sitehub/middleware.rb +2 -2
  31. data/lib/sitehub/path_directive.rb +10 -10
  32. data/lib/sitehub/path_directives.rb +5 -4
  33. data/lib/sitehub/request_mapping.rb +13 -11
  34. data/lib/sitehub/resolver.rb +5 -6
  35. data/lib/sitehub/reverse_proxy.rb +16 -12
  36. data/lib/sitehub/rules.rb +2 -2
  37. data/lib/sitehub/string_sanitiser.rb +1 -1
  38. data/lib/sitehub/transaction_id.rb +3 -3
  39. data/lib/sitehub/version.rb +1 -1
  40. data/lib/sitehub.rb +1 -1
  41. data/sitehub.gemspec +27 -29
  42. data/spec/sitehub/builder_spec.rb +18 -20
  43. data/spec/sitehub/collection/route_collection_spec.rb +16 -14
  44. data/spec/sitehub/collection/split_route_collection_spec.rb +8 -10
  45. data/spec/sitehub/collection_spec.rb +7 -7
  46. data/spec/sitehub/cookie/attribute_spec.rb +3 -3
  47. data/spec/sitehub/cookie/flag_spec.rb +2 -2
  48. data/spec/sitehub/cookie_rewriting_spec.rb +15 -12
  49. data/spec/sitehub/cookie_spec.rb +7 -18
  50. data/spec/sitehub/error_handling_spec.rb +2 -3
  51. data/spec/sitehub/forward_proxies_spec.rb +16 -12
  52. data/spec/sitehub/forward_proxy_builder_spec.rb +53 -30
  53. data/spec/sitehub/forward_proxy_spec.rb +26 -22
  54. data/spec/sitehub/http_headers_spec.rb +17 -18
  55. data/spec/sitehub/integration_spec.rb +4 -5
  56. data/spec/sitehub/logging/access_logger_spec.rb +25 -24
  57. data/spec/sitehub/logging/error_logger_spec.rb +5 -7
  58. data/spec/sitehub/logging/log_entry_spec.rb +2 -5
  59. data/spec/sitehub/logging/log_stash_spec.rb +1 -3
  60. data/spec/sitehub/logging/log_wrapper_spec.rb +0 -4
  61. data/spec/sitehub/middleware_spec.rb +1 -5
  62. data/spec/sitehub/path_directive_spec.rb +4 -7
  63. data/spec/sitehub/path_directives_spec.rb +6 -7
  64. data/spec/sitehub/request_mapping_spec.rb +2 -5
  65. data/spec/sitehub/resolver_spec.rb +1 -1
  66. data/spec/sitehub/reverse_proxy_spec.rb +37 -31
  67. data/spec/sitehub/transaction_id_spec.rb +3 -3
  68. data/spec/sitehub_spec.rb +2 -4
  69. data/spec/support/async/callback.rb +11 -0
  70. data/spec/support/async/middleware.rb +25 -0
  71. data/spec/support/async/response_handler.rb +16 -0
  72. data/spec/support/async.rb +4 -0
  73. data/spec/support/patch/rack/response.rb +13 -21
  74. data/spec/support/shared_contexts/async_context.rb +3 -58
  75. data/spec/support/shared_contexts/middleware_context.rb +15 -17
  76. data/spec/support/shared_contexts/rack_test_context.rb +3 -3
  77. data/spec/support/shared_contexts/sitehub_context.rb +9 -4
  78. data/spec/support/silent_warnings.rb +2 -3
  79. data/tasks/code_quality.rake +15 -0
  80. data/tasks/gem_tasks.rake +1 -0
  81. data/tasks/support/console.rb +7 -0
  82. data/tasks/testing.rake +4 -0
  83. data/tasks/util_tasks.rake +7 -0
  84. metadata +27 -3
  85. data/spec/basket_spec.rb +0 -30
@@ -3,8 +3,7 @@ require 'sitehub/logging/error_logger'
3
3
  class SiteHub
4
4
  module Logging
5
5
  describe ErrorLogger do
6
-
7
- let(:app){ proc{[200, {}, []]}}
6
+ let(:app) { proc { [200, {}, []] } }
8
7
  subject { described_class.new(app) }
9
8
 
10
9
  describe '#initialize' do
@@ -44,7 +43,7 @@ class SiteHub
44
43
  context 'errors have occurred' do
45
44
  it 'logs errors' do
46
45
  log_message = subject.log_message(error: error_message, transaction_id: :transaction_id)
47
- subject.call({ERRORS => errors, Constants::RackHttpHeaderKeys::TRANSACTION_ID => :transaction_id})
46
+ subject.call(ERRORS => errors, Constants::RackHttpHeaderKeys::TRANSACTION_ID => :transaction_id)
48
47
  expect(output.string).to eq(log_message)
49
48
  end
50
49
  end
@@ -52,7 +51,7 @@ class SiteHub
52
51
  context 'no errors have occured' do
53
52
  it 'does not log anything' do
54
53
  expect(logger).to_not receive(:write)
55
- subject.call({ERRORS => []})
54
+ subject.call(ERRORS => [])
56
55
  end
57
56
  end
58
57
  end
@@ -62,17 +61,16 @@ class SiteHub
62
61
  it 'contains the time and date' do
63
62
  now = Time.now
64
63
  expect(Time).to receive(:now).and_return(now)
65
- expected_time = now.strftime("%d/%b/%Y:%H:%M:%S %z")
64
+ expected_time = now.strftime('%d/%b/%Y:%H:%M:%S %z')
66
65
  expect(subject.log_message(error: error, transaction_id: :transaction_id)).to start_with("[#{expected_time}]")
67
66
  end
68
67
 
69
68
  it 'logs statements made against blah' do
70
-
71
69
  expect(subject.log_message(error: error, transaction_id: :transaction_id)).to match(/ERROR: .* - ?#{error}$/)
72
70
  end
73
71
 
74
72
  it 'contains the transation id of the request' do
75
- expect(subject.log_message(error: error, transaction_id: :transaction_id)).to include("ERROR: #{:transaction_id}")
73
+ expect(subject.log_message(error: error, transaction_id: :transaction_id)).to include('ERROR: transaction_id')
76
74
  end
77
75
  end
78
76
  end
@@ -3,8 +3,7 @@ class SiteHub
3
3
  module Logging
4
4
  describe LogEntry do
5
5
  describe '#initialize' do
6
-
7
- let(:time){Time.now}
6
+ let(:time) { Time.now }
8
7
  subject do
9
8
  described_class.new(:message, time)
10
9
  end
@@ -26,9 +25,7 @@ class SiteHub
26
25
  expect(subject.time).to be(:current_time)
27
26
  end
28
27
  end
29
-
30
-
31
28
  end
32
29
  end
33
30
  end
34
- end
31
+ end
@@ -3,13 +3,11 @@ require 'sitehub/logging/log_stash'
3
3
  class SiteHub
4
4
  module Logging
5
5
  describe LogStash do
6
-
7
6
  it 'inherits Array' do
8
7
  expect(subject).to be_a_kind_of(Array)
9
8
  end
10
9
 
11
10
  describe '#<<' do
12
-
13
11
  it 'adds a LogEntry' do
14
12
  allow(Time).to receive(:now).and_return(:current_time)
15
13
  subject << :message
@@ -18,4 +16,4 @@ class SiteHub
18
16
  end
19
17
  end
20
18
  end
21
- end
19
+ end
@@ -1,9 +1,7 @@
1
1
  require 'sitehub/logging/log_wrapper'
2
2
  class SiteHub
3
3
  module Logging
4
-
5
4
  describe LogWrapper do
6
-
7
5
  describe '#write' do
8
6
  let(:logger) { double('logger') }
9
7
  subject do
@@ -19,14 +17,12 @@ class SiteHub
19
17
  end
20
18
 
21
19
  context 'logger responds to write' do
22
-
23
20
  it 'calls << when writing out the log' do
24
21
  message = 'message'
25
22
  expect(logger).to receive(:write).with(message)
26
23
  subject.write(message)
27
24
  end
28
25
  end
29
-
30
26
  end
31
27
  end
32
28
  end
@@ -19,9 +19,7 @@ class SiteHub
19
19
  end
20
20
 
21
21
  describe '#apply_middleware' do
22
-
23
22
  context 'middleware defined' do
24
-
25
23
  it 'wraps the supplied app in the middleware' do
26
24
  subject.use middleware
27
25
  result = subject.apply_middleware(:app)
@@ -61,9 +59,7 @@ class SiteHub
61
59
  expect(block_passed).to be(true)
62
60
  end
63
61
  end
64
-
65
62
  end
66
-
67
63
  end
68
64
  end
69
- end
65
+ end
@@ -1,13 +1,11 @@
1
1
  require 'sitehub/path_directive'
2
2
  class SiteHub
3
3
  describe PathDirective do
4
-
5
4
  subject do
6
5
  described_class.new(%r{/match}, '/path_template')
7
6
  end
8
7
 
9
8
  describe '#match?' do
10
-
11
9
  context 'matcher applies' do
12
10
  it 'returns true' do
13
11
  expect(subject.match?('/match')).to eq(true)
@@ -26,7 +24,7 @@ class SiteHub
26
24
  described_class.new(Regexp.new('http://www.upstream.com/orders/(.*)'), '/$1')
27
25
  end
28
26
 
29
- let(:url){'http://www.upstream.com/orders/123'}
27
+ let(:url) { 'http://www.upstream.com/orders/123' }
30
28
 
31
29
  it 'uses the url to populate the path template' do
32
30
  expect(subject.apply(url)).to eq('/123')
@@ -39,12 +37,11 @@ class SiteHub
39
37
 
40
38
  describe '#path_template' do
41
39
  it 'returns a duplicate of the path_template every time' do
42
- version1, version2 = subject.path_template, subject.path_template
40
+ version1 = subject.path_template
41
+ version2 = subject.path_template
43
42
  expect(version1).to eq(version2)
44
43
  expect(version1).to_not be(version2)
45
44
  end
46
45
  end
47
-
48
46
  end
49
-
50
- end
47
+ end
@@ -10,7 +10,7 @@ class SiteHub
10
10
  it 'leaves the key has a regexp' do
11
11
  key = %r{/.*/}
12
12
  value = '/'
13
- expect(described_class.new(key => value)).to eq([PathDirective.new(key,value)])
13
+ expect(described_class.new(key => value)).to eq([PathDirective.new(key, value)])
14
14
  end
15
15
  end
16
16
 
@@ -18,20 +18,20 @@ class SiteHub
18
18
  it 'converts the key to a regexp' do
19
19
  key = 'string'
20
20
  value = '/'
21
- expect(described_class.new(key => value)).to eq([PathDirective.new(Regexp.new(key),value)])
21
+ expect(described_class.new(key => value)).to eq([PathDirective.new(Regexp.new(key), value)])
22
22
  end
23
23
  end
24
24
  end
25
25
 
26
26
  describe '#find' do
27
- let(:matcher){Regexp.new('/orders/(.*)')}
28
- let(:path_template){'/orders/$1'}
27
+ let(:matcher) { Regexp.new('/orders/(.*)') }
28
+ let(:path_template) { '/orders/$1' }
29
29
  subject do
30
30
  described_class.new(matcher => path_template)
31
31
  end
32
32
  context 'url matches matcher' do
33
33
  it 'returns the path directive' do
34
- expect(subject.find('http://url.com/orders/123')).to eq(PathDirective.new(matcher,path_template))
34
+ expect(subject.find('http://url.com/orders/123')).to eq(PathDirective.new(matcher, path_template))
35
35
  end
36
36
  end
37
37
  context 'url does not matches matcher' do
@@ -39,7 +39,6 @@ class SiteHub
39
39
  expect(subject.find('http://url.com/mismatch')).to eq(nil)
40
40
  end
41
41
  end
42
-
43
42
  end
44
43
  end
45
- end
44
+ end
@@ -2,9 +2,8 @@ require 'sitehub/request_mapping'
2
2
 
3
3
  class SiteHub
4
4
  describe RequestMapping do
5
-
6
5
  describe '#initialize' do
7
- let(:mapped_url){'http://downstream_url'}
6
+ let(:mapped_url) { 'http://downstream_url' }
8
7
  subject do
9
8
  described_class.new(source_url: 'http://upstream.com/articles/123',
10
9
  mapped_url: mapped_url,
@@ -64,8 +63,6 @@ class SiteHub
64
63
  expect(subject.computed_uri).to eq('http://downstream_url/articles?param=value')
65
64
  end
66
65
  end
67
-
68
-
69
66
  end
70
67
  end
71
- end
68
+ end
@@ -12,4 +12,4 @@ class SiteHub
12
12
  end
13
13
  end
14
14
  end
15
- end
15
+ end
@@ -1,36 +1,31 @@
1
1
  class SiteHub
2
-
3
2
  describe ReverseProxy do
4
-
5
3
  include_context :middleware_test
6
4
 
5
+ let(:mapped_path) { '/orders' }
6
+ let(:user_facing_app_url) { "http://example.org#{mapped_path}" }
7
7
 
8
- let(:mapped_path){'/orders'}
9
- let(:user_facing_app_url){"http://example.org#{mapped_path}"}
8
+ let(:downstream_mapping) { 'https://downstream.com/app1/orders' }
9
+ let(:downstream_location) { "#{downstream_mapping}/123/confirmation" }
10
10
 
11
+ let(:request_mapping) do
12
+ RequestMapping.new source_url: "#{user_facing_app_url}/123/payment",
13
+ mapped_url: downstream_mapping,
14
+ mapped_path: mapped_path
15
+ end
11
16
 
12
- let(:downstream_mapping){'https://downstream.com/app1/orders'}
13
- let(:downstream_location){"#{downstream_mapping}/123/confirmation"}
14
- let(:request_mapping){RequestMapping.new source_url: "#{user_facing_app_url}/123/payment", mapped_url: downstream_mapping, mapped_path: mapped_path}
15
17
  let(:app) do
16
- proc{downstream_response}
18
+ proc { downstream_response }
17
19
  end
18
- let(:downstream_response){Rack::Response.new('downstream', 200, {'header1' => 'header1'} )}
20
+ let(:downstream_response) { Rack::Response.new('downstream', 200, 'header1' => 'header1') }
19
21
 
20
- #subject do
21
- # described_class.new(inner_app, [])
22
- #end
23
-
24
- subject(:reverse_proxy){described_class.new(app, [])}
25
- let(:env){{REQUEST_MAPPING => request_mapping}}
22
+ subject(:reverse_proxy) { described_class.new(app, []) }
23
+ let(:env) { { REQUEST_MAPPING => request_mapping } }
26
24
 
27
25
  describe '#call' do
28
-
29
-
30
-
31
26
  subject(:response) do
32
27
  status, headers, body = reverse_proxy.call(env).to_a
33
- Rack::Response.new(body,status, headers)
28
+ Rack::Response.new(body, status, headers)
34
29
  end
35
30
 
36
31
  it 'copies the downstream body in to the response' do
@@ -49,7 +44,11 @@ class SiteHub
49
44
  context 'downstream response contains a cookie' do
50
45
  it 'rewrites it to use the upstream domain' do
51
46
  downstream_response.set_cookie('downstream.cookie', domain: '.downstream.com', value: 'value')
52
- expect(reverse_proxy).to receive(:rewrite_cookies).with(downstream_response.headers, substitute_domain: URI(request_mapping.source_url).host)
47
+
48
+ expect(reverse_proxy)
49
+ .to receive(:rewrite_cookies)
50
+ .with(downstream_response.headers, substitute_domain: URI(request_mapping.source_url).host)
51
+
53
52
  reverse_proxy.call(env)
54
53
  end
55
54
  end
@@ -64,42 +63,49 @@ class SiteHub
64
63
  end
65
64
  end
66
65
 
67
- #Location, Content-Location and URI
66
+ # Location, Content-Location and URI
68
67
  it 'rewrites the Location header' do
69
68
  downstream_response.headers[HttpHeaders::LOCATION_HEADER] = downstream_location
70
- expect(reverse_proxy).to receive(:interpolate_location).with(downstream_location, request_mapping.source_url).and_return(:interpolated_location)
69
+
70
+ expect(reverse_proxy)
71
+ .to receive(:interpolate_location)
72
+ .with(downstream_location, request_mapping.source_url)
73
+ .and_return(:interpolated_location)
74
+
71
75
  reverse_proxy.call(env)
72
76
  expect(downstream_response.headers[HttpHeaders::LOCATION_HEADER]).to eq(:interpolated_location)
73
77
  end
74
-
75
78
  end
76
79
 
77
80
  describe '#interpolate_location' do
78
81
  it 'changes the domain' do
79
- expect(reverse_proxy.interpolate_location(downstream_location, request_mapping.source_url)).to eq("http://example.org/app1/orders/123/confirmation")
82
+ expect(reverse_proxy.interpolate_location(downstream_location, request_mapping.source_url)).to eq('http://example.org/app1/orders/123/confirmation')
80
83
  end
81
84
 
82
85
  context 'there is a directive that applies' do
83
86
  context 'matcher is a regexp' do
84
87
  subject do
85
- directive = {%r{#{downstream_mapping}/(.*)/confirmation} => '/confirmation/$1'}
86
- described_class.new(inner_app,directive)
88
+ directive = { %r{#{downstream_mapping}/(.*)/confirmation} => '/confirmation/$1' }
89
+ described_class.new(inner_app, directive)
87
90
  end
88
91
  it 'changes the path' do
89
- expect(subject.interpolate_location(downstream_location, request_mapping.source_url)).to eq("http://example.org/confirmation/123")
92
+ expect(subject.interpolate_location(downstream_location, request_mapping.source_url)).to eq('http://example.org/confirmation/123')
90
93
  end
91
94
  end
92
95
 
93
96
  context 'matcher is a string' do
97
+ let(:downstream_url) { 'http://downstream.com/confirmation' }
94
98
  subject do
95
- directive = {"http://downstream.com/confirmation" => '/congratulations'}
96
- described_class.new(inner_app,directive)
99
+ directive = { downstream_url => '/congratulations' }
100
+ described_class.new(inner_app, directive)
97
101
  end
98
102
  it 'changes the path' do
99
- expect(subject.interpolate_location('http://downstream.com/confirmation', request_mapping.source_url)).to eq("http://example.org/congratulations")
103
+ actual = subject.interpolate_location(downstream_url, request_mapping.source_url)
104
+ expected = 'http://example.org/congratulations'
105
+ expect(actual).to eq(expected)
100
106
  end
101
107
  end
102
108
  end
103
109
  end
104
110
  end
105
- end
111
+ end
@@ -2,9 +2,9 @@ require 'sitehub/transaction_id'
2
2
 
3
3
  class SiteHub
4
4
  describe TransactionId do
5
- let(:transaction_id){Constants::RackHttpHeaderKeys::TRANSACTION_ID}
5
+ let(:transaction_id) { Constants::RackHttpHeaderKeys::TRANSACTION_ID }
6
6
  subject do
7
- described_class.new(Proc.new{})
7
+ described_class.new(proc {})
8
8
  end
9
9
  it 'adds a unique identifier to the request' do
10
10
  uuid = UUID.generate(:compact)
@@ -18,7 +18,7 @@ class SiteHub
18
18
  context 'transaction id header already exists' do
19
19
  it 'leaves it intact' do
20
20
  expect(UUID).to_not receive(:generate)
21
- env = {transaction_id => :exiting_id}
21
+ env = { transaction_id => :exiting_id }
22
22
  subject.call(env)
23
23
 
24
24
  expect(env[transaction_id]).to eq(:exiting_id)
data/spec/sitehub_spec.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  describe SiteHub do
2
-
3
2
  describe '::build' do
4
3
  it 'gives you a configure sitehub to run in your config.ru' do
5
4
  allow_any_instance_of(SiteHub::Builder).to receive(:build).and_return(:sitehub)
@@ -7,13 +6,12 @@ describe SiteHub do
7
6
  end
8
7
  it 'passes your block on a sitehub builder' do
9
8
  block_called = false
10
- block = Proc.new do
9
+ block = proc do
11
10
  block_called = true
12
11
  end
13
12
 
14
13
  described_class.build(&block)
15
14
  expect(block_called).to eq(true)
16
15
  end
17
-
18
16
  end
19
- end
17
+ end
@@ -0,0 +1,11 @@
1
+ module Async
2
+ class Callback
3
+ attr_reader :response
4
+
5
+ def call(*args)
6
+ status, headers, body = *args.flatten.to_a
7
+ @response = Rack::Response.new(body, status, headers)
8
+ EventMachine.stop if EventMachine.reactor_running?
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ module Async
2
+ class Middleware
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def last_response
8
+ callback.response
9
+ end
10
+
11
+ def callback
12
+ @callback ||= Callback.new
13
+ end
14
+
15
+ def call(env)
16
+ env['async.callback'] = callback
17
+
18
+ catch(:async) do
19
+ @app.call env
20
+ end
21
+
22
+ [200, {}, []]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ module Async
2
+ class ResponseHandler < EM::DefaultDeferrable
3
+ attr_reader :last_response, :callback_args
4
+
5
+ alias arg callback_args
6
+
7
+ def succeed(arg)
8
+ sitehub_response = arg[:downstream_response]
9
+ instance_variable_set(:@arg, arg)
10
+ status, headers, body = *sitehub_response.to_a
11
+ rack_response = Rack::Response.new(body, status, headers)
12
+ instance_variable_set(:@last_response, rack_response)
13
+ EM.stop
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift("#{__dir__}/async")
2
+ require 'middleware'
3
+ require 'response_handler'
4
+ require 'callback'
@@ -1,25 +1,17 @@
1
- class Rack::Response
2
- def cookies
3
- cookies = {}
4
- header['Set-Cookie'].lines.collect { |line| line.scan(/([\.\w]+)=([\.\w\/]+)/) }.each do |cookie_definition_array|
5
- name_value_array = cookie_definition_array.delete_at(0)
6
- name = name_value_array.first
7
- value = name_value_array.last
8
- data = cookie_definition_array.collect { |pair| [pair[0].to_sym, pair[1]] }.to_h
9
- cookies[name] = {value: value}.merge(data)
1
+ module Rack
2
+ class Response
3
+ def cookies
4
+ cookie_key_value_array.each_with_object({}) do |cookie_key_value, cookies|
5
+ name_value_array = cookie_key_value.delete_at(0)
6
+ name, value = *name_value_array
7
+ data = cookie_key_value.collect { |pair| [pair[0].to_sym, pair[1]] }.to_h
8
+ cookies[name] = { value: value }.merge(data)
9
+ cookies
10
+ end
10
11
  end
11
- cookies
12
- end
13
12
 
14
- def cookies_as_hash
15
- cookies = {}
16
- header['Set-Cookie'].lines.collect { |line| line.scan(/([\.\w]+)=([\.\w]+)/) }.each do |cookie_definition_array|
17
- name_value_array = cookie_definition_array.delete_at(0)
18
- name = name_value_array.first
19
- value = name_value_array.last
20
- data = cookie_definition_array.collect { |pair| [pair[0].to_sym, pair[1]] }.to_h
21
- cookies[name] = {value: value}.merge(data)
13
+ def cookie_key_value_array
14
+ header['Set-Cookie'].lines.collect { |line| line.scan(%r{([\.\w]+)=([\.\w/]+)}) }
22
15
  end
23
- cookies
24
16
  end
25
- end
17
+ end
@@ -1,69 +1,14 @@
1
+ require_relative '../async'
1
2
  shared_context :async do
2
- class Callback
3
- attr_reader :response
4
-
5
- def call *args
6
- status, headers, body = *args.flatten.to_a
7
- @response = Rack::Response.new(body, status, headers)
8
- EventMachine.stop if EventMachine.reactor_running?
9
- end
10
- end
11
-
12
3
  def callback
13
- @callback ||= Callback.new
4
+ @callback ||= Async::Callback.new
14
5
  end
15
6
 
16
7
  def async_response_handler
17
- @async_response_handler ||= begin
18
- instance_double(EM::DefaultDeferrable).tap do |handler|
19
- allow(handler).to receive(:succeed) do |arg|
20
- sitehub_response = arg[:downstream_response]
21
- handler.instance_variable_set(:@arg, arg)
22
- sitehub_response = sitehub_response.to_a
23
- handler.instance_variable_set(:@last_response, Rack::Response.new(sitehub_response[2], sitehub_response[0], sitehub_response[1]))
24
- EM.stop
25
- end
26
-
27
- def handler.last_response
28
- @last_response
29
- end
30
-
31
- def handler.callback_args
32
- @arg
33
- end
34
- end
35
- end
8
+ @async_response_handler = Async::ResponseHandler.new
36
9
  end
37
10
 
38
11
  def last_response
39
12
  app.last_response
40
13
  end
41
-
42
- def async_middleware
43
- Class.new do
44
- def initialize app
45
- @app = app
46
- end
47
-
48
- def last_response
49
- callback.response
50
- end
51
-
52
- def callback
53
- @callback ||= Callback.new
54
- end
55
-
56
-
57
- def call env
58
-
59
- env['async.callback'] = callback
60
-
61
- catch(:async) do
62
- @app.call env
63
- end
64
-
65
- [200, {}, []]
66
- end
67
- end
68
- end
69
14
  end
@@ -1,51 +1,49 @@
1
1
  shared_context :middleware_test do
2
-
3
2
  include_context :rack_test
4
3
 
5
- let(:inner_app){
6
- proc{[200, {}, []]}
7
- }
4
+ let(:inner_app) do
5
+ proc { [200, {}, []] }
6
+ end
8
7
 
9
8
  subject(:app) do
10
9
  described_class.new(inner_app)
11
10
  end
12
11
 
13
- def collect_middleware rack_app
12
+ def collect_middleware(rack_app)
14
13
  middleware = [rack_app]
15
- while rack_app = rack_app.instance_variable_get(:@app)
14
+ while (rack_app = rack_app.instance_variable_get(:@app))
16
15
  middleware << rack_app
17
16
  end
18
17
  middleware
19
18
  end
20
19
 
21
-
22
- def find_middleware rack_app, clazz
20
+ def find_middleware(rack_app, clazz)
23
21
  return rack_app if rack_app.is_a?(clazz)
24
- collect_middleware(rack_app).find{|middleware| middleware.is_a?(clazz)}
22
+ collect_middleware(rack_app).find { |middleware| middleware.is_a?(clazz) }
25
23
  end
26
24
 
27
- RSpec::Matchers.define :be_using do |expected, *args|
25
+ RSpec::Matchers.define :be_using do |expected, *_args|
28
26
  match do |actual|
29
- !!find_middleware(actual, expected)
27
+ !find_middleware(actual, expected).nil?
30
28
  end
31
29
  end
32
30
 
33
31
  def create_middleware
34
32
  Class.new do
35
33
  attr_reader :app, :arg
36
- def initialize app, arg=nil, &block
37
- @app, @arg = app, arg
38
- block.call if block
34
+ def initialize(app, arg = nil, &block)
35
+ @app = app
36
+ @arg = arg
37
+ yield if block
39
38
  end
40
39
 
41
- def call env
40
+ def call(env)
42
41
  @app.call env
43
42
  end
44
43
  end
45
-
46
44
  end
47
45
 
48
46
  let(:middleware) do
49
47
  create_middleware
50
48
  end
51
- end
49
+ end
@@ -3,10 +3,10 @@ shared_context :rack_test do
3
3
  include Rack::Test::Methods
4
4
 
5
5
  def env
6
- @env||={}
6
+ @env ||= {}
7
7
  end
8
8
 
9
9
  before :each do |example|
10
- @env = {'async.callback' => callback} if example.metadata[:async]
10
+ @env = { 'async.callback' => callback } if example.metadata[:async]
11
11
  end
12
- end
12
+ end