aus_post_api 1.0.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.
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