Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add #select_example_response config option.

  • Loading branch information...
commit c9c1fd5e737f8720a3e0f7ba1803f266b06cc5a8 1 parent 1ca7799
@myronmarston myronmarston authored
View
15 README.md
@@ -231,6 +231,21 @@ Interpol.default_configuration do |config|
example.data["current_url"] = Rack::Request.new(request_env).url
end
+ # Sets a callback that will be used to determine which example
+ # to return from the stub app. If you provide an endpoint name,
+ # the block will apply only to requests to that endpoint.
+ # If no name is provided, the block will set the default selector
+ # logic. By default, if this config is not set, interpol will use
+ # the first example.
+ #
+ # Used by Interpol::StubApp.
+ config.select_example_response('some-endpoint') do |endpoint_def, request_env|
+ endpoint_def.examples[3]
+ end
+ config.select_example_response do |endpoint_def, request_env|
+ endpoint_def.examples.first
+ end
+
# Determines what to do when Interpol::Sinatra::RequestParamsParser
# detects invalid path or query parameters based on their schema
# definitions. This block will be eval'd in the context of your
View
21 lib/interpol/configuration.rb
@@ -141,6 +141,19 @@ def filter_example_data(&block)
filter_example_data_blocks << block
end
+ def select_example_response(endpoint_name = nil, &block)
+ if endpoint_name
+ named_example_selectors[endpoint_name] = block
+ else
+ named_example_selectors.default = block
+ end
+ end
+
+ def example_response_for(endpoint_def, env)
+ selector = named_example_selectors[endpoint_def.endpoint_name]
+ selector.call(endpoint_def, env)
+ end
+
def self.default
@default ||= Configuration.new
end
@@ -187,6 +200,10 @@ def rack_json_response(status, hash)
'Content-Length' => json.bytesize }, [json]]
end
+ def named_example_selectors
+ @named_example_selectors ||= {}
+ end
+
def register_default_callbacks
request_version do
raise ConfigurationError, "request_version has not been configured"
@@ -229,6 +246,10 @@ def register_default_callbacks
on_invalid_sinatra_request_params do |error|
halt 400, JSON.dump(:error => error.message)
end
+
+ select_example_response do |endpoint_def, _|
+ endpoint_def.examples.first
+ end
end
end
end
View
8 lib/interpol/endpoint.rb
@@ -68,14 +68,6 @@ def find_definitions(version, message_type, &block)
@definitions_hash.fetch([message_type, version], &block)
end
- def find_example_for!(version, message_type)
- find_definition!(version, message_type).examples.first
- end
-
- def find_example_status_code_for!(version)
- find_definition!(version, 'response').example_status_code
- end
-
def available_request_versions
available_versions_matching &:request?
end
View
23 lib/interpol/stub_app.rb
@@ -44,24 +44,25 @@ def build
def endpoint_definition(endpoint)
lambda do
- example, version = settings.
- stub_app_builder.
- example_and_version_for(endpoint, self)
+ endpoint_def = settings.stub_app_builder.endpoint_def_for(endpoint, self)
+ example = settings.stub_app_builder.example_for(endpoint_def, self)
example.validate! if settings.perform_validations?
- status endpoint.find_example_status_code_for!(version)
+ status endpoint_def.example_status_code
JSON.dump(example.data)
end
end
- def example_and_version_for(endpoint, app)
+ def endpoint_def_for(endpoint, app)
version = config.response_version_for(app.request.env, endpoint)
- example = endpoint.find_example_for!(version, 'response')
+ endpoint_def = endpoint.find_definition!(version, 'response')
rescue NoEndpointDefinitionFoundError
- config.sinatra_request_version_unavailable(app, version,
- endpoint.available_response_versions)
- else
- example = example.apply_filters(config.filter_example_data_blocks, app.request.env)
- return example, version
+ config.sinatra_request_version_unavailable \
+ app, version, endpoint.available_response_versions
+ end
+
+ def example_for(endpoint_def, app)
+ example = config.example_response_for(endpoint_def, app.request.env)
+ example.apply_filters(config.filter_example_data_blocks, app.request.env)
end
end
end
View
15 spec/unit/interpol/endpoint_spec.rb
@@ -120,21 +120,6 @@ def build_hash(hash = {})
end
end
- describe "#find_example_for!" do
- let(:hash) { build_hash('definitions' => definitions_array) }
- let(:endpoint) { Endpoint.new(hash) }
-
- it 'returns an example for the requested version' do
- endpoint.find_example_for!('1.2', 'response').data.should eq('e1')
- end
-
- it 'raises an error when given a version it does not have' do
- expect {
- endpoint.find_example_for!('2.1', 'response')
- }.to raise_error(NoEndpointDefinitionFoundError)
- end
- end
-
describe '#route_matches?' do
def endpoint(route)
hash = build_hash('route' => route)
View
79 spec/unit/interpol/stub_app_spec.rb
@@ -36,10 +36,35 @@ module Interpol
EOF
end
+ let_without_indentation(:another_definition_yml) do <<-EOF
+ ---
+ name: another_endpoint
+ route: /another-endpoint
+ method: GET
+ definitions:
+ - versions: ["1.0"]
+ status_codes: ['200']
+ message_type: response
+ schema:
+ type: object
+ properties:
+ example_num: { type: integer }
+ examples:
+ - example_num: 0
+ - example_num: 1
+ - versions: ["1.0"]
+ message_type: request
+ schema: {}
+ examples: []
+ EOF
+ end
+
let(:endpoint) { Endpoint.new(YAML.load endpoint_definition_yml) }
+ let(:another_endpoint) { Endpoint.new(YAML.load another_definition_yml) }
+
let(:default_config) do
lambda do |config|
- config.endpoints = [endpoint]
+ config.endpoints = [endpoint, another_endpoint]
unless response_version_configured?(config) # allow default config to take precedence
config.response_version { |env, _| env.fetch('HTTP_RESPONSE_VERSION') }
@@ -95,6 +120,56 @@ def parsed_body
last_response.should be_ok
end
+ it 'uses the select_example_response callback to select which example gets returned' do
+ Interpol.default_configuration do |c|
+ c.select_example_response do |endpoint_def, request|
+ endpoint_def.examples.last
+ end
+ end
+
+ header 'Response-Version', '1.0'
+ get '/users/3/projects'
+ parsed_body.should include('name' => 'some other project')
+ end
+
+ it 'can select an example based on the request' do
+ Interpol.default_configuration do |c|
+ c.select_example_response do |endpoint_def, env|
+ index = Integer(env.fetch('HTTP_INDEX'))
+ endpoint_def.examples[index]
+ end
+ end
+
+ header 'Response-Version', '1.0'
+
+ header 'Index', '0'
+ get '/another-endpoint'
+ parsed_body.should include('example_num' => 0)
+
+ header 'Index', '1'
+ get '/another-endpoint'
+ parsed_body.should include('example_num' => 1)
+ end
+
+ it 'can have different example selection logic for a particular endpoint' do
+ Interpol.default_configuration do |c|
+ c.select_example_response do |endpoint_def, request|
+ endpoint_def.examples.last
+ end
+
+ c.select_example_response 'another_endpoint' do |endpoint_def, request|
+ endpoint_def.examples.first
+ end
+ end
+
+ header 'Response-Version', '1.0'
+ get '/users/3/projects'
+ parsed_body.should include('name' => 'some other project')
+
+ get '/another-endpoint'
+ parsed_body.should include('example_num' => 0)
+ end
+
it 'uses any provided filters to modify the example data' do
app.settings.stub_app_builder.config.filter_example_data do |example, request_env|
example.data["name"] += " for #{request_env["REQUEST_METHOD"]}"
@@ -144,7 +219,7 @@ def parsed_body
end
let(:endpoint_example) do
- endpoint.find_example_for!('1.0', 'response')
+ endpoint.find_definition!('1.0', 'response').examples.first
end
it 'performs validations by default' do
Please sign in to comment.
Something went wrong with that request. Please try again.