diesel-api-dsl 0.1.3 → 0.1.5
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 +4 -4
- data/Gemfile +4 -0
- data/diesel.gemspec +1 -1
- data/lib/diesel/api_builder.rb +82 -32
- data/lib/diesel/api_group.rb +3 -2
- data/lib/diesel/middleware/auth/api_key.rb +13 -1
- data/lib/diesel/middleware/auth/basic.rb +27 -0
- data/lib/diesel/middleware/auth/oauth2.rb +2 -2
- data/lib/diesel/middleware/convert_json_body.rb +15 -0
- data/lib/diesel/middleware/set_body_parameter.rb +5 -1
- data/lib/diesel/middleware/set_path_parameter.rb +2 -1
- data/lib/diesel/request_context.rb +7 -1
- data/lib/diesel/swagger/definition.rb +1 -1
- data/lib/diesel/swagger/operation.rb +3 -1
- data/lib/diesel/swagger/parser.rb +25 -9
- data/lib/diesel/uri.rb +36 -0
- data/lib/diesel/version.rb +1 -1
- data/spec/diesel/api_builder_spec.rb +9 -3
- data/spec/diesel/swagger/parser_spec.rb +14 -0
- data/spec/diesel_spec.rb +173 -56
- data/spec/files/github.json +186 -0
- data/spec/files/harvest.json +75 -0
- data/spec/files/mandrill.json +502 -0
- data/spec/files/uber.json +43 -0
- data/spec/fixtures/vcr_cassettes/github_checkAuthorization.yml +71 -0
- data/spec/fixtures/vcr_cassettes/github_getUser.yml +82 -0
- data/spec/fixtures/vcr_cassettes/harvest_invoiceList.yml +85 -0
- data/spec/fixtures/vcr_cassettes/mandrill_userPing.yml +44 -0
- data/spec/fixtures/vcr_cassettes/uber_getProducts.yml +60 -0
- data/spec/spec_helper.rb +1 -0
- metadata +28 -6
data/lib/diesel/version.rb
CHANGED
@@ -3,12 +3,18 @@ require 'diesel'
|
|
3
3
|
|
4
4
|
describe Diesel::APIBuilder do
|
5
5
|
|
6
|
-
|
7
|
-
Diesel.parse_specification(File.join(File.dirname(__FILE__), '..', 'files',
|
6
|
+
def build_spec(name)
|
7
|
+
Diesel.parse_specification(File.join(File.dirname(__FILE__), '..', 'files', "#{name}.json"))
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should build a API class from specification" do
|
11
|
-
api = Diesel::APIBuilder.new(
|
11
|
+
api = Diesel::APIBuilder.new(build_spec("pivotal_tracker")).build
|
12
|
+
expect(api).to_not be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should build a API class from specification" do
|
16
|
+
api = Diesel::APIBuilder.new(build_spec("mandrill")).build
|
17
|
+
expect(api).to_not be_nil
|
12
18
|
end
|
13
19
|
|
14
20
|
end
|
@@ -90,4 +90,18 @@ describe Diesel::Swagger::Parser do
|
|
90
90
|
expect(attachments_prop.items.count).to eq 1
|
91
91
|
expect(attachments_prop.items["$ref"]).to eq '#/definitions/Attachment'
|
92
92
|
end
|
93
|
+
|
94
|
+
it "should parse a swagger specification with operation specific security" do
|
95
|
+
specification = Diesel::Swagger::Parser.new.parse(load_spec('github'))
|
96
|
+
op = specification.paths["/applications/{clientId}/tokens/{accessToken}"].get
|
97
|
+
expect(op.security["basic"]).to_not be_nil
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should parse nested schema objects" do
|
101
|
+
specification = Diesel::Swagger::Parser.new.parse(load_spec('mandrill'))
|
102
|
+
op = specification.paths["/messages/send.json"].post
|
103
|
+
request_param = op.parameters.first
|
104
|
+
expect(specification.consumes).to include "application/json"
|
105
|
+
expect(request_param.schema.class).to eq Diesel::Swagger::Definition
|
106
|
+
end
|
93
107
|
end
|
data/spec/diesel_spec.rb
CHANGED
@@ -4,74 +4,191 @@ require 'logger'
|
|
4
4
|
|
5
5
|
describe Diesel do
|
6
6
|
|
7
|
+
def configure_client(client)
|
8
|
+
#client.logger = Logger.new(STDOUT)
|
9
|
+
#client.logger.level = Logger::DEBUG
|
10
|
+
client
|
11
|
+
end
|
12
|
+
|
7
13
|
def load_api(name)
|
8
14
|
fn = File.join(File.dirname(__FILE__), 'files', "#{name}.json")
|
9
15
|
Diesel.load_api(fn)
|
10
16
|
end
|
11
17
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
18
|
+
describe "Pivotal Tracker API" do
|
19
|
+
before do
|
20
|
+
PivotalTracker = load_api('pivotal_tracker')
|
21
|
+
@client = configure_client(PivotalTracker.new(api_token: 'afaketoken'))
|
22
|
+
end
|
23
|
+
|
24
|
+
after do
|
25
|
+
Object.send(:remove_const, :PivotalTracker)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be able to build a client" do
|
29
|
+
VCR.use_cassette('pivotal_tracker_create_story') do
|
30
|
+
result = @client.create_story(
|
31
|
+
project_id: '1053124',
|
32
|
+
story: {
|
33
|
+
name: 'Testing Pivotal API',
|
34
|
+
story_type: :chore
|
35
|
+
})
|
36
|
+
expect(result['kind']).to eq 'story'
|
37
|
+
expect(result).to have_key('id')
|
38
|
+
expect(result.response.code).to eq "200"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "Honeybadger API" do
|
44
|
+
before do
|
45
|
+
Honeybadger = load_api('honeybadger')
|
46
|
+
@client = configure_client(Honeybadger.new(auth_token: 'afaketoken'))
|
47
|
+
end
|
48
|
+
|
49
|
+
after do
|
50
|
+
Object.send(:remove_const, :Honeybadger)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be able to build a Honeybadger API client" do
|
54
|
+
VCR.use_cassette('honeybadger') do
|
55
|
+
results = @client.get_faults(project_id: 3167)
|
56
|
+
expect(results['results'].first).to have_key('project_id')
|
57
|
+
expect(results.response.code).to eq "200"
|
58
|
+
end
|
28
59
|
end
|
29
60
|
end
|
30
61
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
62
|
+
describe "Slack API" do
|
63
|
+
before do
|
64
|
+
Slack = load_api('slack')
|
65
|
+
@client = configure_client(Slack.new)
|
66
|
+
end
|
67
|
+
|
68
|
+
after do
|
69
|
+
Object.send(:remove_const, :Slack)
|
70
|
+
end
|
36
71
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
72
|
+
it "should be able to build a Slack API client" do
|
73
|
+
VCR.use_cassette('slack') do
|
74
|
+
results = @client.post_message(path: 'abcd/efgh/ijkl',
|
75
|
+
payload: {
|
76
|
+
text: 'Testing',
|
77
|
+
username: 'TestBot',
|
78
|
+
attachments: [{
|
79
|
+
fallback: "test fallback text",
|
80
|
+
text: "test text",
|
81
|
+
pretext: "test pretext",
|
82
|
+
fields: [{
|
83
|
+
title: "test field 1",
|
84
|
+
value: "test value 1"
|
85
|
+
},{
|
86
|
+
title: "test field 2",
|
87
|
+
value: "test value 2"
|
88
|
+
}]
|
89
|
+
}]
|
90
|
+
})
|
91
|
+
expect(results.response.code).to eq "200"
|
92
|
+
expect(results.parsed_response).to eq "ok"
|
93
|
+
end
|
41
94
|
end
|
42
95
|
end
|
43
96
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
97
|
+
describe "Github API" do
|
98
|
+
before do
|
99
|
+
Github = load_api("github")
|
100
|
+
@client = configure_client(Github.new(
|
101
|
+
oauth2: { token: "afaketoken" },
|
102
|
+
basic: {
|
103
|
+
username: "afakeclientid",
|
104
|
+
password: "afakeclientsecret"
|
105
|
+
}
|
106
|
+
))
|
107
|
+
end
|
108
|
+
|
109
|
+
after do
|
110
|
+
Object.send(:remove_const, :Github)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should be able to call a zero parameter operation" do
|
114
|
+
VCR.use_cassette('github_getUser') do
|
115
|
+
results = @client.get_user
|
116
|
+
expect(results.response.code).to eq "200"
|
117
|
+
expect(results.parsed_response['login']).to eq "cyu"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should be able to use the appropriate security scheme" do
|
122
|
+
VCR.use_cassette('github_checkAuthorization') do
|
123
|
+
results = @client.check_authorization(
|
124
|
+
client_id: "afakeclientid",
|
125
|
+
access_token: "afakeaccesstoken"
|
126
|
+
)
|
127
|
+
expect(results.response.code).to eq "200"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "Uber API" do
|
133
|
+
before do
|
134
|
+
Uber = load_api("uber")
|
135
|
+
@client = configure_client(Uber.new(
|
136
|
+
server_token: "TEST_SERVER_TOKEN"
|
137
|
+
))
|
138
|
+
end
|
139
|
+
|
140
|
+
after do
|
141
|
+
Object.send(:remove_const, :Uber)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should be able to support x-format extension for apiKey" do
|
145
|
+
VCR.use_cassette('uber_getProducts') do
|
146
|
+
results = @client.get_products(latitude: 33.776776, longitude: -84.389683)
|
147
|
+
expect(results.response.code).to eq "200"
|
148
|
+
expect(results.parsed_response["products"].length).to eq 5
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "Mandrill API" do
|
154
|
+
before do
|
155
|
+
Mandrill = load_api("mandrill")
|
156
|
+
@client = configure_client(Mandrill.new(
|
157
|
+
key: "fakekey"
|
158
|
+
))
|
159
|
+
end
|
160
|
+
|
161
|
+
after do
|
162
|
+
Object.send(:remove_const, :Mandrill)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should be able to support apiKey in JSON body" do
|
166
|
+
VCR.use_cassette('mandrill_userPing') do
|
167
|
+
result = @client.user_ping
|
168
|
+
expect(result.parsed_response).to eq "PONG!"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "Harvest API" do
|
174
|
+
before do
|
175
|
+
Harvest = load_api("harvest")
|
176
|
+
@client = configure_client(Harvest.new(
|
177
|
+
subdomain: "fakedomain",
|
178
|
+
oauth2: {
|
179
|
+
token: "faketoken"
|
180
|
+
}))
|
181
|
+
end
|
182
|
+
|
183
|
+
after do
|
184
|
+
Object.send(:remove_const, :Harvest)
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should be able to x-base-host extension" do
|
188
|
+
VCR.use_cassette('harvest_invoiceList') do
|
189
|
+
result = @client.invoice_list
|
190
|
+
expect(result.length).to eq 2
|
191
|
+
end
|
75
192
|
end
|
76
193
|
end
|
77
194
|
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
{
|
2
|
+
"swagger": "2.0",
|
3
|
+
|
4
|
+
"info": {
|
5
|
+
"title": "Github",
|
6
|
+
"version": "3"
|
7
|
+
},
|
8
|
+
|
9
|
+
"host": "api.github.com",
|
10
|
+
|
11
|
+
"basePath": "/",
|
12
|
+
|
13
|
+
"schemes": ["https"],
|
14
|
+
|
15
|
+
"produces": ["application/json"],
|
16
|
+
|
17
|
+
"securityDefinitions": {
|
18
|
+
"oauth2": {
|
19
|
+
"type": "oauth2",
|
20
|
+
"flow": "accessCode",
|
21
|
+
"authorizationUrl": "https://github.com/login/oauth/authorize",
|
22
|
+
"tokenUrl": "https://github.com/login/oauth/access_token",
|
23
|
+
"scopes": {
|
24
|
+
"user": "Grants read/write access to profile info only.",
|
25
|
+
"user:email": "Grants read access to a user’s email addresses.",
|
26
|
+
"user:follow": "Grants access to follow or unfollow other users.",
|
27
|
+
"public_repo": "Grants read/write access to code, commit statuses, collaborators, and deployment statuses for public repositories and organizations.",
|
28
|
+
"repo": "Grants read/write access to code, commit statuses, collaborators, and deployment statuses for public and private repositories and organizations.",
|
29
|
+
"repo_deployment": "Grants access to deployment statuses for public and private repositories.",
|
30
|
+
"repo:status": "Grants read/write access to public and private repository commit statuses.",
|
31
|
+
"delete_repo": "Grants access to delete adminable repositories.",
|
32
|
+
"notifications": "Grants read access to a user’s notifications.",
|
33
|
+
"gist": "Grants write access to gists.",
|
34
|
+
"read:repo_hook": "Grants read and ping access to hooks in public or private repositories.",
|
35
|
+
"write:repo_hook": "Grants read, write, and ping access to hooks in public or private repositories.",
|
36
|
+
"admin:repo_hook": "Grants read, write, ping, and delete access to hooks in public or private repositories.",
|
37
|
+
"admin:org_hook": "Grants read, write, ping, and delete access to organization hooks.",
|
38
|
+
"read:org": "Read-only access to organization, teams, and membership.",
|
39
|
+
"write:org": "Publicize and unpublicize organization membership.",
|
40
|
+
"admin:org": "Fully manage organization, teams, and memberships.",
|
41
|
+
"read:public_key": "List and view details for public keys.",
|
42
|
+
"write:public_key": "Create, list, and view details for public keys.",
|
43
|
+
"admin:public_key": "Fully manage public keys."
|
44
|
+
}
|
45
|
+
},
|
46
|
+
"basic": {
|
47
|
+
"type": "basic"
|
48
|
+
}
|
49
|
+
},
|
50
|
+
|
51
|
+
"security": {
|
52
|
+
"oauth2": []
|
53
|
+
},
|
54
|
+
|
55
|
+
"paths": {
|
56
|
+
"/user": {
|
57
|
+
"get": {
|
58
|
+
"summary": "Get the authenticated user",
|
59
|
+
"operationId": "getUser"
|
60
|
+
}
|
61
|
+
},
|
62
|
+
"/user/emails": {
|
63
|
+
"get": {
|
64
|
+
"summary": "List email addresses for a user",
|
65
|
+
"operationId": "getUserEmails",
|
66
|
+
"security": {
|
67
|
+
"basic": ["user:email"]
|
68
|
+
}
|
69
|
+
}
|
70
|
+
},
|
71
|
+
"/user/repos": {
|
72
|
+
"get": {
|
73
|
+
"summary": "List repositories that are accessible to the authenticated user.",
|
74
|
+
"operationId": "getUserRepos",
|
75
|
+
"parameters": [{
|
76
|
+
"name": "visibility",
|
77
|
+
"in": "query",
|
78
|
+
"enum": [
|
79
|
+
"all",
|
80
|
+
"public",
|
81
|
+
"private"
|
82
|
+
]
|
83
|
+
}, {
|
84
|
+
"name": "affiliation",
|
85
|
+
"in": "query"
|
86
|
+
}, {
|
87
|
+
"name": "type",
|
88
|
+
"in": "query",
|
89
|
+
"enum": [
|
90
|
+
"all",
|
91
|
+
"owner",
|
92
|
+
"public",
|
93
|
+
"private",
|
94
|
+
"member"
|
95
|
+
]
|
96
|
+
}, {
|
97
|
+
"name": "sort",
|
98
|
+
"in": "query",
|
99
|
+
"enum": [
|
100
|
+
"created",
|
101
|
+
"updated",
|
102
|
+
"pushed",
|
103
|
+
"full_name"
|
104
|
+
]
|
105
|
+
}, {
|
106
|
+
"name": "direction",
|
107
|
+
"in": "query",
|
108
|
+
"enum": [
|
109
|
+
"asc",
|
110
|
+
"desc"
|
111
|
+
]
|
112
|
+
}]
|
113
|
+
}
|
114
|
+
},
|
115
|
+
"/user/orgs": {
|
116
|
+
"get": {
|
117
|
+
"summary": "List organizations for the authenticated user",
|
118
|
+
"operationId": "getUserOrgs",
|
119
|
+
"security": {
|
120
|
+
"oauth2": [
|
121
|
+
"user",
|
122
|
+
"read:org"
|
123
|
+
]
|
124
|
+
}
|
125
|
+
}
|
126
|
+
},
|
127
|
+
"/orgs/{org}/repos": {
|
128
|
+
"get": {
|
129
|
+
"summary": "List repositories for the specified org",
|
130
|
+
"operationId": "getOrgRepos",
|
131
|
+
"parameters": [{
|
132
|
+
"name": "org",
|
133
|
+
"in": "path",
|
134
|
+
"required": true
|
135
|
+
}, {
|
136
|
+
"name": "type",
|
137
|
+
"in": "query",
|
138
|
+
"enum": [
|
139
|
+
"all",
|
140
|
+
"public",
|
141
|
+
"private",
|
142
|
+
"forks",
|
143
|
+
"sources",
|
144
|
+
"member"
|
145
|
+
]
|
146
|
+
}]
|
147
|
+
}
|
148
|
+
},
|
149
|
+
"/repos/{owner}/{repo}/issues/{number}": {
|
150
|
+
"get": {
|
151
|
+
"summary": "Get a single issue",
|
152
|
+
"operationId": "getIssue",
|
153
|
+
"parameters": [{
|
154
|
+
"name": "owner",
|
155
|
+
"in": "path",
|
156
|
+
"required": true
|
157
|
+
},{
|
158
|
+
"name": "repo",
|
159
|
+
"in": "path",
|
160
|
+
"required": true
|
161
|
+
},{
|
162
|
+
"name": "number",
|
163
|
+
"in": "path",
|
164
|
+
"required": true
|
165
|
+
}]
|
166
|
+
}
|
167
|
+
},
|
168
|
+
"/applications/{clientId}/tokens/{accessToken}": {
|
169
|
+
"get": {
|
170
|
+
"operationId": "checkAuthorization",
|
171
|
+
"parameters": [{
|
172
|
+
"name": "clientId",
|
173
|
+
"in": "path",
|
174
|
+
"required": true
|
175
|
+
},{
|
176
|
+
"name": "accessToken",
|
177
|
+
"in": "path",
|
178
|
+
"required": true
|
179
|
+
}],
|
180
|
+
"security": {
|
181
|
+
"basic": []
|
182
|
+
}
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
}
|