apipie-rails 0.3.6 → 0.5.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +23 -7
- data/CHANGELOG.md +147 -2
- data/Gemfile +1 -0
- data/Gemfile.rails41 +2 -0
- data/Gemfile.rails42 +10 -1
- data/Gemfile.rails50 +9 -0
- data/Gemfile.rails51 +9 -0
- data/Gemfile.rails60 +14 -0
- data/PROPOSAL_FOR_RESPONSE_DESCRIPTIONS.md +244 -0
- data/README.rst +570 -17
- data/apipie-rails.gemspec +3 -3
- data/app/controllers/apipie/apipies_controller.rb +48 -17
- data/app/views/apipie/apipies/_method_detail.erb +21 -0
- data/app/views/apipie/apipies/_params.html.erb +4 -2
- data/app/views/apipie/apipies/index.html.erb +5 -1
- data/app/views/apipie/apipies/resource.html.erb +3 -0
- data/app/views/layouts/apipie/apipie.html.erb +1 -1
- data/config/locales/en.yml +1 -0
- data/config/locales/fr.yml +31 -0
- data/config/locales/it.yml +31 -0
- data/config/locales/ja.yml +31 -0
- data/lib/apipie/apipie_module.rb +22 -4
- data/lib/apipie/application.rb +55 -28
- data/lib/apipie/configuration.rb +19 -3
- data/lib/apipie/core_ext/route.rb +9 -0
- data/lib/apipie/dsl_definition.rb +151 -10
- data/lib/apipie/error_description.rb +9 -2
- data/lib/apipie/errors.rb +34 -0
- data/lib/apipie/extractor/collector.rb +4 -0
- data/lib/apipie/extractor/recorder.rb +13 -12
- data/lib/apipie/extractor/writer.rb +83 -55
- data/lib/apipie/extractor.rb +10 -4
- data/lib/apipie/method_description.rb +51 -4
- data/lib/apipie/param_description.rb +56 -2
- data/lib/apipie/resource_description.rb +10 -3
- data/lib/apipie/response_description.rb +131 -0
- data/lib/apipie/response_description_adapter.rb +200 -0
- data/lib/apipie/routes_formatter.rb +1 -1
- data/lib/apipie/rspec/response_validation_helper.rb +194 -0
- data/lib/apipie/static_dispatcher.rb +3 -2
- data/lib/apipie/swagger_generator.rb +708 -0
- data/lib/apipie/tag_list_description.rb +11 -0
- data/lib/apipie/validator.rb +69 -8
- data/lib/apipie/version.rb +1 -1
- data/lib/apipie-rails.rb +7 -0
- data/lib/tasks/apipie.rake +103 -8
- data/spec/controllers/apipies_controller_spec.rb +52 -12
- data/spec/controllers/concerns_controller_spec.rb +2 -2
- data/spec/controllers/extended_controller_spec.rb +14 -0
- data/spec/controllers/memes_controller_spec.rb +10 -0
- data/spec/controllers/users_controller_spec.rb +115 -75
- data/spec/dummy/app/controllers/application_controller.rb +5 -1
- data/spec/dummy/app/controllers/concerns/extending_concern.rb +12 -0
- data/spec/dummy/app/controllers/concerns/sample_controller.rb +5 -5
- data/spec/dummy/app/controllers/extended_controller.rb +14 -0
- data/spec/dummy/app/controllers/pets_controller.rb +408 -0
- data/spec/dummy/app/controllers/pets_using_auto_views_controller.rb +73 -0
- data/spec/dummy/app/controllers/pets_using_self_describing_classes_controller.rb +95 -0
- data/spec/dummy/app/controllers/tagged_cats_controller.rb +32 -0
- data/spec/dummy/app/controllers/tagged_dogs_controller.rb +15 -0
- data/spec/dummy/app/controllers/twitter_example_controller.rb +5 -0
- data/spec/dummy/app/controllers/users_controller.rb +19 -11
- data/spec/dummy/components/test_engine/Gemfile +6 -0
- data/spec/dummy/components/test_engine/app/controllers/test_engine/application_controller.rb +4 -0
- data/spec/dummy/components/test_engine/app/controllers/test_engine/memes_controller.rb +37 -0
- data/spec/dummy/components/test_engine/config/routes.rb +3 -0
- data/spec/dummy/components/test_engine/db/.gitkeep +0 -0
- data/spec/dummy/components/test_engine/lib/test_engine.rb +7 -0
- data/spec/dummy/components/test_engine/test_engine.gemspec +11 -0
- data/spec/dummy/config/application.rb +5 -0
- data/spec/dummy/config/environments/development.rb +3 -0
- data/spec/dummy/config/environments/production.rb +3 -0
- data/spec/dummy/config/environments/test.rb +3 -0
- data/spec/dummy/config/initializers/apipie.rb +3 -1
- data/spec/dummy/config/routes.rb +24 -1
- data/spec/lib/extractor/writer_spec.rb +32 -4
- data/spec/lib/file_handler_spec.rb +18 -0
- data/spec/lib/method_description_spec.rb +34 -0
- data/spec/lib/swagger/openapi_2_0_schema.json +1607 -0
- data/spec/lib/swagger/rake_swagger_spec.rb +139 -0
- data/spec/lib/swagger/response_validation_spec.rb +104 -0
- data/spec/lib/swagger/swagger_dsl_spec.rb +658 -0
- data/spec/lib/validator_spec.rb +58 -0
- data/spec/lib/validators/array_validator_spec.rb +28 -8
- data/spec/spec_helper.rb +68 -0
- metadata +75 -23
- data/Gemfile +0 -7
- data/Gemfile.rails32 +0 -6
- data/Gemfile.rails40 +0 -5
- data/lib/apipie/client/generator.rb +0 -135
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require "json-schema"
|
3
|
+
|
4
|
+
require File.expand_path("../../../dummy/app/controllers/twitter_example_controller.rb", __FILE__)
|
5
|
+
require File.expand_path("../../../dummy/app/controllers/users_controller.rb", __FILE__)
|
6
|
+
require File.expand_path("../../../dummy/app/controllers/pets_controller.rb", __FILE__)
|
7
|
+
|
8
|
+
describe 'rake tasks' do
|
9
|
+
include_context "rake"
|
10
|
+
|
11
|
+
let(:doc_path) { "user_specified_doc_path" }
|
12
|
+
|
13
|
+
before do
|
14
|
+
Apipie.configuration.doc_path = doc_path
|
15
|
+
Apipie.configuration.swagger_suppress_warnings = true
|
16
|
+
allow(Apipie).to receive(:reload_documentation)
|
17
|
+
subject.invoke(*task_args)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'static swagger specification files' do
|
21
|
+
|
22
|
+
after do
|
23
|
+
Dir["#{doc_output}*"].each { |static_file| FileUtils.rm_rf(static_file) }
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:swagger_schema) do
|
27
|
+
File.read(File.join(File.dirname(__FILE__),"openapi_2_0_schema.json"))
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:apidoc_swagger_json) do
|
31
|
+
# note: the filename ends with '_tmp' because this suffix is passed as a parameter to the rake task
|
32
|
+
File.read("#{doc_output}/schema_swagger_tmp.json")
|
33
|
+
end
|
34
|
+
|
35
|
+
let(:apidoc_swagger) do
|
36
|
+
JSON.parse(apidoc_swagger_json)
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:doc_output) do
|
40
|
+
File.join(::Rails.root, doc_path, 'apidoc')
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:ref_output) do
|
44
|
+
File.join(::Rails.root, doc_path, 'apidoc_ref')
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def expect_param_def(http_method, path, param_name, field, value)
|
49
|
+
params = apidoc_swagger["paths"][path][http_method]["parameters"]
|
50
|
+
param = params.select {|p| p if p["name"]==param_name}[0]
|
51
|
+
expect(param[field]).to eq(value)
|
52
|
+
end
|
53
|
+
|
54
|
+
def expect_tags_def(http_method, path, value)
|
55
|
+
params = apidoc_swagger["paths"][path][http_method]["tags"]
|
56
|
+
expect(params).to eq(value)
|
57
|
+
end
|
58
|
+
|
59
|
+
def body_param_def(http_method, path, param_name)
|
60
|
+
params = apidoc_swagger["paths"][path][http_method]["parameters"]
|
61
|
+
body = params.select {|p| p if p["name"]=="body"}[0]
|
62
|
+
schema_properties = body["schema"]["properties"]
|
63
|
+
# print JSON.pretty_generate(schema_properties)
|
64
|
+
param = (schema_properties.select {|k,v| v if k == param_name })[param_name]
|
65
|
+
# print JSON.pretty_generate(param)
|
66
|
+
param
|
67
|
+
end
|
68
|
+
|
69
|
+
def expect_body_param_def(http_method, path, param_name, field, value)
|
70
|
+
param = body_param_def(http_method, path, param_name)
|
71
|
+
expect(param[field]).to eq(value)
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
describe 'apipie:static_swagger_json[development,json,_tmp]' do
|
76
|
+
it "generates static swagger files for the default version of apipie docs" do
|
77
|
+
# print apidoc_swagger_json
|
78
|
+
|
79
|
+
expect(apidoc_swagger["info"]["title"]).to eq("Test app (params in:body)")
|
80
|
+
expect(apidoc_swagger["info"]["version"]).to eq("#{Apipie.configuration.default_version}")
|
81
|
+
end
|
82
|
+
|
83
|
+
it "includes expected values in the generated swagger file" do
|
84
|
+
expect_param_def("get", "/twitter_example/{id}", "screen_name", "in", "query")
|
85
|
+
expect_param_def("put", "/users/{id}", "id", "in", "path")
|
86
|
+
expect_body_param_def("put", "/users/{id}", "oauth", "type", "string")
|
87
|
+
expect_body_param_def("put", "/users/{id}", "user", "type", "object")
|
88
|
+
|
89
|
+
user = body_param_def("put", "/users/{id}", "user")
|
90
|
+
expect(user["properties"]["name"]["type"]).to eq("string")
|
91
|
+
|
92
|
+
expect_param_def("get", "/users/by_department", "department", "in", "query")
|
93
|
+
expect_param_def("get", "/users/by_department", "department", "enum",
|
94
|
+
["finance", "operations", "sales", "marketing", "HR"])
|
95
|
+
|
96
|
+
expect_tags_def("get", "/twitter_example/{id}/followers", %w[twitter_example following index search])
|
97
|
+
end
|
98
|
+
|
99
|
+
it "generates a valid swagger file" do
|
100
|
+
# print apidoc_swagger_json
|
101
|
+
expect(JSON::Validator.validate(swagger_schema, apidoc_swagger_json)).to be_truthy
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'apipie:static_swagger_json[development,form_data,_tmp]' do
|
106
|
+
it "generates static swagger files for the default version of apipie docs" do
|
107
|
+
# print apidoc_swagger_json
|
108
|
+
|
109
|
+
expect(apidoc_swagger["info"]["title"]).to eq("Test app (params in:formData)")
|
110
|
+
expect(apidoc_swagger["info"]["version"]).to eq("#{Apipie.configuration.default_version}")
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
it "includes expected values in the generated swagger file" do
|
115
|
+
expect_param_def("get", "/twitter_example/{id}", "screen_name", "in", "query")
|
116
|
+
expect_param_def("put", "/users/{id}", "id", "in", "path")
|
117
|
+
expect_param_def("put", "/users/{id}", "oauth", "in", "formData")
|
118
|
+
expect_param_def("get", "/users/by_department", "department", "in", "query")
|
119
|
+
expect_param_def("get", "/users/by_department", "department", "enum",
|
120
|
+
["finance", "operations", "sales", "marketing", "HR"])
|
121
|
+
|
122
|
+
expect_tags_def("get", "/twitter_example/{id}/followers", %w[twitter_example following index search])
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
it "generates a valid swagger file" do
|
127
|
+
# print apidoc_swagger_json
|
128
|
+
expect(JSON::Validator.validate(swagger_schema, apidoc_swagger_json)).to be_truthy
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe 'apipie:did_swagger_change[development,form_data,_tmp]' do
|
133
|
+
it "keeps a reference file" do
|
134
|
+
expect(Pathname(ref_output).children.count).to eq(2) # one file for each language
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rack/utils'
|
3
|
+
require 'rspec/expectations'
|
4
|
+
require 'apipie/rspec/response_validation_helper'
|
5
|
+
require "json-schema"
|
6
|
+
|
7
|
+
RSpec.describe PetsController, :type => :controller do
|
8
|
+
before :each do
|
9
|
+
Apipie.configuration.swagger_allow_additional_properties_in_response = false
|
10
|
+
end
|
11
|
+
|
12
|
+
it "does not raise error when rendered output matches the described response" do
|
13
|
+
response = get :return_and_validate_expected_response, {format: :json}
|
14
|
+
expect(response).to match_declared_responses
|
15
|
+
end
|
16
|
+
|
17
|
+
it "does not raise error when rendered output (array) matches the described response" do
|
18
|
+
response = get :return_and_validate_expected_array_response, {format: :json}
|
19
|
+
expect(response).to match_declared_responses
|
20
|
+
end
|
21
|
+
|
22
|
+
it "does not raises error when rendered output includes null in the response" do
|
23
|
+
response = get :return_and_validate_expected_response_with_null, {format: :json}
|
24
|
+
expect(response).to match_declared_responses
|
25
|
+
end
|
26
|
+
|
27
|
+
it "does not raise error when rendered output includes null (instead of an object) in the response" do
|
28
|
+
response = get :return_and_validate_expected_response_with_null_object, {format: :json}
|
29
|
+
expect(response).to match_declared_responses
|
30
|
+
end
|
31
|
+
|
32
|
+
it "raises error when a response field has the wrong type" do
|
33
|
+
response = get :return_and_validate_type_mismatch, {format: :json}
|
34
|
+
expect(response).not_to match_declared_responses
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises error when a response has a missing field" do
|
38
|
+
response = get :return_and_validate_missing_field, {format: :json}
|
39
|
+
expect(response).not_to match_declared_responses
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raises error when a response has an extra property and 'swagger_allow_additional_properties_in_response' is false" do
|
43
|
+
response = get :return_and_validate_extra_property, {format: :json}
|
44
|
+
expect(response).not_to match_declared_responses
|
45
|
+
end
|
46
|
+
|
47
|
+
it "raises error when a response has is array instead of object" do
|
48
|
+
# note: this action returns HTTP 201, not HTTP 200!
|
49
|
+
response = get :return_and_validate_unexpected_array_response, {format: :json}
|
50
|
+
expect(response).not_to match_declared_responses
|
51
|
+
end
|
52
|
+
|
53
|
+
it "does not raise error when a response has an extra property and 'swagger_allow_additional_properties_in_response' is true" do
|
54
|
+
Apipie.configuration.swagger_allow_additional_properties_in_response = true
|
55
|
+
response = get :return_and_validate_extra_property, {format: :json}
|
56
|
+
expect(response).to match_declared_responses
|
57
|
+
end
|
58
|
+
|
59
|
+
it "does not raise error when a response has an extra field and 'additional_properties' is specified in the response" do
|
60
|
+
Apipie.configuration.swagger_allow_additional_properties_in_response = false
|
61
|
+
response = get :return_and_validate_allowed_extra_property, {format: :json}
|
62
|
+
expect(response).to match_declared_responses
|
63
|
+
end
|
64
|
+
|
65
|
+
it "raises error when a response sub-object has an extra field and 'additional_properties' is not specified on it, but specified on the top level of the response" do
|
66
|
+
Apipie.configuration.swagger_allow_additional_properties_in_response = false
|
67
|
+
response = get :sub_object_invalid_extra_property, {format: :json}
|
68
|
+
expect(response).not_to match_declared_responses
|
69
|
+
end
|
70
|
+
|
71
|
+
it "does not rais error when a response sub-object has an extra field and 'additional_properties' is specified on it" do
|
72
|
+
Apipie.configuration.swagger_allow_additional_properties_in_response = false
|
73
|
+
response = get :sub_object_allowed_extra_property, {format: :json}
|
74
|
+
expect(response).to match_declared_responses
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "auto validation" do
|
78
|
+
auto_validate_rendered_views
|
79
|
+
it "raises exception when a response field has the wrong type and auto validation is turned on" do
|
80
|
+
expect { get :return_and_validate_type_mismatch, {format: :json} }.to raise_error(Apipie::ResponseDoesNotMatchSwaggerSchema)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "does not raise an exception when calling an undocumented method" do
|
84
|
+
expect { get :undocumented_method, {format: :json} }.not_to raise_error
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
describe "with array field" do
|
91
|
+
it "no error for valid response" do
|
92
|
+
response = get :returns_response_with_valid_array, {format: :json}
|
93
|
+
expect(response).to match_declared_responses
|
94
|
+
end
|
95
|
+
|
96
|
+
it "error if type of element in the array is wrong" do
|
97
|
+
response = get :returns_response_with_invalid_array, {format: :json}
|
98
|
+
expect(response).not_to match_declared_responses
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
end
|