checkout_ru 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0a282cdafe5a22eec40082c3a726a2f07dff009
4
- data.tar.gz: f34819469e964ef1fbb497bd696ced3f7fd78bab
3
+ metadata.gz: 67ba1776758aff93812e8db9601160ee5a095719
4
+ data.tar.gz: 6b6c449d9ca9aabb1ed0edf0ca63872f1a934922
5
5
  SHA512:
6
- metadata.gz: ce436024add082677decc45b29a184cbc6e654352f3341b78815161ffce4ffcda4072242ca41e97c6e9311a43972c3c28709931dc60cad29473ccff24d075c14
7
- data.tar.gz: f1db0972f18d62420b22662d0ff148af31df5ec01fa38c32cfb9f8962d74d9a878d64cb31176def6f5863635d98b2c7ec92e7eba6991deeb866c0896ee32f57e
6
+ metadata.gz: 442d13b106ee8ab3ab8a2375e99ade2b04eb699e412b8185452c8c88ee975065fc25219c038cd7a4f0a53b18232b16b5b9c841f28c37d81da12fe7a65e5b1466
7
+ data.tar.gz: 05d23e0922f1765dfffcb77c26dc5e74faef7f9103a27eb0f1f090b028a95a797ad78e29016cd13e7abf6a9b43dcd7e2bdbfd06b7c3603d047c56baae10aed8d
@@ -1,3 +1,10 @@
1
+ ## 0.5.1
2
+
3
+ - Support for first specialized error: CheckoutRu::NoDeliveryFoundError.
4
+ It's descendant from CheckoutRu::Error so doesn't break existing rescue code.
5
+ It's raised when checkout.ru has no delivery for certain settlement id.
6
+ - All CheckoutRu::Error exceptions now have `code` attribute
7
+
1
8
  ## 0.5.0
2
9
 
3
10
  - Support new JSON errors (includes support for JSON expired-ticket response)
@@ -11,7 +11,6 @@ require 'checkout_ru/order'
11
11
 
12
12
  module CheckoutRu
13
13
  SERVICE_URL = 'http://platform.checkout.ru'.freeze
14
- Error = Class.new(RuntimeError)
15
14
 
16
15
  class << self
17
16
  attr_accessor \
@@ -0,0 +1,34 @@
1
+ module CheckoutRu
2
+ class Error < RuntimeError
3
+ class << self
4
+ def construct(response)
5
+ code, message = parse_error_response(response)
6
+ error_message = "#{message} (checkout.ru error, code #{code})"
7
+
8
+ case code
9
+ when 4 then NoDeliveryFoundError.new(error_message, code)
10
+ when nil then new(response.inspect)
11
+ else new(error_message, code)
12
+ end
13
+ end
14
+
15
+ def parse_error_response(response)
16
+ if response.respond_to?(:[]) &&
17
+ response[:error_code] &&
18
+ response[:error_message]
19
+
20
+ [response[:error_code], response[:error_message]]
21
+ end
22
+ end
23
+ end
24
+
25
+ attr_reader :code
26
+
27
+ def initialize(message, code = nil)
28
+ @code = code
29
+ super(message)
30
+ end
31
+ end
32
+
33
+ NoDeliveryFoundError = Class.new(Error)
34
+ end
@@ -0,0 +1,37 @@
1
+ module CheckoutRu
2
+ class ExpiredTicketResponse
3
+ attr_reader :response
4
+
5
+ def initialize(response)
6
+ @response = response || {}
7
+ end
8
+
9
+ def match?
10
+ # Checkout.ru changed (broke) invalid ticket responses a few times. These
11
+ # predicates reflect various ways we've seen that tickets can expire.
12
+ json_style_error_after_jan_2015? ||
13
+ old_style_error_before_jan_2015? ||
14
+ broken_error_as_of_oct_06_2014?
15
+ end
16
+
17
+ def json_style_error_after_jan_2015?
18
+ error && error_code == 3 && error_message =~ /is\s+expired\s+or\s+invalid/
19
+ end
20
+
21
+ def old_style_error_before_jan_2015?
22
+ [400, 500].include?(status) && body =~ /is\s+expired\s+or\s+invalid/
23
+ end
24
+
25
+ def broken_error_as_of_oct_06_2014?
26
+ status == 500 && body =~ /Сервис\s+временно\s+не\s+доступен/
27
+ end
28
+
29
+ private
30
+
31
+ def error; response[:error] end
32
+ def error_code; response[:error_code] end
33
+ def error_message; response[:error_message] end
34
+ def body; response[:body] end
35
+ def status; response[:status] end
36
+ end
37
+ end
@@ -1,27 +1,8 @@
1
+ require 'checkout_ru/expired_ticket_response'
2
+ require 'checkout_ru/error'
3
+
1
4
  module CheckoutRu
