easypost 3.0.0 → 3.1.3

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.
@@ -1,25 +1,28 @@
1
1
  module EasyPost
2
2
  class Webhook < Resource
3
3
  def update(params={})
4
+ # NOTE: This method is redefined here since the "url" method conflicts
5
+ # with the objects field
4
6
  unless self.id
5
7
  raise Error.new("Could not determine which URL to request: #{self.class} instance has invalid ID: #{self.id.inspect}")
6
8
  end
7
9
  instance_url = "#{self.class.url}/#{CGI.escape(id)}"
8
10
 
9
- response, api_key = EasyPost.request(:put, instance_url, @api_key, params)
11
+ response = EasyPost.make_request(:put, instance_url, @api_key, params)
10
12
  self.refresh_from(response, api_key, true)
11
13
 
12
14
  return self
13
15
  end
14
16
 
15
17
  def delete
16
- # Note: This method is redefined here since the "url" method conflicts with the objects field
18
+ # NOTE: This method is redefined here since the "url" method conflicts
19
+ # with the objects field
17
20
  unless self.id
18
21
  raise Error.new("Could not determine which URL to request: #{self.class} instance has invalid ID: #{self.id.inspect}")
19
22
  end
20
23
  instance_url = "#{self.class.url}/#{CGI.escape(id)}"
21
24
 
22
- response, api_key = EasyPost.request(:delete, instance_url, @api_key)
25
+ response = EasyPost.make_request(:delete, instance_url, @api_key)
23
26
  refresh_from(response, api_key)
24
27
 
25
28
  return self
data/lib/easypost.rb CHANGED
@@ -1,157 +1,147 @@
1
- require 'cgi'
2
- require 'set'
3
- require 'openssl'
4
- require 'rest_client'
5
- require 'multi_json'
1
+ require "base64"
2
+ require "cgi"
3
+ require "net/http"
6
4
 
7
5
  # Resources
8
- require 'easypost/version'
9
- require 'easypost/util'
10
- require 'easypost/object'
11
- require 'easypost/resource'
12
- require 'easypost/address'
13
- require 'easypost/parcel'
14
- require 'easypost/customs_item'
15
- require 'easypost/customs_info'
16
- require 'easypost/shipment'
17
- require 'easypost/rate'
18
- require 'easypost/postage_label'
19
- require 'easypost/scan_form'
20
- require 'easypost/refund'
21
- require 'easypost/insurance'
22
- require 'easypost/event'
23
- require 'easypost/batch'
24
- require 'easypost/tracker'
25
- require 'easypost/item'
26
- require 'easypost/order'
27
- require 'easypost/pickup'
28
- require 'easypost/pickup_rate'
29
- require 'easypost/printer'
30
- require 'easypost/print_job'
31
- require 'easypost/carrier_account'
32
- require 'easypost/user'
33
- require 'easypost/report'
34
- require 'easypost/webhook'
35
-
36
- require 'easypost/error'
6
+ require "easypost/version"
7
+ require "easypost/util"
8
+ require "easypost/object"
9
+ require "easypost/resource"
10
+ require "easypost/address"
11
+ require "easypost/parcel"
12
+ require "easypost/customs_item"
13
+ require "easypost/customs_info"
14
+ require "easypost/shipment"
15
+ require "easypost/rate"
16
+ require "easypost/postage_label"
17
+ require "easypost/scan_form"
18
+ require "easypost/refund"
19
+ require "easypost/insurance"
20
+ require "easypost/event"
21
+ require "easypost/batch"
22
+ require "easypost/tracker"
23
+ require "easypost/item"
24
+ require "easypost/order"
25
+ require "easypost/pickup"
26
+ require "easypost/pickup_rate"
27
+ require "easypost/printer"
28
+ require "easypost/print_job"
29
+ require "easypost/carrier_account"
30
+ require "easypost/user"
31
+ require "easypost/report"
32
+ require "easypost/webhook"
33
+
34
+ require "easypost/error"
37
35
 
38
36
  module EasyPost
39
- @@api_key = nil
40
- @@api_base = 'https://api.easypost.com/v2'
41
- @@api_version = nil
42
- @@open_timeout = 30
43
- @@timeout = 60
44
-
45
- def self.api_url(url='')
46
- @@api_base + url
47
- end
37
+ @api_key = nil
38
+ @api_base = "https://api.easypost.com"
48
39
 
49
40
  def self.api_key=(api_key)
50
- @@api_key = api_key
41
+ @api_key = api_key
51
42
  end
52
43
 
