venice 0.4.1 → 0.4.2

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.
@@ -9,6 +9,7 @@ module Venice
9
9
  class Client
10
10
  attr_accessor :verification_url
11
11
  attr_writer :shared_secret
12
+ attr_writer :exclude_old_transactions
12
13
 
13
14
  class << self
14
15
  def development
@@ -31,13 +32,13 @@ module Venice
31
32
  def verify!(data, options = {})
32
33
  @verification_url ||= ITUNES_DEVELOPMENT_RECEIPT_VERIFICATION_ENDPOINT
33
34
  @shared_secret = options[:shared_secret] if options[:shared_secret]
35
+ @exclude_old_transactions = options[:exclude_old_transactions] if options[:exclude_old_transactions]
34
36
 
35
- json = json_response_from_verifying_data(data)
36
- status = json['status'].to_i
37
- receipt_attributes = json['receipt'].dup
37
+ json = json_response_from_verifying_data(data, options)
38
+ receipt_attributes = json['receipt'].dup if json['receipt']
38
39
  receipt_attributes['original_json_response'] = json if receipt_attributes
39
40
 
40
- case status
41
+ case json['status'].to_i
41
42
  when 0, 21006
42
43
  receipt = Receipt.new(receipt_attributes)
43
44
 
@@ -55,32 +56,46 @@ module Venice
55
56
 
56
57
  return receipt
57
58
  else
58
- raise Receipt::VerificationError.new(status, receipt)
59
+ raise Receipt::VerificationError, json
59
60
  end
60
61
  end
61
62
 
62
63
  private
63
64
 
64
- def json_response_from_verifying_data(data)
65
+ def json_response_from_verifying_data(data, options = {})
65
66
  parameters = {
66
67
  'receipt-data' => data
67
68
  }
68
69
 
69
70
  parameters['password'] = @shared_secret if @shared_secret
71
+ parameters['exclude-old-transactions'] = @exclude_old_transactions if @exclude_old_transactions
70
72
 
71
73
  uri = URI(@verification_url)
72
74
  http = Net::HTTP.new(uri.host, uri.port)
73
75
  http.use_ssl = true
74
76
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
75
77
 
78
+ http.open_timeout = options[:open_timeout] if options[:open_timeout]
79
+ http.read_timeout = options[:read_timeout] if options[:read_timeout]
80
+
76
81
  request = Net::HTTP::Post.new(uri.request_uri)
77
82
  request['Accept'] = 'application/json'
78
83
  request['Content-Type'] = 'application/json'
79
84
  request.body = parameters.to_json
80
85
 
81
- response = http.request(request)
86
+ begin
87
+ response = http.request(request)
88
+ rescue Timeout::Error
89
+ raise TimeoutError
90
+ end
82
91
 
83
92
  JSON.parse(response.body)
84
93
  end
85
94
  end
95
+
96
+ class Client::TimeoutError < Timeout::Error
97
+ def message
98
+ 'The App Store timed out.'
99
+ end
100
+ end
86
101
  end
@@ -94,7 +94,9 @@ module Venice
94
94
 
95
95
  class << self
96
96
  def verify(data, options = {})
97
- verify!(data, options) rescue false
97
+ verify!(data, options)
98
+ rescue VerificationError, Client::TimeoutError
99
+ false
98
100
  end
99
101
 
100
102
  def verify!(data, options = {})
@@ -121,16 +123,22 @@ module Venice
121
123
  end
122
124
 
123
125
  class VerificationError < StandardError
124
- attr_accessor :code
125
- attr_accessor :receipt
126
+ attr_accessor :json
126
127
 
127
- def initialize(code, receipt)
128
- @code = Integer(code)
129
- @receipt = receipt
128
+ def initialize(json)
129
+ @json = json
130
+ end
131
+
132
+ def code
133
+ Integer(json['status'])
134
+ end
135
+
136
+ def retryable?
137
+ json['is-retryable']
130
138
  end
131
139
 
132
140
  def message
133
- case @code
141
+ case code
134
142
  when 21000
135
143
  'The App Store could not read the JSON object you provided.'
136
144
  when 21002
@@ -152,7 +160,7 @@ module Venice
152
160
  when 21100..21199
153
161
  'Internal data access error.'
154
162
  else
155
- "Unknown Error: #{@code}"
163
+ "Unknown Error: #{code}"
156
164
  end
157
165
  end
158
166
  end
@@ -1,3 +1,3 @@
1
1
  module Venice
2
- VERSION = '0.4.1'
2
+ VERSION = '0.4.2'
3
3
  end
@@ -112,5 +112,50 @@ describe Venice::Client do
112
112
  receipt.latest_receipt_info.should_not be_nil
113
113
  end
114
114
  end
115
+
116
+ context 'with an error response' do
117
+ before do
118
+ client.stub(:json_response_from_verifying_data).and_return(response)
119
+ end
120
+
121
+ let(:response) do
122
+ {
123
+ 'status' => 21000,
124
+ 'receipt' => {}
125
+ }
126
+ end
127
+
128
+ it 'raises a VerificationError' do
129
+ expect do
130
+ client.verify!('asdf')
131
+ end.to raise_error(Venice::Receipt::VerificationError) do |error|
132
+ expect(error.json).to eq(response)
133
+ expect(error.code).to eq(21000)
134
+ expect(error).not_to be_retryable
135
+ end
136
+ end
137
+ end
138
+
139
+ context 'with a retryable error response' do
140
+ before do
141
+ client.stub(:json_response_from_verifying_data).and_return(response)
142
+ end
143
+
144
+ let(:response) do
145
+ {
146
+ 'status' => 21000,
147
+ 'receipt' => {},
148
+ 'is-retryable' => true
149
+ }
150
+ end
151
+
152
+ it 'raises a VerificationError' do
153
+ expect do
154
+ client.verify!('asdf')
155
+ end.to raise_error(Venice::Receipt::VerificationError) do |error|
156
+ expect(error).to be_retryable
157
+ end
158
+ end
159
+ end
115
160
  end
116
161
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: venice
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mattt Thompson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-17 00:00:00.000000000 Z
11
+ date: 2017-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander