agile-proxy 0.1.18 → 0.1.19

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: afae09513ecf329dc7770af13d4813e92582a935
4
- data.tar.gz: 74c3955d0f8677be151e7229ca7afd13867f0e2a
3
+ metadata.gz: 806cb5ed2d0d286c13adb4d4ab3dc7bcad28917d
4
+ data.tar.gz: ab62ffd2e6b2b11908314548d0598599619cd998
5
5
  SHA512:
6
- metadata.gz: 3ba2c19049b3b57a8b76ab09480122d5996ff32195bc6dc569a9400884a2fb91d668cc5e97753c2a57969c89eb97ae202fd3c096293437623068cc2985b14e88
7
- data.tar.gz: b3d8fb2740d5f2be8184c4a532f7a51db14079d1649153f3eeaa8a19a837cfa85245feaa4426b1cc9f3648f86c952639b3e80f43802d516ab529d5dc9a316ce0
6
+ metadata.gz: 99266a1f6aab8c91a2fa1ae70bc7a357a3feb5193ef955da264e953827103a5c39f5b21929a54ff52dc5fd1ce8b80738bf6bdbb20899197bf56d2f9090d855fc
7
+ data.tar.gz: a778c6e2c5b72bf83c714a5a951aad3d0d34a6f104f0b9e3f90fb78fbe9b34769356d15f4d1e9f5af46be7f4c0aa8d9cae123241c22002530cd9f7d2af194656
data/README.md CHANGED
@@ -119,3 +119,6 @@ v0.1.13 Upgraded activerecord and other gems to later versions
119
119
  v0.1.14 - Increased pagination size by default to 50 on stubs until I add the client side code
120
120
  v0.1.15 - 0.1.17 - No functionality change, these were just to try and please travis
121
121
  v0.1.18 - Fixed issue with integration test which was showing up now that travis is working again
122
+ v0.1.19 - Recordings now record the request spec id.
123
+ Recordings can now be accessed via /request_specs/:request_spec_id/recordings to provide recordings specific to the request spec
124
+
@@ -0,0 +1,52 @@
1
+ module AgileProxy
2
+ module Api
3
+ #
4
+ # = A grape API for recordings
5
+ #
6
+ # If the application is set to allow recordings, each HTTP request and response passing
7
+ # through the proxy server will be recorded.
8
+ #
9
+ # This API allows access to those recordings via REST
10
+ #
11
+ class RequestSpecRecordings < Grape::API
12
+ include Grape::Kaminari
13
+ helpers do
14
+ # Convenient access to the record specified in the id parameter
15
+ def record
16
+ current_application.recordings.where(request_spec_id: params[:request_spec_id], id: params[:id]).first
17
+ end
18
+
19
+ def default_json_spec
20
+ {}
21
+ end
22
+ end
23
+
24
+ resource :recordings do
25
+ desc 'List all recordings made for the request spec'
26
+ paginate per_page: 20, max_per_page: 200
27
+ get do
28
+ authenticate!
29
+ scope = current_application.recordings.where({request_spec_id: params[:request_spec_id]})
30
+ { recordings: paginate(scope).as_json(default_json_spec), total: scope.count }
31
+ end
32
+ desc 'Delete all recordings for the application'
33
+ delete do
34
+ authenticate!
35
+ scope = current_application.recordings
36
+ scope.destroy_all request_spec_id: params[:request_spec_id]
37
+ { recordings: [], total: 0 }
38
+ end
39
+ desc 'Get a recording by id'
40
+ get ':id' do
41
+ authenticate!
42
+ record.as_json(default_json_spec)
43
+ end
44
+ delete ':id' do
45
+ authenticate!
46
+ record.tap(&:destroy).as_json(default_json_spec)
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+ end
@@ -79,6 +79,7 @@ module AgileProxy
79
79
  authenticate!
80
80
  record.tap(&:destroy).as_json(default_json_spec)
81
81
  end
82
+
82
83
  end
83
84
  end
84
85
  end
@@ -1,4 +1,5 @@
1
1
  require_relative 'request_specs'
2
+ require_relative 'request_spec_recordings'
2
3
  require_relative 'applications'
3
4
  require_relative 'recordings'
4
5
  module AgileProxy
@@ -34,6 +35,9 @@ module AgileProxy
34
35
  namespace '/applications/:application_id' do