2
5
  class Session
3
- # Checkout.ru changed (broke) invalid ticket responses a few times. These
4
- # hashes reflect various ways we've seen up to date that ticket can expire.
5
- EXPIRED_TICKET_MATCHERS = [
6
- # the new JSON errors
7
- lambda { |r|
8
- r[:error] &&
9
- r[:error_code] == 3 &&
10
- r[:error_message] =~ /is\s+expired\s+or\s+invalid/
11
- },
12
-
13
- # before JSON errors were introduced
14
- lambda { |r|
15
- [400, 500].include?(r[:status]) &&
16
- r[:body] =~ /is\s+expired\s+or\s+invalid/
17
- },
18
-
19
- # broken style as of 10-06-14
20
- lambda { |r|
21
- r[:status] == 500 && r[:body] =~ /Сервис\s+временно\s+не\s+доступен/
22
- }
23
- ].freeze
24
-
25
6
  class << self
26
7
  def initiate
27
8
  ticket = CheckoutRu.get_ticket
@@ -81,10 +62,7 @@ module CheckoutRu
81
62
  end
82
63
 
83
64
  if parsed_response[:error]
84
- msg = "Error code: #{parsed_response[:error_code]}. "\
85
- "Error message: #{parsed_response[:error_message]}"
86
-
87
- raise Error, msg
65
+ raise Error.construct(parsed_response)
88
66
  end
89
67
 
90
68
  parsed_response
@@ -95,9 +73,7 @@ module CheckoutRu
95
73
  end
96
74
 
97
75
  def expired_ticket?(parsed_response)
98
- parsed_response && EXPIRED_TICKET_MATCHERS.any? do |matcher|
99
- matcher.call(parsed_response)
100
- end
76
+ ExpiredTicketResponse.new(parsed_response).match?
101
77
  end
102
78
  end
103
79
  end
@@ -1,3 +1,3 @@
1
1
  module CheckoutRu
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ class ExpiredTicketResponseTest < MiniTest::Test
4
+ def test_json_style_error_after_jan_2015_is_recognized
5
+ response = {
6
+ error: true, error_code: 3, error_message: "Ticket is expired or invalid"
7
+ }
8
+
9
+ assert CheckoutRu::ExpiredTicketResponse.new(response).match?
10
+ end
11
+
12
+ def test_old_style_error_before_jan_2015_is_recognized
13
+ response1 = { status: 400, body: "Ticket is expired or invalid" }
14
+ response2 = { status: 500, body: "Ticket is expired or invalid" }
15
+
16
+ assert CheckoutRu::ExpiredTicketResponse.new(response1).match?
17
+ assert CheckoutRu::ExpiredTicketResponse.new(response2).match?
18
+ end
19
+
20
+ def test_broken_error_as_of_oct_06_2014_is_recognzied
21
+ response = { status: 500, body: "Сервис временно не доступен" }
22
+ assert CheckoutRu::ExpiredTicketResponse.new(response).match?
23
+ end
24
+ end
@@ -85,4 +85,22 @@ class CheckoutRu::SessionTest < MiniTest::Test
85
85
  assert_equal 'г. Москва', place.full_name
