aus_post_api 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +7 -0
  5. data/Gemfile.lock +37 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +147 -0
  8. data/Rakefile +32 -0
  9. data/aus_post_api.gemspec +14 -0
  10. data/lib/aus_post_api.rb +7 -0
  11. data/lib/aus_post_api/dce.rb +15 -0
  12. data/lib/aus_post_api/dce/endpoint.rb +80 -0
  13. data/lib/aus_post_api/dce/validate_australian_address.rb +12 -0
  14. data/lib/aus_post_api/endpoint.rb +66 -0
  15. data/lib/aus_post_api/endpoint/attributes.rb +54 -0
  16. data/lib/aus_post_api/pac.rb +83 -0
  17. data/lib/aus_post_api/pac/country.rb +9 -0
  18. data/lib/aus_post_api/pac/domestic_letter_size.rb +9 -0
  19. data/lib/aus_post_api/pac/domestic_letter_thickness.rb +9 -0
  20. data/lib/aus_post_api/pac/domestic_letter_weight.rb +9 -0
  21. data/lib/aus_post_api/pac/domestic_parcel_size.rb +9 -0
  22. data/lib/aus_post_api/pac/domestic_parcel_type.rb +9 -0
  23. data/lib/aus_post_api/pac/domestic_parcel_weight.rb +9 -0
  24. data/lib/aus_post_api/pac/domestic_postcode_search.rb +12 -0
  25. data/lib/aus_post_api/pac/endpoint.rb +76 -0
  26. data/lib/aus_post_api/pac/international_letter_weight.rb +9 -0
  27. data/lib/aus_post_api/pac/international_parcel_weight.rb +9 -0
  28. data/lib/aus_post_api/pac/postage_letter_domestic_calculate.rb +12 -0
  29. data/lib/aus_post_api/pac/postage_letter_domestic_service.rb +11 -0
  30. data/lib/aus_post_api/pac/postage_letter_international_calculate.rb +12 -0
  31. data/lib/aus_post_api/pac/postage_letter_international_service.rb +11 -0
  32. data/lib/aus_post_api/pac/postage_parcel_domestic_calculate.rb +13 -0
  33. data/lib/aus_post_api/pac/postage_parcel_domestic_service.rb +12 -0
  34. data/lib/aus_post_api/pac/postage_parcel_international_calculate.rb +12 -0
  35. data/lib/aus_post_api/pac/postage_parcel_international_service.rb +11 -0
  36. data/lib/aus_post_api/uri_handler.rb +35 -0
  37. data/spec/aus_post_api/dce/endpoint_spec.rb +86 -0
  38. data/spec/aus_post_api/dce/validate_australian_address_spec.rb +18 -0
  39. data/spec/aus_post_api/dce_spec.rb +33 -0
  40. data/spec/aus_post_api/endpoint/attributes_spec.rb +35 -0
  41. data/spec/aus_post_api/endpoint_spec.rb +43 -0
  42. data/spec/aus_post_api/pac/country_spec.rb +8 -0
  43. data/spec/aus_post_api/pac/domestic_letter_size_spec.rb +8 -0
  44. data/spec/aus_post_api/pac/domestic_letter_thickness_spec.rb +8 -0
  45. data/spec/aus_post_api/pac/domestic_letter_weight_spec.rb +8 -0
  46. data/spec/aus_post_api/pac/domestic_parcel_size_spec.rb +8 -0
  47. data/spec/aus_post_api/pac/domestic_parcel_type_spec.rb +8 -0
  48. data/spec/aus_post_api/pac/domestic_parcel_weight_spec.rb +8 -0
  49. data/spec/aus_post_api/pac/endpoint_spec.rb +109 -0
  50. data/spec/aus_post_api/pac/international_letter_weight_spec.rb +8 -0
  51. data/spec/aus_post_api/pac/international_parcel_weight_spec.rb +8 -0
  52. data/spec/aus_post_api/pac/postage_letter_domestic_calculate_spec.rb +19 -0
  53. data/spec/aus_post_api/pac/postage_letter_domestic_service_spec.rb +15 -0
  54. data/spec/aus_post_api/pac/postage_letter_international_calculate_spec.rb +20 -0
  55. data/spec/aus_post_api/pac/postage_letter_international_service_spec.rb +13 -0
  56. data/spec/aus_post_api/pac/postage_parcel_domestic_calculate_spec.rb +24 -0
  57. data/spec/aus_post_api/pac/postage_parcel_domestic_service_spec.rb +17 -0
  58. data/spec/aus_post_api/pac/postage_parcel_international_calculate_spec.rb +15 -0
  59. data/spec/aus_post_api/pac/postage_parcel_international_service_spec.rb +8 -0
  60. data/spec/aus_post_api/pac/postcode_search_spec.rb +17 -0
  61. data/spec/aus_post_api/pac_spec.rb +101 -0
  62. data/spec/aus_post_api/uri_handler_spec.rb +14 -0
  63. data/spec/shared_examples/shared_examples_for_endpoint_classes.rb +37 -0
  64. data/spec/spec_helper.rb +41 -0
  65. metadata +136 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d5236689702f486d8307a74b0b01ca9c0b8b7733
