russianpost 0.3.0 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90c9d9530331f51349587f14084ab6b1c28aa140
4
- data.tar.gz: 674b6c39bcd65a111a059e02f1a722bd7260d897
3
+ metadata.gz: f25804582583d50312fcdabb61739ab523bb1a60
4
+ data.tar.gz: d884f42475e9c64231dc79608027d8378c71a3ec
5
5
  SHA512:
6
- metadata.gz: 970d71fef77c20e95749f1edd22e6b583d2beaa6708f868320500c918d7f915d47da8bb580d5aacb03e78ea22a781de3a78b9aa43e52b049d26c7b89b5389ece
7
- data.tar.gz: 966878c1fd633dece8e1edf8287c1a3fc5cefb6757d4fa6cafceafddbf58e6f369927011d830e1ea519eff6a72934bfa4636b5a53e7ba9794a854ce541b29761
6
+ metadata.gz: 423ce97c42a91b2f8f964d80457e98b1bd8287ea6af8c8f6aadcb962ca1e9cce25ac995dd270b0253dfc69f00995fe044369145222d4a265002e89c121f9912d
7
+ data.tar.gz: b8c07fa4a085b8fe7b0bb1e89ad38ba3a1ebe67045f9bae77298f68468791ca37940d7829892c7029c4dd22ed97092da342932a7b50a549cba15b45704587cfd
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Russian Post API Client
2
2
 