86
86
  end
87
87
  end
88
+
89
+ def test_get_no_delivery_found_error
90
+ VCR.use_cassette('get_no_delivery_found_error') do
91
+ error = assert_raises(CheckoutRu::NoDeliveryFoundError) do
92
+ @session.calculation(
93
+ :place_id => 'b0122c31-eb1c-40ae-b998-08f9e99a0fa1',
94
+ :total_sum => 1500,
95
+ :assessed_sum => 2000,
96
+ :items_count => 2,
97
+ :total_weight => 1
98
+ )
99
+ end
100
+
101
+ assert_equal 4, error.code
102
+ assert_match /no delivery found/, error.message
103
+ assert_match /code 4/, error.message
104
+ end
105
+ end
88
106
  end
@@ -71,8 +71,6 @@ class CheckoutRuTest < MiniTest::Test
71
71
  end
72
72
  end
73
73
 
74
- # Test is broken. Request on update returns error status without description.
75
- # Must be discussed in skype with support.
76
74
  def test_update_order
77
75
  VCR.use_cassette('update_order') do
78
76
  id = create_order
@@ -0,0 +1,103 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://platform.checkout.ru/service/checkout/calculation?placeId=b0122c31-eb1c-40ae-b998-08f9e99a0fa1&totalSum=1500&assessedSum=2000&itemsCount=2&totalWeight=1&ticket=tests-will-autorequest-a-valid-ticket
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.9
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message:
18
+ headers:
19
+ server:
20
+ - nginx/1.7.7
21
+ date:
22
+ - Wed, 28 Jan 2015 00:46:24 GMT
23
+ content-type:
24
+ - application/json;charset=UTF-8
25
+ transfer-encoding:
26
+ - chunked
27
+ connection:
28
+ - close
29
+ set-cookie:
30
+ - JSESSIONID=B7124F28808555872014EE6D7E9BAF26.srv100; Path=/; HttpOnly
31
+ body:
32
+ encoding: UTF-8
33
+ string: '{"error":true,"errorCode":3,"errorMessage":"ticket: ticket is expired
34
+ or invalid; "}'
35
+ http_version:
36
+ recorded_at: Wed, 28 Jan 2015 00:46:24 GMT
37
+ - request:
38
+ method: get
39
+ uri: http://platform.checkout.ru/service/login/ticket/valid-api-key
40
+ body:
41
+ encoding: US-ASCII
42
+ string: ''
43
+ headers:
44
+ User-Agent:
45
+ - Faraday v0.8.9
46
+ Accept:
47
+ - application/json
48
+ response:
49
+ status:
50
+ code: 200
51
+ message:
52
+ headers:
53
+ server:
54
+ - nginx/1.7.7
55
+ date:
56
+ - Wed, 28 Jan 2015 00:46:24 GMT
57
+ content-type:
58
+ - application/json;charset=UTF-8
59
+ content-length:
60
+ - '113'
61
+ connection:
62
+ - close
63
+ body:
64
+ encoding: UTF-8
65
+ string: '{"ticket":"211e40247d084107eedfcf4ebc5fffb8", "receiverEmailNotRequired":"false",
66
+ "isCashOnDeliveryOnly":"false"}'
67
+ http_version:
68
+ recorded_at: Wed, 28 Jan 2015 00:46:25 GMT
69
+ - request:
70
+ method: get
71
+ uri: http://platform.checkout.ru/service/checkout/calculation?placeId=b0122c31-eb1c-40ae-b998-08f9e99a0fa1&totalSum=1500&assessedSum=2000&itemsCount=2&totalWeight=1&ticket=211e40247d084107eedfcf4ebc5fffb8
72
+ body:
73
+ encoding: US-ASCII
74
+ string: ''
75
+ headers:
76
+ User-Agent:
77
+ - Faraday v0.8.9
78
+ Accept:
79
+ - application/json
80
+ response:
81
+ status:
82
+ code: 200
83
+ message:
84
+ headers:
85
+ server:
86
+ - nginx/1.7.7
87
+ date:
88
+ - Wed, 28 Jan 2015 00:46:25 GMT
89
+ content-type:
90
+ - application/json;charset=UTF-8
91
+ transfer-encoding:
92
+ - chunked
93
+ connection:
94
+ - close
95
+ set-cookie:
96
+ - JSESSIONID=0367069015CE5D427494A3220B42CE5D.srv100; Path=/; HttpOnly
97
+ body:
98
+ encoding: UTF-8
99
+ string: '{"error":true,"errorCode":4,"errorMessage":"no delivery found for place
100
+ specified"}'
101
+ http_version:
102
+ recorded_at: Wed, 28 Jan 2015 00:46:25 GMT
103
+ recorded_with: VCR 2.9.0
@@ -5,7 +5,9 @@ require 'vcr'
5
5
  require 'cgi'
