checkout_ru 0.5.0 → 0.5.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 +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/checkout_ru.rb +0 -1
- data/lib/checkout_ru/error.rb +34 -0
- data/lib/checkout_ru/expired_ticket_response.rb +37 -0
- data/lib/checkout_ru/session.rb +5 -29
- data/lib/checkout_ru/version.rb +1 -1
- data/test/checkout_ru/expired_ticket_response_test.rb +24 -0
- data/test/checkout_ru/session_test.rb +18 -0
- data/test/checkout_ru_test.rb +0 -2
- data/test/fixtures/get_no_delivery_found_error.yml +103 -0
- data/test/test_helper.rb +4 -2
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 67ba1776758aff93812e8db9601160ee5a095719
|
|
4
|
+
data.tar.gz: 6b6c449d9ca9aabb1ed0edf0ca63872f1a934922
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 442d13b106ee8ab3ab8a2375e99ade2b04eb699e412b8185452c8c88ee975065fc25219c038cd7a4f0a53b18232b16b5b9c841f28c37d81da12fe7a65e5b1466
|
|
7
|
+
data.tar.gz: 05d23e0922f1765dfffcb77c26dc5e74faef7f9103a27eb0f1f090b028a95a797ad78e29016cd13e7abf6a9b43dcd7e2bdbfd06b7c3603d047c56baae10aed8d
|
data/CHANGELOG.md
CHANGED
|
@@ -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)
|
data/lib/checkout_ru.rb
CHANGED
|
@@ -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
|
data/lib/checkout_ru/session.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
|
99
|
-
matcher.call(parsed_response)
|
|
100
|
-
end
|
|
76
|
+
ExpiredTicketResponse.new(parsed_response).match?
|
|
101
77
|
end
|
|
102
78
|
end
|
|
103
79
|
end
|
data/lib/checkout_ru/version.rb
CHANGED
|
@@ -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
|
data/test/checkout_ru_test.rb
CHANGED
|
@@ -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
|
data/test/test_helper.rb
CHANGED
|
@@ -5,7 +5,9 @@ require 'vcr'
|
|
|
5
5
|
require 'cgi'
|
|
6
6
|
|
|
7
7
|
REAL_API_KEY = ENV['CHECKOUT_RU_API_KEY']
|
|
8
|
-
|
|
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(
|
|
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.
|
|
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-
|
|
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
|