53
44
  def self.api_key
54
- @@api_key
45
+ @api_key
55
46
  end
56
47
 
57
48
  def self.api_base=(api_base)
58
- @@api_base = api_base
49
+ @api_base = api_base
59
50
  end
60
51
 
61
52
  def self.api_base
62
- @@api_base
53
+ @api_base
63
54
  end
64
55
 
65
- def self.api_version=(version)
66
- @@api_version = version
67
- end
56
+ def self.reset_http_config
57
+ @http_config = {
58
+ timeout: 60,
59
+ open_timeout: 30,
60
+ verify_ssl: OpenSSL::SSL::VERIFY_PEER,
61
+ }
62
+
63
+ ruby_version = Gem::Version.new(RUBY_VERSION)
64
+ if ruby_version >= Gem::Version.new("2.5.0")
65
+ @http_config[:min_version] = OpenSSL::SSL::TLS1_2_VERSION
66
+ else
67
+ @http_config[:ssl_version] = :TLSv1_2
68
+ end
68
69
 
69
- def self.api_version
70
- @@api_version
70
+ @http_config
71
71
  end
72
72
 
73
73
  def self.http_config
74
- @@http_config ||= {
75
- timeout: 60,
76
- open_timeout: 30,
77
- verify_ssl: false,
78
- ssl_version: :TLSv1_2,
79
- }
74
+ @http_config ||= reset_http_config
80
75
  end
81
76
 
82
77
  def self.http_config=(http_config_params)
83
- self.http_config.merge!(http_config_params)
78
+ http_config.merge!(http_config_params)
84
79
  end
85
80
 
86
- def self.request(method, url, api_key, params={}, headers={}, api_key_required=true)
87
- api_key ||= @@api_key
88
- if api_key_required
89
- raise Error.new('No API key provided.') unless api_key
90
- end
81
+ def self.make_client(uri)
82
+ client = if http_config[:proxy]
83
+ proxy_uri = URI(http_config[:proxy])
84
+ Net::HTTP.new(
85
+ uri.host,
86
+ uri.port,
87
+ proxy_uri.host,
88
+ proxy_uri.port,
89
+ proxy_uri.user,
90
+ proxy_uri.password
91
+ )
92
+ else
93
+ Net::HTTP.new(uri.host, uri.port)
94
+ end
95
+ client.use_ssl = true
96
+
97
+ http_config.each do |name, value|
98
+ # Discrepancies between RestClient and Net::HTTP.
99
+ if name == :verify_ssl
100
+ name = :verify_mode
101
+ elsif name == :timeout
102
+ name = :read_timeout
103
+ end
91
104
 
92
- params = Util.objects_to_ids(params)
93
- url = self.api_url(url)
94
- case method.to_s.downcase.to_sym
95
- when :get, :head, :delete
96
- # Make params into GET parameters
97
- if params && params.count > 0
98
- query_string = Util.flatten_params(params).collect{|key, value| "#{key}=#{Util.url_encode(value)}"}.join('&')
99
- url += "#{URI.parse(url).query ? '&' : '?'}#{query_string}"
105
+ # Handled in the creation of the client.
106
+ if name == :proxy
107
+ next
100
108
  end
101
- payload = nil
102
- else
103
- payload = Util.flatten_params(params).collect{|(key, value)| "#{key}=#{Util.url_encode(value)}"}.join('&')
109
+
110
+ client.send("#{name}=", value)
104
111
  end
105
112
 
106
- headers = {
107
- :user_agent => "EasyPost/v2 RubyClient/#{VERSION}",
108
- :authorization => "Bearer #{api_key}",
109
- :content_type => 'application/x-www-form-urlencoded'
110
- }.merge(headers)
111
-
112
- opts = http_config.merge(
113
- {
114
- :method => method,
115
- :url => url,
116
- :headers => headers,
117
- :payload => payload
118
- }
119
- )
113
+ client
114
+ end
120
115
 
121
- begin
122
- response = execute_request(opts)
123
- rescue RestClient::ExceptionWithResponse => e
124
- if response_code = e.http_code and response_body = e.http_body
125
- begin
126
- response_json = MultiJson.load(response_body, :symbolize_keys => true)
127
- rescue MultiJson::DecodeError
128
- raise Error.new("Invalid response from API, unable to decode.", response_code, response_body)
129
- end
130
- begin
131
- raise NoMethodError if response_json[:error][:message] == nil
132
- raise Error.new(response_json[:error][:message], response_code, response_body, response_json)
133
- rescue NoMethodError, TypeError
134
- raise Error.new(response_json[:error], response_code, response_body, response_json)
135
- end
136
- else
137
- raise Error.new(e.message)
138
- end
139
- rescue RestClient::Exception, Errno::ECONNREFUSED => e
140
- raise Error.new(e.message)
116
+ def self.make_request(method, path, api_key=nil, body=nil)
117
+ client = make_client(URI(@api_base))
118
+
119
+ request = Net::HTTP.const_get(method.capitalize).new(path)
120
+ if body
121
+ request.body = JSON.dump(Util.objects_to_ids(body))
141
122
  end
