shipcloud 0.6.0 → 0.11.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 +5 -5
- data/.codeclimate.yml +1 -0
- data/.hound.yml +1 -1
- data/.rubocop.yml +713 -2
- data/.ruby-version +1 -0
- data/.travis.yml +18 -6
- data/CHANGELOG.md +70 -0
- data/README.md +76 -8
- data/bin/rubocop +29 -0
- data/install-cc-test-reporter.sh +4 -0
- data/lib/shipcloud.rb +28 -14
- data/lib/shipcloud/address.rb +2 -1
- data/lib/shipcloud/operations/all.rb +12 -2
- data/lib/shipcloud/operations/create.rb +10 -2
- data/lib/shipcloud/operations/delete.rb +10 -2
- data/lib/shipcloud/operations/find.rb +10 -2
- data/lib/shipcloud/operations/update.rb +12 -4
- data/lib/shipcloud/pickup_request.rb +12 -0
- data/lib/shipcloud/request/base.rb +14 -10
- data/lib/shipcloud/request/connection.rb +18 -12
- data/lib/shipcloud/request/info.rb +7 -5
- data/lib/shipcloud/shipcloud_error.rb +70 -0
- data/lib/shipcloud/shipment.rb +3 -2
- data/lib/shipcloud/tracker.rb +13 -0
- data/lib/shipcloud/version.rb +1 -1
- data/lib/shipcloud/webhook.rb +2 -1
- data/shipcloud.gemspec +9 -8
- data/spec/shipcloud/address_spec.rb +114 -43
- data/spec/shipcloud/carrier_spec.rb +12 -5
- data/spec/shipcloud/pickup_request_spec.rb +136 -0
- data/spec/shipcloud/request/base_spec.rb +51 -13
- data/spec/shipcloud/request/connection_spec.rb +3 -3
- data/spec/shipcloud/request/info_spec.rb +34 -0
- data/spec/shipcloud/shipcloud_error_spec.rb +125 -0
- data/spec/shipcloud/shipment_quote_spec.rb +14 -1
- data/spec/shipcloud/shipment_spec.rb +126 -11
- data/spec/shipcloud/tracker_spec.rb +141 -0
- data/spec/shipcloud/webhooks_spec.rb +70 -6
- data/spec/shipcloud_spec.rb +82 -20
- data/spec/spec_helper.rb +2 -2
- metadata +55 -43
- data/.ruby-style.yml +0 -240
- data/lib/shipcloud/request/validator.rb +0 -33
- data/spec/shipcloud/request/validator_spec.rb +0 -24
@@ -5,9 +5,17 @@ module Shipcloud
|
|
5
5
|
# Finds a given object
|
6
6
|
#
|
7
7
|
# @param [String] id The id of the object that should be found
|
8
|
+
# @param \[String\] optional api_key The api key. If no api key is given, Shipcloud.api_key
|
9
|
+
# will be used for the request
|
8
10
|
# @return [Shipcloud::Base] The found object
|
9
|
-
def find(id)
|
10
|
-
response = Shipcloud.request(
|
11
|
+
def find(id, api_key: nil, affiliate_id: nil)
|
12
|
+
response = Shipcloud.request(
|
13
|
+
:get,
|
14
|
+
"#{base_url}/#{id}",
|
15
|
+
{},
|
16
|
+
api_key: api_key,
|
17
|
+
affiliate_id: affiliate_id,
|
18
|
+
)
|
11
19
|
self.new(response)
|
12
20
|
end
|
13
21
|
end
|
@@ -6,8 +6,12 @@ module Shipcloud
|
|
6
6
|
# Updates a object
|
7
7
|
# @param [String] id The id of the object that should be updated
|
8
8
|
# @param [Hash] attributes The attributes that should be updated
|
9
|
-
|
10
|
-
|
9
|
+
# @param \[String\] optional api_key The api key. If no api key is given, Shipcloud.api_key
|
10
|
+
# will be used for the request
|
11
|
+
def update(id, attributes, api_key: nil, affiliate_id: nil)
|
12
|
+
response = Shipcloud.request(
|
13
|
+
:put, "#{base_url}/#{id}", attributes, api_key: api_key, affiliate_id: affiliate_id
|
14
|
+
)
|
11
15
|
self.new(response)
|
12
16
|
end
|
13
17
|
end
|
@@ -19,8 +23,12 @@ module Shipcloud
|
|
19
23
|
# Updates a object
|
20
24
|
#
|
21
25
|
# @param [Hash] attributes The attributes that should be updated
|
22
|
-
|
23
|
-
|
26
|
+
# @param \[String\] optional api_key The api key. If no api key is given, Shipcloud.api_key
|
27
|
+
# will be used for the request
|
28
|
+
def update(attributes, api_key: nil, affiliate_id: nil)
|
29
|
+
response = Shipcloud.request(
|
30
|
+
:put, "#{base_url}/#{id}", attributes, api_key: api_key, affiliate_id: affiliate_id
|
31
|
+
)
|
24
32
|
set_attributes(response)
|
25
33
|
end
|
26
34
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Shipcloud
|
2
|
+
class PickupRequest < Base
|
3
|
+
include Shipcloud::Operations::Create
|
4
|
+
|
5
|
+
attr_accessor :carrier, :pickup_time, :shipments, :pickup_address
|
6
|
+
attr_reader :id, :carrier_pickup_number
|
7
|
+
|
8
|
+
def self.base_url
|
9
|
+
"pickup_requests"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -2,32 +2,36 @@ module Shipcloud
|
|
2
2
|
module Request
|
3
3
|
class Base
|
4
4
|
attr_reader :info
|
5
|
-
attr_accessor :response
|
6
5
|
|
7
6
|
def initialize(info)
|
8
7
|
@info = info
|
9
8
|
end
|
10
9
|
|
11
10
|
def perform
|
12
|
-
raise AuthenticationError
|
11
|
+
raise AuthenticationError unless @info.api_key
|
12
|
+
|
13
13
|
connection.setup_https
|
14
|
-
|
15
|
-
|
14
|
+
response = connection.request
|
15
|
+
validate_response(response)
|
16
|
+
JSON.parse(response.body) unless response.body.nil?
|
17
|
+
rescue JSON::ParserError
|
18
|
+
raise ShipcloudError.new(response)
|
16
19
|
end
|
17
20
|
|
18
21
|
protected
|
19
22
|
|
20
|
-
def
|
21
|
-
|
23
|
+
def validate_response(response)
|
24
|
+
error = ShipcloudError.from_response(response)
|
25
|
+
if error
|
26
|
+
raise error
|
27
|
+
end
|
22
28
|
end
|
23
29
|
|
30
|
+
# rubocop:disable Naming/MemoizedInstanceVariableName
|
24
31
|
def connection
|
25
32
|
@connection ||= Connection.new(info)
|
26
33
|
end
|
27
|
-
|
28
|
-
def validator
|
29
|
-
@validator ||= Validator.new(info)
|
30
|
-
end
|
34
|
+
# rubocop:enable Naming/MemoizedInstanceVariableName
|
31
35
|
end
|
32
36
|
end
|
33
37
|
end
|
@@ -20,7 +20,7 @@ module Shipcloud
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def request
|
23
|
-
https.start do
|
23
|
+
https.start do
|
24
24
|
https.request(https_request)
|
25
25
|
end
|
26
26
|
end
|
@@ -28,17 +28,23 @@ module Shipcloud
|
|
28
28
|
protected
|
29
29
|
|
30
30
|
def https_request
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
31
|
+
headers = Shipcloud.api_headers.merge("Affiliate-ID" => @info.affiliate_id)
|
32
|
+
https_request =
|
33
|
+
case @info.http_method
|
34
|
+
when :post
|
35
|
+
Net::HTTP::Post.new(@info.url, headers)
|
36
|
+
when :put
|
37
|
+
Net::HTTP::Put.new(@info.url, headers)
|
38
|
+
when :delete
|
39
|
+
Net::HTTP::Delete.new(@info.url, headers)
|
40
|
+
else
|
41
|
+
Net::HTTP::Get.new(
|
42
|
+
@info.path_with_params(@info.url, @info.data),
|
43
|
+
headers,
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
https_request.basic_auth(@info.api_key, "")
|
42
48
|
https_request.body = @info.data.to_json if [:post, :put].include?(@info.http_method)
|
43
49
|
https_request
|
44
50
|
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
module Shipcloud
|
2
2
|
module Request
|
3
3
|
class Info
|
4
|
-
attr_accessor :http_method, :api_url, :data
|
4
|
+
attr_accessor :http_method, :api_url, :api_key, :data, :affiliate_id
|
5
5
|
|
6
|
-
def initialize(http_method, api_url, data)
|
7
|
-
@
|
8
|
-
@
|
9
|
-
@
|
6
|
+
def initialize(http_method, api_url, api_key, data, affiliate_id)
|
7
|
+
@api_key = api_key
|
8
|
+
@http_method = http_method
|
9
|
+
@api_url = api_url
|
10
|
+
@data = data
|
11
|
+
@affiliate_id = affiliate_id
|
10
12
|
end
|
11
13
|
|
12
14
|
def url
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Shipcloud
|
2
|
+
class ShipcloudError < StandardError
|
3
|
+
attr_reader :errors, :response
|
4
|
+
|
5
|
+
def initialize(response = nil)
|
6
|
+
@response = response
|
7
|
+
@errors = parse_errors
|
8
|
+
error_message = errors.empty? ? response_body : errors
|
9
|
+
super(error_message)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the appropriate Shipcloud::ShipcloudError subclass based
|
13
|
+
# on status code
|
14
|
+
#
|
15
|
+
# @param [HTTPResponse] response HTTP response
|
16
|
+
# @return [Shipcloud::ShipcloudError]
|
17
|
+
def self.from_response(response)
|
18
|
+
response_code = response.code.to_i
|
19
|
+
if error_class = error_class_for(response_code)
|
20
|
+
error_class.new(response)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.error_class_for(response_code)
|
25
|
+
case response_code
|
26
|
+
when 400, 422 then InvalidRequestError
|
27
|
+
when 401 then AuthenticationError
|
28
|
+
when 402 then TooManyRequests
|
29
|
+
when 403 then ForbiddenError
|
30
|
+
when 404 then NotFoundError
|
31
|
+
when 400..499 then ClientError
|
32
|
+
when 500..599 then ServerError
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private_class_method :error_class_for
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def parse_errors
|
41
|
+
return [] unless response_body
|
42
|
+
|
43
|
+
data = JSON.parse(response_body)
|
44
|
+
if data.is_a?(Hash) && data["errors"]
|
45
|
+
data["errors"]
|
46
|
+
else
|
47
|
+
[]
|
48
|
+
end
|
49
|
+
rescue JSON::ParserError
|
50
|
+
[]
|
51
|
+
end
|
52
|
+
|
53
|
+
def response_body
|
54
|
+
return unless @response
|
55
|
+
|
56
|
+
@response.body
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Raised on errors in the 400-499 range
|
61
|
+
class ClientError < ShipcloudError; end
|
62
|
+
class AuthenticationError < ClientError; end
|
63
|
+
class ForbiddenError < ClientError; end
|
64
|
+
class InvalidRequestError < ClientError; end
|
65
|
+
class TooManyRequests < ClientError; end
|
66
|
+
class NotFoundError < ClientError; end
|
67
|
+
|
68
|
+
# Raised on errors in the 500-599 range
|
69
|
+
class ServerError < ShipcloudError; end
|
70
|
+
end
|
data/lib/shipcloud/shipment.rb
CHANGED
@@ -4,8 +4,9 @@ module Shipcloud
|
|
4
4
|
include Shipcloud::Operations::Update
|
5
5
|
include Shipcloud::Operations::All
|
6
6
|
|
7
|
-
attr_accessor :from, :to, :carrier, :package, :reference_number
|
8
|
-
attr_reader :id, :created_at, :carrier_tracking_no, :tracking_url, :label_url,
|
7
|
+
attr_accessor :from, :to, :carrier, :package, :reference_number, :metadata
|
8
|
+
attr_reader :id, :created_at, :carrier_tracking_no, :tracking_url, :label_url,
|
9
|
+
:packages, :price, :customs_declaration, :pickup
|
9
10
|
|
10
11
|
def self.index_response_root
|
11
12
|
"#{class_name.downcase}s"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Shipcloud
|
3
|
+
class Tracker < Base
|
4
|
+
include Shipcloud::Operations::All
|
5
|
+
|
6
|
+
attr_accessor :carrier, :carrier_tracking_no
|
7
|
+
attr_reader :id
|
8
|
+
|
9
|
+
def self.index_response_root
|
10
|
+
"#{class_name.downcase}s"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/shipcloud/version.rb
CHANGED
data/lib/shipcloud/webhook.rb
CHANGED
data/shipcloud.gemspec
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path("
|
2
|
+
lib = File.expand_path("lib", __dir__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require "shipcloud/version"
|
5
5
|
|
@@ -19,13 +19,14 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
-
spec.required_ruby_version = ">= 2.
|
22
|
+
spec.required_ruby_version = ">= 2.3"
|
23
23
|
|
24
|
-
spec.add_runtime_dependency "json", "
|
25
|
-
spec.add_development_dependency "bundler", ">= 1.3.0", "< 2.0"
|
26
|
-
spec.add_development_dependency "rake", "~> 10.3"
|
27
|
-
spec.add_development_dependency "rspec", "~> 2.99"
|
28
|
-
spec.add_development_dependency "webmock", "~> 1.18"
|
24
|
+
spec.add_runtime_dependency "json", ">= 1.8.0"
|
29
25
|
spec.add_development_dependency "pry", "~> 0.10"
|
30
|
-
spec.add_development_dependency "
|
26
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.6"
|
28
|
+
spec.add_development_dependency "rubocop", "~> 0.71.0"
|
29
|
+
spec.add_development_dependency "rubocop-performance"
|
30
|
+
spec.add_development_dependency "simplecov"
|
31
|
+
spec.add_development_dependency "webmock", "~> 3.0"
|
31
32
|
end
|
@@ -13,7 +13,8 @@ describe Shipcloud::Address do
|
|
13
13
|
city: 'Hamburg',
|
14
14
|
state: 'Hamburg',
|
15
15
|
country: 'DE',
|
16
|
-
phone: '040/123456789'
|
16
|
+
phone: '040/123456789',
|
17
|
+
email: 'max@mustermail.com',
|
17
18
|
}
|
18
19
|
|
19
20
|
describe '#initialize' do
|
@@ -30,36 +31,79 @@ describe Shipcloud::Address do
|
|
30
31
|
expect(address.state).to eq 'Hamburg'
|
31
32
|
expect(address.country).to eq 'DE'
|
32
33
|
expect(address.phone).to eq '040/123456789'
|
34
|
+
expect(address.email).to eq 'max@mustermail.com'
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
36
38
|
describe '.create' do
|
37
39
|
it 'makes a new POST request using the correct API endpoint' do
|
38
|
-
Shipcloud.
|
40
|
+
expect(Shipcloud).to receive(:request).
|
41
|
+
with(:post, "addresses", valid_attributes, api_key: nil, affiliate_id: nil).
|
42
|
+
and_return("data" => {})
|
43
|
+
|
39
44
|
Shipcloud::Address.create(valid_attributes)
|
40
45
|
end
|
46
|
+
|
47
|
+
it "returns an address containing an id" do
|
48
|
+
expect(Shipcloud).to receive(:request).
|
49
|
+
with(:post, "addresses", valid_attributes, api_key: nil, affiliate_id: nil).
|
50
|
+
and_return(returned_address)
|
51
|
+
|
52
|
+
address = Shipcloud::Address.create(valid_attributes)
|
53
|
+
|
54
|
+
expect(address.id).to eq("1c81efb7-9b95-4dd8-92e3-cac1bca3df6f")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "use the affiliate ID provided for the request" do
|
58
|
+
expect(Shipcloud).to receive(:request).
|
59
|
+
with(:post, "addresses", valid_attributes, api_key: nil, affiliate_id: "affiliate_id").
|
60
|
+
and_return(returned_address)
|
61
|
+
|
62
|
+
address = Shipcloud::Address.create(valid_attributes, affiliate_id: "affiliate_id")
|
63
|
+
|
64
|
+
expect(address.id).to eq("1c81efb7-9b95-4dd8-92e3-cac1bca3df6f")
|
65
|
+
end
|
41
66
|
end
|
42
67
|
|
43
68
|
describe '.find' do
|
44
69
|
it 'makes a new GET request using the correct API endpoint to receive a specific address' do
|
45
|
-
Shipcloud.
|
46
|
-
:get,
|
47
|
-
|
70
|
+
expect(Shipcloud).to receive(:request).with(
|
71
|
+
:get, "addresses/123", {}, api_key: nil, affiliate_id: nil).and_return("id" => "123")
|
72
|
+
|
73
|
+
Shipcloud::Address.find("123")
|
74
|
+
end
|
75
|
+
|
76
|
+
it "use the affiliate ID provided for the request" do
|
77
|
+
expect(Shipcloud).to receive(:request).with(
|
78
|
+
:get, "addresses/123", {}, api_key: nil, affiliate_id: "affiliate_id"
|
79
|
+
).and_return("id" => "123")
|
80
|
+
|
81
|
+
Shipcloud::Address.find("123", affiliate_id: "affiliate_id")
|
48
82
|
end
|
49
83
|
end
|
50
84
|
|
51
85
|
describe '.update' do
|
52
86
|
it 'makes a new PUT request using the correct API endpoint' do
|
53
|
-
Shipcloud.
|
54
|
-
:put,
|
55
|
-
|
87
|
+
expect(Shipcloud).to receive(:request).with(
|
88
|
+
:put, "addresses/123", { street: "Mittelweg" }, api_key: nil, affiliate_id: nil
|
89
|
+
).and_return("data" => {})
|
90
|
+
|
91
|
+
Shipcloud::Address.update("123", street: "Mittelweg")
|
92
|
+
end
|
93
|
+
|
94
|
+
it "use the affiliate ID provided for the request" do
|
95
|
+
expect(Shipcloud).to receive(:request).with(
|
96
|
+
:put, "addresses/123", { street: "Mittelweg" }, api_key: nil, affiliate_id: "affiliate_id"
|
97
|
+
).and_return("data" => {})
|
98
|
+
|
99
|
+
Shipcloud::Address.update("123", { street: "Mittelweg" }, affiliate_id: "affiliate_id")
|
56
100
|
end
|
57
101
|
end
|
58
102
|
|
59
103
|
describe '.all' do
|
60
104
|
it 'makes a new Get request using the correct API endpoint' do
|
61
105
|
expect(Shipcloud).to receive(:request).
|
62
|
-
with(:get,
|
106
|
+
with(:get, "addresses", {}, api_key: nil, affiliate_id: nil).and_return([])
|
63
107
|
|
64
108
|
Shipcloud::Address.all
|
65
109
|
end
|
@@ -73,42 +117,69 @@ describe Shipcloud::Address do
|
|
73
117
|
expect(address).to be_a Shipcloud::Address
|
74
118
|
end
|
75
119
|
end
|
120
|
+
|
121
|
+
it "use the affiliate ID provided for the request" do
|
122
|
+
stub_addresses_request(affiliate_id: "affiliate_id")
|
123
|
+
|
124
|
+
addresses = Shipcloud::Address.all(affiliate_id: "affiliate_id")
|
125
|
+
|
126
|
+
addresses.each do |address|
|
127
|
+
expect(address).to be_a Shipcloud::Address
|
128
|
+
end
|
129
|
+
end
|
76
130
|
end
|
77
131
|
|
78
|
-
def stub_addresses_request
|
132
|
+
def stub_addresses_request(affiliate_id: nil)
|
79
133
|
allow(Shipcloud).to receive(:request).
|
80
|
-
with(:get,
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
134
|
+
with(:get, "addresses", {}, api_key: nil, affiliate_id: affiliate_id).
|
135
|
+
and_return(
|
136
|
+
[
|
137
|
+
{
|
138
|
+
"id" => "1c81efb7-9b95-4dd8-92e3-cac1bca3df6f",
|
139
|
+
"company" => "",
|
140
|
+
"first_name" => "Max",
|
141
|
+
"last_name" => "Mustermann",
|
142
|
+
"care_of" => "",
|
143
|
+
"street" => "Musterstraße",
|
144
|
+
"street_no" => "42",
|
145
|
+
"zip_code" => "12345",
|
146
|
+
"city" => "Musterstadt",
|
147
|
+
"state" => "",
|
148
|
+
"country" => "DE",
|
149
|
+
"phone" => ""
|
150
|
+
},
|
151
|
+
{
|
152
|
+
"id" => "7ea2a290-b456-4ecf-9010-e82b3da298f0",
|
153
|
+
"company" => "Muster-Company",
|
154
|
+
"first_name" => "Max",
|
155
|
+
"last_name" => "Mustermann",
|
156
|
+
"care_of" => "",
|
157
|
+
"street" => "Musterstraße",
|
158
|
+
"street_no" => "42",
|
159
|
+
"zip_code" => "54321",
|
160
|
+
"city" => "Musterstadt",
|
161
|
+
"state" => "",
|
162
|
+
"country" => "DE",
|
163
|
+
"phone" => ""
|
164
|
+
}
|
165
|
+
]
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
169
|
+
def returned_address
|
170
|
+
{
|
171
|
+
"id" => "1c81efb7-9b95-4dd8-92e3-cac1bca3df6f",
|
172
|
+
"company" => "shipcloud GmbH",
|
173
|
+
"first_name" => "Maxi",
|
174
|
+
"last_name" => "Musterfrau",
|
175
|
+
"care_of" => "Mustermann",
|
176
|
+
"street" => "Musterstraße",
|
177
|
+
"street_no" => "123",
|
178
|
+
"zip_code" => "12345",
|
179
|
+
"city" => "Hamburg",
|
180
|
+
"state" => "Hamburg",
|
181
|
+
"country" => "DE",
|
182
|
+
"phone" => "040/123456789",
|
183
|
+
}
|
113
184
|
end
|
114
185
|
end
|