3
- [![Build Status](https://travis-ci.org/artemshitov/russianpost.png?branch=master)](https://travis-ci.org/artemshitov/russianpost)
3
+ [![Build Status](https://travis-ci.org/artemshitov/russianpost.png?branch=master)](https://travis-ci.org/artemshitov/russianpost) [![Code Climate](https://codeclimate.com/github/artemshitov/russianpost.png)](https://codeclimate.com/github/artemshitov/russianpost)
4
4
 
5
5
  Thin wrapper around Russian Post package tracking SOAP API. Works on a per-package basis (contrary to the bulk ticket-based API). Use it at your own risk, since the API may appear unstable and require authorization in future.
6
6
 
@@ -12,7 +12,7 @@ To install gem stand-alone:
12
12
 
13
13
  To use gem in a Rails app, add the following to your `Gemfile`:
14
14
 
15
- gem "russianpost", "~> 0.3.0"
15
+ gem "russianpost", "~> 0.3.1"
16
16
 
17
17
  This gem uses [Savon](http://savonrb.com/), which in turn uses [HTTPI](https://github.com/savonrb/httpi) internally. HTTPI chooses the best HTTP library of those you have installed. For the fastest results, make sure you add [Curb](https://github.com/taf2/curb) to your `Gemfile`:
18
18
 
@@ -0,0 +1,32 @@
1
+ require "russianpost/barcode_validator"
2
+
3
+ module RussianPost
4
+ class Barcode
5
+ extend Forwardable
6
+
7
+ def_delegator :barcode, :=~
8
+
9
+ attr_reader :barcode
10
+
11
+ def initialize(barcode)
12
+ @barcode = barcode.strip.upcase
13
+ raise InvalidBarcode unless valid?
14
+ end
15
+
16
+ def to_s
17
+ barcode
18
+ end
19
+
20
+ def digits
21
+ barcode[/\d+/].split("").map { |d| d.to_i }
22
+ end
23
+
24
+ private
25
+
26
+ def valid?
27
+ BarcodeValidator.validate(self)
28
+ end
29
+ end
30
+
31
+ class InvalidBarcode < ArgumentError; end
32
+ end
@@ -0,0 +1,46 @@
1
+ module RussianPost
2
+ class BarcodeValidator
3
+ attr_reader :barcode, :digits
4
+
5
+ INTERNATIONAL_FORMAT = /\A([A-Z]{2}\d{9}[A-Z]{2})\Z/
6
+ DOMESTIC_FORMAT = /\A(\d{14})\Z/
7
+ WEIGHT_FACTORS = [8, 6, 4, 2, 3, 5, 9, 7, 0]
8
+
9
+ def self.validate(barcode)
10
+ new(barcode).valid?
11
+ end
12
+
13
+ def initialize(barcode)
14
+ @barcode = barcode
15
+ @digits = barcode.digits
16
+ end
17
+
18
+ def valid?
19
+ valid_international? || valid_domestic?
20
+ end
21
+
22
+
23
+ private
24
+
25
+ def valid_international?
26
+ barcode =~ INTERNATIONAL_FORMAT && digits.last == checkdigit
27
+ end
28
+
29
+ def valid_domestic?
30
+ barcode =~ DOMESTIC_FORMAT
31
+ end
32
+
33
+ def checkdigit
34
+ if (1..9).include? checksum
35
+ checksum
36
+ else
37
+ checksum == 10 ? 0 : 5
38
+ end
39
+ end
40
+
41
+ def checksum
42
+ product = digits.zip(WEIGHT_FACTORS)
43
+ (11 - product.map{|i| i.reduce(:*)}.reduce(:+)) % 11
44
+ end
45
+ end
46
+ end
@@ -3,11 +3,16 @@ require "savon"
3
3
  module RussianPost
4
4
  class Client
5
5
  attr_reader :savon, :endpoint, :namespace
6
+
7
+ ENDPOINT = "http://voh.russianpost.ru:8080/niips-operationhistory-web/OperationHistory"
8
+ NAMESPACE = "http://russianpost.org/operationhistory/data"
6
9
 
7
- def initialize
8
- @endpoint = "http://voh.russianpost.ru:8080/niips-operationhistory-web/OperationHistory"
9
- @namespace = "http://russianpost.org/operationhistory/data"
10
- @savon = Savon.client(endpoint: endpoint, namespace: namespace, log: false)
10
+ def initialize(opts = {})
11
+ @savon = Savon.client(
12
+ endpoint: ENDPOINT,
13
+ namespace: NAMESPACE,
14
+ open_timeout: opts[:timeout] || 10, # in seconds
15
+ log: false)
11
16
  end
12
17
 
13
18
  def call(opts = {barcode: nil})
@@ -1,15 +1,14 @@
1
1
  require "russianpost/client"
2
2
  require "russianpost/operations_factory"
3
+ require "russianpost/barcode"
3
4
 
4
5
  module RussianPost
5
6
  class Parcel
6
7
  attr_reader :barcode, :client
7
8
 
8
9
  def initialize(barcode, opts = {})
9
- @barcode = barcode.upcase
10
+ @barcode = Barcode.new(barcode)
10
11
  @client = (opts[:client] || Client).new
11
-
12
- raise InvalidBarcode unless barcode_is_valid?
13
12
  end
14
13
 
15
14
  def operations
@@ -21,11 +20,5 @@ module RussianPost
21
20
  def fetch_operations
22
21
  OperationsFactory.build(client.call(barcode: barcode))
23
22
  end
24
-
25
- def barcode_is_valid?
26
- barcode =~ /\A([A-Z]{2}\d{9}[A-Z]{2})|(\d{14})\z/
27
- end
28
23
  end
29
-
30
- class InvalidBarcode < ArgumentError; end
31
24
  end
@@ -1,3 +1,3 @@
1
1
  module Russianpost
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -0,0 +1,23 @@
1
+ require "test_helper"
2
+ require "russianpost/barcode"
3
+
4
+ class BarcodeTest < MiniTest::Unit::TestCase
5
+ def test_implicitly_converts_to_string
6
+ barcode = RussianPost::Barcode.new("RD025500807SE")
7
+ assert_equal "bar RD025500807SE", "bar #{barcode}"
8
+ end
9
+
10
+ def test_raises_on_invalid_barcode
11
+ ["123", "RR123456789EE"].each do |barcode|
12
+ assert_raises RussianPost::InvalidBarcode do
13
+ RussianPost::Barcode.new(barcode)
14
+ end
15
+ end
16
+ end
17
+
18
+ def test_doesnt_raise_on_valid_barcode
19
+ ["RD025500807SE", "12345678901234"].each do |barcode|
20
+ RussianPost::Barcode.new(barcode)
21
+ end
22
+ end
23
+ end
@@ -12,7 +12,7 @@ class ParcelTest < MiniTest::Unit::TestCase
12
12
 
13
13
  def test_returns_empty_array_on_nonexistent_parcel
14
14
  VCR.use_cassette("nonexistent_parcel") do
15
- parcel = RussianPost::Parcel.new("RR123456789EE")
15
+ parcel = RussianPost::Parcel.new("RR123456785EE")
16
16
  assert_kind_of Array, parcel.operations
17
17
  assert parcel.operations.empty?
18
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: russianpost
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Shitov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-21 00:00:00.000000000 Z
11
+ date: 2013-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -96,6 +96,8 @@ files:
96
96
  - README.md
97
97
  - Rakefile
98
98
  - lib/russianpost.rb
99
+ - lib/russianpost/barcode.rb
100
+ - lib/russianpost/barcode_validator.rb
99
101
  - lib/russianpost/client.rb
100
102
  - lib/russianpost/operation.rb
101
103
  - lib/russianpost/operations_factory.rb
@@ -104,6 +106,7 @@ files:
104
106
  - russianpost.gemspec
105
107
  - test/fixtures/vcr_cassettes/nonexistent_parcel.yml
106
108
  - test/fixtures/vcr_cassettes/valid_barcode.yml
109
+ - test/russianpost/barcode_test.rb
107
110
  - test/russianpost/client_test.rb
108
111
  - test/russianpost/parcel_test.rb
109
112
  - test/test_helper.rb
@@ -134,6 +137,7 @@ summary: Russian Post package tracking API client
134
137
  test_files:
135
138
  - test/fixtures/vcr_cassettes/nonexistent_parcel.yml
136
139
  - test/fixtures/vcr_cassettes/valid_barcode.yml
140
+ - test/russianpost/barcode_test.rb
137
141
  - test/russianpost/client_test.rb
138
142
  - test/russianpost/parcel_test.rb
139
143
  - test/test_helper.rb