apiture 0.2.0
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 +7 -0
- data/.gitignore +19 -0
- data/Gemfile +8 -0
- data/LICENSE +20 -0
- data/README.md +38 -0
- data/Rakefile +6 -0
- data/apiture.gemspec +30 -0
- data/lib/apiture.rb +24 -0
- data/lib/apiture/api_base.rb +27 -0
- data/lib/apiture/api_builder.rb +196 -0
- data/lib/apiture/api_error.rb +3 -0
- data/lib/apiture/api_group.rb +28 -0
- data/lib/apiture/data_model.rb +24 -0
- data/lib/apiture/endpoint.rb +25 -0
- data/lib/apiture/middleware/auth/api_key.rb +39 -0
- data/lib/apiture/middleware/auth/basic.rb +25 -0
- data/lib/apiture/middleware/auth/oauth2.rb +31 -0
- data/lib/apiture/middleware/convert_json_body.rb +15 -0
- data/lib/apiture/middleware/debug.rb +20 -0
- data/lib/apiture/middleware/set_body_parameter.rb +20 -0
- data/lib/apiture/middleware/set_header.rb +15 -0
- data/lib/apiture/middleware/set_parameter_base.rb +37 -0
- data/lib/apiture/middleware/set_path_parameter.rb +18 -0
- data/lib/apiture/middleware/set_query_parameter.rb +13 -0
- data/lib/apiture/middleware_builder.rb +15 -0
- data/lib/apiture/middleware_stack.rb +21 -0
- data/lib/apiture/request_context.rb +103 -0
- data/lib/apiture/swagger/data_type_field.rb +25 -0
- data/lib/apiture/swagger/definition.rb +20 -0
- data/lib/apiture/swagger/external_docs.rb +10 -0
- data/lib/apiture/swagger/info.rb +14 -0
- data/lib/apiture/swagger/node.rb +149 -0
- data/lib/apiture/swagger/operation.rb +32 -0
- data/lib/apiture/swagger/parameter.rb +35 -0
- data/lib/apiture/swagger/parser.rb +148 -0
- data/lib/apiture/swagger/path.rb +37 -0
- data/lib/apiture/swagger/property.rb +15 -0
- data/lib/apiture/swagger/security.rb +21 -0
- data/lib/apiture/swagger/security_definition.rb +23 -0
- data/lib/apiture/swagger/specification.rb +31 -0
- data/lib/apiture/uri.rb +36 -0
- data/lib/apiture/utils/inflections.rb +46 -0
- data/lib/apiture/version.rb +3 -0
- data/spec/apiture/api_builder_spec.rb +20 -0
- data/spec/apiture/swagger/parser_spec.rb +107 -0
- data/spec/apiture/swagger/specification_spec.rb +19 -0
- data/spec/apiture_spec.rb +228 -0
- data/spec/files/github.json +186 -0
- data/spec/files/harvest.json +75 -0
- data/spec/files/honeybadger.json +80 -0
- data/spec/files/mandrill.json +502 -0
- data/spec/files/pivotal_tracker.json +94 -0
- data/spec/files/slack.json +88 -0
- data/spec/files/uber.json +43 -0
- data/spec/fixtures/vcr_cassettes/github_checkAuthorization.yml +70 -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/honeybadger.yml +98 -0
- data/spec/fixtures/vcr_cassettes/mandrill_messageSend.yml +44 -0
- data/spec/fixtures/vcr_cassettes/mandrill_userPing.yml +44 -0
- data/spec/fixtures/vcr_cassettes/pivotal_tracker_create_story.yml +61 -0
- data/spec/fixtures/vcr_cassettes/slack.yml +43 -0
- data/spec/fixtures/vcr_cassettes/uber_getProducts.yml +60 -0
- data/spec/spec_helper.rb +11 -0
- metadata +241 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'apiture/swagger/node'
|
2
|
+
|
3
|
+
module Apiture
|
4
|
+
module Swagger
|
5
|
+
class Security < Node
|
6
|
+
attr_reader :id
|
7
|
+
|
8
|
+
attribute :scopes
|
9
|
+
|
10
|
+
def initialize(id)
|
11
|
+
super()
|
12
|
+
@id = id
|
13
|
+
end
|
14
|
+
|
15
|
+
def serializable_hash
|
16
|
+
scopes || []
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'apiture/swagger/node'
|
2
|
+
|
3
|
+
module Apiture
|
4
|
+
module Swagger
|
5
|
+
class SecurityDefinition < Node
|
6
|
+
attr_reader :id
|
7
|
+
|
8
|
+
attribute :type
|
9
|
+
attribute :description
|
10
|
+
attribute :name
|
11
|
+
attribute :in, symbolize: true
|
12
|
+
attribute :flow
|
13
|
+
attribute :authorization_url
|
14
|
+
attribute :token_url
|
15
|
+
attribute :scopes
|
16
|
+
|
17
|
+
def initialize(id)
|
18
|
+
super()
|
19
|
+
@id = id
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'apiture/swagger/info'
|
2
|
+
require 'apiture/swagger/external_docs'
|
3
|
+
require 'apiture/swagger/security'
|
4
|
+
require 'apiture/swagger/security_definition'
|
5
|
+
require 'apiture/swagger/path'
|
6
|
+
require 'apiture/swagger/definition'
|
7
|
+
# require 'apiture/swagger/response'
|
8
|
+
|
9
|
+
module Apiture
|
10
|
+
module Swagger
|
11
|
+
class Specification < Node
|
12
|
+
attribute :swagger
|
13
|
+
attribute :info, validate: true
|
14
|
+
attribute :host
|
15
|
+
attribute :base_path
|
16
|
+
attribute :external_docs, validate: true
|
17
|
+
|
18
|
+
list :schemes
|
19
|
+
list :consumes
|
20
|
+
list :produces
|
21
|
+
list :tags, validate: true
|
22
|
+
|
23
|
+
hash :paths, validate: true
|
24
|
+
hash :definitions, validate: true
|
25
|
+
hash :parameters, validate: true
|
26
|
+
hash :responses, validate: true
|
27
|
+
hash :security_definitions, validate: true
|
28
|
+
hash :security, validate: true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/apiture/uri.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module Apiture
|
2
|
+
class URI
|
3
|
+
|
4
|
+
components = [:scheme, :host, :base_host, :subdomain, :base_path, :resource_path]
|
5
|
+
|
6
|
+
attr_reader *components
|
7
|
+
|
8
|
+
components.each do |comp|
|
9
|
+
define_method "#{comp}=".to_sym do |v|
|
10
|
+
instance_variable_set("@#{comp}", v)
|
11
|
+
build_url
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
build_url
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def build_url
|
22
|
+
host = if base_host && subdomain
|
23
|
+
[subdomain, base_host].join('.')
|
24
|
+
else
|
25
|
+
self.host
|
26
|
+
end
|
27
|
+
[
|
28
|
+
scheme,
|
29
|
+
'://',
|
30
|
+
host,
|
31
|
+
base_path,
|
32
|
+
resource_path
|
33
|
+
].join('')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Apiture
|
2
|
+
module Utils
|
3
|
+
module Inflections
|
4
|
+
|
5
|
+
def self.acronyms
|
6
|
+
@@acronyms ||= {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.acronym_regex
|
10
|
+
@@acronym_regex ||= /(?=a)b/
|
11
|
+
end
|
12
|
+
|
13
|
+
def camelize(term, uppercase_first_letter = true)
|
14
|
+
string = term.to_s
|
15
|
+
if uppercase_first_letter
|
16
|
+
string = string.sub(/^[a-z\d]*/) { ::Apiture::Utils::Inflections.acronyms[$&] || $&.capitalize }
|
17
|
+
else
|
18
|
+
string = string.sub(/^(?:#{::Apiture::Utils::Inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
|
19
|
+
end
|
20
|
+
string.gsub!(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{::Apiture::Utils::Inflections.acronyms[$2] || $2.capitalize}" }
|
21
|
+
string.gsub!('/', '::')
|
22
|
+
string
|
23
|
+
end
|
24
|
+
|
25
|
+
def underscore(camel_cased_word)
|
26
|
+
word = camel_cased_word.to_s.gsub('::', '/')
|
27
|
+
word.gsub!(/(?:([A-Za-z\d])|^)(#{::Apiture::Utils::Inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
|
28
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
29
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
30
|
+
word.tr!("-", "_")
|
31
|
+
word.downcase!
|
32
|
+
word
|
33
|
+
end
|
34
|
+
|
35
|
+
def constantize(camel_cased_word)
|
36
|
+
unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
|
37
|
+
raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
|
38
|
+
end
|
39
|
+
|
40
|
+
Object.module_eval("::#{$1}", __FILE__, __LINE__)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
Apiture::Utils::Inflections.extend(Apiture::Utils::Inflections)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'apiture'
|
3
|
+
|
4
|
+
describe Apiture::APIBuilder do
|
5
|
+
|
6
|
+
def build_spec(name)
|
7
|
+
Apiture.parse_specification(File.join(File.dirname(__FILE__), '..', 'files', "#{name}.json"))
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should build a API class from specification" do
|
11
|
+
api = Apiture::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 = Apiture::APIBuilder.new(build_spec("mandrill")).build
|
17
|
+
expect(api).to_not be_nil
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'apiture/swagger/parser'
|
3
|
+
|
4
|
+
describe Apiture::Swagger::Parser do
|
5
|
+
subject { Apiture::Swagger::Parser }
|
6
|
+
|
7
|
+
def load_spec(name)
|
8
|
+
File.read(File.join(File.dirname(__FILE__), '..', '..', 'files', "#{name}.json"))
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should parse a swagger specification" do
|
12
|
+
specification = Apiture::Swagger::Parser.new.parse(load_spec('pivotal_tracker'))
|
13
|
+
expect(specification).to_not be_nil
|
14
|
+
|
15
|
+
expect(specification.host).to eq "www.pivotaltracker.com"
|
16
|
+
expect(specification.schemes).to include "https"
|
17
|
+
expect(specification.base_path).to eq "/services/v5"
|
18
|
+
|
19
|
+
expect(specification.info).to_not be_nil
|
20
|
+
expect(specification.info.title).to eq "PivotalTracker"
|
21
|
+
expect(specification.info.version).to eq "5"
|
22
|
+
|
23
|
+
api_token = specification.security_definitions['apiToken']
|
24
|
+
expect(api_token).to_not be_nil
|
25
|
+
expect(api_token.type).to eq "apiKey"
|
26
|
+
expect(api_token.in).to eq :header
|
27
|
+
expect(api_token.name).to eq "X-TrackerToken"
|
28
|
+
|
29
|
+
security = specification.security['apiToken']
|
30
|
+
expect(security).to_not be_nil
|
31
|
+
|
32
|
+
expect(specification.produces).to include "application/json"
|
33
|
+
|
34
|
+
expect(specification.paths.count).to eq 1
|
35
|
+
|
36
|
+
path = specification.paths["/projects/{projectId}/stories"]
|
37
|
+
expect(path).to_not be_nil
|
38
|
+
|
39
|
+
expect(path.post).to_not be_nil
|
40
|
+
expect(path.post.operation_id).to eq "createStory"
|
41
|
+
expect(path.post.external_docs.url).to eq "https://www.pivotaltracker.com/help/api/rest/v5#projects_project_id_stories_post"
|
42
|
+
|
43
|
+
expect(path.post.parameters.count).to eq 2
|
44
|
+
|
45
|
+
param1 = path.post.parameters[0]
|
46
|
+
expect(param1).to_not be_nil
|
47
|
+
expect(param1.in).to eq :path
|
48
|
+
expect(param1.name).to eq "projectId"
|
49
|
+
expect(param1).to be_required
|
50
|
+
|
51
|
+
param2 = path.post.parameters[1]
|
52
|
+
expect(param2).to_not be_nil
|
53
|
+
expect(param2.in).to eq :body
|
54
|
+
expect(param2.name).to eq "story"
|
55
|
+
expect(param2).to be_required
|
56
|
+
expect(param2.schema).to eq "NewStory"
|
57
|
+
|
58
|
+
expect(specification.definitions.count).to eq 1
|
59
|
+
|
60
|
+
definition = specification.definitions["NewStory"]
|
61
|
+
expect(definition).to_not be_nil
|
62
|
+
expect(definition.required).to eq ["name"]
|
63
|
+
|
64
|
+
expect(definition.properties.count).to eq 15
|
65
|
+
|
66
|
+
prop1 = definition.properties["cl_numbers"]
|
67
|
+
expect(prop1).to_not be_nil
|
68
|
+
expect(prop1.type).to eq :string
|
69
|
+
|
70
|
+
prop2 = definition.properties["current_state"]
|
71
|
+
expect(prop2).to_not be_nil
|
72
|
+
expect(prop2.type).to eq :string
|
73
|
+
expect(prop2.enum).to eq [
|
74
|
+
"accepted",
|
75
|
+
"delivered",
|
76
|
+
"finished",
|
77
|
+
"started",
|
78
|
+
"rejected",
|
79
|
+
"unstarted",
|
80
|
+
"unscheduled"
|
81
|
+
]
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should parse a swagger specification with an array of schema objects" do
|
85
|
+
specification = Apiture::Swagger::Parser.new.parse(load_spec('slack'))
|
86
|
+
payload = specification.definitions["Payload"]
|
87
|
+
|
88
|
+
attachments_prop = payload.properties['attachments']
|
89
|
+
expect(attachments_prop.type).to eq :array
|
90
|
+
expect(attachments_prop.items.count).to eq 1
|
91
|
+
expect(attachments_prop.items["$ref"]).to eq '#/definitions/Attachment'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should parse a swagger specification with operation specific security" do
|
95
|
+
specification = Apiture::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 = Apiture::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 Apiture::Swagger::Definition
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'apiture/swagger/specification'
|
3
|
+
|
4
|
+
describe Apiture::Swagger::Specification do
|
5
|
+
|
6
|
+
it "should serialize security node as key and scopes" do
|
7
|
+
spec = described_class.new
|
8
|
+
|
9
|
+
security = Apiture::Swagger::Security.new('oauth')
|
10
|
+
security.scopes = ['email']
|
11
|
+
spec.security = { 'oauth' => security }
|
12
|
+
|
13
|
+
hash = spec.serializable_hash
|
14
|
+
security_hash = hash['security']
|
15
|
+
expect(security_hash).to_not be_nil
|
16
|
+
scopes = security_hash['oauth']
|
17
|
+
expect(scopes).to eq ['email']
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'apiture'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
describe Apiture do
|
6
|
+
|
7
|
+
def configure_client(client)
|
8
|
+
#client.logger = Logger.new(STDOUT)
|
9
|
+
#client.logger.level = Logger::DEBUG
|
10
|
+
client
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_api(name)
|
14
|
+
fn = File.join(File.dirname(__FILE__), 'files', "#{name}.json")
|
15
|
+
Apiture.load_api(fn)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe do
|
19
|
+
let(:parser) { double("parser") }
|
20
|
+
|
21
|
+
before do
|
22
|
+
allow(File).to receive(:read)
|
23
|
+
expect(Apiture::Swagger::Parser).to receive(:new).and_return(parser)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should auto-detect whether it is parsing YAML file" do
|
27
|
+
expect(parser).to receive(:parse_yaml)
|
28
|
+
Apiture.parse_specification("foo.yml")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should auto-detect whether it is parsing JSON file" do
|
32
|
+
expect(parser).to receive(:parse_json)
|
33
|
+
Apiture.parse_specification("foo.json")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "Pivotal Tracker API" do
|
38
|
+
before do
|
39
|
+
PivotalTracker = load_api('pivotal_tracker')
|
40
|
+
@client = configure_client(PivotalTracker.new(api_token: 'afaketoken'))
|
41
|
+
end
|
42
|
+
|
43
|
+
after do
|
44
|
+
Object.send(:remove_const, :PivotalTracker)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should be able to build a client" do
|
48
|
+
VCR.use_cassette('pivotal_tracker_create_story') do
|
49
|
+
result = @client.create_story(
|
50
|
+
project_id: '1053124',
|
51
|
+
story: {
|
52
|
+
name: 'Testing Pivotal API',
|
53
|
+
story_type: :chore
|
54
|
+
})
|
55
|
+
expect(result.body['kind']).to eq 'story'
|
56
|
+
expect(result.body).to have_key('id')
|
57
|
+
expect(result.status).to eq 200
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "Honeybadger API" do
|
63
|
+
before do
|
64
|
+
Honeybadger = load_api('honeybadger')
|
65
|
+
@client = configure_client(Honeybadger.new(auth_token: 'afaketoken'))
|
66
|
+
end
|
67
|
+
|
68
|
+
after do
|
69
|
+
Object.send(:remove_const, :Honeybadger)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should be able to build a Honeybadger API client" do
|
73
|
+
VCR.use_cassette('honeybadger') do
|
74
|
+
results = @client.get_faults(project_id: 3167)
|
75
|
+
expect(results.body['results'].first).to have_key('project_id')
|
76
|
+
expect(results.status).to eq 200
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "Slack API" do
|
82
|
+
before do
|
83
|
+
Slack = load_api('slack')
|
84
|
+
@client = configure_client(Slack.new)
|
85
|
+
end
|
86
|
+
|
87
|
+
after do
|
88
|
+
Object.send(:remove_const, :Slack)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should be able to build a Slack API client" do
|
92
|
+
VCR.use_cassette('slack') do
|
93
|
+
results = @client.post_message(path: 'abcd/efgh/ijkl',
|
94
|
+
payload: {
|
95
|
+
text: 'Testing',
|
96
|
+
username: 'TestBot',
|
97
|
+
attachments: [{
|
98
|
+
fallback: "test fallback text",
|
99
|
+
text: "test text",
|
100
|
+
pretext: "test pretext",
|
101
|
+
fields: [{
|
102
|
+
title: "test field 1",
|
103
|
+
value: "test value 1"
|
104
|
+
},{
|
105
|
+
title: "test field 2",
|
106
|
+
value: "test value 2"
|
107
|
+
}]
|
108
|
+
}]
|
109
|
+
})
|
110
|
+
expect(results.status).to eq 200
|
111
|
+
expect(results.body).to eq "ok"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "Github API" do
|
117
|
+
before do
|
118
|
+
Github = load_api("github")
|
119
|
+
@client = configure_client(Github.new(
|
120
|
+
oauth2: { token: "afaketoken" },
|
121
|
+
basic: {
|
122
|
+
username: "afakeclientid",
|
123
|
+
password: "afakeclientsecret"
|
124
|
+
}
|
125
|
+
))
|
126
|
+
end
|
127
|
+
|
128
|
+
after do
|
129
|
+
Object.send(:remove_const, :Github)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should be able to call a zero parameter operation" do
|
133
|
+
VCR.use_cassette('github_getUser') do
|
134
|
+
results = @client.get_user
|
135
|
+
expect(results.status).to eq 200
|
136
|
+
expect(results.body['login']).to eq "cyu"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should be able to use the appropriate security scheme" do
|
141
|
+
VCR.use_cassette('github_checkAuthorization') do
|
142
|
+
results = @client.check_authorization(
|
143
|
+
client_id: "afakeclientid",
|
144
|
+
access_token: "afaketoken"
|
145
|
+
)
|
146
|
+
expect(results.status).to eq 200
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "Uber API" do
|
152
|
+
before do
|
153
|
+
Uber = load_api("uber")
|
154
|
+
@client = configure_client(Uber.new(
|
155
|
+
server_token: "TEST_SERVER_TOKEN"
|
156
|
+
))
|
157
|
+
end
|
158
|
+
|
159
|
+
after do
|
160
|
+
Object.send(:remove_const, :Uber)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should be able to support x-format extension for apiKey" do
|
164
|
+
VCR.use_cassette('uber_getProducts') do
|
165
|
+
results = @client.get_products(latitude: 33.776776, longitude: -84.389683)
|
166
|
+
expect(results.status).to eq 200
|
167
|
+
expect(results.body["products"].length).to eq 5
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "Mandrill API" do
|
173
|
+
before do
|
174
|
+
Mandrill = load_api("mandrill")
|
175
|
+
@client = configure_client(Mandrill.new(
|
176
|
+
key: "fakekey"
|
177
|
+
))
|
178
|
+
end
|
179
|
+
|
180
|
+
after do
|
181
|
+
Object.send(:remove_const, :Mandrill)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should be able to support apiKey in JSON body" do
|
185
|
+
VCR.use_cassette('mandrill_userPing') do
|
186
|
+
result = @client.user_ping
|
187
|
+
expect(result.body).to eq "PONG!"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should be able to build request with apiKey and parameters in JSON body" do
|
192
|
+
VCR.use_cassette('mandrill_messageSend') do
|
193
|
+
result = @client.message_send(request: {
|
194
|
+
message: {
|
195
|
+
text: "testing",
|
196
|
+
subject: "testing",
|
197
|
+
from_email: "test@test.com",
|
198
|
+
to: [ { email: "test@example.com" } ]
|
199
|
+
}
|
200
|
+
}).body
|
201
|
+
expect(result.first["email"]).to eq "test@example.com"
|
202
|
+
expect(result.first["status"]).to eq "sent"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe "Harvest API" do
|
208
|
+
before do
|
209
|
+
Harvest = load_api("harvest")
|
210
|
+
@client = configure_client(Harvest.new(
|
211
|
+
subdomain: "fakedomain",
|
212
|
+
oauth2: {
|
213
|
+
token: "faketoken"
|
214
|
+
}))
|
215
|
+
end
|
216
|
+
|
217
|
+
after do
|
218
|
+
Object.send(:remove_const, :Harvest)
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should support x-base-host extension" do
|
222
|
+
VCR.use_cassette('harvest_invoiceList') do
|
223
|
+
result = @client.invoice_list.body
|
224
|
+
expect(result.length).to eq 2
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|