grape-swagger 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+
3
+ describe "API Models" do
4
+
5
+ before :all do
6
+ module Entities
7
+ class Something < Grape::Entity
8
+ expose :text, :documentation => { :type => "string", :desc => "Content of something." }
9
+ end
10
+ end
11
+
12
+ module Entities
13
+ module Some
14
+ class Thing < Grape::Entity
15
+ expose :text, :documentation => { :type => "string", :desc => "Content of something." }
16
+ end
17
+ end
18
+ end
19
+
20
+ class ModelsApi < Grape::API
21
+ format :json
22
+ desc 'This gets something.', {
23
+ entity: Entities::Something
24
+ }
25
+ get '/something' do
26
+ something = OpenStruct.new text: 'something'
27
+ present something, with: Entities::Something
28
+ end
29
+
30
+ desc 'This gets thing.', {
31
+ entity: Entities::Some::Thing
32
+ }
33
+ get "/thing" do
34
+ thing = OpenStruct.new text: 'thing'
35
+ present thing, with: Entities::Some::Thing
36
+ end
37
+ add_swagger_documentation
38
+ end
39
+ end
40
+
41
+ def app; ModelsApi; end
42
+
43
+ it "should document specified models" do
44
+ get '/swagger_doc'
45
+ JSON.parse(last_response.body).should == {
46
+ "apiVersion" => "0.1",
47
+ "swaggerVersion" => "1.2",
48
+ "basePath" => "http://example.org",
49
+ "info" => {},
50
+ "produces" => ["application/json"],
51
+ "operations" => [],
52
+ "apis" => [
53
+ { "path" => "/something.{format}" },
54
+ { "path" => "/thing.{format}" },
55
+ { "path" => "/swagger_doc.{format}" }
56
+ ]
57
+ }
58
+ end
59
+
60
+ it "should include type when specified" do
61
+ get '/swagger_doc/something.json'
62
+ JSON.parse(last_response.body).should == {
63
+ "apiVersion" => "0.1",
64
+ "swaggerVersion" => "1.2",
65
+ "basePath" => "http://example.org",
66
+ "resourcePath" => "",
67
+ "apis" => [{
68
+ "path" => "/something.{format}",
69
+ "operations" => [{
70
+ "produces" => [
71
+ "application/json"
72
+ ],
73
+ "notes" => "",
74
+ "type" => "Something",
75
+ "summary" => "This gets something.",
76
+ "nickname" => "GET-something---format-",
77
+ "httpMethod" => "GET",
78
+ "parameters" => []
79
+ }]
80
+ }],
81
+ "models" => {
82
+ "Something" => {
83
+ "id" => "Something",
84
+ "name" => "Something",
85
+ "properties" => {
86
+ "text" => {
87
+ "type" => "string",
88
+ "description" => "Content of something."
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ end
95
+
96
+ it "should include nested type when specified" do
97
+ get '/swagger_doc/thing.json'
98
+ JSON.parse(last_response.body).should == {
99
+ "apiVersion" => "0.1",
100
+ "swaggerVersion" => "1.2",
101
+ "basePath" => "http://example.org",
102
+ "resourcePath" => "",
103
+ "apis" => [{
104
+ "path" => "/thing.{format}",
105
+ "operations" => [{
106
+ "produces" => [
107
+ "application/json"
108
+ ],
109
+ "notes" => "",
110
+ "type" => "Some::Thing",
111
+ "summary" => "This gets thing.",
112
+ "nickname" => "GET-thing---format-",
113
+ "httpMethod" => "GET",
114
+ "parameters" => []
115
+ }]
116
+ }],
117
+ "models" => {
118
+ "Some::Thing" => {
119
+ "id" => "Some::Thing",
120
+ "name" => "Some::Thing",
121
+ "properties" => {
122
+ "text" => {
123
+ "type" => "string",
124
+ "description" => "Content of something."
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
130
+ end
131
+
132
+ end
@@ -2,21 +2,91 @@ require 'spec_helper'
2
2
 
3
3
  describe "Default API" do
4
4
 
5
- before(:all) do
6
- class NotAMountedApi < Grape::API
7
- desc 'this gets something'
8
- get '/something' do
9
- {:bla => 'something'}
5
+ context 'with no additional options' do
6
+ before :all do
7
+ class NotAMountedApi < Grape::API
8
+ format :json
9
+ desc 'This gets something.'
10
+ get '/something' do
11
+ { bla: 'something' }
12
+ end
13
+ add_swagger_documentation
14
+ end
15
+ end
16
+
17
+ def app; NotAMountedApi; end
18
+
19
+ it "should document something" do
20
+ get '/swagger_doc'
21
+ JSON.parse(last_response.body).should == {
22
+ "apiVersion" => "0.1",
23
+ "swaggerVersion" => "1.2",
24
+ "basePath" => "http://example.org",
25
+ "info" => {},
26
+ "produces" => ["application/json"],
27
+ "operations" => [],
28
+ "apis" => [
29
+ { "path" => "/something.{format}" },
30
+ { "path" => "/swagger_doc.{format}" }
31
+ ]
32
+ }
33
+ end
34
+
35
+ context "path inside the apis array" do
36
+ it "should start with a forward slash" do
37
+ get '/swagger_doc'
38
+ JSON.parse(last_response.body)['apis'].each do |api|
39
+ api['path'].should start_with "/"
40
+ end
10
41
  end
11
- add_swagger_documentation
12
42
  end
13
43
  end
14
44
 
15
- def app; NotAMountedApi; end
45
+ context 'with API info' do
46
+ before :all do
47
+ class ApiInfoTest < Grape::API
48
+ format :json
49
+ add_swagger_documentation info: {
50
+ title: 'My API Title',
51
+ description: 'A description of my API',
52
+ license: 'Apache 2',
53
+ license_url: 'http://test.com',
54
+ terms_of_service_url: 'http://terms.com',
55
+ contact: 'support@test.com'
56
+ }
57
+ end
58
+ get '/swagger_doc'
59
+ end
60
+
61
+ def app; ApiInfoTest; end
16
62
 
17
- it "should document something" do
18
- get '/swagger_doc'
19
- last_response.body.should == "{:apiVersion=>\"0.1\", :swaggerVersion=>\"1.1\", :basePath=>\"http://example.org\", :operations=>[], :apis=>[{:path=>\"/swagger_doc/something.{format}\"}, {:path=>\"/swagger_doc/swagger_doc.{format}\"}]}"
63
+ subject do
64
+ JSON.parse(last_response.body)['info']
65
+ end
66
+
67
+ it 'should document API title' do
68
+ expect(subject['title']).to eql('My API Title')
69
+ end
70
+
71
+ it 'should document API description' do
72
+ expect(subject['description']).to eql('A description of my API')
73
+ end
74
+
75
+ it 'should document the license' do
76
+ expect(subject['license']).to eql('Apache 2')
77
+ end
78
+
79
+ it 'should document the license url' do
80
+ expect(subject['licenseUrl']).to eql('http://test.com')
81
+ end
82
+
83
+ it 'should document the terms of service url' do
84
+ expect(subject['termsOfServiceUrl']).to eql('http://terms.com')
85
+ end
86
+
87
+ it 'should document the contact email' do
88
+ expect(subject['contact']).to eql('support@test.com')
89
+ end
20
90
  end
21
91
 
22
92
  end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Form Params" do
4
+
5
+ before :all do
6
+ class FormParamApi < Grape::API
7
+ format :json
8
+
9
+ params do
10
+ requires :name, type: String, desc: "name of item"
11
+ end
12
+ post '/items' do
13
+ {}
14
+ end
15
+
16
+ params do
17
+ requires :id, type: Integer, desc: "id of item"
18
+ requires :name, type: String, desc: "name of item"
19
+ end
20
+ put '/items/:id' do
21
+ {}
22
+ end
23
+
24
+ params do
25
+ requires :id, type: Integer, desc: "id of item"
26
+ requires :name, type: String, desc: "name of item"
27
+ end
28
+ patch '/items/:id' do
29
+ {}
30
+ end
31
+
32
+ add_swagger_documentation
33
+ end
34
+ end
35
+
36
+ def app; FormParamApi; end
37
+
38
+ it "retrieves the documentation form params" do
39
+ get '/swagger_doc/items.json'
40
+
41
+ JSON.parse(last_response.body).should == {
42
+ "apiVersion" => "0.1",
43
+ "swaggerVersion" => "1.2",
44
+ "resourcePath" => "",
45
+ "basePath"=>"http://example.org",
46
+ "apis" => [
47
+ {
48
+ "path" => "/items.{format}",
49
+ "operations" => [
50
+ {
51
+ "produces" => ["application/json"],
52
+ "notes" => "",
53
+ "summary" => "",
54
+ "nickname" => "POST-items---format-",
55
+ "httpMethod" => "POST",
56
+ "parameters" => [ { "paramType" => "form", "name" => "name", "description" => "name of item", "type" => "String", "dataType" => "String", "required" => true } ]
57
+ }
58
+ ]
59
+ }, {
60
+ "path" => "/items/{id}.{format}",
61
+ "operations" => [
62
+ {
63
+ "produces" => ["application/json"],
64
+ "notes" => "",
65
+ "summary" => "",
66
+ "nickname" => "PUT-items--id---format-",
67
+ "httpMethod" => "PUT",
68
+ "parameters" => [ { "paramType" => "path", "name" => "id", "description" => "id of item", "type" => "Integer", "dataType" => "Integer", "required" => true }, { "paramType" => "form", "name" => "name", "description" => "name of item", "type" => "String", "dataType" => "String", "required" => true } ]
69
+ },
70
+ {
71
+ "produces" => ["application/json"],
72
+ "notes" => "",
73
+ "summary" => "",
74
+ "nickname" => "PATCH-items--id---format-",
75
+ "httpMethod" => "PATCH",
76
+ "parameters" => [ { "paramType" => "path", "name" => "id", "description" => "id of item", "type" => "Integer", "dataType" => "Integer", "required" => true }, { "paramType" => "form", "name" => "name", "description" => "name of item", "type" => "String", "dataType" => "String", "required" => true } ]
77
+ }
78
+ ]
79
+ }
80
+ ]
81
+ }
82
+ end
83
+ end
@@ -0,0 +1,107 @@
1
+ require 'spec_helper'
2
+
3
+ describe "helpers" do
4
+
5
+ before :all do
6
+ class HelperTestAPI < Grape::API
7
+ add_swagger_documentation
8
+ end
9
+ end
10
+
11
+ before :each do
12
+ @api = Object.new
13
+
14
+ # after injecting grape-swagger into the Test API we get the helper methods
15
+ # back from the first endpoint's class (the API mounted by grape-swagger
16
+ # to serve the swagger_doc
17
+
18
+ @api.extend HelperTestAPI.endpoints.first.options[:app].helpers
19
+ end
20
+
21
+ context "parsing parameters" do
22
+ it "parses params as query strings for a GET" do
23
+ params = {
24
+ name: { type: 'String', desc: "A name", required: true, defaultValue: 'default' },
25
+ level: 'max'
26
+ }
27
+ path = "/coolness"
28
+ method = "GET"
29
+ @api.parse_params(params, path, method).should == [
30
+ { paramType: "query", name: :name, description: "A name", type: "String", dataType: "String", required: true, defaultValue: 'default' },
31
+ { paramType: "query", name: :level, description: "", type: "String", dataType: "String", required: false }
32
+ ]
33
+ end
34
+
35
+ it "parses params as form for a POST" do
36
+ params = {
37
+ name: { type: 'String', :desc => "A name", required: true },
38
+ level: 'max'
39
+ }
40
+ path = "/coolness"
41
+ method = "POST"
42
+ @api.parse_params(params, path, method).should == [
43
+ { paramType: "form", name: :name, description: "A name", type: "String", dataType: "String", required: true },
44
+ { paramType: "form", name: :level, description: "", type: "String", dataType: "String", required: false }
45
+ ]
46
+ end
47
+
48
+ context "custom type" do
49
+ before :all do
50
+ class CustomType
51
+ end
52
+ end
53
+ it "parses a custom parameters" do
54
+ params = {
55
+ option: { type: CustomType, desc: "Custom option" }
56
+ }
57
+ path = "/coolness"
58
+ method = "GET"
59
+ @api.parse_params(params, path, method).should == [
60
+ { paramType: "query", name: :option, description: "Custom option", type: "CustomType", dataType: "CustomType", required: false }
61
+ ]
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ context "parsing the path" do
68
+ it "parses the path" do
69
+ path = ":abc/def(.:format)"
70
+ @api.parse_path(path, nil).should == "{abc}/def.{format}"
71
+ end
72
+
73
+ it "parses a path that has vars with underscores in the name" do
74
+ path = "abc/:def_g(.:format)"
75
+ @api.parse_path(path, nil).should == "abc/{def_g}.{format}"
76
+ end
77
+
78
+ it "parses a path that has vars with numbers in the name" do
79
+ path = "abc/:sha1(.:format)"
80
+ @api.parse_path(path, nil).should == "abc/{sha1}.{format}"
81
+ end
82
+
83
+ it "parses a path that has multiple variables" do
84
+ path1 = "abc/:def/:geh(.:format)"
85
+ path2 = "abc/:def:geh(.:format)"
86
+ @api.parse_path(path1, nil).should == "abc/{def}/{geh}.{format}"
87
+ @api.parse_path(path2, nil).should == "abc/{def}{geh}.{format}"
88
+ end
89
+
90
+ it "parses the path with a specified version" do
91
+ path = ":abc/{version}/def(.:format)"
92
+ @api.parse_path(path, 'v1').should == "{abc}/v1/def.{format}"
93
+ end
94
+ end
95
+
96
+ context "parsing header parameters" do
97
+ it "parses params for the header" do
98
+ params = {
99
+ "XAuthToken" => { description: "A required header.", required: true, defaultValue: 'default' }
100
+ }
101
+ @api.parse_header_params(params).should == [
102
+ { paramType: "header", name: "XAuthToken", description: "A required header.", type: "String", dataType: "String", required: true, defaultValue: 'default' }
103
+ ]
104
+ end
105
+ end
106
+
107
+ end
@@ -10,6 +10,4 @@ describe Grape::API do
10
10
  Grape::API.should respond_to :add_swagger_documentation
11
11
  end
12
12
 
13
-
14
-
15
13
  end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe "a hide mounted api" do
4
+ before :all do
5
+ class HideMountedApi < Grape::API
6
+ desc 'Show this endpoint'
7
+ get '/simple' do
8
+ { :foo => 'bar' }
9
+ end
10
+
11
+ desc 'Hide this endpoint', {
12
+ :hidden => true
13
+ }
14
+ get '/hide' do
15
+ { :foo => 'bar' }
16
+ end
17
+ end
18
+
19
+ class HideApi < Grape::API
20
+ mount HideMountedApi
21
+ add_swagger_documentation
22
+ end
23
+ end
24
+
25
+ def app; HideApi end
26
+
27
+ it "retrieves swagger-documentation that doesn't include hidden endpoints" do
28
+ get '/swagger_doc.json'
29
+ JSON.parse(last_response.body).should == {
30
+ "apiVersion" => "0.1",
31
+ "swaggerVersion" => "1.2",
32
+ "basePath" => "http://example.org",
33
+ "info" => {},
34
+ "produces" => ["application/xml", "application/json", "text/plain"],
35
+ "operations" => [],
36
+ "apis" => [
37
+ { "path" => "/simple.{format}" },
38
+ { "path" => "/swagger_doc.{format}" }
39
+ ]
40
+ }
41
+ end
42
+ end
43
+
44
+
45
+ describe "a hide mounted api with same namespace" do
46
+ before :all do
47
+ class HideNamespaceMountedApi < Grape::API
48
+ desc 'Show this endpoint'
49
+ get '/simple/show' do
50
+ { :foo => 'bar' }
51
+ end
52
+
53
+ desc 'Hide this endpoint', {
54
+ :hidden => true
55
+ }
56
+ get '/simple/hide' do
57
+ { :foo => 'bar' }
58
+ end
59
+ end
60
+
61
+ class HideNamespaceApi < Grape::API
62
+ mount HideNamespaceMountedApi
63
+ add_swagger_documentation
64
+ end
65
+ end
66
+
67
+ def app; HideNamespaceApi end
68
+
69
+ it "retrieves swagger-documentation on /swagger_doc" do
70
+ get '/swagger_doc.json'
71
+ JSON.parse(last_response.body).should == {
72
+ "apiVersion" => "0.1",
73
+ "swaggerVersion" => "1.2",
74
+ "basePath" => "http://example.org",
75
+ "info" => {},
76
+ "produces" => ["application/xml", "application/json", "text/plain"],
77
+ "operations" => [],
78
+ "apis" => [
79
+ { "path" => "/simple.{format}" },
80
+ { "path" => "/swagger_doc.{format}" }
81
+ ]
82
+ }
83
+ end
84
+
85
+ it "retrieves the documentation for mounted-api that doesn't include hidden endpoints" do
86
+ get '/swagger_doc/simple.json'
87
+ JSON.parse(last_response.body).should == {
88
+ "apiVersion" => "0.1",
89
+ "swaggerVersion" => "1.2",
90
+ "basePath" => "http://example.org",
91
+ "resourcePath" => "",
92
+ "apis" => [{
93
+ "path" => "/simple/show.{format}",
94
+ "operations" => [{
95
+ "produces" => ["application/xml", "application/json", "text/plain"],
96
+ "notes" => nil,
97
+ "notes" => "",
98
+ "summary" => "Show this endpoint",
99
+ "nickname" => "GET-simple-show---format-",
100
+ "httpMethod" => "GET",
101
+ "parameters" => []
102
+ }]
103
+ }]
104
+ }
105
+ end
106
+ end