postmates 0.1.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.
@@ -0,0 +1,9 @@
1
+ module Postmates
2
+ class Error < StandardError; end # custom Postmates error class
3
+ class BadRequest < Error; end # 400
4
+ class Unauthorized < Error; end # 401
5
+ class Forbidden < Error; end # 403
6
+ class NotFound < Error; end # 404
7
+ class InternalServerError < Error; end # 500
8
+ class ServiceUnavailable < Error; end # 503
9
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'utils'
2
+
3
+ module Postmates
4
+ class Quote
5
+ include Postmates::Utils
6
+ attr_reader :id, :created_at, :expires_at, :fee,
7
+ :currency, :dropoff_eta, :duration
8
+
9
+ def initialize(hash)
10
+ @id = hash['id']
11
+ @fee = hash['fee']
12
+ @currency = hash['currency']
13
+ @duration = hash['duration']
14
+ @created_at = timeify hash['created']
15
+ @expires_at = timeify hash['expires']
16
+ @dropoff_eta = timeify hash['dropoff_eta']
17
+ end
18
+
19
+ def expired?
20
+ Time.now.utc.to_datetime > expires_at
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'response'
2
+
3
+ module Postmates
4
+ module Request
5
+ def get(path, options = {})
6
+ request(:get, path, options)
7
+ end
8
+
9
+ def post(path, options = {})
10
+ request(:post, path, options)
11
+ end
12
+
13
+ private
14
+
15
+ def request(method, path, options)
16
+ response = connection.send(method) do |request|
17
+ case method
18
+ when :get
19
+ request.url(path, options)
20
+ when :post
21
+ request.path = path
22
+ request.body = options unless options.empty?
23
+ end
24
+ end
25
+ raw_response ? response : Response.build(response.body)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'utils'
2
+ require_relative 'quote'
3
+ require_relative 'delivery'
4
+
5
+ module Postmates
6
+ module Response
7
+ class << self
8
+ include Postmates::Utils
9
+
10
+ def build(body)
11
+ kind = body['object'] || body['kind']
12
+ case kind
13
+ when 'list'
14
+ body['data'].map { |del| Delivery.new(del) }.tap do |list|
15
+ list.instance_variable_set(:@total_count, body['total_count'])
16
+ list.instance_variable_set(:@next_href, urlify(body['next_href']))
17
+ list.class.module_eval { attr_reader :total_count, :next_href }
18
+ end
19
+ when 'delivery'
20
+ Delivery.new(body)
21
+ when 'delivery_quote'
22
+ Quote.new(body)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ require 'uri'
2
+ require 'date'
3
+
4
+ module Postmates
5
+ module Utils
6
+ def urlify(href)
7
+ URI(href) if href
8
+ end
9
+
10
+ def timeify(timestamp)
11
+ DateTime.iso8601 timestamp if timestamp
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Postmates
2
+ class Version
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ PATCH = 0
6
+ PRE = nil
7
+
8
+ class << self
9
+ def to_s
10
+ [MAJOR, MINOR, PATCH, PRE].compact.join('.')
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'postmates/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'postmates'
8
+ s.version = Postmates::Version
9
+ s.authors = ['Rahul Horé']
10
+ s.email = ['hore.rahul@gmail.com']
11
+ s.summary = %q{Ruby wrapper for the Postmates API}
12
+ s.description = %q{Ruby client for the Postmates API}
13
+ s.homepage = 'https://github.com/O-I/postmates'
14
+ s.license = 'MIT'
15
+ s.files = `git ls-files -z`.split("\x0")
16
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
17
+ s.files = s.files - s.test_files
18
+ s.require_paths = ['lib']
19
+ s.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
20
+
21
+ s.add_runtime_dependency 'faraday', ['< 0.10', '>= 0.7']
22
+ s.add_runtime_dependency 'faraday_middleware', ['< 0.10', '>= 0.8']
23
+ s.add_development_dependency 'bundler', '~> 1.7'
24
+ s.add_development_dependency 'rake', '~> 10.0'
25
+ s.add_development_dependency 'rspec', '~> 3.0'
26
+ s.add_development_dependency 'webmock', '~> 1.0'
27
+ s.add_development_dependency 'simplecov', '~> 0.9.0'
28
+ s.add_development_dependency 'coveralls', '~> 0.7.0'
29
+ end
@@ -0,0 +1,116 @@
1
+ describe Postmates::Client do
2
+ let(:client) { postmates_test_client }
3
+ let(:customer_id) { client.customer_id }
4
+
5
+ context 'Customer Delivery endpoints' do
6
+
7
+ describe '#quote' do
8
+ let(:path) { path_to 'delivery_quotes' }
9
+ let(:params) { payload 'quote_params.json' }
10
+ before { stub_post path, params.merge(returns: 'quote.json') }
11
+
12
+ it 'fetches a delivery quote' do
13
+ expect(client.quote(params).id).to eq 'dqt_K9LFfpSZCdAJsk'
14
+ expect(client.quote(params).fee).to eq 1350
15
+ expect(client.quote(params).expired?).to be true
16
+ end
17
+
18
+ it 'returns a Postmates::Quote' do
19
+ expect(client.quote(params)).to be_a Postmates::Quote
20
+ end
21
+ end
22
+
23
+ describe '#create' do
24
+ let(:path) { path_to 'deliveries' }
25
+ let(:params) { payload 'create_params.json' }
26
+ before { stub_post path, params.merge(returns: 'delivery.json') }
27
+
28
+ it 'creates a delivery' do
29
+ expect(client.create(params).id).to eq 'del_K9LFxVVbl5sac-'
30
+ expect(client.create(params).quote_id).to eq 'dqt_K9LFfpSZCdAJsk'
31
+ expect(client.create(params).status).to eq 'pending'
32
+ expect(client.create(params).manifest['description'])
33
+ .to eq 'a box of kittens'
34
+ expect(client.create(params).delivered?).to be false
35
+ end
36
+
37
+ it 'returns a Postmates::Delivery' do
38
+ expect(client.create(params)).to be_a Postmates::Delivery
39
+ end
40
+ end
41
+
42
+ describe '#list' do
43
+ let(:path) { path_to 'deliveries' }
44
+ before { stub_get path, returns: 'deliveries.json' }
45
+
46
+ it 'fetches a list of deliveries' do
47
+ expect(client.list.size).to eq 6
48
+ expect(client.list.first(3).map(&:id))
49
+ .to eq %w(del_K9LFxVVbl5sac- del_K9FmiEl7tKY2i- del_K9Fm9OU1DhW3x-)
50
+ expect(client.list.map(&:status).uniq).to eq %w(delivered canceled)
51
+ end
52
+
53
+ it 'returns an array of Postmates::Delivery objects' do
54
+ expect(client.list).to be_an Array
55
+ expect(client.list.first).to be_a Postmates::Delivery
56
+ end
57
+ end
58
+
59
+ describe '#retrieve' do
60
+ let(:delivery_id) { 'del_K9LFxVVbl5sac-' }
61
+ let(:path) { path_to "deliveries/#{delivery_id}" }
62
+ before { stub_get path, returns: 'delivery.json' }
63
+
64
+ it 'fetches a single delivery by id' do
65
+ expect(client.retrieve(delivery_id).id).to eq 'del_K9LFxVVbl5sac-'
66
+ expect(client.retrieve(delivery_id).quote_id).to eq 'dqt_K9LFfpSZCdAJsk'
67
+ expect(client.retrieve(delivery_id).status).to eq 'pending'
68
+ expect(client.retrieve(delivery_id).manifest['description'])
69
+ .to eq 'a box of kittens'
70
+ expect(client.retrieve(delivery_id).delivered?).to be false
71
+ end
72
+
73
+ it 'returns a Postmates::Delivery' do
74
+ expect(client.retrieve(delivery_id)).to be_a Postmates::Delivery
75
+ end
76
+ end
77
+
78
+ describe '#cancel' do
79
+ let(:delivery_id) { 'del_K9LFxVVbl5sac-' }
80
+ let(:path) { path_to "deliveries/#{delivery_id}/cancel" }
81
+ before { stub_post path, returns: 'delivery.json' }
82
+
83
+ it 'cancels a single delivery by id' do
84
+ expect(client.cancel(delivery_id).id).to eq 'del_K9LFxVVbl5sac-'
85
+ expect(client.cancel(delivery_id).quote_id).to eq 'dqt_K9LFfpSZCdAJsk'
86
+ expect(client.cancel(delivery_id).status).to eq 'pending'
87
+ expect(client.cancel(delivery_id).manifest['description'])
88
+ .to eq 'a box of kittens'
89
+ expect(client.cancel(delivery_id).delivered?).to be false
90
+ end
91
+
92
+ it 'returns a Postmates::Delivery' do
93
+ expect(client.cancel(delivery_id)).to be_a Postmates::Delivery
94
+ end
95
+ end
96
+
97
+ describe '#return' do
98
+ let(:delivery_id) { 'del_K9LFxVVbl5sac-' }
99
+ let(:path) { path_to "deliveries/#{delivery_id}/return" }
100
+ before { stub_post path, returns: 'delivery.json' }
101
+
102
+ it 'returns a single delivery by id' do
103
+ expect(client.return(delivery_id).id).to eq 'del_K9LFxVVbl5sac-'
104
+ expect(client.return(delivery_id).quote_id).to eq 'dqt_K9LFfpSZCdAJsk'
105
+ expect(client.return(delivery_id).status).to eq 'pending'
106
+ expect(client.return(delivery_id).manifest['description'])
107
+ .to eq 'a box of kittens'
108
+ expect(client.return(delivery_id).delivered?).to be false
109
+ end
110
+
111
+ it 'returns a Postmates::Delivery' do
112
+ expect(client.return(delivery_id)).to be_a Postmates::Delivery
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,82 @@
1
+ describe Postmates::Error do
2
+ let(:client) { postmates_test_client }
3
+ let(:customer_id) { client.customer_id }
4
+
5
+ context 'A request' do
6
+ describe 'with invalid parameters' do
7
+ let(:params) { {} }
8
+ before do
9
+ stub_post(path_to('deliveries'),
10
+ params.merge(response_code: 400,
11
+ returns: 'invalid_params.json'))
12
+ end
13
+
14
+ it 'raises Postmates::BadRequest' do
15
+ expect { client.create }
16
+ .to raise_error Postmates::BadRequest
17
+ end
18
+ end
19
+
20
+ describe 'with incorrect authentication' do
21
+ let(:bad_client) { Postmates.new }
22
+ before do
23
+ stub_get(path_to('deliveries'),
24
+ response_code: 401, returns: 'unauthorized.json')
25
+ end
26
+
27
+ it 'raises Postmates::Unauthorized' do
28
+ expect { bad_client.list }
29
+ .to raise_error Postmates::Unauthorized
30
+ end
31
+ end
32
+
33
+ describe 'Forbidden' do
34
+ let(:bad_client) { Postmates.new }
35
+ before do
36
+ stub_get(path_to('deliveries'),
37
+ response_code: 403, returns: 'forbidden.json')
38
+ end
39
+
40
+ it 'raises Postmates::Forbidden' do
41
+ expect { bad_client.list }
42
+ .to raise_error Postmates::Forbidden
43
+ end
44
+ end
45
+
46
+ describe 'for a non-existent resource' do
47
+ before do
48
+ stub_get(path_to('deliveries/bad-id'),
49
+ response_code: 404, returns: 'not_found.json')
50
+ end
51
+
52
+ it 'raises Postmates::NotFound' do
53
+ expect { client.retrieve('bad-id') }
54
+ .to raise_error Postmates::NotFound
55
+ end
56
+ end
57
+
58
+ describe 'when there is a problem processing the request' do
59
+ before do
60
+ stub_get(path_to('deliveries'),
61
+ response_code: 500, returns: 'server_error.json')
62
+ end
63
+
64
+ it 'raises Postmates::InternalServerError' do
65
+ expect { client.list }
66
+ .to raise_error Postmates::InternalServerError
67
+ end
68
+ end
69
+
70
+ describe 'when service is unavailable' do
71
+ before do
72
+ stub_get(path_to('deliveries'),
73
+ response_code: 503, returns: 'service_unavailable.json')
74
+ end
75
+
76
+ it 'raises Postmates::ServiceUnavailable' do
77
+ expect { client.list }
78
+ .to raise_error Postmates::ServiceUnavailable
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,14 @@
1
+ {
2
+ "manifest": "a box of kittens",
3
+ "pickup_name": "The Warehouse",
4
+ "pickup_address": "20 McAllister St, San Francisco, CA",
5
+ "pickup_phone_number": "555-555-5555",
6
+ "pickup_business_name": "Optional Pickup Business Name, Inc.",
7
+ "pickup_notes": "Optional note that this is Invoice #123",
8
+ "dropoff_name": "Alice",
9
+ "dropoff_address": "101 Market St, San Francisco, CA",
10
+ "dropoff_phone_number": "415-555-1234",
11
+ "dropoff_business_name": "Optional Dropoff Business Name, Inc.",
12
+ "dropoff_notes": "Optional note to ring the bell",
13
+ "quote_id": "dqt_K9LFfpSZCdAJsk"
14
+ }
@@ -0,0 +1,242 @@
1
+ {
2
+ "url": "/v1/customers/cus_K8HxOXUT-7afSV/deliveries",
3
+ "total_count": 6,
4
+ "object": "list",
5
+ "data": [
6
+ {
7
+ "status": "delivered",
8
+ "dropoff": {
9
+ "phone_number": "415-555-1234",
10
+ "notes": "Optional note to ring the bell",
11
+ "location": {
12
+ "lat": 37.7930812,
13
+ "lng": -122.395944
14
+ },
15
+ "name": "Alice, Optional Dropoff Business Name, Inc.",
16
+ "address": "101 Market Street"
17
+ },
18
+ "updated": "2015-01-01T18:27:03Z",
19
+ "fee": 1350,
20
+ "quote_id": "dqt_K9LFfpSZCdAJsk",
21
+ "complete": true,
22
+ "courier": null,
23
+ "created": "2015-01-01T18:24:54Z",
24
+ "kind": "delivery",
25
+ "manifest": {
26
+ "description": "a box of kittens"
27
+ },
28
+ "currency": "usd",
29
+ "pickup": {
30
+ "phone_number": "555-555-5555",
31
+ "notes": "Optional note that this is Invoice #123",
32
+ "location": {
33
+ "lat": 37.7811372,
34
+ "lng": -122.4123037
35
+ },
36
+ "name": "The Warehouse, Optional Pickup Business Name, Inc.",
37
+ "address": "20 McAllister Street"
38
+ },
39
+ "dropoff_deadline": "2015-01-01T19:24:54Z",
40
+ "live_mode": false,
41
+ "pickup_eta": null,
42
+ "dropoff_eta": null,
43
+ "id": "del_K9LFxVVbl5sac-"
44
+ },
45
+ {
46
+ "status": "delivered",
47
+ "dropoff": {
48
+ "phone_number": "555-555-5555",
49
+ "notes": "Optional note that this is Invoice #123",
50
+ "location": {
51
+ "lat": 37.7811372,
52
+ "lng": -122.4123037
53
+ },
54
+ "name": "The Warehouse, Optional Pickup Business Name, Inc.",
55
+ "address": "20 McAllister Street"
56
+ },
57
+ "updated": "2014-12-31T17:32:49Z",
58
+ "fee": 1350,
59
+ "quote_id": "dqt_K9Fmi-hAt07qS-",
60
+ "complete": true,
61
+ "courier": null,
62
+ "created": "2014-12-31T17:30:32Z",
63
+ "kind": "delivery",
64
+ "manifest": {
65
+ "description": "a box of kittens"
66
+ },
67
+ "currency": "usd",
68
+ "pickup": {
69
+ "phone_number": "415-555-1234",
70
+ "notes": "Optional note to ring the bell",
71
+ "location": {
72
+ "lat": 37.7930812,
73
+ "lng": -122.395944
74
+ },
75
+ "name": "Alice, Optional Dropoff Business Name, Inc.",
76
+ "address": "101 Market Street"
77
+ },
78
+ "dropoff_deadline": "2014-12-31T18:31:32Z",
79
+ "live_mode": false,
80
+ "pickup_eta": null,
81
+ "dropoff_eta": null,
82
+ "id": "del_K9FmiEl7tKY2i-"
83
+ },
84
+ {
85
+ "status": "delivered",
86
+ "dropoff": {
87
+ "phone_number": "415-555-1234",
88
+ "notes": "Optional note to ring the bell",
89
+ "location": {
90
+ "lat": 37.7930812,
91
+ "lng": -122.395944
92
+ },
93
+ "name": "Alice, Optional Dropoff Business Name, Inc.",
94
+ "address": "101 Market Street"
95
+ },
96
+ "updated": "2014-12-31T17:30:09Z",
97
+ "fee": 1350,
98
+ "quote_id": "dqt_K9Fln3UUgk4WG-",
99
+ "complete": true,
100
+ "courier": null,
101
+ "created": "2014-12-31T17:28:09Z",
102
+ "kind": "delivery",
103
+ "manifest": {
104
+ "description": "a box of kittens"
105
+ },
106
+ "currency": "usd",
107
+ "pickup": {
108
+ "phone_number": "555-555-5555",
109
+ "notes": "Optional note that this is Invoice #123",
110
+ "location": {
111
+ "lat": 37.7811372,
112
+ "lng": -122.4123037
113
+ },
114
+ "name": "The Warehouse, Optional Pickup Business Name, Inc.",
115
+ "address": "20 McAllister Street"
116
+ },
117
+ "dropoff_deadline": "2014-12-31T18:28:09Z",
118
+ "live_mode": false,
119
+ "pickup_eta": null,
120
+ "dropoff_eta": null,
121
+ "id": "del_K9Fm9OU1DhW3x-"
122
+ },
123
+ {
124
+ "status": "canceled",
125
+ "dropoff": {
126
+ "phone_number": "415-555-1234",
127
+ "notes": "Optional note to ring the bell",
128
+ "location": {
129
+ "lat": 37.7930812,
130
+ "lng": -122.395944
131
+ },
132
+ "name": "Alice, Optional Dropoff Business Name, Inc.",
133
+ "address": "101 Market Street"
134
+ },
135
+ "updated": "2014-12-31T03:36:10Z",
136
+ "fee": 1350,
137
+ "quote_id": "dqt_K9Cir_jMr6pQD-",
138
+ "complete": true,
139
+ "courier": null,
140
+ "created": "2014-12-31T03:35:32Z",
141
+ "kind": "delivery",
142
+ "manifest": {
143
+ "description": "a box of kittens"
144
+ },
145
+ "currency": "usd",
146
+ "pickup": {
147
+ "phone_number": "555-555-5555",
148
+ "notes": "Optional note that this is Invoice #123",
149
+ "location": {
150
+ "lat": 37.7811372,
151
+ "lng": -122.4123037
152
+ },
153
+ "name": "The Warehouse, Optional Pickup Business Name, Inc.",
154
+ "address": "20 McAllister Street"
155
+ },
156
+ "dropoff_deadline": "2014-12-31T04:35:32Z",
157
+ "live_mode": false,
158
+ "pickup_eta": null,
159
+ "dropoff_eta": null,
160
+ "id": "del_K9Cj0ADtceFwZV"
161
+ },
162
+ {
163
+ "status": "delivered",
164
+ "dropoff": {
165
+ "phone_number": "415-555-1234",
166
+ "notes": "Optional note to ring the bell",
167
+ "location": {
168
+ "lat": 37.7930812,
169
+ "lng": -122.395944
170
+ },
171
+ "name": "Alice, Optional Dropoff Business Name, Inc.",
172
+ "address": "101 Market Street"
173
+ },
174
+ "updated": "2014-12-26T01:57:57Z",
175
+ "fee": 1350,
176
+ "quote_id": "dqt_K8mzmLxTbVBc--",
177
+ "complete": true,
178
+ "courier": null,
179
+ "created": "2014-12-26T01:56:08Z",
180
+ "kind": "delivery",
181
+ "manifest": {
182
+ "description": "a box of kittens"
183
+ },
184
+ "currency": "usd",
185
+ "pickup": {
186
+ "phone_number": "555-555-5555",
187
+ "notes": "Optional note that this is Invoice #123",
188
+ "location": {
189
+ "lat": 37.7811372,
190
+ "lng": -122.4123037
191
+ },
192
+ "name": "The Warehouse, Optional Pickup Business Name, Inc.",
193
+ "address": "20 McAllister Street"
194
+ },
195
+ "dropoff_deadline": "2014-12-26T02:56:08Z",
196
+ "live_mode": false,
197
+ "pickup_eta": null,
198
+ "dropoff_eta": null,
199
+ "id": "del_K8n-DBrcvQXVGV"
200
+ },
201
+ {
202
+ "status": "delivered",
203
+ "dropoff": {
204
+ "phone_number": "415-555-1234",
205
+ "notes": "Optional note to ring the bell",
206
+ "location": {
207
+ "lat": 37.7930812,
208
+ "lng": -122.395944
209
+ },
210
+ "name": "Alice, Optional Dropoff Business Name, Inc.",
211
+ "address": "101 Market Street"
212
+ },
213
+ "updated": "2014-12-26T00:30:24Z",
214
+ "fee": 1350,
215
+ "quote_id": "dqt_K8mf7VkEo5-n-V",
216
+ "complete": true,
217
+ "courier": null,
218
+ "created": "2014-12-26T00:28:12Z",
219
+ "kind": "delivery",
220
+ "manifest": {
221
+ "description": "a box of kittens"
222
+ },
223
+ "currency": "usd",
224
+ "pickup": {
225
+ "phone_number": "555-555-5555",
226
+ "notes": "Optional note that this is Invoice #123",
227
+ "location": {
228
+ "lat": 37.7811372,
229
+ "lng": -122.4123037
230
+ },
231
+ "name": "The Warehouse, Optional Pickup Business Name, Inc.",
232
+ "address": "20 McAllister Street"
233
+ },
234
+ "dropoff_deadline": "2014-12-26T02:28:12Z",
235
+ "live_mode": false,
236
+ "pickup_eta": null,
237
+ "dropoff_eta": null,
238
+ "id": "del_K8mfb4I7idlgh-"
239
+ }
240
+ ],
241
+ "next_href": null
242
+ }