shared_examples_for 'versioning' do it 'sets the API version' do subject.format :txt subject.version 'v1', macro_options subject.get :hello do "Version: #{request.env['api.version']}" end versioned_get '/hello', 'v1', macro_options expect(last_response.body).to eql 'Version: v1' end it 'adds the prefix before the API version' do subject.format :txt subject.prefix 'api' subject.version 'v1', macro_options subject.get :hello do "Version: #{request.env['api.version']}" end versioned_get '/hello', 'v1', macro_options.merge(prefix: 'api') expect(last_response.body).to eql 'Version: v1' end it 'is able to specify version as a nesting' do subject.version 'v2', macro_options subject.get '/awesome' do 'Radical' end subject.version 'v1', macro_options do get '/legacy' do 'Totally' end end versioned_get '/awesome', 'v1', macro_options expect(last_response.status).to eql 404 versioned_get '/awesome', 'v2', macro_options expect(last_response.status).to eql 200 versioned_get '/legacy', 'v1', macro_options expect(last_response.status).to eql 200 versioned_get '/legacy', 'v2', macro_options expect(last_response.status).to eql 404 end it 'is able to specify multiple versions' do subject.version 'v1', 'v2', macro_options subject.get 'awesome' do 'I exist' end versioned_get '/awesome', 'v1', macro_options expect(last_response.status).to eql 200 versioned_get '/awesome', 'v2', macro_options expect(last_response.status).to eql 200 versioned_get '/awesome', 'v3', macro_options expect(last_response.status).to eql 404 end context 'with different versions for the same endpoint' do context 'without a prefix' do it 'allows the same endpoint to be implemented' do subject.format :txt subject.version 'v2', macro_options subject.get 'version' do request.env['api.version'] end subject.version 'v1', macro_options do get 'version' do 'version ' + request.env['api.version'] end end versioned_get '/version', 'v2', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2') versioned_get '/version', 'v1', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('version v1') end end context 'with a prefix' do it 'allows the same endpoint to be implemented' do subject.format :txt subject.prefix 'api' subject.version 'v2', macro_options subject.get 'version' do request.env['api.version'] end subject.version 'v1', macro_options do get 'version' do 'version ' + request.env['api.version'] end end versioned_get '/version', 'v1', macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('version v1') versioned_get '/version', 'v2', macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2') end end end context 'with before block defined within a version block' do it 'calls before block that is defined within the version block' do subject.format :txt subject.prefix 'api' subject.version 'v2', macro_options do before do @output ||= 'v2-' end get 'version' do @output += 'version' end end subject.version 'v1', macro_options do before do @output ||= 'v1-' end get 'version' do @output += 'version' end end versioned_get '/version', 'v1', macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('v1-version') versioned_get '/version', 'v2', macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2-version') end end it 'does not overwrite version parameter with API version' do subject.format :txt subject.version 'v1', macro_options subject.params { requires :version } subject.get :api_version_with_version_param do params[:version] end versioned_get '/api_version_with_version_param?version=1', 'v1', macro_options expect(last_response.body).to eql '1' end context 'with catch-all' do let(:options) { macro_options } let(:v1) do klass = Class.new(Grape::API) klass.version 'v1', options klass.get 'version' do 'v1' end klass end let(:v2) do klass = Class.new(Grape::API) klass.version 'v2', options klass.get 'version' do 'v2' end klass end before do subject.format :txt subject.mount v1 subject.mount v2 subject.route :any, '*path' do params[:path] end end context 'v1' do it 'finds endpoint' do versioned_get '/version', 'v1', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('v1') end it 'finds catch all' do versioned_get '/whatever', 'v1', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to end_with 'whatever' end end context 'v2' do it 'finds endpoint' do versioned_get '/version', 'v2', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2') end it 'finds catch all' do versioned_get '/whatever', 'v2', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to end_with 'whatever' end end end end