agile-proxy 0.1.18 → 0.1.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/lib/agile_proxy/api/request_spec_recordings.rb +52 -0
- data/lib/agile_proxy/api/request_specs.rb +1 -0
- data/lib/agile_proxy/api/root.rb +4 -0
- data/lib/agile_proxy/handlers/request_handler.rb +2 -1
- data/lib/agile_proxy/handlers/stub_handler.rb +1 -0
- data/lib/agile_proxy/model/response.rb +2 -8
- data/lib/agile_proxy/version.rb +1 -1
- data/spec/integration/helpers/request_spec_helper.rb +29 -15
- data/spec/integration/specs/lib/server_spec.rb +19 -0
- data/spec/unit/agile_proxy/api/request_spec_recordings_spec.rb +119 -0
- data/spec/unit/agile_proxy/handlers/request_handler_spec.rb +3 -3
- data/spec/unit/agile_proxy/handlers/stub_handler_spec.rb +18 -8
- metadata +134 -131
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 806cb5ed2d0d286c13adb4d4ab3dc7bcad28917d
|
4
|
+
data.tar.gz: ab62ffd2e6b2b11908314548d0598599619cd998
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/agile_proxy/api/root.rb
CHANGED
@@ -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
|
-
|
44
|
-
|
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]
|
data/lib/agile_proxy/version.rb
CHANGED
@@ -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
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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, {}, ''])
|