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 +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, {}, ''])
|