agile-proxy 0.1.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.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/.bowerrc +3 -0
  3. data/.gitignore +8 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +36 -0
  6. data/.travis.yml +8 -0
  7. data/Gemfile +4 -0
  8. data/Gemfile.lock +267 -0
  9. data/Guardfile +20 -0
  10. data/LICENSE +22 -0
  11. data/README.md +93 -0
  12. data/Rakefile +13 -0
  13. data/agile-proxy.gemspec +50 -0
  14. data/assets/index.html +39 -0
  15. data/assets/ui/app/HttpFlexibleProxyApi.js +31 -0
  16. data/assets/ui/app/app.js +1 -0
  17. data/assets/ui/app/controller/Stubs.js +64 -0
  18. data/assets/ui/app/controller/main.js +12 -0
  19. data/assets/ui/app/directive/AppEnhancedFormElement.js +21 -0
  20. data/assets/ui/app/directive/AppFor.js +16 -0
  21. data/assets/ui/app/directive/AppResponseEditor.js +54 -0
  22. data/assets/ui/app/model/RequestSpec.js +6 -0
  23. data/assets/ui/app/routes.js +10 -0
  24. data/assets/ui/app/service/Dialog.js +49 -0
  25. data/assets/ui/app/service/DomId.js +10 -0
  26. data/assets/ui/app/service/Error.js +7 -0
  27. data/assets/ui/app/service/Stub.js +36 -0
  28. data/assets/ui/app/view/404.html +2 -0
  29. data/assets/ui/app/view/dialog/error.html +10 -0
  30. data/assets/ui/app/view/dialog/yesNo.html +8 -0
  31. data/assets/ui/app/view/responses/editForm.html +78 -0
  32. data/assets/ui/app/view/status.html +1 -0
  33. data/assets/ui/app/view/stubs.html +19 -0
  34. data/assets/ui/app/view/stubs/edit.html +58 -0
  35. data/assets/ui/css/main.css +3 -0
  36. data/bin/agile_proxy +113 -0
  37. data/bower.json +27 -0
  38. data/config.yml +6 -0
  39. data/db.yml +10 -0
  40. data/db/migrations/20140818110800_create_users.rb +9 -0
  41. data/db/migrations/20140818134700_create_applications.rb +10 -0
  42. data/db/migrations/20140818135200_create_request_specs.rb +13 -0
  43. data/db/migrations/20140821115300_create_responses.rb +14 -0
  44. data/db/migrations/20140823082900_add_method_to_request_specs.rb +7 -0
  45. data/db/migrations/20140823083900_rename_request_spec_columns.rb +8 -0
  46. data/db/migrations/20141031072100_add_url_type_to_request_specs.rb +8 -0
  47. data/db/migrations/20141105125600_add_conditions_to_request_specs.rb +7 -0
  48. data/db/migrations/20141106083100_add_username_and_password_to_applications.rb +8 -0
  49. data/db/migrations/20141119143800_add_record_to_applications.rb +7 -0
  50. data/db/migrations/20141119174300_create_recordings.rb +18 -0
  51. data/db/schema.rb +78 -0
  52. data/examples/README.md +1 -0
  53. data/examples/facebook_api.html +59 -0
  54. data/examples/tumblr_api.html +22 -0
  55. data/lib/agile_proxy.rb +8 -0
  56. data/lib/agile_proxy/api/applications.rb +77 -0
  57. data/lib/agile_proxy/api/recordings.rb +52 -0
  58. data/lib/agile_proxy/api/request_specs.rb +85 -0
  59. data/lib/agile_proxy/api/root.rb +41 -0
  60. data/lib/agile_proxy/config.rb +63 -0
  61. data/lib/agile_proxy/handlers/handler.rb +43 -0
  62. data/lib/agile_proxy/handlers/proxy_handler.rb +110 -0
  63. data/lib/agile_proxy/handlers/request_handler.rb +57 -0
  64. data/lib/agile_proxy/handlers/stub_handler.rb +113 -0
  65. data/lib/agile_proxy/mitm.crt +22 -0
  66. data/lib/agile_proxy/mitm.key +27 -0
  67. data/lib/agile_proxy/model/application.rb +20 -0
  68. data/lib/agile_proxy/model/recording.rb +16 -0
  69. data/lib/agile_proxy/model/request_spec.rb +47 -0
  70. data/lib/agile_proxy/model/response.rb +56 -0
  71. data/lib/agile_proxy/model/user.rb +17 -0
  72. data/lib/agile_proxy/proxy_connection.rb +113 -0
  73. data/lib/agile_proxy/route.rb +106 -0
  74. data/lib/agile_proxy/router.rb +99 -0
  75. data/lib/agile_proxy/server.rb +85 -0
  76. data/lib/agile_proxy/servers/api.rb +41 -0
  77. data/lib/agile_proxy/servers/request_spec.rb +30 -0
  78. data/lib/agile_proxy/version.rb +6 -0
  79. data/load_proxy.js +39 -0
  80. data/log/.gitkeep +0 -0
  81. data/spec/common_helper.rb +32 -0
  82. data/spec/fixtures/test-server.crt +15 -0
  83. data/spec/fixtures/test-server.key +15 -0
  84. data/spec/integration/helpers/request_spec_helper.rb +60 -0
  85. data/spec/integration/specs/lib/server_spec.rb +407 -0
  86. data/spec/integration_spec_helper.rb +18 -0
  87. data/spec/spec_helper.rb +39 -0
  88. data/spec/support/test_server.rb +75 -0
  89. data/spec/unit/agile_proxy/api/applications_spec.rb +102 -0
  90. data/spec/unit/agile_proxy/api/common_helper.rb +31 -0
  91. data/spec/unit/agile_proxy/api/recordings_spec.rb +115 -0
  92. data/spec/unit/agile_proxy/api/request_specs_spec.rb +159 -0
  93. data/spec/unit/agile_proxy/handlers/handler_spec.rb +8 -0
  94. data/spec/unit/agile_proxy/handlers/proxy_handler_spec.rb +138 -0
  95. data/spec/unit/agile_proxy/handlers/request_handler_spec.rb +55 -0
  96. data/spec/unit/agile_proxy/handlers/stub_handler_spec.rb +154 -0
  97. data/spec/unit/agile_proxy/model/recording_spec.rb +0 -0
  98. data/spec/unit/agile_proxy/model/request_spec_spec.rb +45 -0
  99. data/spec/unit/agile_proxy/model/response_spec.rb +38 -0
  100. data/spec/unit/agile_proxy/server_spec.rb +88 -0
  101. data/spec/unit/agile_proxy/servers/api_spec.rb +31 -0
  102. data/spec/unit/agile_proxy/servers/request_spec_spec.rb +32 -0
  103. metadata +618 -0
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe AgileProxy::Handler do
4
+ let(:handler) { Class.new { include AgileProxy::Handler }.new }
5
+ it '#handle_request raises an error if not overridden' do
6
+ expect(handler.call(nil)).to eql([500, {}, 'The handler has not overridden the handle_request method!'])
7
+ end
8
+ end
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+
3
+ describe AgileProxy::ProxyHandler do
4
+ subject { AgileProxy::ProxyHandler.new }
5
+ let(:request) do
6
+ ActionDispatch::Request.new to_rack_env(
7
+ method: 'post',
8
+ url: 'http://example.test:8080/index?some=param',
9
+ headers: { 'Accept-Encoding' => 'gzip',
10
+ 'Cache-Control' => 'no-cache' },
11
+ body: 'Some body'
12
+ )
13
+ end
14
+
15
+ def request_for_url(url)
16
+ ActionDispatch::Request.new to_rack_env(
17
+ method: 'post',
18
+ url: url,
19
+ headers: { 'Accept-Encoding' => 'gzip',
20
+ 'Cache-Control' => 'no-cache' },
21
+ body: 'Some body'
22
+ )
23
+ end
24
+
25
+ describe '#handles_request?' do
26
+ context 'with non-whitelisted requests enabled' do
27
+ before do
28
+ expect(AgileProxy.config).to receive(:non_whitelisted_requests_disabled).and_return(false)
29
+ end
30
+ end
31
+ context 'with non-whitelisted requests disabled' do
32
+ before do
33
+ expect(AgileProxy.config).to receive(:non_whitelisted_requests_disabled).and_return(true)
34
+ end
35
+
36
+ it 'does not handle requests that are not white or black listed' do
37
+ expect(subject.send(:handles_request?, request)).to be_falsy
38
+ end
39
+
40
+ context 'a whitelisted host' do
41
+ context 'with a blacklisted path' do
42
+ before do
43
+ expect(AgileProxy.config).to receive(:path_blacklist) { ['/index'] }
44
+ end
45
+
46
+ it 'does not handle requests for blacklisted paths' do
47
+ req = request_for_url 'http://example.test:8080/index?some=param'
48
+ expect(subject.send(:handles_request?, req)).to be_falsy
49
+ end
50
+ end
51
+ context 'without a port' do
52
+ before do
53
+ expect(AgileProxy.config).to receive(:whitelist) { ['example.test'] }
54
+ end
55
+
56
+ it 'handles requests for the host without a port' do
57
+ req = request_for_url 'http://example.test'
58
+ expect(subject.send(:handles_request?, req)).to be_truthy
59
+ end
60
+
61
+ it 'handles requests for the host with a port' do
62
+ req = request_for_url 'http://example.test:8080'
63
+ expect(subject.send(:handles_request?, req)).to be_truthy
64
+ end
65
+ end
66
+
67
+ context 'with a port' do
68
+ before do
69
+ expect(AgileProxy.config).to receive(:whitelist) { ['example.test:8080'] }
70
+ end
71
+
72
+ it 'does not handle requests whitelisted for a specific port' do
73
+ req = request_for_url 'http://example.test'
74
+ expect(subject.send(:handles_request?, req)).to be_falsy
75
+ end
76
+
77
+ it 'handles requests for the host with a port' do
78
+ req = request_for_url 'http://example.test:8080'
79
+ expect(subject.send(:handles_request?, req)).to be_truthy
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ describe '#call' do
87
+ it 'returns nil if it does not handle the request' do
88
+ expect(subject).to receive(:handles_request?).and_return(false)
89
+ expect(subject.call(request.env)).to eql [404, {}, 'Not proxied']
90
+ end
91
+
92
+ context 'with a handled request' do
93
+ let(:response_header) do
94
+ header = Struct.new(:status, :raw).new
95
+ header.status = 200
96
+ header.raw = {}
97
+ header
98
+ end
99
+
100
+ let(:em_response) { double('response') }
101
+ let(:em_request) do
102
+ double('EM::HttpRequest', error: nil, response: em_response, response_header: response_header)
103
+ end
104
+
105
+ before do
106
+ allow(subject).to receive(:handles_request?).and_return(true)
107
+ allow(em_response).to receive(:force_encoding).and_return('The response body')
108
+ allow(EventMachine::HttpRequest).to receive(:new).and_return(em_request)
109
+ expect(em_request).to receive(:post).and_return(em_request)
110
+ end
111
+
112
+ it 'Should pass through a not allowed response' do
113
+ allow(response_header).to receive(:status).and_return(503)
114
+ expect(subject.call(request.env)).to eql [503, { 'Connection' => 'close' }, 'The response body']
115
+ end
116
+ it 'returns any error in the response' do
117
+ allow(em_request).to receive(:error).and_return('ERROR!')
118
+ expect(subject.call(request.env)).to eql([500, {}, "Request to #{request.url} failed with error: ERROR!"])
119
+ end
120
+
121
+ it 'returns a hashed response if the request succeeds' do
122
+ expect(subject.call(request.env)).to eql([200, { 'Connection' => 'close' }, 'The response body'])
123
+ end
124
+
125
+ it 'returns nil if both the error and response are for some reason nil' do
126
+ allow(em_request).to receive(:response).and_return(nil)
127
+ expect(subject.call(request.env)).to eql [404, {}, 'Not proxied']
128
+ end
129
+
130
+ it 'uses the timeouts defined in configuration' do
131
+ allow(AgileProxy.config).to receive(:proxied_request_inactivity_timeout).and_return(42)
132
+ allow(AgileProxy.config).to receive(:proxied_request_connect_timeout).and_return(24)
133
+ expect(EventMachine::HttpRequest).to receive(:new).with(request.url, inactivity_timeout: 42, connect_timeout: 24)
134
+ subject.call(request.env)
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe AgileProxy::RequestHandler do
4
+ subject { AgileProxy::RequestHandler.new }
5
+
6
+ it 'implements Handler' do
7
+ expect(subject).to be_a AgileProxy::Handler
8
+ end
9
+
10
+ context 'with stubbed handlers' do
11
+ let(:env) { to_rack_env(url: 'http://dummy.host.com/index.html') }
12
+ let(:stub_handler) { Class.new }
13
+ let(:proxy_handler) { Class.new }
14
+ let(:application_class) { Class.new }
15
+ let(:recordings_class) { Class.new }
16
+ let(:application) { double('Application', record_requests: false, recordings: recordings_class) }
17
+
18
+ before do
19
+ stub_const 'AgileProxy::StubHandler', stub_handler
20
+ stub_const 'AgileProxy::ProxyHandler', proxy_handler
21
+ stub_const 'AgileProxy::Application', application_class
22
+ allow(application_class).to receive(:where).and_return [application]
23
+ end
24
+
25
+ describe '#call' do
26
+ it 'returns error 500 if no handlers handle the request' do
27
+ expect_any_instance_of(stub_handler).to receive(:call).and_return [404, {}, 'It didnt work']
28
+ expect_any_instance_of(proxy_handler).to receive(:call).and_return [404, {}, 'It didnt work']
29
+ expect(subject.call(env)).to start_with [500, {}]
30
+ end
31
+
32
+ it 'returns 200 immediately if the stub handler handles the request' do
33
+ expect_any_instance_of(stub_handler).to receive(:call).with(env).and_return [200, {}, 'Some data']
34
+ expect_any_instance_of(proxy_handler).to_not receive(:call)
35
+ expect(subject.call(env)).to eql [200, {}, 'Some data']
36
+ end
37
+
38
+ it 'returns true if the proxy handler handles the request' do
39
+ expect_any_instance_of(stub_handler).to receive(:call).with(env).and_return [404, {}, 'Irrelevant']
40
+ expect_any_instance_of(proxy_handler).to receive(:call).with(env).and_return [200, {}, 'Some data']
41
+ expect(subject.call(env)).to eql [200, {}, 'Some data']
42
+ end
43
+
44
+ it 'Calls application.recordings.create if record_requests is true' do
45
+ allow(application).to receive(:record_requests).and_return true
46
+ expect(application.recordings).to receive(:create)
47
+ expect_any_instance_of(stub_handler).to receive(:call).with(env).and_return [200, {}, 'Some data']
48
+ expect_any_instance_of(proxy_handler).to_not receive(:call)
49
+ expect(subject.call(env)).to eql [200, {}, 'Some data']
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,154 @@
1
+ require 'spec_helper'
2
+
3
+ describe AgileProxy::StubHandler do
4
+ let(:route_not_found_response) { [404, { 'X-Cascade' => 'pass' }, ['Not Found']] }
5
+ let(:handler) { AgileProxy::StubHandler.new }
6
+ let(:request) do
7
+ request_for(
8
+ method: 'GET',
9
+ url: 'http://example.test:8080/index?some=param',
10
+ headers: { 'Accept-Encoding' => 'gzip',
11
+ 'Cache-Control' => 'no-cache' }
12
+ )
13
+ end
14
+ let(:application_class) { Class.new }
15
+ let(:request_spec_class) { Class.new }
16
+ let(:application) { application_class.new }
17
+
18
+ def request_for(options)
19
+ request = ActionDispatch::Request.new(to_rack_env(options))
20
+ request.params
21
+ request
22
+ end
23
+
24
+ before :each do
25
+ stub_const('AgileProxy::Application', application_class)
26
+ allow(application_class).to receive(:where).and_return application_class
27
+ allow(application_class).to receive(:first).and_return application
28
+ allow(application).to receive(:request_specs).and_return request_spec_class
29
+ end
30
+ describe 'With find_stub mocked' do
31
+
32
+ describe '#handle_request' do
33
+ it 'returns 404 if the request is not stubbed' do
34
+ stub = double('stub', http_method: 'GET', url: 'http://example.test:8080/index', conditions: {}, call: [404, {}, 'Not found'])
35
+ expect(request_spec_class).to receive(:where).and_return double('association', all: [stub])
36
+ expect(handler.call(to_rack_env(url: 'http://example.test:8080/index'))).to eql [404, {}, 'Not found']
37
+ end
38
+
39
+ it 'returns a response hash if the request is stubbed' do
40
+ stub = double('stub', http_method: 'GET', url: 'http://example.test:8080/index', conditions: {}, call: [200, { 'Content-Type' => 'application/json' }, 'Some content'])
41
+ expect(request_spec_class).to receive(:where).and_return double('association', all: [stub])
42
+ expect(handler.call(request.env)).to eql([200, { 'Content-Type' => 'application/json' }, 'Some content'])
43
+ end
44
+ it 'Passes on the correct parameters to the stub call method' do
45
+ stub = double('stub', http_method: 'GET', url: 'http://example.test:8080/index', conditions: {})
46
+ expect(request_spec_class).to receive(:where).and_return double('association', all: [stub])
47
+ body = request.body.read
48
+ request.body.rewind
49
+ expect(stub).to receive(:call).with({ some: 'param' }, { 'Accept-Encoding' => 'gzip', 'Cache-Control' => 'no-cache' }, body).and_return([200, { 'Content-Type' => 'application/json' }, 'Some Content'])
50
+ expect(handler.call(request.env)).to eql([200, { 'Content-Type' => 'application/json' }, 'Some Content'])
51
+
52
+ end
53
+ describe 'Routing patterns' do
54
+ describe 'With a simple GET match on the root of a domain' do
55
+ let(:request_stub) { double 'stub', url: 'http://example.com', http_method: 'GET', conditions: {} }
56
+ before :each do
57
+ allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://example.com%').and_return double('association', all: [request_stub])
58
+ allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://subdomain.example.com%').and_return double('association', all: [])
59
+ allow(request_stub).to receive(:call).and_return([200, {}, ''])
60
+ end
61
+ it 'Should match with a get on the same domain but not with a post or a different domain' do
62
+ expect(handler.call(request_for(url: 'http://example.com').env)).to eql([200, {}, ''])
63
+ expect(handler.call(request_for(url: 'http://example.com/').env)).to eql([200, {}, ''])
64
+ expect(handler.call(request_for(url: 'http://example.com/', method: 'POST').env)).to eql route_not_found_response
65
+ expect(handler.call(request_for(url: 'http://subdomain.example.com/').env)).to eql route_not_found_response
66
+ end
67
+
68
+ end
69
+ describe 'With a simple GET match inside a domain' do
70
+ let(:request_stub) { double 'stub for simple get inside a domain', url: 'http://example.com/index', http_method: 'GET', conditions: {} }
71
+ before :each do
72
+ allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://example.com%').and_return double('association', all: [request_stub])
73
+ allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://subdomain.example.com%').and_return double('association', all: [])
74
+ expect(request_stub).to receive(:call).and_return([200, {}, ''])
75
+ end
76
+ it 'Should match with a get on the same domain but not with a post or a different domain' do
77
+ expect(handler.call(request_for(url: 'http://example.com/index').env)).to eql([200, {}, ''])
78
+ expect(handler.call(request_for(method: 'POST', url: 'http://example.com/index').env)).to eql route_not_found_response
79
+ expect(handler.call(request_for(url: 'http://subdomain.example.com/index').env)).to eql route_not_found_response
80
+ expect(handler.call(request_for(url: 'http://example.com/').env)).to eql route_not_found_response
81
+ expect(handler.call(request_for(url: 'http://example.com').env)).to eql route_not_found_response
82
+ end
83
+
84
+ end
85
+ describe 'With a simple POST match on the root of a domain' do
86
+ let(:request_stub) { double 'stub', url: 'http://example.com', http_method: 'POST', conditions: {} }
87
+ before :each do
88
+ allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://example.com%').and_return double('association', all: [request_stub])
89
+ allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://subdomain.example.com%').and_return double('association', all: [])
90
+ allow(request_stub).to receive(:call).and_return([200, {}, ''])
91
+ end
92
+ it 'Should match with a post on the same domain but not with a get or a post on a different domain' do
93
+ expect(handler.call(request_for(method: 'POST', url: 'http://example.com').env)).to eql([200, {}, ''])
94
+ expect(handler.call(request_for(method: 'POST', url: 'http://example.com/').env)).to eql([200, {}, ''])
95
+ expect(handler.call(request_for(url: 'http://example.com/').env)).to eql route_not_found_response
96
+ expect(handler.call(request_for(method: 'POST', url: 'http://subdomain.example.com/').env)).to eql route_not_found_response
97
+ end
98
+
99
+ end
100
+ describe 'With a more complex route with conditions inside a domain' do
101
+ let(:request_stub) { double 'stub for complex route inside a domain', url: 'http://example.com/users/:user_id/index', http_method: 'GET', conditions: { user_id: '1' }.to_json }
102
+ before :each do
103
+ allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://example.com%').and_return double('association', all: [request_stub])
104
+ expect(request_stub).to receive(:call).and_return([200, {}, ''])
105
+ end
106
+ it 'Should match with a get on the same domain but not with a post or a different domain' do
107
+ expect(handler.call(request_for(url: 'http://example.com/users/1/index').env)).to eql([200, {}, ''])
108
+ expect(handler.call(request_for(url: 'http://example.com/users/2/index').env)).to eql route_not_found_response
109
+ expect(handler.call(request_for(method: 'POST', url: 'http://example.com/users/1/index').env)).to eql route_not_found_response
110
+ expect(handler.call(request_for(url: 'http://example.com/users/1/').env)).to eql route_not_found_response
111
+ expect(handler.call(request_for(url: 'http://example.com/users/1').env)).to eql route_not_found_response
112
+ end
113
+ end
114
+ describe 'With a more complex route with conditions including query params inside a domain' do
115
+ let(:request_stub) { double 'stub for complex route inside a domain', url: 'http://example.com/users/:user_id/index', http_method: 'GET', conditions: { user_id: '1', extra_1: 'extra_1', extra_2: 'extra_2' }.to_json }
116
+ before :each do
117
+ allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://example.com%').and_return double('association', all: [request_stub])
118
+ allow(request_stub).to receive(:call).and_return([200, {}, ''])
119
+ end
120
+ it 'Should match with a get on the same domain but not with a post or a different domain' do
121
+ expect(handler.call(request_for(url: 'http://example.com/users/1/index?extra_1=extra_1&extra_2=extra_2').env)).to eql([200, {}, ''])
122
+ expect(handler.call(request_for(url: 'http://example.com/users/1/index?some_other=2&extra_1=extra_1&extra_2=extra_2').env)).to eql([200, {}, ''])
123
+ expect(handler.call(request_for(url: 'http://example.com/users/2/index').env)).to eql route_not_found_response
124
+ expect(handler.call(request_for(method: 'POST', url: 'http://example.com/users/1/index').env)).to eql route_not_found_response
125
+ expect(handler.call(request_for(url: 'http://example.com/users/1/').env)).to eql route_not_found_response
126
+ expect(handler.call(request_for(url: 'http://example.com/users/1').env)).to eql route_not_found_response
127
+ end
128
+ end
129
+
130
+ # it 'should match regexps' do
131
+ # expect(AgileProxy::RequestSpec.new(:url => "http:\/\/.+\.com", :method => :post, :regex => true).
132
+ # matches?('POST', 'http://example.com')).to be
133
+ # expect(AgileProxy::RequestSpec.new(:url => "http:\/\/.+\.co\.uk", :method => :get, :regex => true).
134
+ # matches?('GET', 'http://example.com')).to_not be
135
+ # end
136
+ #
137
+ # it 'should match up to but not including query strings' do
138
+ # stub = AgileProxy::RequestSpec.new(:url => 'http://example.com/foo/bar/')
139
+ # expect(stub.matches?('GET', 'http://example.com/foo/')).to_not be
140
+ # expect(stub.matches?('GET', 'http://example.com/foo/bar/')).to be
141
+ # expect(stub.matches?('GET', 'http://example.com/foo/bar/?baz=bap')).to be
142
+ # end
143
+ # it 'Should match routes using pattern matching' do
144
+ # stub = AgileProxy::RequestSpec.new(:url => "http://example.com/users/:user_id/application/:application_id")
145
+ # expect(stub.matches?('GET', 'http://example.com/users/user_id/application/application_id')).to be
146
+ # expect(stub.matches?('GET', 'http://example.com/users/user_id/somethingelse/application_id')).not_to be
147
+ # end
148
+
149
+ end
150
+ end
151
+
152
+ end
153
+
154
+ end
File without changes
@@ -0,0 +1,45 @@
1
+ require 'agile_proxy/model/request_spec'
2
+ describe AgileProxy::RequestSpec do
3
+ let(:response_class) do
4
+ Class.new do
5
+ def initialize(config = {})
6
+ @config = config
7
+ end
8
+ attr_accessor :config
9
+
10
+ end
11
+ end
12
+ let(:mock_response) { response_class.new }
13
+ before :each do
14
+ stub_const('AgileProxy::Response', response_class)
15
+ end
16
+ it 'Should allow a nested response' do
17
+ subject.should accept_nested_attributes_for(:response)
18
+ end
19
+ it 'Should belong to a user' do
20
+ expect(subject).to belong_to(:user)
21
+ end
22
+ it 'Should belong to an application' do
23
+ expect(subject).to belong_to(:application)
24
+ end
25
+ it 'Should belong to a response' do
26
+ expect(subject).to belong_to(:response)
27
+ end
28
+
29
+ describe 'Interface for the stub handler' do
30
+ context '#call (without #and_return)' do
31
+ let(:subject) { AgileProxy::RequestSpec.new(url: 'url') }
32
+ it 'returns a 204 empty response' do
33
+ expect(subject).to receive(:response).and_return nil
34
+ expect(subject.call({}, {}, nil)).to eql [204, { 'Content-Type' => 'text/plain' }, '']
35
+ end
36
+ end
37
+ context '#call With conditions' do
38
+ let(:subject) { AgileProxy::RequestSpec.new(url: 'url', conditions: '{"a": 1, "b": 2}') }
39
+ it 'returns a the correct json' do
40
+ expect(subject.conditions_json).to eql('a' => 1, 'b' => 2)
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,38 @@
1
+ require 'em-synchrony'
2
+ require 'spec_helper'
3
+ describe AgileProxy::Response do
4
+ it 'Should have many requests ' do
5
+ expect(subject).to have_many(:request_specs)
6
+ end
7
+ it 'Should serialize the headers in json format' do
8
+ expect(subject).to serialize(:headers)
9
+ end
10
+ describe 'With a configured delay' do
11
+ before :each do
12
+ subject.delay = 0.5
13
+ subject.content = 'Test'
14
+ subject.content_type = 'text/plain'
15
+ end
16
+ it 'Should respond with a delay using the Em::Synchrony.sleep method' do
17
+ expect(EventMachine::Synchrony).to receive(:sleep).with(0.5)
18
+ expect(subject.to_rack({}, {}, '')).to eql([200, { 'Content-Type' => 'text/plain' }, 'Test'])
19
+ end
20
+
21
+ end
22
+ describe 'Using templates' do
23
+ describe 'Using text' do
24
+ before :each do
25
+ subject.is_template = true
26
+ subject.content = 'Hello {{name}}'
27
+ subject.content_type = 'text/plain'
28
+ end
29
+ it 'Should pass the params to the template and the output should be correct' do
30
+ expect(subject.to_rack({ name: 'World' }, {}, '')).to eql([200, { 'Content-Type' => 'text/plain' }, 'Hello World'])
31
+ end
32
+ it 'Should deal with if a parameter is missing' do
33
+ expect(subject.to_rack({}, {}, '')).to eql([500, { 'Content-Type' => 'text/plain' }, "Missing var or method 'name' in data."])
34
+ end
35
+ end
36
+ end
37
+
38
+ end