candy_check 0.1.0.pre → 0.3.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.
- checksums.yaml +5 -5
- data/.rubocop.yml +23 -0
- data/.ruby-version +1 -1
- data/.travis.yml +7 -8
- data/Guardfile +42 -0
- data/MIGRATION_GUIDE_0_2_0.md +141 -0
- data/README.md +86 -26
- data/Rakefile +1 -1
- data/candy_check.gemspec +33 -25
- data/lib/candy_check/app_store/receipt_collection.rb +5 -3
- data/lib/candy_check/app_store/subscription_verification.rb +25 -1
- data/lib/candy_check/app_store/verification.rb +1 -1
- data/lib/candy_check/app_store/verifier.rb +11 -11
- data/lib/candy_check/cli/app.rb +16 -33
- data/lib/candy_check/cli/commands/play_store.rb +12 -13
- data/lib/candy_check/play_store.rb +20 -10
- data/lib/candy_check/play_store/acknowledger.rb +19 -0
- data/lib/candy_check/play_store/android_publisher_service.rb +6 -0
- data/lib/candy_check/play_store/product_acknowledgements/acknowledgement.rb +45 -0
- data/lib/candy_check/play_store/product_acknowledgements/response.rb +24 -0
- data/lib/candy_check/play_store/product_purchases/product_purchase.rb +90 -0
- data/lib/candy_check/play_store/product_purchases/product_verification.rb +53 -0
- data/lib/candy_check/play_store/subscription_purchases/subscription_purchase.rb +154 -0
- data/lib/candy_check/play_store/subscription_purchases/subscription_verification.rb +55 -0
- data/lib/candy_check/play_store/verification_failure.rb +8 -6
- data/lib/candy_check/play_store/verifier.rb +24 -49
- data/lib/candy_check/utils/config.rb +5 -3
- data/lib/candy_check/version.rb +1 -1
- data/spec/app_store/receipt_collection_spec.rb +33 -0
- data/spec/app_store/subscription_verification_spec.rb +35 -2
- data/spec/app_store/verifier_spec.rb +24 -5
- data/spec/candy_check_spec.rb +2 -2
- data/spec/cli/commands/play_store_spec.rb +10 -43
- data/spec/fixtures/play_store/random_dummy_key.json +12 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_acknowledgements/acknowledged.yml +105 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_acknowledgements/already_acknowledged.yml +124 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_acknowledgements/refunded.yml +122 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_purchases/permission_denied.yml +196 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_purchases/response_with_empty_body.yml +183 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_purchases/valid_but_not_consumed.yml +122 -0
- data/spec/fixtures/vcr_cassettes/play_store/subscription_purchases/permission_denied.yml +196 -0
- data/spec/fixtures/vcr_cassettes/play_store/subscription_purchases/valid_but_expired.yml +127 -0
- data/spec/play_store/acknowledger_spec.rb +48 -0
- data/spec/play_store/product_acknowledgements/acknowledgement_spec.rb +54 -0
- data/spec/play_store/product_acknowledgements/response_spec.rb +66 -0
- data/spec/play_store/product_purchases/product_purchase_spec.rb +110 -0
- data/spec/play_store/product_purchases/product_verification_spec.rb +49 -0
- data/spec/play_store/subscription_purchases/subscription_purchase_spec.rb +237 -0
- data/spec/play_store/subscription_purchases/subscription_verification_spec.rb +65 -0
- data/spec/play_store/verification_failure_spec.rb +18 -18
- data/spec/play_store/verifier_spec.rb +32 -96
- data/spec/spec_helper.rb +32 -10
- metadata +175 -75
- data/lib/candy_check/play_store/client.rb +0 -126
- data/lib/candy_check/play_store/config.rb +0 -51
- data/lib/candy_check/play_store/discovery_repository.rb +0 -33
- data/lib/candy_check/play_store/receipt.rb +0 -81
- data/lib/candy_check/play_store/subscription.rb +0 -138
- data/lib/candy_check/play_store/subscription_verification.rb +0 -30
- data/lib/candy_check/play_store/verification.rb +0 -48
- data/spec/fixtures/api_cache.dump +0 -1
- data/spec/fixtures/play_store/api_cache.dump +0 -1
- data/spec/fixtures/play_store/auth_failure.txt +0 -18
- data/spec/fixtures/play_store/auth_success.txt +0 -20
- data/spec/fixtures/play_store/discovery.txt +0 -2841
- data/spec/fixtures/play_store/dummy.p12 +0 -0
- data/spec/fixtures/play_store/empty.txt +0 -17
- data/spec/fixtures/play_store/products_failure.txt +0 -29
- data/spec/fixtures/play_store/products_success.txt +0 -22
- data/spec/play_store/client_spec.rb +0 -125
- data/spec/play_store/config_spec.rb +0 -96
- data/spec/play_store/discovery_respository_spec.rb +0 -31
- data/spec/play_store/receipt_spec.rb +0 -88
- data/spec/play_store/subscription_spec.rb +0 -138
- data/spec/play_store/subscription_verification_spec.rb +0 -98
- data/spec/play_store/verification_spec.rb +0 -82
@@ -0,0 +1,110 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CandyCheck::PlayStore::ProductPurchases::ProductPurchase do
|
4
|
+
subject { CandyCheck::PlayStore::ProductPurchases::ProductPurchase.new(fake_product_purchase) }
|
5
|
+
|
6
|
+
describe "valid and non-consumed product" do
|
7
|
+
let(:fake_product_purchase) do
|
8
|
+
FakeProductPurchase.new(
|
9
|
+
consumption_state: 0,
|
10
|
+
developer_payload: "payload that gets stored and returned",
|
11
|
+
kind: "androidpublisher#productPurchase",
|
12
|
+
order_id: "ABC123",
|
13
|
+
purchase_state: 0,
|
14
|
+
purchase_time_millis: 1421676237413,
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "is valid?" do
|
19
|
+
subject.valid?.must_be_true
|
20
|
+
end
|
21
|
+
|
22
|
+
it "is not consumed" do
|
23
|
+
subject.consumed?.must_be_false
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns the purchase_state" do
|
27
|
+
subject.purchase_state.must_equal 0
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns the consumption_state" do
|
31
|
+
subject.consumption_state.must_equal 0
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns the developer_payload" do
|
35
|
+
subject.developer_payload.must_equal "payload that gets stored and returned"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns the kind" do
|
39
|
+
subject.kind.must_equal "androidpublisher#productPurchase"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns the purchase_time_millis" do
|
43
|
+
subject.purchase_time_millis.must_equal 1_421_676_237_413
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns the purchased_at" do
|
47
|
+
expected = DateTime.new(2015, 1, 19, 14, 3, 57)
|
48
|
+
subject.purchased_at.must_equal expected
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "valid and consumed product" do
|
53
|
+
let(:fake_product_purchase) do
|
54
|
+
FakeProductPurchase.new(
|
55
|
+
consumption_state: 1,
|
56
|
+
developer_payload: "payload that gets stored and returned",
|
57
|
+
kind: "androidpublisher#productPurchase",
|
58
|
+
order_id: "ABC123",
|
59
|
+
purchase_state: 0,
|
60
|
+
purchase_time_millis: 1421676237413,
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "is valid?" do
|
65
|
+
subject.valid?.must_be_true
|
66
|
+
end
|
67
|
+
|
68
|
+
it "is consumed?" do
|
69
|
+
subject.consumed?.must_be_true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "non-valid product" do
|
74
|
+
let(:fake_product_purchase) do
|
75
|
+
FakeProductPurchase.new(
|
76
|
+
consumption_state: 0,
|
77
|
+
developer_payload: "payload that gets stored and returned",
|
78
|
+
kind: "androidpublisher#productPurchase",
|
79
|
+
order_id: "ABC123",
|
80
|
+
purchase_state: 1,
|
81
|
+
purchase_time_millis: 1421676237413,
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "is valid?" do
|
86
|
+
subject.valid?.must_be_false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
class FakeProductPurchase
|
93
|
+
FIELDS = [
|
94
|
+
:consumption_state,
|
95
|
+
:developer_payload,
|
96
|
+
:kind,
|
97
|
+
:order_id,
|
98
|
+
:purchase_state,
|
99
|
+
:purchase_time_millis,
|
100
|
+
].freeze
|
101
|
+
|
102
|
+
attr_accessor *FIELDS
|
103
|
+
|
104
|
+
def initialize(hash)
|
105
|
+
FIELDS.each do |key|
|
106
|
+
self.public_send("#{key}=", hash[key])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CandyCheck::PlayStore::ProductPurchases::ProductVerification do
|
4
|
+
subject do
|
5
|
+
CandyCheck::PlayStore::ProductPurchases::ProductVerification.new(
|
6
|
+
package_name: package_name,
|
7
|
+
product_id: product_id,
|
8
|
+
token: token,
|
9
|
+
authorization: authorization,
|
10
|
+
)
|
11
|
+
end
|
12
|
+
let(:package_name) { "my_package_name" }
|
13
|
+
let(:product_id) { "my_product_id" }
|
14
|
+
let(:token) { "my_token" }
|
15
|
+
let(:json_key_file) { File.expand_path("../../fixtures/play_store/random_dummy_key.json", __dir__) }
|
16
|
+
|
17
|
+
let(:authorization) { CandyCheck::PlayStore.authorization(json_key_file) }
|
18
|
+
|
19
|
+
describe "valid" do
|
20
|
+
it "returns a product purchase" do
|
21
|
+
VCR.use_cassette("play_store/product_purchases/valid_but_not_consumed") do
|
22
|
+
result = subject.call!
|
23
|
+
result.must_be_instance_of CandyCheck::PlayStore::ProductPurchases::ProductPurchase
|
24
|
+
result.valid?.must_be_true
|
25
|
+
result.consumed?.must_be_false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "failure" do
|
31
|
+
it "returns a verification failure" do
|
32
|
+
VCR.use_cassette("play_store/product_purchases/permission_denied") do
|
33
|
+
result = subject.call!
|
34
|
+
result.must_be_instance_of CandyCheck::PlayStore::VerificationFailure
|
35
|
+
result.code.must_equal 401
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "empty" do
|
41
|
+
it "returns a verification failure" do
|
42
|
+
VCR.use_cassette("play_store/product_purchases/response_with_empty_body") do
|
43
|
+
result = subject.call!
|
44
|
+
result.must_be_instance_of CandyCheck::PlayStore::VerificationFailure
|
45
|
+
result.code.must_equal(-1)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,237 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CandyCheck::PlayStore::SubscriptionPurchases::SubscriptionPurchase do
|
4
|
+
subject { CandyCheck::PlayStore::SubscriptionPurchases::SubscriptionPurchase.new(fake_subscription_purchase) }
|
5
|
+
|
6
|
+
describe "expired and canceled subscription" do
|
7
|
+
let(:fake_subscription_purchase) do
|
8
|
+
FakeSubscriptionPurchase.new(
|
9
|
+
kind: "androidpublisher#subscriptionPurchase",
|
10
|
+
start_time_millis: 1459540113244,
|
11
|
+
expiry_time_millis: 1462132088610,
|
12
|
+
auto_renewing: false,
|
13
|
+
developer_payload: "payload that gets stored and returned",
|
14
|
+
cancel_reason: 0,
|
15
|
+
payment_state: 1,
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "is expired?" do
|
20
|
+
subject.expired?.must_be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "is canceled by user" do
|
24
|
+
subject.canceled_by_user?.must_be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns the payment_state" do
|
28
|
+
subject.payment_state.must_equal 1
|
29
|
+
end
|
30
|
+
|
31
|
+
it "considers a payment as valid" do
|
32
|
+
subject.payment_received?.must_be_true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "checks that auto renewal status is false" do
|
36
|
+
subject.auto_renewing?.must_be_false
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns the developer_payload" do
|
40
|
+
subject.developer_payload.must_equal \
|
41
|
+
"payload that gets stored and returned"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns the kind" do
|
45
|
+
subject.kind.must_equal "androidpublisher#subscriptionPurchase"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns the start_time_millis" do
|
49
|
+
subject.start_time_millis.must_equal 145_954_011_324_4
|
50
|
+
end
|
51
|
+
|
52
|
+
it "returns the expiry_time_millis" do
|
53
|
+
subject.expiry_time_millis.must_equal 146_213_208_861_0
|
54
|
+
end
|
55
|
+
|
56
|
+
it "returns the starts_at" do
|
57
|
+
expected = DateTime.new(2016, 4, 1, 19, 48, 33)
|
58
|
+
subject.starts_at.must_equal expected
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns the expires_at" do
|
62
|
+
expected = DateTime.new(2016, 5, 1, 19, 48, 8)
|
63
|
+
subject.expires_at.must_equal expected
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "unexpired and renewing subscription" do
|
68
|
+
two_days_from_now = DateTime.now + 2
|
69
|
+
let(:fake_subscription_purchase) do
|
70
|
+
FakeSubscriptionPurchase.new(
|
71
|
+
kind: "androidpublisher#subscriptionPurchase",
|
72
|
+
start_time_millis: 1459540113244,
|
73
|
+
expiry_time_millis: (two_days_from_now.to_time.to_i * 1000),
|
74
|
+
auto_renewing: true,
|
75
|
+
developer_payload: "payload that gets stored and returned",
|
76
|
+
cancel_reason: 0,
|
77
|
+
payment_state: 1,
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "is expired?" do
|
82
|
+
subject.expired?.must_be_false
|
83
|
+
end
|
84
|
+
|
85
|
+
it "is two days left until it is overdue" do
|
86
|
+
subject.overdue_days.must_equal(-2)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "expired due to payment failure" do
|
91
|
+
let(:fake_subscription_purchase) do
|
92
|
+
FakeSubscriptionPurchase.new(
|
93
|
+
kind: "androidpublisher#subscriptionPurchase",
|
94
|
+
start_time_millis: 1459540113244,
|
95
|
+
expiry_time_millis: 1462132088610,
|
96
|
+
auto_renewing: true,
|
97
|
+
developer_payload: "payload that gets stored and returned",
|
98
|
+
cancel_reason: 1,
|
99
|
+
payment_state: 1,
|
100
|
+
)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "is expired?" do
|
104
|
+
subject.expired?.must_be_true
|
105
|
+
end
|
106
|
+
|
107
|
+
it "is payment_failed?" do
|
108
|
+
subject.payment_failed?.must_be_true
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "subscription cancelation by user" do
|
113
|
+
describe "when subscription is not canceled" do
|
114
|
+
let(:fake_subscription_purchase) do
|
115
|
+
FakeSubscriptionPurchase.new(
|
116
|
+
kind: "androidpublisher#subscriptionPurchase",
|
117
|
+
start_time_millis: 1459540113244,
|
118
|
+
expiry_time_millis: 1462132088610,
|
119
|
+
auto_renewing: true,
|
120
|
+
developer_payload: "payload that gets stored and returned",
|
121
|
+
payment_state: 1,
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "is not canceled?" do
|
126
|
+
subject.canceled_by_user?.must_be_false
|
127
|
+
end
|
128
|
+
|
129
|
+
it "returns nil user_cancellation_time_millis" do
|
130
|
+
subject.user_cancellation_time_millis.must_be_nil
|
131
|
+
end
|
132
|
+
|
133
|
+
it "returns nil canceled_at" do
|
134
|
+
subject.canceled_at.must_be_nil
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "when subscription is canceled" do
|
139
|
+
let(:fake_subscription_purchase) do
|
140
|
+
FakeSubscriptionPurchase.new(
|
141
|
+
kind: "androidpublisher#subscriptionPurchase",
|
142
|
+
start_time_millis: 1459540113244,
|
143
|
+
expiry_time_millis: 1462132088610,
|
144
|
+
user_cancellation_time_millis: 1461872888000,
|
145
|
+
auto_renewing: true,
|
146
|
+
developer_payload: "payload that gets stored and returned",
|
147
|
+
cancel_reason: 0,
|
148
|
+
payment_state: 1,
|
149
|
+
)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "is canceled?" do
|
153
|
+
subject.canceled_by_user?.must_be_true
|
154
|
+
end
|
155
|
+
|
156
|
+
it "returns the user_cancellation_time_millis" do
|
157
|
+
subject.user_cancellation_time_millis.must_equal 1_461_872_888_000
|
158
|
+
end
|
159
|
+
|
160
|
+
it "returns the starts_at" do
|
161
|
+
expected = DateTime.new(2016, 4, 28, 19, 48, 8)
|
162
|
+
subject.canceled_at.must_equal expected
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "expired with pending payment" do
|
168
|
+
let(:fake_subscription_purchase) do
|
169
|
+
FakeSubscriptionPurchase.new(
|
170
|
+
kind: "androidpublisher#subscriptionPurchase",
|
171
|
+
start_time_millis: 1459540113244,
|
172
|
+
expiry_time_millis: 1462132088610,
|
173
|
+
auto_renewing: true,
|
174
|
+
developer_payload: "payload that gets stored and returned",
|
175
|
+
cancel_reason: 0,
|
176
|
+
payment_state: 0,
|
177
|
+
)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "is expired?" do
|
181
|
+
subject.expired?.must_be_true
|
182
|
+
end
|
183
|
+
|
184
|
+
it "is payment_pending?" do
|
185
|
+
subject.payment_pending?.must_be_true
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "trial" do
|
190
|
+
let(:fake_subscription_purchase) do
|
191
|
+
FakeSubscriptionPurchase.new(
|
192
|
+
kind: "androidpublisher#subscriptionPurchase",
|
193
|
+
start_time_millis: 1459540113244,
|
194
|
+
expiry_time_millis: 1462132088610,
|
195
|
+
auto_renewing: false,
|
196
|
+
developer_payload: "payload that gets stored and returned",
|
197
|
+
cancel_reason: 0,
|
198
|
+
payment_state: 1,
|
199
|
+
price_currency_code: "SOMECODE",
|
200
|
+
price_amount_micros: 0,
|
201
|
+
)
|
202
|
+
end
|
203
|
+
|
204
|
+
it "is trial?" do
|
205
|
+
subject.trial?.must_be_true
|
206
|
+
end
|
207
|
+
|
208
|
+
it "returns the price_currency_code" do
|
209
|
+
subject.price_currency_code.must_equal "SOMECODE"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
private
|
214
|
+
|
215
|
+
class FakeSubscriptionPurchase
|
216
|
+
FIELDS = [
|
217
|
+
:kind,
|
218
|
+
:start_time_millis,
|
219
|
+
:expiry_time_millis,
|
220
|
+
:user_cancellation_time_millis,
|
221
|
+
:auto_renewing,
|
222
|
+
:developer_payload,
|
223
|
+
:cancel_reason,
|
224
|
+
:payment_state,
|
225
|
+
:price_amount_micros,
|
226
|
+
:price_currency_code,
|
227
|
+
].freeze
|
228
|
+
|
229
|
+
attr_accessor *FIELDS
|
230
|
+
|
231
|
+
def initialize(hash)
|
232
|
+
FIELDS.each do |key|
|
233
|
+
self.public_send("#{key}=", hash[key])
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CandyCheck::PlayStore::SubscriptionPurchases::SubscriptionVerification do
|
4
|
+
subject do
|
5
|
+
CandyCheck::PlayStore::SubscriptionPurchases::SubscriptionVerification.new(
|
6
|
+
package_name: package_name,
|
7
|
+
subscription_id: subscription_id,
|
8
|
+
token: token,
|
9
|
+
authorization: authorization,
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:json_key_file) { File.expand_path("../../fixtures/play_store/random_dummy_key.json", __dir__) }
|
14
|
+
let(:authorization) { CandyCheck::PlayStore.authorization(json_key_file) }
|
15
|
+
|
16
|
+
let(:package_name) { "my_package_name" }
|
17
|
+
let(:subscription_id) { "my_subscription_id" }
|
18
|
+
let(:token) { "my_token" }
|
19
|
+
|
20
|
+
describe "valid" do
|
21
|
+
it "returns a subscription" do
|
22
|
+
VCR.use_cassette("play_store/subscription_purchases/valid_but_expired") do
|
23
|
+
result = subject.call!
|
24
|
+
|
25
|
+
result.must_be_instance_of CandyCheck::PlayStore::SubscriptionPurchases::SubscriptionPurchase
|
26
|
+
result.expired?.must_be_true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "failure" do
|
32
|
+
it "returns a verification failure" do
|
33
|
+
VCR.use_cassette("play_store/subscription_purchases/permission_denied") do
|
34
|
+
result = subject.call!
|
35
|
+
result.must_be_instance_of CandyCheck::PlayStore::VerificationFailure
|
36
|
+
result.code.must_equal 401
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "empty" do
|
42
|
+
let(:response) do
|
43
|
+
{}
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns a verification failure" do
|
47
|
+
result = subject.call!
|
48
|
+
result.must_be_instance_of CandyCheck::PlayStore::VerificationFailure
|
49
|
+
result.code.must_equal(-1)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "invalid response kind" do
|
54
|
+
let(:response) do
|
55
|
+
{
|
56
|
+
"kind" => "something weird",
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns a verification failure" do
|
61
|
+
result = subject.call!
|
62
|
+
result.must_be_instance_of CandyCheck::PlayStore::VerificationFailure
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|