35
36
  mount Api::Recordings
36
37
  mount Api::RequestSpecs
38
+ namespace '/request_specs/:request_spec_id' do
39
+ mount Api::RequestSpecRecordings
40
+ end
37
41
  end
38
42
  end
39
43
  end
@@ -42,7 +42,8 @@ module AgileProxy
42
42
  request_method: request.request_method,
43
43
  response_headers: rack_response[1],
44
44
  response_body: rack_response[2],
45
- response_status: rack_response[0]
45
+ response_status: rack_response[0],
46
+ request_spec_id: env['agile_proxy.request_spec_id']
46
47
  end
47
48
  rack_response
48
49
  end
@@ -62,6 +62,7 @@ module AgileProxy
62
62
  route_spec = {
63
63
  path => proc do |router_env|
64
64
  AgileProxy.log(:info, "agile-proxy: STUB #{method} for '#{request.url}'")
65
+ router_env['agile_proxy.request_spec_id'] = spec.id
65
66
  spec.call(HashWithIndifferentAccess.new(router_env['action_dispatch.request.path_parameters'].merge(router_env['action_dispatch.request.query_parameters']).merge(router_env['action_dispatch.request.request_parameters'])), headers, body)
66
67
  end
67
68
  }
@@ -40,14 +40,8 @@ module AgileProxy
40
40
  output_status_code = status_code
41
41
  if is_template
42
42
  data = OpenStruct.new input_params
