Skip to content

Commit

Permalink
Merge 5e24766 into c377d7f
Browse files Browse the repository at this point in the history
  • Loading branch information
bwillis committed Apr 6, 2016
2 parents c377d7f + 5e24766 commit eb2b4c5
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 25 deletions.
14 changes: 12 additions & 2 deletions lib/generators/templates/versioncake.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,18 @@
# ```
# config.extraction_strategy = [:http_accept_parameter, :http_header, :request_parameter, :path_parameter, :query_parameter]

# Version when no version in present in the request. If none is specified then it will error
config.missing_version = 5
# Missing Version
# What to use when no version in present in the request.
#
# Defaults to `:unversioned_template`
#
# Integer value:
# the version number to use
#
# `:unversioned_template` value:
# If you are using `rails_view_versioning` this will render the "base template" aka
# the template without a version number.
# config.missing_version = :unversioned_template

# Set the version key that clients will send example: `API-VERSION: 5`, api_version=2
# config.version_key = 'api_version'
Expand Down
18 changes: 16 additions & 2 deletions lib/versioncake/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ class Configuration
SUPPORTED_VERSIONS_DEFAULT = (1..10)
VERSION_KEY_DEFAULT = 'api_version'

attr_reader :extraction_strategies, :response_strategies, :supported_version_numbers, :versioned_resources
attr_reader :extraction_strategies, :response_strategies, :supported_version_numbers,
:versioned_resources, :default_version, :missing_version_use_unversioned_template
attr_accessor :missing_version, :version_key, :rails_view_versioning

