apipierails3 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +17 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +27 -0
- data/APACHE-LICENSE-2.0 +202 -0
- data/CHANGELOG.md +469 -0
- data/Gemfile +1 -0
- data/Gemfile.rails32 +6 -0
- data/Gemfile.rails41 +6 -0
- data/Gemfile.rails42 +11 -0
- data/Gemfile.rails50 +6 -0
- data/Gemfile.rails51 +7 -0
- data/MIT-LICENSE +20 -0
- data/NOTICE +4 -0
- data/PROPOSAL_FOR_RESPONSE_DESCRIPTIONS.md +244 -0
- data/README.rst +1874 -0
- data/Rakefile +13 -0
- data/apipierails3.gemspec +27 -0
- data/app/controllers/apipie/apipies_controller.rb +199 -0
- data/app/helpers/apipie_helper.rb +10 -0
- data/app/public/apipie/javascripts/apipie.js +6 -0
- data/app/public/apipie/javascripts/bundled/bootstrap-collapse.js +138 -0
- data/app/public/apipie/javascripts/bundled/bootstrap.js +1726 -0
- data/app/public/apipie/javascripts/bundled/jquery.js +5 -0
- data/app/public/apipie/javascripts/bundled/prettify.js +28 -0
- data/app/public/apipie/stylesheets/application.css +7 -0
- data/app/public/apipie/stylesheets/bundled/bootstrap-responsive.min.css +12 -0
- data/app/public/apipie/stylesheets/bundled/bootstrap.min.css +689 -0
- data/app/public/apipie/stylesheets/bundled/prettify.css +30 -0
- data/app/views/apipie/apipies/_disqus.html.erb +13 -0
- data/app/views/apipie/apipies/_errors.html.erb +23 -0
- data/app/views/apipie/apipies/_headers.html.erb +26 -0
- data/app/views/apipie/apipies/_languages.erb +6 -0
- data/app/views/apipie/apipies/_metadata.erb +1 -0
- data/app/views/apipie/apipies/_method_detail.erb +61 -0
- data/app/views/apipie/apipies/_params.html.erb +42 -0
- data/app/views/apipie/apipies/_params_plain.html.erb +20 -0
- data/app/views/apipie/apipies/apipie_404.html.erb +17 -0
- data/app/views/apipie/apipies/apipie_checksum.json.erb +1 -0
- data/app/views/apipie/apipies/getting_started.html.erb +6 -0
- data/app/views/apipie/apipies/index.html.erb +56 -0
- data/app/views/apipie/apipies/method.html.erb +41 -0
- data/app/views/apipie/apipies/plain.html.erb +77 -0
- data/app/views/apipie/apipies/resource.html.erb +80 -0
- data/app/views/apipie/apipies/static.html.erb +103 -0
- data/app/views/layouts/apipie/apipie.html.erb +27 -0
- data/config/locales/de.yml +28 -0
- data/config/locales/en.yml +32 -0
- data/config/locales/es.yml +28 -0
- data/config/locales/fr.yml +31 -0
- data/config/locales/it.yml +31 -0
- data/config/locales/ja.yml +31 -0
- data/config/locales/pl.yml +28 -0
- data/config/locales/pt-BR.yml +28 -0
- data/config/locales/ru.yml +28 -0
- data/config/locales/tr.yml +28 -0
- data/config/locales/zh-CN.yml +28 -0
- data/config/locales/zh-TW.yml +28 -0
- data/images/screenshot-1.png +0 -0
- data/images/screenshot-2.png +0 -0
- data/lib/apipie/apipie_module.rb +83 -0
- data/lib/apipie/application.rb +462 -0
- data/lib/apipie/configuration.rb +186 -0
- data/lib/apipie/dsl_definition.rb +607 -0
- data/lib/apipie/error_description.rb +44 -0
- data/lib/apipie/errors.rb +86 -0
- data/lib/apipie/extractor.rb +177 -0
- data/lib/apipie/extractor/collector.rb +117 -0
- data/lib/apipie/extractor/recorder.rb +166 -0
- data/lib/apipie/extractor/writer.rb +454 -0
- data/lib/apipie/helpers.rb +73 -0
- data/lib/apipie/markup.rb +48 -0
- data/lib/apipie/method_description.rb +273 -0
- data/lib/apipie/middleware/checksum_in_headers.rb +35 -0
- data/lib/apipie/param_description.rb +280 -0
- data/lib/apipie/railtie.rb +9 -0
- data/lib/apipie/resource_description.rb +124 -0
- data/lib/apipie/response_description.rb +131 -0
- data/lib/apipie/response_description_adapter.rb +200 -0
- data/lib/apipie/routes_formatter.rb +33 -0
- data/lib/apipie/routing.rb +16 -0
- data/lib/apipie/rspec/response_validation_helper.rb +192 -0
- data/lib/apipie/see_description.rb +39 -0
- data/lib/apipie/static_dispatcher.rb +69 -0
- data/lib/apipie/swagger_generator.rb +707 -0
- data/lib/apipie/tag_list_description.rb +11 -0
- data/lib/apipie/validator.rb +526 -0
- data/lib/apipie/version.rb +3 -0
- data/lib/apipierails3.rb +25 -0
- data/lib/generators/apipie/install/README +6 -0
- data/lib/generators/apipie/install/install_generator.rb +25 -0
- data/lib/generators/apipie/install/templates/initializer.rb.erb +7 -0
- data/lib/generators/apipie/views_generator.rb +11 -0
- data/lib/tasks/apipie.rake +345 -0
- data/rel-eng/packages/.readme +3 -0
- data/rel-eng/packages/rubygem-apipie-rails +1 -0
- data/rel-eng/tito.props +5 -0
- data/spec/controllers/api/v1/architectures_controller_spec.rb +29 -0
- data/spec/controllers/api/v2/architectures_controller_spec.rb +12 -0
- data/spec/controllers/api/v2/nested/resources_controller_spec.rb +11 -0
- data/spec/controllers/apipies_controller_spec.rb +273 -0
- data/spec/controllers/concerns_controller_spec.rb +42 -0
- data/spec/controllers/extended_controller_spec.rb +11 -0
- data/spec/controllers/users_controller_spec.rb +740 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/api/base_controller.rb +4 -0
- data/spec/dummy/app/controllers/api/v1/architectures_controller.rb +43 -0
- data/spec/dummy/app/controllers/api/v1/base_controller.rb +11 -0
- data/spec/dummy/app/controllers/api/v2/architectures_controller.rb +30 -0
- data/spec/dummy/app/controllers/api/v2/base_controller.rb +11 -0
- data/spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb +32 -0
- data/spec/dummy/app/controllers/api/v2/nested/resources_controller.rb +33 -0
- data/spec/dummy/app/controllers/application_controller.rb +18 -0
- data/spec/dummy/app/controllers/concerns/extending_concern.rb +11 -0
- data/spec/dummy/app/controllers/concerns/sample_controller.rb +41 -0
- data/spec/dummy/app/controllers/concerns_controller.rb +8 -0
- data/spec/dummy/app/controllers/extended_controller.rb +14 -0
- data/spec/dummy/app/controllers/files_controller.rb +5 -0
- data/spec/dummy/app/controllers/overridden_concerns_controller.rb +31 -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 +307 -0
- data/spec/dummy/app/controllers/users_controller.rb +297 -0
- data/spec/dummy/app/views/layouts/application.html.erb +21 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +49 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +21 -0
- data/spec/dummy/config/environment.rb +8 -0
- data/spec/dummy/config/environments/development.rb +28 -0
- data/spec/dummy/config/environments/production.rb +52 -0
- data/spec/dummy/config/environments/test.rb +38 -0
- data/spec/dummy/config/initializers/apipie.rb +110 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +8 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +51 -0
- data/spec/dummy/db/.gitkeep +0 -0
- data/spec/dummy/doc/apipie_examples.json +1 -0
- data/spec/dummy/doc/users/desc_from_file.md +1 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/lib/application_spec.rb +49 -0
- data/spec/lib/extractor/extractor_spec.rb +9 -0
- data/spec/lib/extractor/middleware_spec.rb +44 -0
- data/spec/lib/extractor/writer_spec.rb +110 -0
- data/spec/lib/file_handler_spec.rb +18 -0
- data/spec/lib/method_description_spec.rb +98 -0
- data/spec/lib/param_description_spec.rb +345 -0
- data/spec/lib/param_group_spec.rb +60 -0
- data/spec/lib/rake_spec.rb +71 -0
- data/spec/lib/resource_description_spec.rb +48 -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 +113 -0
- data/spec/lib/validators/array_validator_spec.rb +85 -0
- data/spec/spec_helper.rb +109 -0
- data/spec/support/rake.rb +21 -0
- metadata +415 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Apipie::Extractor::Recorder::Middleware do
|
|
4
|
+
let(:app) { lambda { |env| [200, env, "app"] } }
|
|
5
|
+
let(:stack) { Apipie::Extractor::Recorder::Middleware.new(app) }
|
|
6
|
+
let(:request) { Rack::MockRequest.new(stack) }
|
|
7
|
+
let(:response) { request.get('/') }
|
|
8
|
+
|
|
9
|
+
it 'correctly process request without recording' do
|
|
10
|
+
expect(stack).not_to receive(:analyze)
|
|
11
|
+
response
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "analyze request if recording is set" do
|
|
15
|
+
Apipie.configuration.record = true
|
|
16
|
+
expect(Apipie::Extractor.call_recorder).to receive(:analyse_env)
|
|
17
|
+
expect(Apipie::Extractor.call_recorder).to receive(:analyse_response)
|
|
18
|
+
expect(Apipie::Extractor).to receive(:clean_call_recorder)
|
|
19
|
+
response
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe 'with a multipart post' do
|
|
23
|
+
let(:form_hash) do
|
|
24
|
+
{
|
|
25
|
+
'stringbody' => 'this is a string body',
|
|
26
|
+
'filebody' => {:head => 'X-Fake-Header: fake1\r\n'},
|
|
27
|
+
'files' => {
|
|
28
|
+
'0' => {:head => 'X-Fake-Header: fake2\r\n'}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
let(:response) do
|
|
34
|
+
request.post('/', 'rack.request.form_hash' => form_hash)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'reformats form parts' do
|
|
38
|
+
Apipie.configuration.record = true
|
|
39
|
+
# expect reformat_multipart_data to invoke content_disposition
|
|
40
|
+
expect(Apipie::Extractor.call_recorder).to receive(:content_disposition)
|
|
41
|
+
response
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Apipie::Extractor::Writer do
|
|
4
|
+
|
|
5
|
+
let(:collector) { double "collector" }
|
|
6
|
+
let(:writer_class) { Apipie::Extractor::Writer }
|
|
7
|
+
let(:writer) { writer_class.new(collector) }
|
|
8
|
+
let(:test_examples_file) { File.join(Rails.root, "doc", "apipie_examples_test.json") }
|
|
9
|
+
let(:records) { {
|
|
10
|
+
"concern_resources#show" =>
|
|
11
|
+
[{
|
|
12
|
+
:controller=>ConcernsController,
|
|
13
|
+
:action=>"show",
|
|
14
|
+
:verb=>:GET,
|
|
15
|
+
:path=>"/api/concerns/5",
|
|
16
|
+
:params=>{},
|
|
17
|
+
:query=>"session=secret_hash",
|
|
18
|
+
:request_data=>nil,
|
|
19
|
+
:response_data=>"OK {\"session\"=>\"secret_hash\", \"id\"=>\"5\", \"controller\"=>\"concerns\", \"action\"=>\"show\"}",
|
|
20
|
+
:code=>"200"
|
|
21
|
+
}, {
|
|
22
|
+
:controller=>ConcernsController,
|
|
23
|
+
:action=>"show",
|
|
24
|
+
:verb=>:GET,
|
|
25
|
+
:path=>"/api/concerns/5",
|
|
26
|
+
:params=>{},
|
|
27
|
+
:query=>"",
|
|
28
|
+
:request_data=>nil,
|
|
29
|
+
:response_data=>"OK {\"id\"=>\"5\", \"controller\"=>\"concerns\", \"action\"=>\"show\"}",
|
|
30
|
+
:code=>"200"
|
|
31
|
+
}]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
let(:loaded_records) { {
|
|
35
|
+
"concern_resources#show" =>
|
|
36
|
+
[{
|
|
37
|
+
"verb"=>:GET,
|
|
38
|
+
"path"=>"/api/concerns/5",
|
|
39
|
+
"versions"=>["development"],
|
|
40
|
+
"query"=>"session=secret_hash",
|
|
41
|
+
"request_data"=>nil,
|
|
42
|
+
"response_data"=>"OK {\"session\"=>\"secret_hash\", \"id\"=>\"5\", \"controller\"=>\"concerns\", \"action\"=>\"show\"}",
|
|
43
|
+
"code"=>"200",
|
|
44
|
+
"show_in_doc"=>1,
|
|
45
|
+
"recorded"=>true
|
|
46
|
+
}, {
|
|
47
|
+
"verb"=>:GET,
|
|
48
|
+
"path"=>"/api/concerns/5",
|
|
49
|
+
"versions"=>["development"],
|
|
50
|
+
"query"=>"",
|
|
51
|
+
"request_data"=>nil,
|
|
52
|
+
"response_data"=>"OK {\"id\"=>\"5\", \"controller\"=>\"concerns\", \"action\"=>\"show\"}",
|
|
53
|
+
"code"=>"200",
|
|
54
|
+
"show_in_doc"=>0,
|
|
55
|
+
"recorded"=>true
|
|
56
|
+
}]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
context 'with doc_path overriden in configuration' do
|
|
61
|
+
around(:each) do |example|
|
|
62
|
+
standard_path = Apipie.configuration.doc_path
|
|
63
|
+
Apipie.configuration.doc_path = 'user_specified_doc_path'
|
|
64
|
+
example.run
|
|
65
|
+
Apipie.configuration.doc_path = standard_path
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'should use the doc_path specified in configuration' do
|
|
69
|
+
expect(writer_class.examples_file).to eql(File.join(Rails.root, 'user_specified_doc_path', 'apipie_examples.json'))
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context 'when compressing examples' do
|
|
74
|
+
around(:each) do |example|
|
|
75
|
+
Apipie.configuration.compress_examples = true
|
|
76
|
+
example.run
|
|
77
|
+
FileUtils.rm(writer_class.examples_file) if File.exist?(writer_class.examples_file)
|
|
78
|
+
Apipie.configuration.compress_examples = nil
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'should write to a compressed file' do
|
|
82
|
+
expect(writer_class.examples_file).to match(/\.gz$/)
|
|
83
|
+
writer_class.write_recorded_examples(records)
|
|
84
|
+
expect(File.exist?(writer_class.examples_file))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'should read from a compressed file' do
|
|
88
|
+
writer_class.write_recorded_examples(records)
|
|
89
|
+
expected_string = writer_class.send(:serialize_examples, records)
|
|
90
|
+
expect(writer_class.load_recorded_examples)
|
|
91
|
+
.to eql(writer_class.send(:deserialize_examples, expected_string))
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe "storing of examples" do
|
|
96
|
+
before do
|
|
97
|
+
allow(writer_class).to receive(:examples_file) { test_examples_file }
|
|
98
|
+
expect(collector).to receive(:records).and_return(records)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "should read and write examples" do
|
|
102
|
+
writer.write_examples
|
|
103
|
+
expect(writer.send(:load_recorded_examples)).to eql(loaded_records)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
after do
|
|
107
|
+
File.unlink(test_examples_file) if File.exists?(test_examples_file)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Apipie::FileHandler do
|
|
4
|
+
|
|
5
|
+
describe "match?" do
|
|
6
|
+
let(:file_handler) { Apipie::FileHandler.new File.dirname(__FILE__) }
|
|
7
|
+
|
|
8
|
+
it { expect(file_handler.match? 'file_handler_spec.rb').to be_truthy }
|
|
9
|
+
it { expect(file_handler.match? 'foo.bar').to be_falsy }
|
|
10
|
+
|
|
11
|
+
context 'path contains null bytes' do
|
|
12
|
+
let(:path) { "foo%00.bar" }
|
|
13
|
+
|
|
14
|
+
it { expect(file_handler.match? path).to be_falsy }
|
|
15
|
+
it { expect { file_handler.match? path }.to_not raise_error }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Apipie::MethodDescription do
|
|
4
|
+
|
|
5
|
+
let(:dsl_data) { ActionController::Base.send(:_apipie_dsl_data_init) }
|
|
6
|
+
|
|
7
|
+
describe "metadata" do
|
|
8
|
+
|
|
9
|
+
before(:each) do
|
|
10
|
+
@resource = Apipie::ResourceDescription.new(ApplicationController, "dummy")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should return nil when no metadata is provided" do
|
|
14
|
+
method = Apipie::MethodDescription.new(:a, @resource, dsl_data)
|
|
15
|
+
expect(method.to_json[:metadata]).to eq(nil)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should return the metadata" do
|
|
19
|
+
meta = {
|
|
20
|
+
:lenght => 32,
|
|
21
|
+
:weight => '830g'
|
|
22
|
+
}
|
|
23
|
+
method = Apipie::MethodDescription.new(:a, @resource, dsl_data.update(:meta => meta))
|
|
24
|
+
expect(method.to_json[:metadata]).to eq(meta)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "deprecated flag" do
|
|
30
|
+
before(:each) do
|
|
31
|
+
@resource = Apipie::ResourceDescription.new(ApplicationController, "dummy")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should return the deprecated flag when provided" do
|
|
35
|
+
dsl_data[:api_args] = [[:GET, "/foo/bar", "description", {:deprecated => true}]]
|
|
36
|
+
method = Apipie::MethodDescription.new(:a, @resource, dsl_data)
|
|
37
|
+
expect(method.method_apis_to_json.first[:deprecated]).to eq(true)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should return the deprecated flag if resource is deprecated" do
|
|
41
|
+
@resource.instance_variable_set("@_deprecated", true)
|
|
42
|
+
dsl_data[:api_args] = [[:GET, "/foo/bar", "description", {}]]
|
|
43
|
+
method = Apipie::MethodDescription.new(:a, @resource, dsl_data)
|
|
44
|
+
expect(method.method_apis_to_json.first[:deprecated]).to eq(true)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "params descriptions" do
|
|
49
|
+
|
|
50
|
+
before(:each) do
|
|
51
|
+
@resource = Apipie::ResourceDescription.new(ApplicationController, "dummy")
|
|
52
|
+
dsl_data[:params] = [[:a, String, nil, {}, nil],
|
|
53
|
+
[:b, String, nil, {}, nil],
|
|
54
|
+
[:c, String, nil, {}, nil]]
|
|
55
|
+
@method = Apipie::MethodDescription.new(:a, @resource, dsl_data)
|
|
56
|
+
@resource.add_method_description @method
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should be ordered" do
|
|
60
|
+
expect(@method.params.keys).to eq([:a, :b, :c])
|
|
61
|
+
expect(@method.to_json[:params].map{|h| h[:name]}).to eq(['a', 'b', 'c'])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should be still ordered" do
|
|
65
|
+
expect(@method.params.keys).to eq([:a, :b, :c])
|
|
66
|
+
expect(@method.to_json[:params].map{|h| h[:name]}).to eq(['a', 'b', 'c'])
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe "response-only properties" do
|
|
72
|
+
before(:each) do
|
|
73
|
+
@resource = Apipie::ResourceDescription.new(ApplicationController, "dummy")
|
|
74
|
+
dsl_data[:params] = [[:a, String, nil, {:only_in => :request}, nil],
|
|
75
|
+
[:b, String, nil, {:only_in => :response}, nil],
|
|
76
|
+
[:c, String, nil, {}, nil]]
|
|
77
|
+
@method = Apipie::MethodDescription.new(:a, @resource, dsl_data)
|
|
78
|
+
@resource.add_method_description @method
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "should ignore response-only parameters" do
|
|
82
|
+
expect(@method.params.keys).to eq([:a, :c])
|
|
83
|
+
expect(@method.to_json[:params].map{|h| h[:name]}).to eq(['a', 'c'])
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
describe "'returns' properties" do
|
|
89
|
+
it "should raise an error if both :param_group and :array_of are specified in 'returns'" do
|
|
90
|
+
@resource = Apipie::ResourceDescription.new(ApplicationController, "dummy")
|
|
91
|
+
dsl_data[:returns] = { 200 => [{:param_group => 'pet', :array_of => 'pet'}, nil, nil] }
|
|
92
|
+
|
|
93
|
+
expect {Apipie::MethodDescription.new(:a, @resource, dsl_data)}.to raise_error(Apipie::ReturnsMultipleDefinitionError)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
end
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Apipie::ParamDescription do
|
|
4
|
+
|
|
5
|
+
let(:dsl_data) { ActionController::Base.send(:_apipie_dsl_data_init) }
|
|
6
|
+
|
|
7
|
+
let(:resource_desc) do
|
|
8
|
+
Apipie::ResourceDescription.new(UsersController, "users")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:method_desc) do
|
|
12
|
+
Apipie::MethodDescription.new(:show, resource_desc, dsl_data)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "metadata" do
|
|
16
|
+
|
|
17
|
+
it "should return nil when no metadata is provided" do
|
|
18
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String)
|
|
19
|
+
expect(param.to_json[:metadata]).to eq(nil)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should return the metadata" do
|
|
23
|
+
meta = {
|
|
24
|
+
:lenght => 32,
|
|
25
|
+
:weight => '830g'
|
|
26
|
+
}
|
|
27
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String, :meta => meta)
|
|
28
|
+
expect(param.to_json[:metadata]).to eq(meta)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "show option" do
|
|
34
|
+
|
|
35
|
+
it "should return true when show option is not provided" do
|
|
36
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String)
|
|
37
|
+
expect(param.to_json[:show]).to eq(true)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should return the show option" do
|
|
41
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String, :show => true)
|
|
42
|
+
expect(param.to_json[:show]).to eq(true)
|
|
43
|
+
|
|
44
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String, :show => false)
|
|
45
|
+
expect(param.to_json[:show]).to eq(false)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe "full_name" do
|
|
51
|
+
context "with no nested parameters" do
|
|
52
|
+
|
|
53
|
+
it "should return name" do
|
|
54
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String)
|
|
55
|
+
expect(param.to_json[:full_name]).to eq('some_param')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context "with nested parameters" do
|
|
61
|
+
|
|
62
|
+
it "should return the parameter's name nested in the parents name" do
|
|
63
|
+
parent_param = Apipie::ParamDescription.new(method_desc, :parent, String)
|
|
64
|
+
nested_param = Apipie::ParamDescription.new(method_desc, :nested, String, :parent => parent_param)
|
|
65
|
+
|
|
66
|
+
expect(nested_param.to_json[:full_name]).to eq('parent[nested]')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context "with the parent parameter set to not show" do
|
|
70
|
+
|
|
71
|
+
it "should return just the parameter's name" do
|
|
72
|
+
parent_param = Apipie::ParamDescription.new(method_desc, :parent, String, :show => false)
|
|
73
|
+
nested_param = Apipie::ParamDescription.new(method_desc, :nested, String, :parent => parent_param)
|
|
74
|
+
|
|
75
|
+
expect(nested_param.to_json[:full_name]).to eq('nested')
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
describe "manual validation text" do
|
|
83
|
+
it "should allow manual text" do
|
|
84
|
+
param = Apipie::ParamDescription.new(method_desc, :hidden_param, nil, :validations => "must be foo")
|
|
85
|
+
|
|
86
|
+
expect(param.validations).to include("\n<p>must be foo</p>\n")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "should allow multiple items" do
|
|
90
|
+
param = Apipie::ParamDescription.new(method_desc, :hidden_param, nil, :validations => ["> 0", "< 5"])
|
|
91
|
+
|
|
92
|
+
expect(param.validations).to include("\n<p>> 0</p>\n")
|
|
93
|
+
expect(param.validations).to include("\n<p>< 5</p>\n")
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe "validator selection" do
|
|
98
|
+
|
|
99
|
+
it "should allow nil validator" do
|
|
100
|
+
param = Apipie::ParamDescription.new(method_desc, :hidden_param, nil)
|
|
101
|
+
expect(param.validator).to be_nil
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "should throw exception on unknown validator" do
|
|
105
|
+
expect { Apipie::ParamDescription.new(method_desc, :param, :unknown) }.to raise_error(RuntimeError, /Validator.*not found/)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "should pick type validator" do
|
|
109
|
+
expect(Apipie::Validator::BaseValidator).to receive(:find).and_return(:validator_instance)
|
|
110
|
+
param = Apipie::ParamDescription.new(method_desc, :param, String)
|
|
111
|
+
expect(param.validator).to eq(:validator_instance)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe "concern substitution" do
|
|
117
|
+
|
|
118
|
+
let(:concern_dsl_data) { dsl_data.merge(:from_concern => true) }
|
|
119
|
+
|
|
120
|
+
let(:concern_resource_desc) do
|
|
121
|
+
Apipie::ResourceDescription.new(ConcernsController, "concerns")
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
let(:concern_method_desc) do
|
|
125
|
+
Apipie::MethodDescription.new(:show, concern_resource_desc, concern_dsl_data)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "should replace string parameter name with colon prefix" do
|
|
129
|
+
param = Apipie::ParamDescription.new(concern_method_desc, ":string_subst", String)
|
|
130
|
+
expect(param.name).to eq("string")
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "should replace symbol parameter name" do
|
|
134
|
+
param = Apipie::ParamDescription.new(concern_method_desc, :concern, String)
|
|
135
|
+
expect(param.name).to eq(:user)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "should keep original value for strings without colon prefixes" do
|
|
139
|
+
param = Apipie::ParamDescription.new(concern_method_desc, "string_subst", String)
|
|
140
|
+
expect(param.name).to eq("string_subst")
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "should keep the original value when a string can't be replaced" do
|
|
144
|
+
param = Apipie::ParamDescription.new(concern_method_desc, ":param", String)
|
|
145
|
+
expect(param.name).to eq(":param")
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "should keep the original value when a symbol can't be replaced" do
|
|
149
|
+
param = Apipie::ParamDescription.new(concern_method_desc, :param, String)
|
|
150
|
+
expect(param.name).to eq(:param)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
describe "required_by_default config option" do
|
|
156
|
+
context "parameters required by default" do
|
|
157
|
+
|
|
158
|
+
before { Apipie.configuration.required_by_default = true }
|
|
159
|
+
|
|
160
|
+
it "should set param as required by default" do
|
|
161
|
+
param = Apipie::ParamDescription.new(method_desc, :required_by_default, String)
|
|
162
|
+
expect(param.required).to be true
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "should be possible to set param as optional" do
|
|
166
|
+
param = Apipie::ParamDescription.new(method_desc, :optional, String, :required => false)
|
|
167
|
+
expect(param.required).to be false
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
context "parameters optional by default" do
|
|
173
|
+
|
|
174
|
+
before { Apipie.configuration.required_by_default = false }
|
|
175
|
+
|
|
176
|
+
it "should set param as optional by default" do
|
|
177
|
+
param = Apipie::ParamDescription.new(method_desc, :optional_by_default, String)
|
|
178
|
+
expect(param.required).to be false
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it "should be possible to set param as required" do
|
|
182
|
+
param = Apipie::ParamDescription.new(method_desc, :required, String, 'description','required' => true)
|
|
183
|
+
expect(param.required).to be true
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
describe "required params on given actions" do
|
|
191
|
+
let(:method_desc) do
|
|
192
|
+
Apipie::MethodDescription.new(:create, resource_desc, dsl_data)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
context "when the param is required for current action" do
|
|
196
|
+
it "should set param as required" do
|
|
197
|
+
param = Apipie::ParamDescription.new(method_desc, :required, String, 'description','required' => :create)
|
|
198
|
+
expect(param.required).to be true
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
context "when the param is required for multiple actions" do
|
|
203
|
+
it "should set param as required if it match current action" do
|
|
204
|
+
param = Apipie::ParamDescription.new(method_desc, :required, String, 'description','required' => [:update, :create])
|
|
205
|
+
expect(param.required).to be true
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
context "when the param is not required for current action" do
|
|
210
|
+
it "should set param as not required" do
|
|
211
|
+
param = Apipie::ParamDescription.new(method_desc, :required, String, 'description','required' => :update)
|
|
212
|
+
expect(param.required).to be false
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
describe "required params in action aware validator" do
|
|
218
|
+
|
|
219
|
+
subject { method_description.params[:user].validator.params_ordered }
|
|
220
|
+
|
|
221
|
+
let(:required) do
|
|
222
|
+
subject.find_all(&:required).map(&:name)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
let(:allowed_nil) do
|
|
226
|
+
subject.find_all(&:allow_nil).map(&:name)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
context "with resource creation" do
|
|
230
|
+
|
|
231
|
+
let(:method_description) do
|
|
232
|
+
Apipie.get_method_description(UsersController, :create)
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
it "makes the param required" do
|
|
236
|
+
expect(required).to include :name
|
|
237
|
+
expect(required).to include :pass
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "doesn't allow nil" do
|
|
241
|
+
expect(allowed_nil).not_to include :name
|
|
242
|
+
expect(allowed_nil).not_to include :pass
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
context "with resource update" do
|
|
247
|
+
|
|
248
|
+
let(:method_description) do
|
|
249
|
+
Apipie.get_method_description(UsersController, :update)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it "doesn't make the param required" do
|
|
253
|
+
expect(required).not_to include :name
|
|
254
|
+
expect(required).not_to include :pass
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
it "doesn't allow nil" do
|
|
258
|
+
expect(allowed_nil).not_to include :name
|
|
259
|
+
expect(allowed_nil).not_to include :pass
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
it "doesn't touch params with explicitly set allow_nil" do
|
|
263
|
+
expect(allowed_nil).not_to include :membership
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
context "with explicitly setting action type in param group" do
|
|
268
|
+
let(:method_description) do
|
|
269
|
+
Apipie.get_method_description(UsersController, :admin_create)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
it "makes the param required" do
|
|
273
|
+
expect(required).to include :name
|
|
274
|
+
expect(required).to include :pass
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
it "doesn't allow nil" do
|
|
278
|
+
expect(allowed_nil).not_to include :name
|
|
279
|
+
expect(allowed_nil).not_to include :pass
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
describe 'sub params' do
|
|
286
|
+
|
|
287
|
+
context 'with HashValidator' do
|
|
288
|
+
|
|
289
|
+
subject do
|
|
290
|
+
Apipie::ParamDescription.new(method_desc, :param, Hash) do
|
|
291
|
+
param :answer, Fixnum
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
it "should include the nested params in the json" do
|
|
296
|
+
sub_params = subject.to_json[:params]
|
|
297
|
+
expect(sub_params.size).to eq(1)
|
|
298
|
+
sub_param = sub_params.first
|
|
299
|
+
expect(sub_param[:name]).to eq("answer")
|
|
300
|
+
expect(sub_param[:full_name]).to eq("param[answer]")
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
context 'with NestedValidator' do
|
|
306
|
+
|
|
307
|
+
subject do
|
|
308
|
+
Apipie::ParamDescription.new(method_desc, :param, Array) do
|
|
309
|
+
param :answer, Fixnum
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
it "should include the nested params in the json" do
|
|
314
|
+
sub_params = subject.to_json[:params]
|
|
315
|
+
expect(sub_params.size).to eq(1)
|
|
316
|
+
sub_param = sub_params.first
|
|
317
|
+
expect(sub_param[:name]).to eq("answer")
|
|
318
|
+
expect(sub_param[:full_name]).to eq("param[answer]")
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
context 'with flat validator' do
|
|
324
|
+
|
|
325
|
+
subject do
|
|
326
|
+
Apipie::ParamDescription.new(method_desc, :param, String)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
it "should include the nested params in the json" do
|
|
330
|
+
expect(subject.to_json[:params]).to be_nil
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
describe "Array with classes" do
|
|
338
|
+
it "should be valid for objects included in class array" do
|
|
339
|
+
param = Apipie::ParamDescription.new(method_desc, :param, [Fixnum, String])
|
|
340
|
+
expect { param.validate("1") }.not_to raise_error
|
|
341
|
+
expect { param.validate(Fixnum) }.to raise_error(Apipie::ParamInvalid)
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
end
|