43
- begin
44
- template = Tilt['handlebars'].new { output_content }
45
- output_content = template.render data
46
- rescue ::FlavourSaver::UnknownHelperException => ex
47
- method = ex.message.match(/Template context doesn't respond to method "(.*)"/)[1]
48
- output_content = "Missing var or method '#{method}' in data."
49
- output_status_code = 500
50
- end
43
+ template = Tilt['handlebars'].new { output_content }
44
+ output_content = template.render data
51
45
  end
52
46
  EventMachine::Synchrony.sleep(delay) if delay > 0
53
47
  [output_status_code, output_headers, output_content]
@@ -2,5 +2,5 @@
2
2
  #
3
3
  # The Agile Proxy module is a common namespace for all classes / sub modules.
4
4
  module AgileProxy
5
- VERSION = '0.1.18'
5
+ VERSION = '0.1.19'
6
6
  end
@@ -4,10 +4,22 @@ module AgileProxy
4
4
  module Integration
5
5
  # A helper for 'request spec' integration tests
6
6
  module RequestSpecHelper
7
+ class Spec
8
+ attr_accessor :url, :name, :body
9
+ def self.for(url, name, body)
10
+ obj = new
11
+ obj.url=url + '/'
12
+ obj.name = name
13
+ obj.body = body
14
+ obj.body = obj.body.with_indifferent_access if obj.body.is_a? Hash
15
+ obj
16
+ end
17
+ end
18
+
7
19
  def load_small_set_of_request_specs(options = {})
8
20
  let(:recordings_resource) { RestClient::Resource.new "http://localhost:#{api_port}/api/v1/users/1/applications/#{@recording_application_id}/recordings", headers: { content_type: 'application/json' } }
9
21
  before :context do
10
-
22
+ @stubs_with_recordings = []
11
23
  def configure_applications
12
24
  application_resource.delete # Delete all applications
13
25
  @non_recording_application_id = JSON.parse(application_resource.post user_id: 1, name: 'Non recording app', username: 'anonymous', password: 'password')['id']
@@ -21,8 +33,9 @@ module AgileProxy
21
33
 
22
34
  def create_request_spec(attrs)
23
35
  non_recording_resource.post ActiveSupport::JSON.encode attrs
24
- recording_resource.post ActiveSupport::JSON.encode attrs
36
+ recording_response = JSON.parse recording_resource.post(ActiveSupport::JSON.encode attrs).body
25
37
  direct_resource.post ActiveSupport::JSON.encode attrs
38
+ recording_response
26
39
  end
27
40
 
28
41
  def non_recording_resource
@@ -37,26 +50,27 @@ module AgileProxy
37
50
  @__direct_resource ||= RestClient::Resource.new "http://localhost:#{api_port}/api/v1/users/1/applications/#{@direct_application_id}/request_specs", headers: { content_type: 'application/json' }
38
51
  end
39
52
 
53
+
40
54
  # Delete all first
41
55
  configure_applications
42
56
  # Now, add some stubs via the REST interface
43
57
  [@http_url, @https_url, @http_url_no_proxy, @https_url_no_proxy].each do |url|
44
- create_request_spec url: "#{url}/index.html", response: { content_type: 'text/html', content: '<html><body>This Is An Older Mock</body></html>' } #This is intentional - the system should always use the latest
45
- create_request_spec url: "#{url}/index.html", response: { content_type: 'text/html', content: '<html><body>Mocked Content</body></html>' }
46
- create_request_spec url: "#{url}/api/forums", response: { content_type: 'application/json', content: JSON.pretty_generate(forums: [], total: 0) }
47
- create_request_spec url: "#{url}/api/forums", http_method: 'POST', response: { content_type: 'application/json', content: '{"created": true}' }
48
- create_request_spec url: "#{url}/api/forums/:forum_id/:post_id", response: { content_type: 'text/html', content: '<html><body><h1>Sorted By: {{sort}}</h1><h2>{{forum_id}}</h2><h3>{{post_id}}</h3></body></html>', is_template: true }
49
- create_request_spec url: "#{url}/api/forums/:forum_id/:post_id", http_method: 'PUT', response: { content_type: 'application/json', content: '{"updated": true}' }
50
- create_request_spec url: "#{url}/api/forums/:forum_id/:post_id", http_method: 'DELETE', response: { content_type: 'application/json', content: '{"deleted": true}' }
51
- create_request_spec url: "#{url}/api/forums/:forum_id/:post_id", conditions: '{"post_id": "special"}', response: { content_type: 'text/html', content: '<html><body><h1>Sorted By: {{sort}}</h1><h2>{{forum_id}}</h2><h3>{{post_id}}</h3><p>This is a special response</p></body></html>', is_template: true }
52
- create_request_spec url: "#{url}/api/forums/:forum_id/:post_id", conditions: '{"post_id": "special", "sort": "eversospecial"}', response: { content_type: 'text/html', content: '<html><body><h1>Sorted By: {{sort}}</h1><h2>{{forum_id}}</h2><h3>{{post_id}}</h3><p>This is an ever so special response</p></body></html>', is_template: true }
53
- create_request_spec url: "#{url}/api/forums/:forum_id", http_method: 'POST',response: { content_type: 'text/html', content: '<html><body><h1></h1><h2>WRONG RESULT</h2><h3>{{forum_id}}</h3><p>This is an incorrect result probably because the conditions are being ignored ?</p></body></html>'}
54
- create_request_spec url: "#{url}/api/forums/:forum_id", http_method: 'POST', conditions: '{"posted_var":"special_value"}', response: { content_type: 'text/html', content: '<html><body><h1></h1><h2>{{posted_var}}</h2><h3>{{forum_id}}</h3><p>This should get data from the POSTed data</p></body></html>', is_template: true }
55
- create_request_spec url: "#{url}/api/forums/:forum_id/posts", response: { content_type: 'application/json', content: JSON.pretty_generate(posts: [
58
+ @stubs_with_recordings.push Spec.for url, 'index_old', create_request_spec(url: "#{url}/index.html", response: { content_type: 'text/html', content: '<html><body>This Is An Older Mock</body></html>' }) #This is intentional - the system should always use the latest
59
+ @stubs_with_recordings.push Spec.for url, 'index', create_request_spec(url: "#{url}/index.html", response: { content_type: 'text/html', content: '<html><body>Mocked Content</body></html>' })
60
+ @stubs_with_recordings.push Spec.for url, 'api_forums', create_request_spec(url: "#{url}/api/forums", response: { content_type: 'application/json', content: JSON.pretty_generate(forums: [], total: 0) })
61
+ @stubs_with_recordings.push Spec.for url, 'api_forums_post', create_request_spec(url: "#{url}/api/forums", http_method: 'POST', response: { content_type: 'application/json', content: '{"created": true}' })
62
+ @stubs_with_recordings.push Spec.for url, 'api_forum_post', create_request_spec(url: "#{url}/api/forums/:forum_id/:post_id", response: { content_type: 'text/html', content: '<html><body><h1>Sorted By: {{sort}}</h1><h2>{{forum_id}}</h2><h3>{{post_id}}</h3></body></html>', is_template: true })
63
+ @stubs_with_recordings.push Spec.for url, 'api_forum_post_put', create_request_spec(url: "#{url}/api/forums/:forum_id/:post_id", http_method: 'PUT', response: { content_type: 'application/json', content: '{"updated": true}' })
64
+ @stubs_with_recordings.push Spec.for url, 'api_forum_post_delete', create_request_spec(url: "#{url}/api/forums/:forum_id/:post_id", http_method: 'DELETE', response: { content_type: 'application/json', content: '{"deleted": true}' })
65
+ @stubs_with_recordings.push Spec.for url, 'api_forum_post_special', create_request_spec(url: "#{url}/api/forums/:forum_id/:post_id", conditions: '{"post_id": "special"}', response: { content_type: 'text/html', content: '<html><body><h1>Sorted By: {{sort}}</h1><h2>{{forum_id}}</h2><h3>{{post_id}}</h3><p>This is a special response</p></body></html>', is_template: true })
66
+ @stubs_with_recordings.push Spec.for url, 'api_forum_post_ever_so_special', create_request_spec(url: "#{url}/api/forums/:forum_id/:post_id", conditions: '{"post_id": "special", "sort": "eversospecial"}', response: { content_type: 'text/html', content: '<html><body><h1>Sorted By: {{sort}}</h1><h2>{{forum_id}}</h2><h3>{{post_id}}</h3><p>This is an ever so special response</p></body></html>', is_template: true })
67
+ @stubs_with_recordings.push Spec.for url, 'api_forum_update', create_request_spec(url: "#{url}/api/forums/:forum_id", http_method: 'POST',response: { content_type: 'text/html', content: '<html><body><h1></h1><h2>WRONG RESULT</h2><h3>{{forum_id}}</h3><p>This is an incorrect result probably because the conditions are being ignored ?</p></body></html>'})
68
+ @stubs_with_recordings.push Spec.for url, 'api_forum_update_special', create_request_spec(url: "#{url}/api/forums/:forum_id", http_method: 'POST', conditions: '{"posted_var":"special_value"}', response: { content_type: 'text/html', content: '<html><body><h1></h1><h2>{{posted_var}}</h2><h3>{{forum_id}}</h3><p>This should get data from the POSTed data</p></body></html>', is_template: true })
69
+ @stubs_with_recordings.push Spec.for url, 'api_forums_post', create_request_spec(url: "#{url}/api/forums/:forum_id/posts", response: { content_type: 'application/json', content: JSON.pretty_generate(posts: [
56
70
  { forum_id: '{{forum_id}}', subject: 'My first post' },
57
71
  { forum_id: '{{forum_id}}', subject: 'My second post' },
58
72
  { forum_id: '{{forum_id}}', subject: 'My third post' }
59
- ], total: 3), is_template: true }
73
+ ], total: 3), is_template: true })
60
74
  end
61
75
  end
62
76
  before :each do
@@ -3,6 +3,7 @@ require 'integration_spec_helper'
3
3
  # require 'spec_helper'
4
4
  require 'agile_proxy'
5
5
  require 'resolv'
6
+ require 'rest_client'
6
7
 
7
8
  shared_examples_for 'a proxy server' do |options = {}|
8
9
  if options.key?(:recording) && options[:recording]
@@ -32,15 +33,32 @@ shared_examples_for 'a proxy server' do |options = {}|
32
33
  end
33
34
 
34
35
  shared_examples_for 'a request stub' do |options = {}|
36
+ recording = false
35
37
  if options.key?(:recording) && options[:recording]
38
+ recording = true
36
39
  after :each do
37
40
  data = recordings_resource.get
38
41
  count = JSON.parse(data)['total']
39
42
  expect(count).to eql(1)
40
43
  end
41
44
  end
45
+ def find_stub(client, name)
46
+ @stubs_with_recordings.select { |stub| stub.url == client.url_prefix.to_s && stub.name == name}.first
47
+ end
48
+ def rest_client_for_stub(stub)
49
+ RestClient::Resource.new("http://localhost:#{api_port}/api/v1/users/1/applications/#{@recording_application_id}/request_specs/#{stub.body[:id]}/recordings", content_type: :json )
50
+ end
51
+ def recordings_for(name)
52
+ stub = find_stub(http, name)
53
+ JSON.parse(rest_client_for_stub(stub).get).with_indifferent_access
54
+ end
55
+ def recordings_matcher_for(name, path)
56
+ stub = find_stub(http, name)
57
+ {recordings: a_collection_containing_exactly(a_hash_including request_body: '', request_url: "#{http.url_prefix}#{path.gsub(/^\//, '')}", request_method: 'GET', request_spec_id: stub.body[:id])}
58
+ end
42
59
  it 'should stub GET requests' do
43
60
  expect(http.get('/index.html').body).to eql '<html><body>Mocked Content</body></html>'
61
+ expect(recordings_for 'index').to include(recordings_matcher_for('index', '/index.html')) if recording
44
62
  end
45
63
 
46
64
  it 'should stub GET response statuses' do
@@ -52,6 +70,7 @@ shared_examples_for 'a request stub' do |options = {}|
52
70
  expect(ActiveSupport::JSON.decode(resp.body).symbolize_keys).to eql forums: [], total: 0
53
71
  expect(resp.status).to eql 200
54
72
  expect(resp.headers['Content-Type']).to eql 'application/json'
73
+ expect(recordings_for 'api_forums').to include(recordings_matcher_for('api_forums', '/api/forums')) if recording
55
74
  end
56
75
 
57
76
  it 'Should get the mocked content with parameter substitution for the /api/forums/:forum_id/posts url' do
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+ require_relative 'common_helper'
3
+ require 'rack/test'
4
+
5
+ describe AgileProxy::Api::RequestSpecRecordings, api_test: true do
6
+ include Rack::Test::Methods
7
+ include AgileProxy::Test::Api::Common
8
+ let(:applications_assoc_class) do
9
+ Class.new do
10
+ end
11
+ end
12
+ let(:recordings_assoc_class) do
13
+ Class.new do
14
+ def self.destroy_all
15
+ end
16
+ end
17
+ end
18
+ let(:application_instance) { applications_assoc_class.new }
19
+
20
+ before :each do
21
+ expect(current_user).to receive(:applications).and_return(applications_assoc_class)
22
+ expect(applications_assoc_class).to receive(:where).with(id: '1').and_return applications_assoc_class
23
+ expect(applications_assoc_class).to receive(:first).and_return application_instance
24
+ expect(application_instance).to receive(:recordings).and_return recordings_assoc_class
25
+
26
+ end
27
+ describe 'GET /users/1/applications/1/recordings' do
28
+ let(:recordings_result) do
29
+ [
30
+ {
31
+ application_id: 1,
32
+ request_headers: '{}',
33
+ request_body: '',
34
+ request_url: 'http://www.test.com/1',
35
+ request_method: 'GET',
36
+ response_headers: '{}',
37
+ response_body: '{}',
38
+ response_status: '200',
39
+ request_spec_id: 2
40
+ }.stringify_keys,
41
+ {
42
+ application_id: 1,
43
+ request_headers: '{}',
44
+ request_body: '',
45
+ request_url: 'http://www.test.com/2',
46
+ request_method: 'GET',
47
+ response_headers: '{}',
48
+ response_body: '{}',
49
+ response_status: '200',
50
+ request_spec_id: 2
51
+ }.stringify_keys,
52
+ {
53
+ application_id: 1,
54
+ request_headers: '{}',
55
+ request_body: '',
56
+ request_url: 'http://www.test.com/3',
57
+ request_method: 'GET',
58
+ response_headers: '{}',
59
+ response_body: '{}',
60
+ response_status: '200',
61
+ request_spec_id: 2
62
+ }.stringify_keys
63
+ ]
64
+ end
65
+ before :each do
66
+ expect(recordings_assoc_class).to receive(:where).with(request_spec_id: '2').and_return recordings_assoc_class
67
+ expect(recordings_assoc_class).to receive(:page).and_return recordings_assoc_class
68
+ expect(recordings_assoc_class).to receive(:per).and_return recordings_assoc_class
69
+ expect(recordings_assoc_class).to receive(:padding).and_return recordings_assoc_class
70
+ expect(recordings_assoc_class).to receive(:total_count).and_return 3
71
+ expect(recordings_assoc_class).to receive(:num_pages).and_return 1
72
+ expect(recordings_assoc_class).to receive(:current_page).and_return 1
73
+ expect(recordings_assoc_class).to receive(:next_page).and_return 1
74
+ expect(recordings_assoc_class).to receive(:prev_page).and_return 1
75
+ expect(recordings_assoc_class).to receive(:count).and_return 3
76
+ expect(recordings_assoc_class).to receive(:as_json).with({}).and_return recordings_result
77
+
78
+ end
79
+ it 'returns a populated array of recordings' do
80
+ get '/v1/users/1/applications/1/request_specs/2/recordings'
81
+ expect(last_response.status).to eq(200)
82
+ expect(JSON.parse(last_response.body)).to eq('recordings' => recordings_result, 'total' => 3)
83
+ end
84
+ end
85
+ describe 'DELETE /users/1/applications/1/request_specs/2/recordings' do
86
+ it 'Should destroy all applications for the request spec' do
87
+ expect(recordings_assoc_class).to receive(:destroy_all).with(request_spec_id: '2')
88
+ delete '/v1/users/1/applications/1/request_specs/2/recordings'
89
+ expect(last_response.status).to eq(200)
90
+ expect(JSON.parse(last_response.body).symbolize_keys).to eql(recordings: [], total: 0)
91
+ end
92
+ end
93
+ describe '/users/1/applications/1/request_specs/2/recordings/10' do
94
+ let(:recording_instance) { recordings_assoc_class.new }
95
+ let(:persisted_attributes) { { request_headers: '', response_headers: {} } }
96
+ before :each do
97
+ expect(recordings_assoc_class).to receive(:where).with(request_spec_id: '2', id: '10').and_return recordings_assoc_class
98
+ expect(recordings_assoc_class).to receive(:first).and_return recording_instance
99
+ expect(recording_instance).to receive(:as_json).with({}).and_return persisted_attributes
100
+ end
101
+ context 'GET' do
102
+ it 'Should fetch an individual recording' do
103
+ get '/v1/users/1/applications/1/request_specs/2/recordings/10'
104
+ expect(last_response.status).to eq(200)
105
+ expect(JSON.parse(last_response.body).symbolize_keys).to eql(persisted_attributes)
106
+
107
+ end
108
+ end
109
+ context 'DELETE' do
110
+ it 'Should delete an individual recording' do
111
+ expect(recording_instance).to receive(:destroy)
112
+ delete '/v1/users/1/applications/1/request_specs/2/recordings/10'
113
+ expect(last_response.status).to eq(200)
114
+ expect(JSON.parse(last_response.body).symbolize_keys).to eql(persisted_attributes)
115
+ end
116
+ end
117
+ end
118
+
119
+ end
@@ -8,7 +8,7 @@ describe AgileProxy::RequestHandler do
8
8
  end
9
9
 
10
10
  context 'with stubbed handlers' do
11
- let(:env) { to_rack_env(url: 'http://dummy.host.com/index.html') }
11
+ let(:env) { to_rack_env(url: 'http://dummy.host.com/index.html').merge('agile_proxy.request_spec_id' => 8) }
12
12
  let(:stub_handler) { Class.new }
13
13
  let(:proxy_handler) { Class.new }
14
14
  let(:application_class) { Class.new }
@@ -41,9 +41,9 @@ describe AgileProxy::RequestHandler do
41
41
  expect(subject.call(env)).to eql [200, {}, 'Some data']
42
42
  end
43
43
 
44
- it 'Calls application.recordings.create if record_requests is true' do
44
+ it 'Calls application.recordings.create with a reference to the stub if record_requests is true' do
45
45
  allow(application).to receive(:record_requests).and_return true
46
- expect(application.recordings).to receive(:create)
46
+ expect(application.recordings).to receive(:create).with(a_hash_including request_spec_id: 8)
47
47
  expect_any_instance_of(stub_handler).to receive(:call).with(env).and_return [200, {}, 'Some data']
48
48
  expect_any_instance_of(proxy_handler).to_not receive(:call)
49
49
  expect(subject.call(env)).to eql [200, {}, 'Some data']
@@ -31,18 +31,28 @@ describe AgileProxy::StubHandler do
31
31
 
32
32
  describe '#handle_request' do
33
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_json: {}, call: [404, {}, 'Not found'])
34
+ stub = double('stub', http_method: 'GET', url: 'http://example.test:8080/index', conditions_json: {}, call: [404, {}, 'Not found'], id: 5)
35
35
  expect(request_spec_class).to receive(:where).and_return double('association', all: [stub])