def initialize
@versioned_resources = []
@version_key = VERSION_KEY_DEFAULT
@rails_view_versioning = true
@missing_version_use_unversioned_template = true
@default_version = nil
self.supported_version_numbers = SUPPORTED_VERSIONS_DEFAULT
self.extraction_strategy = [
:http_accept_parameter,
Expand All @@ -25,6 +28,17 @@ def initialize
self.response_strategy = []
end

def missing_version=(val)
@missing_version = val
if @missing_version == :unversioned_template
@missing_version_use_unversioned_template = true
@default_version = nil
else
@missing_version_use_unversioned_template = false
@default_version = val
end
end

def extraction_strategy=(val)
@extraction_strategies = []
Array.wrap(val).each do |configured_strategy|
Expand Down Expand Up @@ -76,4 +90,4 @@ def resource(regex, obsolete, unsupported, supported)
@resources << VersionCake::VersionedResource.new(regex, obsolete, unsupported, supported)
end
end
end
end
30 changes: 22 additions & 8 deletions lib/versioncake/controller_additions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,31 @@ def version_context
# @return No explicit return, but several attributes are exposed
def check_version!(override_version=nil)
return unless version_context

case version_context.result
when :version_invalid, :version_too_high, :version_too_low, :unknown
raise UnsupportedVersionError.new('Unsupported version error')
when :obsolete
raise ObsoleteVersionError.new('The version given is obsolete')
when :no_version

check_for_version_errors!(version_context.result)
configure_rails_view_versioning(version_context)
end

def check_for_version_errors!(result)
case result
when :version_invalid, :version_too_high, :version_too_low, :unknown
raise UnsupportedVersionError.new('Unsupported version error')
when :obsolete
raise ObsoleteVersionError.new('The version given is obsolete')
when :no_version
unless VersionCake.config.missing_version_use_unversioned_template
raise MissingVersionError.new('No version was given')
end
end
end

def configure_rails_view_versioning(version_context)
return unless VersionCake.config.rails_view_versioning

if VersionCake.config.rails_view_versioning
if version_context.result == :no_version &&
VersionCake.config.missing_version_use_unversioned_template
@_lookup_context.versions = nil
else
@_lookup_context.versions = version_context.available_versions.map { |n| :"v#{n}" }
end
end
Expand Down
6 changes: 3 additions & 3 deletions lib/versioncake/test_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ module VersionCake
module TestHelpers
# Test helper the mimics the middleware because we do not
# have middleware during tests.
def set_request_version(resource, version)
service = VersionCake::VersionContextService.new(VersionCake.config)
def set_request_version(resource, version, config=VersionCake.config)
service = VersionCake::VersionContextService.new(config)
@request.env['versioncake.context'] = service.create_context resource, version
end

def set_version_context(status, resource=nil, version=nil)
@request.env['versioncake.context'] = VersionCake::VersionContext.new(version, resource, status)
end
end
end
end
2 changes: 1 addition & 1 deletion lib/versioncake/version_context_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class VersionContextService

def initialize(config)
@versioned_resources = config.versioned_resources
@default_version = config.missing_version
@default_version = config.default_version
@strategies = config.extraction_strategies
end

Expand Down
25 changes: 24 additions & 1 deletion spec/integration/controller/renders_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

context '#index' do
render_views
before { set_request_version 'renders', request_version }
let(:config) { VersionCake.config }
before { set_request_version 'renders', request_version, config }
before { response_body }

context 'when requesting the non latest version' do
Expand Down Expand Up @@ -36,6 +37,28 @@
it { expect(response_body).to eq 'template v2' }
end

context 'when requesting without a version' do
context 'and missing version is configured to unversioned_template' do
let(:request_version) { nil }

# TODO: Restructure
# Need a better way to stub/unstub the `VersionCake.config` that generates
# the context and is used in the controller.
let(:config) do
VersionCake.config.tap do |config|
config.missing_version = :unversioned_template
end
end
after { VersionCake.config.missing_version = nil }
# /TODO

it { expect(controller.request_version).to eq nil }
it { expect(controller.is_latest_version?).to be_falsey }
it { expect(controller.is_deprecated_version?).to be_falsey }
it { expect(response_body).to eq 'base template' }
end
end

context '#set_version' do
let(:request_options) { { 'override_version' => 2 } }
let(:request_version) { 3 }
Expand Down
32 changes: 25 additions & 7 deletions spec/integration/rack/middleware_regression_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,27 @@

describe VersionCake::Rack::Middleware do
let(:app) do
_config = config
rack = Rack::Builder.new do
config = VersionCake::Configuration.new
config.resources { |r| r.resource %r{.*}, [], [], (1..5) }
use VersionCake::Rack::Middleware, config
run lambda { |env| [ 200, {},[ env['versioncake.context'].version ] ] }
use VersionCake::Rack::Middleware, _config
run lambda { |env| [ 200, {},[ "version is #{env['versioncake.context'].version}" ] ] }
end
Rack::MockRequest.new(rack)
end
let(:config) do
config = VersionCake::Configuration.new
config.resources { |r| r.resource %r{.*}, [], [], (1..5) }
config
end

test_cases = YAML.load(File.open('./spec/fixtures/test_cases.yml'))
test_cases.each do |test_case|
context 'for a test case' do


let(:data) { test_case['request'] || {} }
let(:method) { (data['method'] || 'get').to_sym }
let(:headers) { data['headers'] || {} }
let(:params) { data['params'] || {} }
let(:test_response) { test_case['response'] }
let(:test_response) { "version is #{test_case['response']}" }

it "test yml test cases" do
begin
Expand All @@ -40,4 +42,20 @@ def custom_message(headers, params, method, actual_response, expected_response)
data << "params:#{params}" if params
"Expected #{data.join(',')} with method #{method} to yield '#{expected_response}', but got '#{actual_response}'"
end

context 'when configured with unversioned template' do
let(:config) do
config = VersionCake::Configuration.new
config.resources { |r| r.resource %r{.*}, [], [], (1..5) }
config.missing_version = :unversioned_template
config
end

context 'and the request does not contain a version' do
it 'does not include a version (rails will convert nil => unversioned template)' do
_response_status, _response_headers, response = app.request('get', '/renders')
expect(response.body).to eq 'version is ' # nil
end
end
end
end
16 changes: 16 additions & 0 deletions spec/unit/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@
it { expect(config.latest_version).to eq 54 }
end

context '#missing_version' do
before { config.missing_version = 5 }

it { expect(config.missing_version).to eq 5 }
it { expect(config.default_version).to eq 5 }
it { expect(config.missing_version_use_unversioned_template).to eq false }

context 'when set to use the base template' do
before { config.missing_version = :unversioned_template }

it { expect(config.missing_version).to eq :unversioned_template }
it { expect(config.default_version).to be_nil }
it { expect(config.missing_version_use_unversioned_template).to eq true }
end
end

context 'by default' do
it 'has all extraction strategies' do
expect(config.extraction_strategies.map(&:class)).to match_array(
Expand Down
19 changes: 18 additions & 1 deletion spec/unit/version_context_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@
let(:config) do
double('config',
versioned_resources: [resource_user, resource_all],
missing_version: 9,
default_version: default_version,
extraction_strategies: [
VersionCake::CustomStrategy.new(lambda{ |req| req.version })
]
)
end
let(:default_version) { 6 }
let(:service) { described_class.new(config) }

describe '#create_context_from_request' do
Expand All @@ -52,6 +53,22 @@
it { expect(context.resource).to eq resource_user }
it { expect(context.result).to eq :obsolete }
end

context 'for a missing version' do
let(:request) { double(version: nil, path: 'users/123') }

it { expect(context.version).to eq 6 }
it { expect(context.resource).to eq resource_user }
it { expect(context.result).to eq :supported }

context 'when no default version is configured' do
let(:default_version) { nil }

it { expect(context.version).to eq nil }
it { expect(context.resource).to eq resource_user }
it { expect(context.result).to eq :no_version }
end
end
end

describe '#create_context' do
Expand Down

0 comments on commit eb2b4c5

Please sign in to comment.