6
6
 
7
7
  REAL_API_KEY = ENV['CHECKOUT_RU_API_KEY']
8
- CheckoutRu.api_key = ENV['CHECKOUT_RU_API_KEY'] || 'valid-api-key'
8
+ FAKE_API_KEY = 'valid-api-key'
9
+
10
+ CheckoutRu.api_key = REAL_API_KEY || FAKE_API_KEY
9
11
  CheckoutRu.auto_renew_session = true
10
12
 
11
13
  VCR.configure do |c|
@@ -13,7 +15,7 @@ VCR.configure do |c|
13
15
  c.hook_into :faraday
14
16
 
15
17
  if REAL_API_KEY
16
- c.filter_sensitive_data('valid-api-key') { CheckoutRu.api_key }
18
+ c.filter_sensitive_data(FAKE_API_KEY) { REAL_API_KEY }
17
19
  end
18
20
 
19
21
  c.before_record do |i|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: checkout_ru
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxim Chernyak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-21 00:00:00.000000000 Z
11
+ date: 2015-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -182,15 +182,19 @@ files:
182
182
  - lib/checkout_ru/address.rb
183
183
  - lib/checkout_ru/delivery.rb
184
184
  - lib/checkout_ru/entity.rb
185
+ - lib/checkout_ru/error.rb
186
+ - lib/checkout_ru/expired_ticket_response.rb
185
187
  - lib/checkout_ru/item.rb
186
188
  - lib/checkout_ru/order.rb
187
189
  - lib/checkout_ru/session.rb
188
190
  - lib/checkout_ru/user.rb
189
191
  - lib/checkout_ru/version.rb
192
+ - test/checkout_ru/expired_ticket_response_test.rb
190
193
  - test/checkout_ru/session_test.rb
191
194
  - test/checkout_ru_test.rb
192
195
  - test/fixtures/calculation.yml
193
196
  - test/fixtures/create_order.yml
197
+ - test/fixtures/get_no_delivery_found_error.yml
194
198
  - test/fixtures/get_place_by_postal_code.yml
195
199
  - test/fixtures/get_places_by_query.yml
196
200
  - test/fixtures/get_postal_code_by_address.yml
@@ -227,10 +231,12 @@ signing_key:
227
231
  specification_version: 4
228
232
  summary: Ruby client for checkout.ru
229
233
  test_files:
234
+ - test/checkout_ru/expired_ticket_response_test.rb
230
235
  - test/checkout_ru/session_test.rb
231
236
  - test/checkout_ru_test.rb
232
237
  - test/fixtures/calculation.yml
233
238
  - test/fixtures/create_order.yml
239
+ - test/fixtures/get_no_delivery_found_error.yml
234
240
  - test/fixtures/get_place_by_postal_code.yml
235
241
  - test/fixtures/get_places_by_query.yml
236
242
  - test/fixtures/get_postal_code_by_address.yml