142
123
 
143
- begin
144
- response_json = MultiJson.load(response.body, :symbolize_keys => true)
145
- rescue MultiJson::DecodeError
146
- raise Error.new("Invalid response object from API, unable to decode.", response.code, response.body)
124
+ request["Content-Type"] = "application/json"
125
+ request["User-Agent"] = "EasyPost/v2 RubyClient/#{VERSION} Ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
126
+ if api_key = api_key || @api_key
127
+ request["Authorization"] = "Basic #{Base64.strict_encode64("#{api_key}:")}"
147
128
  end
148
129
 
149
- return [response_json, api_key]
150
- end
130
+ response = client.request(request)
151
131
 
152
- private
132
+ if (400..599).include? response.code.to_i
133
+ error = JSON.parse(response.body)["error"]
134
+ raise Error.new(error["message"], response.code.to_i, error["code"], error["errors"])
135
+ end
153
136
 
154
- def self.execute_request(opts)
155
- RestClient::Request.execute(opts)
137
+ if response["Content-Type"].include? "application/json"
138
+ JSON.parse(response.body)
139
+ else
140
+ response.body
141
+ end
142
+ rescue JSON::ParserError
143
+ raise RuntimeError.new(
144
+ "Invalid response object from API, unable to decode.\n#{response.body}"
145
+ )
156
146
  end
157
147
  end
metadata CHANGED
@@ -1,93 +1,96 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easypost
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.3
5
5
  platform: ruby
6
6
  authors:
7
- - Sawyer Bateman
7
+ - Jake Epstein
8
+ - Andrew Tribone
9
+ - James Brown
8
10
  autorequire:
9
11
  bindir: bin
10
12
  cert_chain: []
11
- date: 2018-02-15 00:00:00.000000000 Z
13
+ date: 2020-06-26 00:00:00.000000000 Z
12
14
  dependencies:
13
15
  - !ruby/object:Gem::Dependency
14
- name: rest-client
16
+ name: pry
15
17
  requirement: !ruby/object:Gem::Requirement
16
18
  requirements:
17
- - - ">="
19
+ - - "~>"
18
20
  - !ruby/object:Gem::Version
19
- version: '1.7'
20
- type: :runtime
21
+ version: '0.13'
22
+ type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
23
25
  requirements:
24
- - - ">="
26
+ - - "~>"
25
27
  - !ruby/object:Gem::Version
26
- version: '1.7'
28
+ version: '0.13'
27
29
  - !ruby/object:Gem::Dependency
28
- name: multi_json
30
+ name: rake
29
31
  requirement: !ruby/object:Gem::Requirement
30
32
  requirements:
31
- - - ">="
33
+ - - "~>"
32
34
  - !ruby/object:Gem::Version
33
- version: 1.3.0
34
- type: :runtime
35
+ version: '13.0'
36
+ type: :development
35
37
  prerelease: false
36
38
  version_requirements: !ruby/object:Gem::Requirement
37
39
  requirements:
38
- - - ">="
40
+ - - "~>"
39
41
  - !ruby/object:Gem::Version
40
- version: 1.3.0
42
+ version: '13.0'
41
43
  - !ruby/object:Gem::Dependency
42
- name: bundler
44
+ name: rspec
43
45
  requirement: !ruby/object:Gem::Requirement
44
46
  requirements:
45
47
  - - "~>"
46
48
  - !ruby/object:Gem::Version
47
- version: '1.7'
49
+ version: '3.9'
48
50
  type: :development
49
51
  prerelease: false
50
52
  version_requirements: !ruby/object:Gem::Requirement
51
53
  requirements:
52
54
  - - "~>"
53
55
  - !ruby/object:Gem::Version
54
- version: '1.7'
56
+ version: '3.9'
55
57
  - !ruby/object:Gem::Dependency
56
- name: rake
58
+ name: webmock
57
59
  requirement: !ruby/object:Gem::Requirement
58
60
  requirements:
59
61
  - - "~>"