36
36
  expect(handler.call(to_rack_env(url: 'http://example.test:8080/index'))).to eql [404, {}, 'Not found']
37
37
  end
38
38
 
39
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_json: {}, call: [200, { 'Content-Type' => 'application/json' }, 'Some content'])
40
+ stub = double('stub', http_method: 'GET', url: 'http://example.test:8080/index', conditions_json: {}, call: [200, { 'Content-Type' => 'application/json' }, 'Some content'], id: 5)
41
41
  expect(request_spec_class).to receive(:where).and_return double('association', all: [stub])
42
42
  expect(handler.call(request.env)).to eql([200, { 'Content-Type' => 'application/json' }, 'Some content'])
43
43
  end
44
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_json: {})
45
+ stub = double('stub', http_method: 'GET', url: 'http://example.test:8080/index', conditions_json: {}, id: 5)
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
+ expect(request.env).to include('agile_proxy.request_spec_id' => stub.id)
52
+
53
+ end
54
+ it 'should store the id of the request spec in the rack environment when call is called' do
55
+ stub = double('stub', http_method: 'GET', url: 'http://example.test:8080/index', conditions_json: {}, id: 5)
46
56
  expect(request_spec_class).to receive(:where).and_return double('association', all: [stub])
47
57
  body = request.body.read
