shipcloud 0.7.0 → 0.8.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.
@@ -5,10 +5,18 @@ rvm:
5
5
  - 2.1.7
6
6
  - 2.2.4
7
7
  - 2.3.0
8
- - rbx-2
8
+ matrix:
9
+ allow_failures:
10
+ - rvm: rbx-2
11
+ include:
12
+ - rvm: rbx-2
13
+ script: bundle exec rake spec
9
14
  notifications:
10
15
  flowdock:
11
16
  secure: fSZxX5z3bHWT8aCFKBFrDDt5o3Jb6EFWcm+pAcMabpfDHc4iktWuCUlSM405798TRdKdws1A2RncQGYiQyLbqNvtLz48dvj4BxgYW7P/vg0koN+I/H2MjpZeuIQ7BRSEJIq2sAYNVya+hSil+SPEBMTngJiP6VYG0dm6fFnRkyk=
12
17
  addons:
13
18
  code_climate:
14
19
  repo_token: 704eb62133d951ce460a6047a15a58e0a521aa20ec6a533fa7a37585f8a75602
20
+ after_success:
21
+ - bundle exec codeclimate-test-reporter
22
+
@@ -1,11 +1,28 @@
1
1
  ## [Unreleased]
2
2
  ### Added
3
3
 
4
+ ### Changed
5
+
6
+ ### Deprecated
7
+
4
8
  ### Removed
5
9
 