60
62
  - !ruby/object:Gem::Version
61
- version: '10.0'
63
+ version: '3.8'
62
64
  type: :development
63
65
  prerelease: false
64
66
  version_requirements: !ruby/object:Gem::Requirement
65
67
  requirements:
66
68
  - - "~>"
67
69
  - !ruby/object:Gem::Version
68
- version: '10.0'
70
+ version: '3.8'
69
71
  - !ruby/object:Gem::Dependency
70
- name: rspec
72
+ name: vcr
71
73
  requirement: !ruby/object:Gem::Requirement
72
74
  requirements:
73
75
  - - "~>"
74
76
  - !ruby/object:Gem::Version
75
- version: '2.13'
77
+ version: '5.1'
76
78
  type: :development
77
79
  prerelease: false
78
80
  version_requirements: !ruby/object:Gem::Requirement
79
81
  requirements:
80
82
  - - "~>"
81
83
  - !ruby/object:Gem::Version
82
- version: '2.13'
84
+ version: '5.1'
83
85
  description: Client library for accessing the EasyPost shipping API via Ruby.
84
- email: contact@easypost.com
86
+ email: support@easypost.com
85
87
  executables:
86
88
  - easypost-irb
87
89
  extensions: []
88
90
  extra_rdoc_files: []
89
91
  files:
90
92
  - ".gitignore"
93
+ - ".travis.yml"
91
94
  - CHANGELOG
92
95
  - Gemfile
93
96
  - LICENSE
@@ -95,7 +98,6 @@ files:
95
98
  - Rakefile
96
99
  - VERSION
97
100
  - bin/easypost-irb
98
- - circle.yml
99
101
  - easypost.gemspec
100
102
  - lib/easypost.rb
101
103
  - lib/easypost/address.rb
@@ -126,23 +128,9 @@ files:
126
128
  - lib/easypost/util.rb
127
129
  - lib/easypost/version.rb
128
130
  - lib/easypost/webhook.rb
129
- - spec/address_spec.rb
130
- - spec/batch_spec.rb
131
- - spec/carrier_account_spec.rb
132
- - spec/insurance_spec.rb
133
- - spec/item_spec.rb
134
- - spec/order_spec.rb
135
- - spec/pickup_spec.rb
136
- - spec/report_spec.rb
137
- - spec/scan_form_spec.rb
138
- - spec/shipment_spec.rb
139
- - spec/spec_helper.rb
140
- - spec/support/constant.rb
141
- - spec/tracker_spec.rb
142
- - spec/user_spec.rb
143
- - spec/webhook_spec.rb
144
131
  homepage: https://www.easypost.com/docs
145
- licenses: []
132
+ licenses:
133
+ - MIT
146
134
  metadata: {}
147
135
  post_install_message:
148
136
  rdoc_options: []
@@ -152,7 +140,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
152
140
  requirements:
153
141
  - - "~>"
154
142
  - !ruby/object:Gem::Version
155
- version: '2.0'
143
+ version: '2.2'
156
144
  required_rubygems_version: !ruby/object:Gem::Requirement
157
145
  requirements:
158
146
  - - ">="
@@ -164,19 +152,4 @@ rubygems_version: 2.2.2
164
152
  signing_key:
165
153
  specification_version: 4
166
154
  summary: EasyPost Ruby Client Library