48
58
  request.body.rewind
@@ -52,7 +62,7 @@ describe AgileProxy::StubHandler do
52
62
  end
53
63
  describe 'Routing patterns' do
54
64
  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_json: {} }
65
+ let(:request_stub) { double 'stub', url: 'http://example.com', http_method: 'GET', conditions_json: {}, id: 5 }
56
66
  before :each do
57
67
  allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://example.com%').and_return double('association', all: [request_stub])
58
68
  allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://subdomain.example.com%').and_return double('association', all: [])
@@ -67,7 +77,7 @@ describe AgileProxy::StubHandler do
67
77
 
68
78
  end
69
79
  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_json: {} }
80
+ let(:request_stub) { double 'stub for simple get inside a domain', url: 'http://example.com/index', http_method: 'GET', conditions_json: {}, id: 5 }
71
81
  before :each do
72
82
  allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://example.com%').and_return double('association', all: [request_stub])
73
83
  allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://subdomain.example.com%').and_return double('association', all: [])
@@ -83,7 +93,7 @@ describe AgileProxy::StubHandler do
83
93
 
84
94
  end
85
95
  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_json: {} }
96
+ let(:request_stub) { double 'stub', url: 'http://example.com', http_method: 'POST', conditions_json: {}, id: 5 }
87
97
  before :each do