4
+ data.tar.gz: aec946ad8ea44c0ea0358b819470328c658ec7dc
5
+ SHA512:
6
+ metadata.gz: 4aa3123f0a1231cb164673ca8d32f9a4c133f2fbe36669ac0ef4466391a9095957f87447485ff3e6c29cc71ef41bfab27ca5c869e179cf7272fa57c7814f6d77
7
+ data.tar.gz: df27ce56b45e696c99a44bfe78b8e0aab0d16b1d9ab24d08424d7e10885aedc91f94b88a78793658902fc23274df41ea13c86165e73f65e374fb959381b06990
@@ -0,0 +1,2 @@
1
+ spec/fixtures/**/*.*
2
+ aus_post_api*.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'rspec'
4
+ gem 'vcr'
5
+ gem 'webmock'
6
+ gem 'rake'
7
+ gem 'require_all'
@@ -0,0 +1,37 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ addressable (2.3.8)
5
+ crack (0.4.2)
6
+ safe_yaml (~> 1.0.0)
7
+ diff-lcs (1.2.5)
8
+ rake (10.4.2)
9
+ require_all (1.3.2)
10
+ rspec (3.2.0)
11
+ rspec-core (~> 3.2.0)
12
+ rspec-expectations (~> 3.2.0)
13
+ rspec-mocks (~> 3.2.0)
14
+ rspec-core (3.2.3)
15
+ rspec-support (~> 3.2.0)
16
+ rspec-expectations (3.2.1)
17
+ diff-lcs (>= 1.2.0, < 2.0)
18
+ rspec-support (~> 3.2.0)
19
+ rspec-mocks (3.2.1)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.2.0)
22
+ rspec-support (3.2.2)
23
+ safe_yaml (1.0.4)
24
+ vcr (2.9.3)
25
+ webmock (1.21.0)
26
+ addressable (>= 2.3.6)
27
+ crack (>= 0.3.2)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ rake
34
+ require_all
35
+ rspec
36
+ vcr
37
+ webmock
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Jared Shay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,147 @@
1
+ # AusPostAPI
2
+
3
+ The AusPostAPI gem is a wrapper around the Australia Post Developer API. Currently only the Postage Assesment Calculator (PAC) API is implemented.
4
+
5
+ ## Documentation
6
+
7
+ Full and up to date documentation can be found at https://developers.auspost.com.au/apis
8
+
9
+ *see below for full list of endpoints that can be called from this gem*
10
+
11
+ ## Usage
12
+
13
+ ### Ruby
14
+
15
+ ```ruby
16
+ AusPostAPI::PAC.new(config).endpoint(params)
17
+ ```
18
+
19
+ ### Rails
20
+
21
+ ```ruby
22
+ # config/initializers/aus_post_api.rb
23
+
24
+ $aus_post_api = AusPostAPI::PAC.new(config)
25
+
26
+ # app/some_file.rb
27
+
28
+ $aus_post_api.endpoint(params)
29
+ ```
30
+
31
+ ## Configuration
32
+ The gem requires a `FORMAT` of either `'json'` or `'xml'`, and the `PAC_AUTH_KEY` to be set. You can get an auth key at https://developers.auspost.com.au/sign-up-for-an-API-key
33
+
34
+ ```ruby
35
+ {
36
+ FORMAT: 'xml',
37
+ PAC_API_KEY: 123-456
38
+ }
39
+ ```
40
+
41
+ ## Endpoints
42
+
43
+ There are no validations on any parameters. Consult the Australia Post documentation for what units and limitations apply.
44
+
45
+ ```
46
+ domestic_postcode_search
47
+ Required Attributes:
48
+ - q
49
+ Optional Attributes:
50
+ - state
51
+ - excludepostboxflag
52
+
53
+ country
54
+
55
+ domestic_letter_thickness
56
+
57
+ domestic_letter_weight
58
+
59
+ domestic_letter_size
60
+
61
+ international_letter_weight
62
+
63
+ international_parcel_weight
64
+
65
+ domestic_parcel_weight
66
+
67
+ domestic_parcel_type
68
+
69
+ domestic_parcel_size
70
+
71
+ postage_letter_domestic_service
72
+ Required Attributes:
73
+ - length
74
+ - width
75
+ - thickness
76
+ - weight
77
+
78
+ postage_parcel_domestic_service
79
+ Required Attributes:
80
+ - from_postcode
81
+ - to_postcode
82
+ - length
83
+ - width
84
+ - height
85
+ - weight
86
+
87
+ postage_letter_international_service
88
+ Required Attributes:
89
+ - country_code
90
+ - weight
91
+
92
+ postage_parcel_international_service
93
+ Required Attributes:
94
+ - country_code
95
+ - weight
96
+
97
+ postage_parcel_domestic_calculate
98
+ Required Attributes:
99
+ - from_postcode
100
+ - to_postcode
101
+ - length
102
+ - width
103
+ - height
104
+ - weight
105
+ - service_code
106
+ Optional Attributes:
107
+ - option_code
108
+ - suboption_code
109
+ - extra_cover
110
+
111
+ postage_parcel_international_calculate
112
+ Required Attributes:
113
+ - country_code
114
+ - weight
115
+ - service_code
116
+ Optional Attributes:
117
+ - option_code
118
+ - suboption_code
119
+ - extra_cover
120
+
121
+ postage_letter_domestic_calculate
122
+ Required Attributes:
123
+ - service_code
124
+ - weight
125
+ Optional Attributes:
126
+ - option_code
127
+ - suboption_code
128
+ - extra_cover
129
+
130
+ postage_letter_international_calculate
131
+ Required Attributes:
132
+ - country_code
133
+ - service_code
134
+ Optional Attributes:
135
+ - weight
136
+ - option_code
137
+ - suboption_code
138
+ - extra_cover
139
+ ```
140
+
141
+ ## Testing
142
+ Set the config `TEST: true` for use in testing environments. This will use the Australia Post testing endpoint, and ignore any api keys provided.
143
+
144
+ *note: at the time of writing this the testing endpoint is unreliable. Consider getting additional api keys for testing purposes and not setting the TEST parameter in your tests*
145
+
146
+ ## Contributing
147
+ Fork and PR!
@@ -0,0 +1,32 @@
1
+ desc "Open an irb session preloaded with the aus_post gem"
2
+ task :console do
3
+ sh "irb -I lib -r aus_post_api.rb"
4
+ end
5
+
6
+ desc "Display all PAC endpoints with a list of required values"
7
+ task :pac_docs do
8
+ require_relative 'lib/aus_post_api'
9
+
10
+
11
+ docs = ""
12
+ (AusPostAPI::PAC.instance_methods - Object.instance_methods).each do |method|
13
+ klass = "AusPostAPI::PAC::#{method.to_s.split("_").map(&:capitalize).join}"
14
+ required = Kernel.const_get(klass).required_attributes
15
+ optional = Kernel.const_get(klass).optional_attributes
16
+
17
+ docs << method.to_s
18
+ docs << "\n"
19
+
20
+ if !required.empty?
21
+ docs << " Required Attributes:\n"
22
+ required.each { |attr| docs << " - #{attr}\n"}
23
+ end
24
+ if !optional.empty?
25
+ docs << " Optional Attributes:\n"
26
+ optional.each { |attr| docs << " - #{attr}\n"}
27
+ end
28
+ docs << "\n"
29
+ end
30
+
31
+ puts docs.chomp!
32
+ end
@@ -0,0 +1,14 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.authors = ["JaredShay"]
3
+ gem.email = ["jared.shay@gmail.com"]
4
+ gem.description = %q{Wrapper for Australia Post's developer API}
5
+ gem.summary = %q{Wrapper for Australia Post's developer API}
6
+ gem.homepage = "https://github.com/jaredshay/aus_post_api"
7
+
8
+ gem.files = `git ls-files`.split("\n")
9
+ gem.test_files = `git ls-files -- spec/*`.split("\n")
10
+ gem.name = "aus_post_api"
11
+ gem.require_paths = ["lib"]
12
+ gem.version = '1.0.0'
13
+ gem.license = "MIT"
14
+ end
@@ -0,0 +1,7 @@
1
+ require 'require_all'
2
+
3
+ require_all 'lib'
4
+
5
+ # The AusPostAPI module is the top level name space for the gem.
6
+ module AusPostAPI
7
+ end
@@ -0,0 +1,15 @@
1
+ module AusPostAPI
2
+ # The PAC class implements methods specified by the Australia Post Delivery
3
+ # Choices API. A config hash must be supplied that specifies a valid
4
+ # DCE_AUTH_KEY, and request format. Setting the key TEST to true in the config
5
+ # hash will ignore any supplied auth_key and use the test endpoint.
6
+ class DCE
7
+ def initialize(config)
8
+ @config = config
9
+ end
10
+
11
+ def validate_australian_address(params = {})
12
+ AusPostAPI::DCE::ValidateAustralianAddress.new(params, @config).execute
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,80 @@
1
+ require 'base64'
2
+
3
+ module AusPostAPI
4
+ class DCE
5
+ # Abstract class that defines a DCE::Endpoint. It implements the `uri` &
6
+ # `headers` methods and expects the `api_uri` method to be implemented.
7
+ class Endpoint < AusPostAPI::Endpoint
8
+ LIVE_URI = 'https://api.auspost.com.au/'
9
+ FORMATS = ['json', 'xml']
10
+
11
+ def uri
12
+ "#{LIVE_URI}/#{api_uri}.#{format}?#{params}"
13
+ end
14
+
15
+ def headers
16
+ { "Authorization" => "Basic #{basic_auth}" }
17
+ end
18
+
19
+ private
20
+
21
+ def api_uri
22
+ raise ImplementationError.new('api_uri')
23
+ end
24
+
25
+ def format
26
+ if @config[:FORMAT].nil?
27
+ raise NoFormatProvidedError
28
+ else
29
+ if !FORMATS.include?(@config[:FORMAT])
30
+ raise InvalidFormatError
31
+ else
32
+ @config[:FORMAT]
33
+ end
34
+ end
35
+ end
36
+
37
+ def params
38
+ [].tap { |result|
39
+ @attributes.keys.each { |a| result << "#{a}=#{self.send(a).split.join('+')}" }
40
+ }.join('&')
41
+ end
42
+
43
+ def basic_auth
44
+ Base64.encode64("#{username}:#{password}")
45
+ end
46
+
47
+ def username
48
+ raise NoHeaderProvidedError.new('USERNAME') if @config[:USERNAME].nil?
49
+
50
+ @config[:USERNAME]
51
+ end
52
+
53
+ def password
54
+ raise NoHeaderProvidedError.new('PASSWORD') if @config[:PASSWORD].nil?
55
+
56
+ @config[:PASSWORD]
57
+ end
58
+
59
+ class NoHeaderProvidedError < StandardError
60
+ def initialize(header)
61
+ super("The called endpoint requires the #{header} config to be set")
62
+ end
63
+ end
64
+
65
+ class InvalidFormatError < StandardError
66
+ def initialize
67
+ super("Accepted formats are: #{AusPostAPI::DCE::Endpoint::FORMATS.join(', ')}")
68
+ end
69
+ end
70
+
71
+ class NoFormatProvidedError < InvalidFormatError; end
72
+
73
+ class ImplementationError < StandardError
74
+ def initialize(method)
75
+ super("No #{method} implemented")
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,12 @@
1
+ module AusPostAPI
2
+ class DCE
3
+ class ValidateAustralianAddress < AusPostAPI::DCE::Endpoint
4
+ required_attributes :addressline1, :suburb, :postcode, :state, :country
5
+ optional_attributes :addressline2
6
+
7
+ def api_uri
8
+ "ValidateAddress"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,66 @@
1
+ require_relative "./endpoint/attributes"
2
+
3
+ # The Endpoint class is an abstract class that sets attributes and handles the
4
+ # execution of API endoint calls.
5
+ #
6
+ # It requires two instance methods to be defined.
7
+ # * `uri` - returns a valid uri string that represents the full api path
8
+ # * `headers` - returns a hash of key value pairs for the request
9
+ #
10
+ # The attributes module adds class level methods for specifying the attributes
11
+ # of the API call.
12
+ # * `required_attributes`
13
+ # * `optional_attributes`
14
+ module AusPostAPI
15
+ class Endpoint
16
+ include AusPostAPI::Endpoint::Attributes
17
+
18
+ def initialize(attributes, config, uri_handler = AusPostAPI::UriHandler)
19
+ @config = config
20
+ @attributes = attributes
21
+ @uri_handler = uri_handler
22
+
23
+ set_attributes
24
+ end
25
+
26
+ def execute
27
+ @uri_handler.call(uri, headers)
28
+ end
29
+
30
+ private
31
+
32
+ def uri
33
+ raise ImplementationError.new("uri")
34
+ end
35
+
36
+ def headers
37
+ raise ImplementationError.new("headers")
38
+ end
39
+
40
+ def set_attributes
41
+ required_param = -> (attr) { raise RequiredArgumentError.new(attr) }
42
+
43
+ required_attributes.each do |attr|
44
+ self.send("#{attr}=", @attributes.fetch(attr, &required_param))
45
+ end
46
+
47
+ optional_attributes.each do |attr|
48
+ if @attributes.has_key?(attr)
49
+ self.send("#{attr}=", @attributes.fetch(attr))
50
+ end
51
+ end
52
+ end
53
+
54
+ class RequiredArgumentError < StandardError
55
+ def initialize(attr)
56
+ super("#{attr} is a required argument")
57
+ end
58
+ end
59
+
60
+ class ImplementationError < StandardError
61
+ def initialize(method)
62
+ super("No #{method} implemented")
63
+ end
64
+ end
65
+ end
66
+ end