power_api 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +9 -0
- data/.hound.yml +4 -0
- data/.rspec +3 -0
- data/.rubocop.yml +479 -0
- data/.ruby-version +1 -0
- data/.travis.yml +15 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +310 -0
- data/Guardfile +15 -0
- data/LICENSE.txt +21 -0
- data/README.md +904 -0
- data/Rakefile +10 -0
- data/app/assets/config/power_api_manifest.js +2 -0
- data/app/assets/images/power_api/.keep +0 -0
- data/app/assets/javascripts/power_api/application.js +13 -0
- data/app/assets/stylesheets/power_api/application.css +15 -0
- data/app/controllers/concerns/api/deprecated.rb +23 -0
- data/app/controllers/concerns/api/error.rb +37 -0
- data/app/controllers/concerns/api/filtered.rb +15 -0
- data/app/controllers/concerns/api/versioned.rb +36 -0
- data/app/controllers/power_api/base_controller.rb +14 -0
- data/app/helpers/power_api/application_helper.rb +4 -0
- data/app/jobs/power_api/application_job.rb +4 -0
- data/app/mailers/power_api/application_mailer.rb +6 -0
- data/app/models/power_api/application_record.rb +5 -0
- data/app/responders/api_responder.rb +13 -0
- data/app/views/layouts/power_api/application.html.erb +14 -0
- data/bin/rails +14 -0
- data/config/routes.rb +2 -0
- data/lib/generators/power_api/controller/USAGE +5 -0
- data/lib/generators/power_api/controller/controller_generator.rb +152 -0
- data/lib/generators/power_api/install/USAGE +5 -0
- data/lib/generators/power_api/install/install_generator.rb +67 -0
- data/lib/generators/power_api/version/USAGE +5 -0
- data/lib/generators/power_api/version/version_generator.rb +54 -0
- data/lib/power_api.rb +35 -0
- data/lib/power_api/engine.rb +28 -0
- data/lib/power_api/errors.rb +4 -0
- data/lib/power_api/generator_helper/active_record_resource.rb +192 -0
- data/lib/power_api/generator_helper/ams_helper.rb +43 -0
- data/lib/power_api/generator_helper/controller_helper.rb +184 -0
- data/lib/power_api/generator_helper/pagination_helper.rb +48 -0
- data/lib/power_api/generator_helper/resource_helper.rb +33 -0
- data/lib/power_api/generator_helper/routes_helper.rb +91 -0
- data/lib/power_api/generator_helper/rubocop_helper.rb +11 -0
- data/lib/power_api/generator_helper/simple_token_auth_helper.rb +124 -0
- data/lib/power_api/generator_helper/swagger_helper.rb +463 -0
- data/lib/power_api/generator_helper/template_builder_helper.rb +23 -0
- data/lib/power_api/generator_helper/version_helper.rb +16 -0
- data/lib/power_api/generator_helpers.rb +25 -0
- data/lib/power_api/version.rb +3 -0
- data/lib/tasks/power_api_tasks.rake +4 -0
- data/power_api.gemspec +44 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +5 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/javascripts/cable.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/concerns/api/deprecated_spec.rb +37 -0
- data/spec/dummy/app/controllers/concerns/api/error_spec.rb +97 -0
- data/spec/dummy/app/controllers/concerns/api/filtered_spec.rb +42 -0
- data/spec/dummy/app/controllers/concerns/api/versioned_spec.rb +64 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/blog.rb +5 -0
- data/spec/dummy/app/models/portfolio.rb +5 -0
- data/spec/dummy/app/models/user.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +38 -0
- data/spec/dummy/bin/update +29 -0
- data/spec/dummy/bin/yarn +11 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +54 -0
- data/spec/dummy/config/environments/production.rb +91 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +14 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +56 -0
- data/spec/dummy/config/routes.rb +12 -0
- data/spec/dummy/config/secrets.yml +32 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/db/migrate/20190322205209_create_blogs.rb +10 -0
- data/spec/dummy/db/migrate/20200215225917_create_users.rb +9 -0
- data/spec/dummy/db/migrate/20200227150449_create_portfolios.rb +10 -0
- data/spec/dummy/db/migrate/20200227150548_add_portfolio_id_blogs.rb +5 -0
- data/spec/dummy/db/schema.rb +38 -0
- data/spec/dummy/package.json +5 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/spec/assets/image.png +0 -0
- data/spec/dummy/spec/assets/video.mp4 +0 -0
- data/spec/dummy/spec/factories/blogs.rb +7 -0
- data/spec/dummy/spec/factories/portfolios.rb +6 -0
- data/spec/dummy/spec/factories/users.rb +5 -0
- data/spec/dummy/spec/lib/power_api/generator_helper/ams_helper_spec.rb +87 -0
- data/spec/dummy/spec/lib/power_api/generator_helper/controller_helper_spec.rb +361 -0
- data/spec/dummy/spec/lib/power_api/generator_helper/pagination_helper_spec.rb +56 -0
- data/spec/dummy/spec/lib/power_api/generator_helper/resource_helper_spec.rb +31 -0
- data/spec/dummy/spec/lib/power_api/generator_helper/routes_helper_spec.rb +179 -0
- data/spec/dummy/spec/lib/power_api/generator_helper/simple_token_auth_helper_spec.rb +164 -0
- data/spec/dummy/spec/lib/power_api/generator_helper/swagger_helper_spec.rb +451 -0
- data/spec/dummy/spec/lib/power_api/generator_helper/version_helper_spec.rb +55 -0
- data/spec/dummy/spec/support/shared_examples/active_record_resource.rb +101 -0
- data/spec/dummy/spec/support/shared_examples/active_record_resource_atrributes.rb +164 -0
- data/spec/dummy/spec/support/test_generator_helpers.rb +29 -0
- data/spec/dummy/spec/support/test_helpers.rb +11 -0
- data/spec/rails_helper.rb +49 -0
- data/spec/spec_helper.rb +9 -0
- metadata +602 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
module PowerApi::GeneratorHelper::TemplateBuilderHelper
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
def concat_tpl_statements(*methods)
|
5
|
+
methods.reject(&:blank?).join("\n")
|
6
|
+
end
|
7
|
+
|
8
|
+
def concat_tpl_method(method_name, *method_lines)
|
9
|
+
concat_tpl_statements(
|
10
|
+
"def #{method_name}",
|
11
|
+
*method_lines,
|
12
|
+
"end"
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def tpl_class(class_def, *statements)
|
17
|
+
concat_tpl_statements(
|
18
|
+
"class #{class_def}",
|
19
|
+
*statements,
|
20
|
+
"end\n"
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module PowerApi::GeneratorHelper::VersionHelper
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
attr_reader :version_number
|
6
|
+
end
|
7
|
+
|
8
|
+
def version_number=(value)
|
9
|
+
@version_number = value.to_s.to_i
|
10
|
+
raise PowerApi::GeneratorError.new("invalid version number") if version_number < 1
|
11
|
+
end
|
12
|
+
|
13
|
+
def first_version?
|
14
|
+
version_number.to_i == 1
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module PowerApi
|
2
|
+
class GeneratorHelpers
|
3
|
+
include GeneratorHelper::ResourceHelper
|
4
|
+
include GeneratorHelper::VersionHelper
|
5
|
+
include GeneratorHelper::SwaggerHelper
|
6
|
+
include GeneratorHelper::AmsHelper
|
7
|
+
include GeneratorHelper::ControllerHelper
|
8
|
+
include GeneratorHelper::RoutesHelper
|
9
|
+
include GeneratorHelper::PaginationHelper
|
10
|
+
include GeneratorHelper::SimpleTokenAuthHelper
|
11
|
+
include GeneratorHelper::RubocopHelper
|
12
|
+
|
13
|
+
def initialize(config = {})
|
14
|
+
config.each do |attribute, value|
|
15
|
+
load_attribute(attribute, value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def load_attribute(attribute, value)
|
22
|
+
send("#{attribute}=", value)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/power_api.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
# Maintain your gem"s version:
|
4
|
+
require "power_api/version"
|
5
|
+
|
6
|
+
# Describe your gem and declare its dependencies:
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "power_api"
|
9
|
+
s.version = PowerApi::VERSION
|
10
|
+
s.authors = ["Platanus", "Leandro Segovia"]
|
11
|
+
s.email = ["rubygems@platan.us", "ldlsegovia@gmail.com"]
|
12
|
+
s.homepage = "https://github.com/platanus/power_api"
|
13
|
+
s.summary = "Set of other gems and configurations designed to build incredible APIs"
|
14
|
+
s.description = "It is a Rails engine that gathers a set of other gems and configurations designed to build incredible APIs"
|
15
|
+
s.license = "MIT"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split($/).reject { |fn| fn.start_with? "spec" }
|
18
|
+
s.bindir = "exe"
|
19
|
+
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
s.test_files = Dir["spec/**/*"]
|
21
|
+
|
22
|
+
s.add_dependency "rails", ">= 4.2.0"
|
23
|
+
|
24
|
+
s.add_dependency "active_model_serializers", "~> 0.10.0"
|
25
|
+
s.add_dependency "api-pagination"
|
26
|
+
s.add_dependency "kaminari"
|
27
|
+
s.add_dependency "ransack"
|
28
|
+
s.add_dependency "responders"
|
29
|
+
s.add_dependency "rswag-api"
|
30
|
+
s.add_dependency "rswag-ui"
|
31
|
+
s.add_dependency "simple_token_authentication", "~> 1.0"
|
32
|
+
s.add_dependency "versionist", "~> 1.0"
|
33
|
+
|
34
|
+
s.add_development_dependency "coveralls"
|
35
|
+
s.add_development_dependency "factory_bot_rails"
|
36
|
+
s.add_development_dependency "guard-rspec"
|
37
|
+
s.add_development_dependency "pry"
|
38
|
+
s.add_development_dependency "pry-rails"
|
39
|
+
s.add_development_dependency "rspec-rails"
|
40
|
+
s.add_development_dependency "rswag-specs"
|
41
|
+
s.add_development_dependency "rubocop", "0.65.0"
|
42
|
+
s.add_development_dependency "rubocop-rspec"
|
43
|
+
s.add_development_dependency "sqlite3", "~> 1.3.0"
|
44
|
+
end
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// Action Cable provides the framework to deal with WebSockets in Rails.
|
2
|
+
// You can generate new channels where WebSocket features live using the `rails generate channel` command.
|
3
|
+
//
|
4
|
+
//= require action_cable
|
5
|
+
//= require_self
|
6
|
+
//= require_tree ./channels
|
7
|
+
|
8
|
+
(function() {
|
9
|
+
this.App || (this.App = {});
|
10
|
+
|
11
|
+
App.cable = ActionCable.createConsumer();
|
12
|
+
|
13
|
+
}).call(this);
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Api::Deprecated', type: :controller do
|
4
|
+
before do
|
5
|
+
routes.draw { get :action1, to: "anonymous#action" }
|
6
|
+
|
7
|
+
get :action
|
8
|
+
end
|
9
|
+
|
10
|
+
context "with deprecated action" do
|
11
|
+
controller do
|
12
|
+
include ::Api::Deprecated
|
13
|
+
|
14
|
+
deprecate :action
|
15
|
+
|
16
|
+
def action
|
17
|
+
head :ok
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it { expect(response.status).to eq(200) }
|
22
|
+
it { expect(response.headers["Deprecated"]).to eq(true) }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with deprecated action" do
|
26
|
+
controller do
|
27
|
+
include ::Api::Deprecated
|
28
|
+
|
29
|
+
def action
|
30
|
+
head :ok
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it { expect(response.status).to eq(200) }
|
35
|
+
it { expect(response.headers["Deprecated"]).to be_nil }
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Api::Error', type: :controller do
|
4
|
+
before do
|
5
|
+
routes.draw { get :action, to: "anonymous#action" }
|
6
|
+
|
7
|
+
get :action
|
8
|
+
end
|
9
|
+
|
10
|
+
def response_body
|
11
|
+
JSON.parse(response.body).deep_symbolize_keys
|
12
|
+
end
|
13
|
+
|
14
|
+
context "with Exception error" do
|
15
|
+
let(:expected_response) do
|
16
|
+
{
|
17
|
+
detail: ":-(",
|
18
|
+
message: "server_error",
|
19
|
+
type: "RuntimeError"
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
controller do
|
24
|
+
include ::Api::Error
|
25
|
+
|
26
|
+
def action
|
27
|
+
raise ':-('
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it { expect(response_body).to eq(expected_response) }
|
32
|
+
it { expect(response.status).to eq(500) }
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with ActiveRecord::RecordNotFound error" do
|
36
|
+
let(:expected_response) do
|
37
|
+
{
|
38
|
+
detail: ":-(",
|
39
|
+
message: "record_not_found"
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
controller do
|
44
|
+
include ::Api::Error
|
45
|
+
|
46
|
+
def action
|
47
|
+
raise ActiveRecord::RecordNotFound.new(":-(")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it { expect(response_body).to eq(expected_response) }
|
52
|
+
it { expect(response.status).to eq(404) }
|
53
|
+
end
|
54
|
+
|
55
|
+
context "with ActiveModel::ForbiddenAttributesError error" do
|
56
|
+
let(:expected_response) do
|
57
|
+
{
|
58
|
+
detail: ":-(",
|
59
|
+
message: "protected_attributes"
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
controller do
|
64
|
+
include ::Api::Error
|
65
|
+
|
66
|
+
def action
|
67
|
+
raise ActiveModel::ForbiddenAttributesError.new(":-(")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it { expect(response_body).to eq(expected_response) }
|
72
|
+
it { expect(response.status).to eq(400) }
|
73
|
+
end
|
74
|
+
|
75
|
+
context "with ActiveRecord::RecordInvalid error" do
|
76
|
+
let(:expected_response) do
|
77
|
+
{
|
78
|
+
message: "invalid_attributes",
|
79
|
+
errors: {
|
80
|
+
body: ["can't be blank"],
|
81
|
+
title: ["can't be blank"]
|
82
|
+
}
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
controller do
|
87
|
+
include ::Api::Error
|
88
|
+
|
89
|
+
def action
|
90
|
+
raise Blog.create!
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
it { expect(response_body).to eq(expected_response) }
|
95
|
+
it { expect(response.status).to eq(400) }
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Api::Filtered', type: :controller do
|
4
|
+
let(:filters) do
|
5
|
+
nil
|
6
|
+
end
|
7
|
+
|
8
|
+
controller do
|
9
|
+
include ::Api::Filtered
|
10
|
+
|
11
|
+
def action
|
12
|
+
render json: filtered_collection(Blog.all)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
before do
|
17
|
+
routes.draw { get :action, to: "anonymous#action" }
|
18
|
+
|
19
|
+
create(:blog, title: "Lean's blog")
|
20
|
+
create(:blog, title: "Santiago's blog")
|
21
|
+
|
22
|
+
get :action, params: { q: filters }
|
23
|
+
end
|
24
|
+
|
25
|
+
def resources_count
|
26
|
+
JSON.parse(response.body).count
|
27
|
+
end
|
28
|
+
|
29
|
+
it { expect(resources_count).to eq(2) }
|
30
|
+
it { expect(response.status).to eq(200) }
|
31
|
+
|
32
|
+
context "with filters" do
|
33
|
+
let(:filters) do
|
34
|
+
{
|
35
|
+
title_cont: "Lean"
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
it { expect(resources_count).to eq(1) }
|
40
|
+
it { expect(response.status).to eq(200) }
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Api::Versioned', type: :controller do
|
4
|
+
let(:available_versions) { 1 }
|
5
|
+
let(:headers) do
|
6
|
+
{}
|
7
|
+
end
|
8
|
+
|
9
|
+
before do
|
10
|
+
allow(ENV).to receive(:fetch).with(
|
11
|
+
"AVAILABLE_API_VERSIONS", 1
|
12
|
+
).and_return(available_versions)
|
13
|
+
|
14
|
+
routes.draw { get :action, to: "anonymous#action" }
|
15
|
+
request.headers.merge!(headers) unless headers.blank?
|
16
|
+
get :action
|
17
|
+
end
|
18
|
+
|
19
|
+
controller do
|
20
|
+
include ::Api::Versioned
|
21
|
+
include ::Api::Error
|
22
|
+
|
23
|
+
def action
|
24
|
+
head :ok
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with default version" do
|
29
|
+
it { expect(response.status).to eq(200) }
|
30
|
+
it { expect(response.headers["Content-Type"]).to eq("text/html; version=1") }
|
31
|
+
|
32
|
+
context "with invalid version header" do
|
33
|
+
let(:headers) do
|
34
|
+
{
|
35
|
+
"Accept" => "version=2"
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
it { expect(response.status).to eq(400) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with multiple versions" do
|
44
|
+
let(:available_versions) { 2 }
|
45
|
+
let(:headers) do
|
46
|
+
{
|
47
|
+
"Accept" => "version=2"
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
it { expect(response.status).to eq(200) }
|
52
|
+
it { expect(response.headers["Content-Type"]).to eq("text/html; version=2") }
|
53
|
+
|
54
|
+
context "with invalid version header" do
|
55
|
+
let(:headers) do
|
56
|
+
{
|
57
|
+
"Accept" => "version=3"
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
it { expect(response.status).to eq(400) }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|