6
- ### Changed
10
+ ### Fixed
11
+
12
+ ### Security
13
+
14
+ ## [0.8.0] - 2017-07-03
15
+ ### Added
16
+ - Add attribute ```metadata``` to class ```Shipcloud::Shipment``` in order to transmit JSON data (#16).
17
+ - Add resource pickup_request in order to submit pickup request to shipcloud
18
+ - Add attribute ```pickup_address``` to class ```Shipcloud::PickupRequest``` to submit an alternative address for pickup request to shipcloud
19
+ - Add ```delete``` operation for ```webhook``` resource
20
+ - Add attribute ```deactivated``` to class ```Shipcloud::Webhook```
21
+ - Add ```affiliate_id``` to ```Shipcloud::Configuration``` and submit it (or a default affiliate id) via API headers to shipcloud
22
+ - Add class ```Shipcloud::Tracker``` with create, find, and index operations
7
23
 
8
24
  ### Fixed
25
+ - Parse response only when it is not empty
9
26
 
10
27
  ## [0.7.0] - 2016-01-21
11
28
  ### Added
data/README.md CHANGED
@@ -55,7 +55,7 @@ You can sign up for a developer account at *[shipcloud.io](http://www.shipcloud.
55
55
 
56
56
  ### Create a new shipment
57
57
 
58
- To create a new Shipment on the shipclod platform, you need to provide the name of the carrier, to- and from-address, and the package dimensions.
58
+ To create a new Shipment on the shipcloud platform, you need to provide the name of the carrier, to- and from-address, and the package dimensions.
59
59
  For details, see *[shipcloud API documentation on Shipments](http://developers.shipcloud.io/reference/#shipments)*
60
60
  ```ruby
61
61
  Shipcloud::Shipment.create(
@@ -74,9 +74,23 @@ shipment = Shipcloud::Shipment.create(...) # parameters ommitted
74
74
  shipment.tracking_url # -> http://track.shipcloud.io/uzdgu22z3ed12
75
75
  ```
76
76
 
77
+ ### Get a list of shipments
78
+
79
+ You can get a list of all shipments from the shipcloud platform. Shipments can be filtered by providing optional parameters. For more information and a list of valid parameters see *[shipcloud API documentation on Shipments Index](https://developers.shipcloud.io/reference/#getting-a-list-of-shipments)*
80
+
81
+ ```ruby
82
+ Shipcloud::Shipment.all(
83
+ carrier: 'ups',
84
+ per_page: 25,
85
+ page: 2
86
+ )
87
+ ```
88
+
89
+ `Shipment#all` will return an array of `Shipcloud::Shipment` objects, matching the given parameters.
90
+
77
91
  ### Get a shipment quote
78
92
 
79
- To get a shipment qoute from the shipclod platform, you need to provide the name of the carrier, the service, to- and from-address, and the package dimensions.
93
+ To get a shipment qoute from the shipcloud platform, you need to provide the name of the carrier, the service, to- and from-address, and the package dimensions.
80
94
  For details, see *[shipcloud API documentation on shipment quotes](https://developers.shipcloud.io/reference/#shipment-quotes)*
81
95
 
82
96
  ```ruby
@@ -108,6 +122,43 @@ shipment_quote = Shipcloud::ShipmentQuote.create(
108
122
  shipment_quote.price # => 6.2
109
123
  ```
110
124
 
125
+ ### Create a pickup request
126
+
127
+ To request parcels being picked up, you need to provide the carrier name and the time (earliest and latest) your shipments shall be fetched.
128
+
129
+ ```ruby
130
+ pickup_request = Shipcloud::PickupRequest.create(
131
+ carrier: 'dpd',
132
+ pickup_time: {
133
+ earliest: "2016-04-04T09:00:00+02:00",
134
+ latest: "2016-04-04T18:00:00+02:00"
135
+ }
136
+ )
137
+
138
+ pickup_request.id # => "dje892dj20d2odj20"
139
+ pickup_request.carrier_pickup_number # => "12345"
140
+ ```
141
+
142
+ You may also provide a list of shipment ids to specify only certain shipments to be included in the pickup request.
143
+
144
+ ```ruby
145
+ pickup_request = Shipcloud::PickupRequest.create(
146
+ carrier: 'dpd',
147
+ pickup_time: {
148
+ earliest: "2016-04-04T09:00:00+02:00",
149
+ latest: "2016-04-04T18:00:00+02:00"
150
+ },
151
+ shipments: [
152
+ { id: "abc_123"}
153
+ ]
154
+ )
155
+
156
+ pickup_request.id # => "dje892dj20d2odj20"
157
+ pickup_request.carrier_pickup_number # => "12345"
158
+ ```
159
+
160
+
161
+
111
162
  ## Contributing
112
163
 
113
164
  1. Fork it
@@ -13,11 +13,15 @@ module Shipcloud
13
13
  "User-Agent" => "shipcloud-ruby v#{Shipcloud::VERSION}, API #{Shipcloud::API_VERSION}, #{RUBY_VERSION}, #{RUBY_PLATFORM}, #{RUBY_PATCHLEVEL}"
14
14
  }
15
15
 
16
+ DEFAULT_AFFILIATE_ID = "integration.shipcloud-ruby-gem.v#{Shipcloud::VERSION}".freeze
17
+
16
18
  autoload :Base, "shipcloud/base"
17
19
  autoload :Shipment, "shipcloud/shipment"
18
20
  autoload :Carrier, "shipcloud/carrier"
19
21
  autoload :Address, "shipcloud/address"
22
+ autoload :PickupRequest, "shipcloud/pickup_request"
20
23
  autoload :ShipmentQuote, "shipcloud/shipment_quote"
24
+ autoload :Tracker, "shipcloud/tracker"
21
25
  autoload :Webhook, "shipcloud/webhook"
22
26
 
23
27
  module Operations
@@ -46,9 +50,14 @@ module Shipcloud
46
50
  yield(configuration)
47
51
  end
48
52
 
53
+ def self.api_headers
54
+ API_HEADERS.merge(
55
+ "Affiliate-ID" => configuration.affiliate_id || DEFAULT_AFFILIATE_ID
56
+ )
57
+ end
49
58
 
50
59
  class Configuration
51
- attr_accessor :api_key, :api_base, :use_ssl, :debug
60
+ attr_accessor :affiliate_id, :api_key, :api_base, :use_ssl, :debug
52
61
 
53
62
  def initialize
54
63
  @api_key = nil
@@ -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
@@ -12,7 +12,7 @@ module Shipcloud
12
12
  connection.setup_https
13
13
  response = connection.request
14
14
  validate_response(response)
15
- JSON.parse(response.body)
15
+ JSON.parse(response.body) unless response.body.nil?
16
16
  rescue JSON::ParserError
17
17
  raise ShipcloudError.new(response)
18
18
  end
@@ -28,16 +28,21 @@ module Shipcloud
28
28
  protected
29
29
 
30
30
  def https_request
31
- https_request = case @info.http_method
32
- when :post
33
- Net::HTTP::Post.new(@info.url, API_HEADERS)
34
- when :put
35
- Net::HTTP::Put.new(@info.url, API_HEADERS)
36
- when :delete
37
- Net::HTTP::Delete.new(@info.url, API_HEADERS)
38
- else
39
- Net::HTTP::Get.new(@info.path_with_params(@info.url, @info.data), API_HEADERS)
40
- end
31
+ https_request =
32
+ case @info.http_method
33
+ when :post
34
+ Net::HTTP::Post.new(@info.url, Shipcloud.api_headers)
35
+ when :put
36
+ Net::HTTP::Put.new(@info.url, Shipcloud.api_headers)
37
+ when :delete
38
+ Net::HTTP::Delete.new(@info.url, Shipcloud.api_headers)
39
+ else
40
+ Net::HTTP::Get.new(
41
+ @info.path_with_params(@info.url, @info.data),
42
+ Shipcloud.api_headers,
43
+ )
44
+ end
45
+
41
46
  https_request.basic_auth(@info.api_key, "")
42
47
  https_request.body = @info.data.to_json if [:post, :put].include?(@info.http_method)
43
48
  https_request
@@ -26,6 +26,7 @@ module Shipcloud
26
26
  when 400, 422 then InvalidRequestError
27
27
  when 401 then AuthenticationError
28
28
  when 402 then TooManyRequests
29
+ when 403 then ForbiddenError
29
30
  when 404 then NotFoundError
30
31
  when 400..499 then ClientError
31
32
  when 500..599 then ServerError
@@ -57,6 +58,7 @@ module Shipcloud
57
58
  # Raised on errors in the 400-499 range
58
59
  class ClientError < ShipcloudError; end
59
60
  class AuthenticationError < ClientError; end
61
+ class ForbiddenError < ClientError; end
60
62
  class InvalidRequestError < ClientError; end
61
63
  class TooManyRequests < ClientError; end
62
64
  class NotFoundError < ClientError; end
@@ -4,7 +4,7 @@ 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
7
+ attr_accessor :from, :to, :carrier, :package, :reference_number, :metadata
8
8
  attr_reader :id, :created_at, :carrier_tracking_no, :tracking_url, :label_url, :packages, :price
9
9
 
10
10
  def self.index_response_root
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Shipcloud
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0".freeze
3
3
  end
@@ -1,8 +1,9 @@
1
1
  module Shipcloud
2
2
  class Webhook < Base
3
3
  include Shipcloud::Operations::All
4
+ include Shipcloud::Operations::Delete
4
5
 
5
- attr_reader :url, :event_types
6
+ attr_reader :url, :event_types, :deactivated
6
7
 
7
8
  def self.index_response_root
8
9
  "webhooks"
@@ -0,0 +1,123 @@
1
+ require "spec_helper"
2
+
3
+ describe Shipcloud::PickupRequest do
4
+ valid_attributes = {
5
+ carrier: "dpd",
6
+ pickup_time: {
7
+ earliest: "2015-09-15T09:00:00+02:00",
8
+ latest: "2015-09-15T18:00:00+02:00"
9
+ },
10
+ shipments: [
11
+ { id: "abc_123" }
12
+ ]
13
+ }
14
+
15
+ valid_attributes_with_pickup_address = {
16
+ carrier: "dpd",
17
+ pickup_time: {
18
+ earliest: "2015-09-15T09:00:00+02:00",
19
+ latest: "2015-09-15T18:00:00+02:00"
20
+ },
21
+ pickup_address: {
22
+ company: "Muster-Company",
23
+ first_name: "Max",
24
+ last_name: "Mustermann",
25
+ street: "Musterstraße",
26
+ street_no: "42",
27
+ zip_code: "54321",
28
+ city: "Musterstadt",
29
+ country: "DE",
30
+ phone: "555-555"
31
+ },
32
+ shipments: [
33
+ { id: "abc_123" }
34
+ ]
35
+ }
36
+
37
+ describe "#initialize" do
38
+ it "initializes all attributes correctly" do
39
+ pickup_request = Shipcloud::PickupRequest.new(valid_attributes_with_pickup_address)
40
+
41
+ expect(pickup_request.carrier).to eq "dpd"
42
+ expect(pickup_request.pickup_time[:earliest]).to eq "2015-09-15T09:00:00+02:00"
43
+ expect(pickup_request.pickup_time[:latest]).to eq "2015-09-15T18:00:00+02:00"
44
+ expect(pickup_request.pickup_address[:company]).to eq "Muster-Company"
45
+ expect(pickup_request.pickup_address[:first_name]).to eq "Max"
46
+ expect(pickup_request.pickup_address[:last_name]).to eq "Mustermann"
47
+ expect(pickup_request.pickup_address[:street]).to eq "Musterstraße"
48
+ expect(pickup_request.pickup_address[:street_no]).to eq "42"
49
+ expect(pickup_request.pickup_address[:zip_code]).to eq "54321"
50
+ expect(pickup_request.pickup_address[:country]).to eq "DE"
51
+ expect(pickup_request.pickup_address[:phone]).to eq "555-555"
52
+ expect(pickup_request.shipments).to eq [{ id: "abc_123" }]
53
+ end
54
+ end
55
+
56
+ describe ".create" do
57
+ it "makes a new POST request using the correct API endpoint" do
58
+ expect(Shipcloud).to receive(:request).
59
+ with(:post, "pickup_requests", valid_attributes, api_key: nil).
60
+ and_return("data" => {})
61
+
62
+ Shipcloud::PickupRequest.create(valid_attributes)
63
+ end
64
+
65
+ it "returns pickup request id" do
66
+ allow(Shipcloud).to receive(:request).
67
+ and_return(
68
+ "id" => "123456",
69
+ "carrier_pickup_number" => "abcdef",
70
+ "carrier" => "dpd",
71
+ "pickup_time" => {
72
+ "earliest" => "2015-09-15T09:00:00+02:00",
73
+ "latest" => "2015-09-15T18:00:00+02:00"
74
+ }
75
+ )
76
+
77
+ pickup_request = Shipcloud::PickupRequest.create(valid_attributes)
78
+
79
+ expect(pickup_request.id).to eq "123456"
80
+ expect(pickup_request.carrier_pickup_number).to eq "abcdef"
81
+ end
82
+
83
+ it "returns a pickup_address" do
84
+ allow(Shipcloud).to receive(:request).
85
+ and_return(
86
+ "id" => "123456",
87
+ "carrier_pickup_number" => "abcdef",
88
+ "carrier" => "dpd",
89
+ "pickup_time" => {
90
+ "earliest" => "2015-09-15T09:00:00+02:00",
91
+ "latest" => "2015-09-15T18:00:00+02:00"
92
+ },
93
+ "pickup_address" => {
94
+ "id" => "522a7cb1-d6c8-418c-ac26-011127ab5bbe",
95
+ "company" => "Muster-Company",
96
+ "first_name" => "Max",
97
+ "last_name" => "Mustermann",
98
+ "street" => "Musterstraße",
99
+ "street_no" => "42",
100
+ "zip_code" => "54321",
101
+ "city" => "Musterstadt",
102
+ "country" => "DE",
103
+ "phone" => "555-555"
104
+ }
105
+ )
106
+
107
+ pickup_request = Shipcloud::PickupRequest.create(valid_attributes_with_pickup_address)
108
+
109
+ expect(pickup_request.pickup_address).to eq(
110
+ "id" => "522a7cb1-d6c8-418c-ac26-011127ab5bbe",
111
+ "company" => "Muster-Company",
112
+ "first_name" => "Max",
113
+ "last_name" => "Mustermann",
114
+ "street" => "Musterstraße",
115
+ "street_no" => "42",
116
+ "zip_code" => "54321",
117
+ "city" => "Musterstadt",
118
+ "country" => "DE",
119
+ "phone" => "555-555"
120
+ )
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe Shipcloud::Request::Info do
5
+ describe "#url" do
6
+ it "returns the correct url" do
7
+ info = Shipcloud::Request::Info.new(:get, "shipments", "api_key", {})
8
+
9
+ expect(info.url).to eq "/v1/shipments"
10
+ end
11
+ end
12
+
13
+ describe "#path_with_params" do
14
+ it "returns just the path if there aren't any params" do
15
+ info = Shipcloud::Request::Info.new(:get, "shipments", "api_key", {})
16
+ path = info.path_with_params(info.url, info.data)
17
+
18
+ expect(path).to eq "/v1/shipments"
19
+ end
20
+
21
+ it "returns the path and given params" do
22
+ info = Shipcloud::Request::Info.new(:get, "shipments", "api_key", foo: "bar")
23
+ path = info.path_with_params(info.url, info.data)
24
+
25
+ expect(path).to eq "/v1/shipments?foo=bar"
26
+ end
27
+ end
28
+ end
@@ -18,6 +18,15 @@ describe Shipcloud::Shipment do
18
18
  length: 40,
19
19
  width: 20,
20
20
  height: 20
21
+ },
22
+ metadata: {
23
+ product: {
24
+ name: "foo"
25
+ },
26
+ category: {
27
+ id: "123456",
28
+ name: "bar"
29
+ }
21
30
  }
22
31
  }
23
32
  end
@@ -43,6 +52,20 @@ describe Shipcloud::Shipment do
43
52
  expect(shipment.package[:width]).to eq 20
44
53
  expect(shipment.package[:height]).to eq 20
45
54
  end
55
+
56
+ it "initializes the metadata correctly" do
57
+ metadata = {
58
+ category: {
59
+ id: "123456",
60
+ name: "bar"
61
+ },
62
+ product: {
63
+ name: "foo"
64
+ }
65
+ }
66
+
67
+ expect(shipment.metadata).to eq metadata
68
+ end
46
69
  end
47
70
 
48
71
  describe ".create" do
@@ -75,6 +98,13 @@ describe Shipcloud::Shipment do
75
98
  and_return(true)
76
99
  Shipcloud::Shipment.delete("123")
77
100
  end
101
+
102
+ it "doesn't raise an error" do
103
+ stub_request(:delete, "https://your-api-key:@api.shipcloud.io/v1/shipments/123").
104
+ to_return(status: 204, body: "")
105
+ expect { Shipcloud::Shipment.delete("123", api_key: "your-api-key") }.
106
+ to_not raise_error
107
+ end
78
108
  end
79
109
 
80
110
  describe ".all" do