167
- test_files:
168
- - spec/address_spec.rb
169
- - spec/batch_spec.rb
170
- - spec/carrier_account_spec.rb
171
- - spec/insurance_spec.rb
172
- - spec/item_spec.rb
173
- - spec/order_spec.rb
174
- - spec/pickup_spec.rb
175
- - spec/report_spec.rb
176
- - spec/scan_form_spec.rb
177
- - spec/shipment_spec.rb
178
- - spec/spec_helper.rb
179
- - spec/support/constant.rb
180
- - spec/tracker_spec.rb
181
- - spec/user_spec.rb
182
- - spec/webhook_spec.rb
155
+ test_files: []
data/circle.yml DELETED
@@ -1,3 +0,0 @@
1
- machine:
2
- ruby:
3
- version: 2.0.0
data/spec/address_spec.rb DELETED
@@ -1,81 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe EasyPost::Address do
4
- describe ".create_and_verify" do
5
- context "for a successful response without an address" do
6
- it "should raise an error" do
7
- expect(EasyPost).to receive(:request).and_return([{}, ""])
8
- expect {
9
- EasyPost::Address.create_and_verify(ADDRESS[:california])
10
- }.to raise_error EasyPost::Error, /Unable to verify addres/
11
- end
12
- end
13
- end
14
-
15
- describe '#create' do
16
- it 'creates an address object' do
17
- address = EasyPost::Address.create(ADDRESS[:california])
18
-
19
- expect(address).to be_an_instance_of(EasyPost::Address)
20
- expect(address.company).to eq('EasyPost')
21
- end
22
- end
23
-
24
- describe '#verify' do
25
- it 'verifies an address with an error' do
26
- address = EasyPost::Address.create(
27
- ADDRESS[:california].reject {|k,v| k == :street1 || k == :company}
28
- )
29
-
30
- expect(address.street1).to be_nil
31
- expect(address.street2).to eq('Unit 1')
32
- expect(address.city).to eq('San Francisco')
33
- expect(address.state).to eq('CA')
34
- expect(address.zip).to eq('94107')
35
- expect(address.country).to eq('US')
36
-
37
- expect {
38
- address.verify()
39
- }.to raise_error EasyPost::Error, /Unable to verify addres/
40
- end
41
-
42
- it 'verifies an address without message' do
43
- address = EasyPost::Address.create(ADDRESS[:california])
44
-
45
- expect(address.street2).to be
46
-
47
- verified_address = address.verify()
48
- expect(verified_address).to be_an_instance_of(EasyPost::Address)
49
- expect(verified_address[:message]).to be_nil
50
- end
51
-
52
- it 'verifies an address using a carrier' do
53
- address = EasyPost::Address.create(ADDRESS[:california])
54
-
55
- expect(address.company).to eq('EasyPost')
56
- expect(address.street1).to eq('164 Townsend Street')
57
- expect(address.city).to eq('San Francisco')
58
- expect(address.state).to eq('CA')
59
- expect(address.zip).to eq('94107')
60
- expect(address.country).to eq('US')
61
-
62
- verified_address = address.verify(carrier: :usps)
63
- expect(verified_address).to be_an_instance_of(EasyPost::Address)
64
- end
65
-
66
- it 'is not able to verify address' do
67
- address = EasyPost::Address.create(
68
- company: 'Simpler Postage Inc',
69
- street1: '388 Junk Teerts',
70
- street2: 'Apt 20',
71
- city: 'San Francisco',
72
- state: 'CA',
73
- zip: '941abc07'
74
- )
75
-
76
- expect {
77
- address.verify()
78
- }.to raise_error(EasyPost::Error, /Unable to verify addres/)
79
- end
80
- end
81
- end
data/spec/batch_spec.rb DELETED
@@ -1,48 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe EasyPost::Batch do
4
- describe '#create' do
5
- it 'creates a batch object' do
6
- batch = EasyPost::Batch.create({
7
- shipment: [{
8
- from_address: ADDRESS[:california],
9
- to_address: EasyPost::Address.create(ADDRESS[:missouri]),
10
- parcel: EasyPost::Parcel.create(PARCEL[:dimensions])
11
- }, {
12
- from_address: ADDRESS[:california],
13
- to_address: EasyPost::Address.create(ADDRESS[:canada]),
14
- parcel: EasyPost::Parcel.create(PARCEL[:dimensions]),
15
- }],
16
- reference: "batch123456789"
17
- })
18
- expect(batch).to be_an_instance_of(EasyPost::Batch)
19
- expect(batch.num_shipments).to eq(2)
20
- expect(batch.reference).to eq("batch123456789")
21
- expect(batch.state).to eq("creating")
22
- end
23
- end
24
-
25
- describe '#create_and_buy' do
26
- it 'creates a batch object and delayed jobs for purchasing the postage_labels' do
27
- batch = EasyPost::Batch.create({
28
- shipment: [{
29
- from_address: ADDRESS[:california],
30
- to_address: EasyPost::Address.create(ADDRESS[:missouri]),
31
- parcel: EasyPost::Parcel.create(PARCEL[:dimensions]),
32
- carrier: "usps",
33
- service: "priority"
34
- }, {
35
- from_address: ADDRESS[:california],
36
- to_address: EasyPost::Address.create(ADDRESS[:canada]),
37
- parcel: EasyPost::Parcel.create(PARCEL[:dimensions]),
38
- carrier: "usps",
39
- service: "prioritymailinternational"
40
- }],
41
- reference: "batch123456789"
42
- })
43
- expect(batch).to be_an_instance_of(EasyPost::Batch)
44
- expect(batch.state).to eq("creating")
45
- expect(batch.num_shipments).to eq(2)
46
- end
47
- end
48
- end