sendle-api 0.0.2 → 0.0.11
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/Changelog.md +5 -0
- data/README.md +99 -5
- data/lib/sendle/api.rb +46 -3
- data/lib/sendle/api/actions/base.rb +51 -0
- data/lib/sendle/api/actions/create.rb +31 -0
- data/lib/sendle/api/actions/destroy.rb +23 -0
- data/lib/sendle/api/actions/index.rb +16 -14
- data/lib/sendle/api/actions/show.rb +23 -0
- data/lib/sendle/api/constants.rb +4 -0
- data/lib/sendle/api/errors/invalid_plan.rb +16 -0
- data/lib/sendle/api/errors/missing_params.rb +16 -0
- data/lib/sendle/api/errors/payment_required.rb +9 -0
- data/lib/sendle/api/errors/precondition_failed.rb +9 -0
- data/lib/sendle/api/errors/unprocessable_entity.rb +19 -0
- data/lib/sendle/api/factories/errors.rb +26 -0
- data/lib/sendle/api/order.rb +41 -0
- data/lib/sendle/api/ping.rb +8 -3
- data/lib/sendle/api/quote.rb +28 -0
- data/lib/sendle/api/resource.rb +64 -0
- data/lib/sendle/api/responses/json.rb +15 -0
- data/lib/sendle/api/sugars/create.rb +13 -0
- data/lib/sendle/api/sugars/destroy.rb +13 -0
- data/lib/sendle/api/sugars/index.rb +13 -0
- data/lib/sendle/api/sugars/show.rb +13 -0
- data/lib/sendle/api/utils.rb +24 -0
- data/lib/sendle/api/version.rb +1 -1
- data/spec/sendle/api/order_spec.rb +249 -0
- data/spec/sendle/api/ping_spec.rb +9 -1
- data/spec/sendle/api/quote_spec.rb +103 -0
- data/spec/sendle/api_spec.rb +22 -0
- data/spec/sendle/errors/missing_params_spec.rb +13 -0
- data/spec/support/helpers.rb +15 -1
- data/spec/support/shared_examples/with_credentials_spec.rb +1 -1
- metadata +29 -3
- data/lib/sendle/utils/actions.rb +0 -19
@@ -0,0 +1,26 @@
|
|
1
|
+
module Sendle
|
2
|
+
module Api
|
3
|
+
module Factories
|
4
|
+
class Errors
|
5
|
+
|
6
|
+
def self.new_error(rest_client_error)
|
7
|
+
response = JSON.parse(rest_client_error.response)
|
8
|
+
error_text = response['error_description']
|
9
|
+
messages = response['messages']
|
10
|
+
|
11
|
+
case rest_client_error
|
12
|
+
when RestClient::Unauthorized
|
13
|
+
Sendle::Api::Errors::Unauthorized.new(error_text)
|
14
|
+
when RestClient::PaymentRequired
|
15
|
+
Sendle::Api::Errors::PaymentRequired.new(error_text)
|
16
|
+
when RestClient::UnprocessableEntity
|
17
|
+
Sendle::Api::Errors::UnprocessableEntity.new(messages)
|
18
|
+
when RestClient::PreconditionFailed
|
19
|
+
Sendle::Api::Errors::PreconditionFailed.new(error_text)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class Sendle::Api::Order < Sendle::Api::Resource
|
2
|
+
include Sendle::Api::Actions::Create
|
3
|
+
include Sendle::Api::Actions::Show
|
4
|
+
include Sendle::Api::Actions::Destroy
|
5
|
+
|
6
|
+
def url
|
7
|
+
Sendle::Api.base_url + "orders"
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate_create_request!(params)
|
11
|
+
# Checking for required params of parcel
|
12
|
+
required = %w( pickup_date kilogram_weight cubic_metre_volume )
|
13
|
+
validate_presence_of!(required, params)
|
14
|
+
|
15
|
+
# Checking for sender params
|
16
|
+
raise Sendle::Api::Errors::MissingParams.new(['sender']) unless hash_contains?(params, :sender)
|
17
|
+
|
18
|
+
sender_params = params[:sender]
|
19
|
+
raise Sendle::Api::Errors::MissingParams.new(['sender:contact']) unless hash_contains?(sender_params, :contact)
|
20
|
+
required = %w( name phone )
|
21
|
+
validate_presence_of!(required, sender_params[:contact])
|
22
|
+
|
23
|
+
raise Sendle::Api::Errors::MissingParams.new(['sender:address']) unless hash_contains?(sender_params, :address)
|
24
|
+
required = %w( address_line1 suburb postcode state_name )
|
25
|
+
validate_presence_of!(required, sender_params[:address])
|
26
|
+
|
27
|
+
# Checking for receiver params
|
28
|
+
raise Sendle::Api::Errors::MissingParams.new(['receiver']) unless hash_contains?(params, :receiver)
|
29
|
+
|
30
|
+
receiver_params = params[:receiver]
|
31
|
+
raise Sendle::Api::Errors::MissingParams.new(['receiver:contact']) unless hash_contains?(receiver_params, :contact)
|
32
|
+
required = %w( name )
|
33
|
+
validate_presence_of!(required, receiver_params[:contact])
|
34
|
+
|
35
|
+
raise Sendle::Api::Errors::MissingParams.new(['receiver:address']) unless hash_contains?(receiver_params, :address)
|
36
|
+
required = %w( address_line1 suburb postcode state_name )
|
37
|
+
validate_presence_of!(required, receiver_params[:address])
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/sendle/api/ping.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
|
-
class Sendle::Api::Ping
|
2
|
-
|
1
|
+
class Sendle::Api::Ping < Sendle::Api::Resource
|
2
|
+
include Sendle::Api::Actions::Index
|
3
3
|
|
4
4
|
class << self
|
5
5
|
alias_method :execute, :index
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
8
|
+
def url
|
9
9
|
Sendle::Api.base_url + "ping"
|
10
10
|
end
|
11
|
+
|
12
|
+
def process_index_response(response)
|
13
|
+
Sendle::Api::Responses::Pong.new
|
14
|
+
end
|
15
|
+
|
11
16
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Sendle::Api::Quote < Sendle::Api::Resource
|
2
|
+
include Sendle::Api::Actions::Index
|
3
|
+
|
4
|
+
class << self
|
5
|
+
alias_method :execute, :index
|
6
|
+
end
|
7
|
+
|
8
|
+
def url
|
9
|
+
Sendle::Api.base_url + "quote"
|
10
|
+
end
|
11
|
+
|
12
|
+
def include_credentials?
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate_index_request!(params)
|
17
|
+
# Checking for required params
|
18
|
+
required = %w( pickup_suburb pickup_postcode delivery_suburb delivery_postcode kilogram_weight)
|
19
|
+
validate_presence_of!(required, params)
|
20
|
+
|
21
|
+
# Checking for valid plan_name, if passed in
|
22
|
+
if params[:plan_name]
|
23
|
+
plan_name = params[:plan_name]
|
24
|
+
raise Sendle::Api::Errors::InvalidPlan.new(plan_name) unless PLANS.include?(plan_name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
class Sendle::Api::Resource
|
2
|
+
include Sendle::Api::Actions::Base
|
3
|
+
|
4
|
+
def url
|
5
|
+
raise "An API Resource must implement the url method."
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.url
|
9
|
+
self.new.url
|
10
|
+
end
|
11
|
+
|
12
|
+
def include_credentials?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
#Index action hook methods
|
17
|
+
def validate_index_request!(params)
|
18
|
+
end
|
19
|
+
|
20
|
+
def process_index_response(response)
|
21
|
+
return_json(response)
|
22
|
+
end
|
23
|
+
|
24
|
+
#Create action hook methods
|
25
|
+
def validate_create_request!(params)
|
26
|
+
end
|
27
|
+
|
28
|
+
def process_create_response(response)
|
29
|
+
return_json(response)
|
30
|
+
end
|
31
|
+
|
32
|
+
#Show action hook methods
|
33
|
+
def process_show_response(response)
|
34
|
+
return_json(response)
|
35
|
+
end
|
36
|
+
|
37
|
+
#Destroy action hook methods
|
38
|
+
def process_destroy_response(response)
|
39
|
+
return_json(response)
|
40
|
+
end
|
41
|
+
|
42
|
+
def method_missing(m, *args, &blk)
|
43
|
+
if Sendle::Api::Utils.respond_to?(m)
|
44
|
+
Sendle::Api::Utils.send(m, *args)
|
45
|
+
else
|
46
|
+
super(m, *args, blk)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def return_json(response)
|
53
|
+
Sendle::Api::Responses::Json.new(response)
|
54
|
+
end
|
55
|
+
|
56
|
+
def validate_presence_of!(required_params, hash)
|
57
|
+
symbolize_strings(required_params).each do |required_param|
|
58
|
+
if (!hash.key?(required_param) || nullish?(hash[required_param]))
|
59
|
+
raise Sendle::Api::Errors::MissingParams.new(required_params)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sendle
|
2
|
+
module Api
|
3
|
+
class Utils
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def symbolize_strings(array_string)
|
8
|
+
array_string.map { |x| x.to_sym }
|
9
|
+
end
|
10
|
+
|
11
|
+
def nullish?(v)
|
12
|
+
v.nil? || v.to_s.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
def hash_contains?(hash, key)
|
16
|
+
hash.key?(key) && !hash[key].nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/lib/sendle/api/version.rb
CHANGED
@@ -0,0 +1,249 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Sendle::Api::Order do
|
4
|
+
|
5
|
+
let(:api_key) { 'fake_key' }
|
6
|
+
let(:sendle_id) { 'fake_id' }
|
7
|
+
|
8
|
+
before do
|
9
|
+
Sendle::Api.api_key = api_key
|
10
|
+
Sendle::Api.sendle_id = sendle_id
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#create" do
|
14
|
+
let(:params) {
|
15
|
+
{
|
16
|
+
pickup_date: "2016-05-05",
|
17
|
+
description: "Kryptonite",
|
18
|
+
kilogram_weight: 1,
|
19
|
+
cubic_metre_volume: 0.01,
|
20
|
+
customer_reference: "SupBdayPressie",
|
21
|
+
sender: {
|
22
|
+
contact: {
|
23
|
+
name: "Lex Luthor",
|
24
|
+
phone: "0412 345 678"
|
25
|
+
},
|
26
|
+
address: {
|
27
|
+
address_line1: "123 Gotham Ln",
|
28
|
+
suburb: "Sydney",
|
29
|
+
state_name: "NSW",
|
30
|
+
postcode: "2000",
|
31
|
+
country: "Australia"
|
32
|
+
},
|
33
|
+
instructions: "Knock loudly"
|
34
|
+
},
|
35
|
+
receiver: {
|
36
|
+
contact: {
|
37
|
+
name: "Clark Kent",
|
38
|
+
email: "clarkissuper@dailyplanet.xyz"
|
39
|
+
},
|
40
|
+
address: {
|
41
|
+
address_line1: "80 Wentworth Park Road",
|
42
|
+
suburb: "Glebe",
|
43
|
+
state_name: "NSW",
|
44
|
+
postcode: "2037",
|
45
|
+
country: "Australia"
|
46
|
+
},
|
47
|
+
instructions: "Give directly to Clark"
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
it_behaves_like "a resource action with credentials"
|
53
|
+
|
54
|
+
describe "parcel param validation" do
|
55
|
+
it "validates presence of required params" do
|
56
|
+
params[:pickup_date] = nil
|
57
|
+
params[:kilogram_weight] = nil
|
58
|
+
params[:cubic_metre_volume] = nil
|
59
|
+
|
60
|
+
expect {
|
61
|
+
Sendle::Api::Order.create(params)
|
62
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: pickup_date, kilogram_weight, cubic_metre_volume. Please check your request and try again.")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "sender details" do
|
67
|
+
it "validates presence of sender object" do
|
68
|
+
params[:sender] = nil
|
69
|
+
|
70
|
+
expect {
|
71
|
+
Sendle::Api::Order.create(params)
|
72
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: sender. Please check your request and try again.")
|
73
|
+
end
|
74
|
+
|
75
|
+
it "validates presence of contact" do
|
76
|
+
params[:sender][:contact] = nil
|
77
|
+
|
78
|
+
expect {
|
79
|
+
Sendle::Api::Order.create(params)
|
80
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: sender:contact. Please check your request and try again.")
|
81
|
+
end
|
82
|
+
|
83
|
+
it "validates name and phone of contact" do
|
84
|
+
expect {
|
85
|
+
[:phone, :name].each { |attr| params[:sender][:contact][attr] = nil }
|
86
|
+
Sendle::Api::Order.create(params)
|
87
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: name, phone. Please check your request and try again.")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "validates presence of address" do
|
91
|
+
params[:sender][:address] = nil
|
92
|
+
|
93
|
+
expect {
|
94
|
+
Sendle::Api::Order.create(params)
|
95
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: sender:address. Please check your request and try again.")
|
96
|
+
end
|
97
|
+
|
98
|
+
it "validates address_line1, suburb, postcode, state_name of the address" do
|
99
|
+
expect {
|
100
|
+
[:address_line1, :suburb, :postcode, :state_name].each { |attr| params[:sender][:address][attr] = nil }
|
101
|
+
Sendle::Api::Order.create(params)
|
102
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: address_line1, suburb, postcode, state_name. Please check your request and try again.")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "receiver details" do
|
107
|
+
it "validates presence of receiver object" do
|
108
|
+
params[:receiver] = nil
|
109
|
+
|
110
|
+
expect {
|
111
|
+
Sendle::Api::Order.create(params)
|
112
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: receiver. Please check your request and try again.")
|
113
|
+
end
|
114
|
+
|
115
|
+
it "validates presence of contact" do
|
116
|
+
params[:receiver][:contact] = nil
|
117
|
+
|
118
|
+
expect {
|
119
|
+
Sendle::Api::Order.create(params)
|
120
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: receiver:contact. Please check your request and try again.")
|
121
|
+
end
|
122
|
+
|
123
|
+
it "validates name of receiver" do
|
124
|
+
expect {
|
125
|
+
params[:receiver][:contact][:name] = nil
|
126
|
+
Sendle::Api::Order.create(params)
|
127
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: name. Please check your request and try again.")
|
128
|
+
end
|
129
|
+
|
130
|
+
it "validates presence of address" do
|
131
|
+
params[:receiver][:address] = nil
|
132
|
+
|
133
|
+
expect {
|
134
|
+
Sendle::Api::Order.create(params)
|
135
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: receiver:address. Please check your request and try again.")
|
136
|
+
end
|
137
|
+
|
138
|
+
it "validates address_line1, suburb, postcode, state_name of the address" do
|
139
|
+
expect {
|
140
|
+
[:address_line1, :suburb, :postcode, :state_name].each { |attr| params[:receiver][:address][attr] = nil }
|
141
|
+
Sendle::Api::Order.create(params)
|
142
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: address_line1, suburb, postcode, state_name. Please check your request and try again.")
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
it "handles 412" do
|
147
|
+
expect(RestClient::Request).to receive(:execute).and_raise(PRECONDITION_FAILED_ERROR)
|
148
|
+
|
149
|
+
expect {
|
150
|
+
Sendle::Api::Order.create(params)
|
151
|
+
}.to raise_error(Sendle::Api::Errors::PreconditionFailed, "The account associated with this API key has not accepted the dangerous goods terms. Please visit your Account Settings in https://www.sendle.com/dashboard/ to view and accept these terms.")
|
152
|
+
end
|
153
|
+
|
154
|
+
it "makes the correct request" do
|
155
|
+
expected_params = {
|
156
|
+
method: :post,
|
157
|
+
url: Sendle::Api::Order.url,
|
158
|
+
headers: {
|
159
|
+
accept: :json,
|
160
|
+
content_type: :json
|
161
|
+
},
|
162
|
+
payload: params
|
163
|
+
}
|
164
|
+
|
165
|
+
expect(RestClient::Request).to receive(:execute).with(hash_including(expected_params)).and_return(ORDER_CREATED_RESPONSE)
|
166
|
+
|
167
|
+
Sendle::Api::Order.create(params)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "returns the correct response" do
|
171
|
+
allow(RestClient::Request).to receive(:execute).and_return(ORDER_CREATED_RESPONSE)
|
172
|
+
|
173
|
+
response = Sendle::Api::Order.create(params)
|
174
|
+
|
175
|
+
expect(response).to be_a Sendle::Api::Responses::Json
|
176
|
+
expect(response.json).to eq JSON.parse(ORDER_CREATED_RESPONSE)
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "#show" do
|
182
|
+
let(:order_id) { "9dbadcd6-ee57-488e-a175-49e378ad29ff" }
|
183
|
+
|
184
|
+
it "throws an error if id isn't provided" do
|
185
|
+
expect {
|
186
|
+
Sendle::Api::Order.show(nil)
|
187
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: id. Please check your request and try again.")
|
188
|
+
end
|
189
|
+
|
190
|
+
it "makes the correct request" do
|
191
|
+
expected_params = {
|
192
|
+
method: :get,
|
193
|
+
url: Sendle::Api::Order.url + "/#{order_id}",
|
194
|
+
headers: {
|
195
|
+
accept: :json,
|
196
|
+
content_type: :json
|
197
|
+
}
|
198
|
+
}
|
199
|
+
|
200
|
+
expect(RestClient::Request).to receive(:execute).with(hash_including(expected_params)).and_return(ORDER_CREATED_RESPONSE)
|
201
|
+
|
202
|
+
Sendle::Api::Order.show(order_id)
|
203
|
+
end
|
204
|
+
|
205
|
+
it "returns the correct response" do
|
206
|
+
allow(RestClient::Request).to receive(:execute).and_return(ORDER_GET_RESPONSE)
|
207
|
+
|
208
|
+
response = Sendle::Api::Order.show(order_id)
|
209
|
+
|
210
|
+
expect(response).to be_a Sendle::Api::Responses::Json
|
211
|
+
expect(response.json).to eq JSON.parse(ORDER_GET_RESPONSE)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "#destroy" do
|
216
|
+
let(:order_id) { "9dbadcd6-ee57-488e-a175-49e378ad29ff" }
|
217
|
+
|
218
|
+
it "throws an error if id isn't provided" do
|
219
|
+
expect {
|
220
|
+
Sendle::Api::Order.destroy(nil)
|
221
|
+
}.to raise_error(Sendle::Api::Errors::MissingParams, "The following params are required: id. Please check your request and try again.")
|
222
|
+
end
|
223
|
+
|
224
|
+
it "makes the correct request" do
|
225
|
+
expected_params = {
|
226
|
+
method: :delete,
|
227
|
+
url: Sendle::Api::Order.url + "/#{order_id}",
|
228
|
+
headers: {
|
229
|
+
accept: :json,
|
230
|
+
content_type: :json
|
231
|
+
}
|
232
|
+
}
|
233
|
+
|
234
|
+
expect(RestClient::Request).to receive(:execute).with(hash_including(expected_params)).and_return(ORDER_DELETE_RESPONSE)
|
235
|
+
|
236
|
+
Sendle::Api::Order.destroy(order_id)
|
237
|
+
end
|
238
|
+
|
239
|
+
it "returns the correct response" do
|
240
|
+
allow(RestClient::Request).to receive(:execute).and_return(ORDER_DELETE_RESPONSE)
|
241
|
+
|
242
|
+
response = Sendle::Api::Order.destroy(order_id)
|
243
|
+
|
244
|
+
expect(response).to be_a Sendle::Api::Responses::Json
|
245
|
+
expect(response.json).to eq JSON.parse(ORDER_DELETE_RESPONSE)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|