88
98
  allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://example.com%').and_return double('association', all: [request_stub])
89
99
  allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://subdomain.example.com%').and_return double('association', all: [])
@@ -99,7 +109,7 @@ describe AgileProxy::StubHandler do
99
109
 
100
110
  end
101
111
  describe 'With a more complex route with conditions inside a domain' do
102
- let(:request_stub) { double 'stub for complex route inside a domain', url: 'http://example.com/users/:user_id/index', http_method: 'GET', conditions_json: { user_id: '1' } }
112
+ let(:request_stub) { double 'stub for complex route inside a domain', url: 'http://example.com/users/:user_id/index', http_method: 'GET', conditions_json: { user_id: '1' }, id: 5 }
103
113
  before :each do
104
114
  allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://example.com%').and_return double('association', all: [request_stub])
105
115
  expect(request_stub).to receive(:call).and_return([200, {}, ''])
@@ -113,7 +123,7 @@ describe AgileProxy::StubHandler do
113
123
  end
114
124
  end
115
125
  describe 'With a more complex route with conditions including query params inside a domain' do
116
- let(:request_stub) { double 'stub for complex route inside a domain', url: 'http://example.com/users/:user_id/index', http_method: 'GET', conditions_json: { user_id: '1', extra_1: 'extra_1', extra_2: 'extra_2' } }
126
+ let(:request_stub) { double 'stub for complex route inside a domain', url: 'http://example.com/users/:user_id/index', http_method: 'GET', conditions_json: { user_id: '1', extra_1: 'extra_1', extra_2: 'extra_2' }, id: 5 }
117
127
  before :each do
118
128
  allow(request_spec_class).to receive(:where).with('url LIKE ?', 'http://example.com%').and_return double('association', all: [request_stub])
119
129
  allow(request_stub).to receive(:call).and_return([200, {}, ''])