itunes-receipt-mock 0.0.4
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 +7 -0
- data/lib/itunes_receipt_mock.rb +29 -0
- data/lib/itunes_receipt_mock/mixins.rb +18 -0
- data/lib/itunes_receipt_mock/purchase.rb +39 -0
- data/lib/itunes_receipt_mock/receipt.rb +67 -0
- data/lib/itunes_receipt_mock/subscription.rb +27 -0
- data/lib/itunes_receipt_mock/validation.rb +70 -0
- data/lib/itunes_receipt_mock/version.rb +5 -0
- data/spec/module_spec.rb +57 -0
- data/spec/receipt_spec.rb +164 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/validation_spec.rb +99 -0
- metadata +153 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7adc738d9fac2d63cf39275cc7dfe88e9fc793a6
|
4
|
+
data.tar.gz: 778c95fc0e66fe9964a69bdf618056d74d5501fc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 34cca824abfcfadc5b7f6be8bda9d654381c7f909857c4bcddd5ca2320b1d5f5f05045385c431ae73c8ffe0cfb7a43b3e2d3a5f1f2d288990e820ea722d56f0b
|
7
|
+
data.tar.gz: 15b52051edcd807605abb864d6af519769346feaaf0dcd0b8e70e30e13e8503e47c6853796c8a5b6c090c8b8097717b60a32638a4c94a3c48b8b01ca9d45a615
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'itunes_receipt_mock/mixins'
|
3
|
+
require 'itunes_receipt_mock/validation'
|
4
|
+
require 'itunes_receipt_mock/receipt'
|
5
|
+
require 'itunes_receipt_mock/purchase'
|
6
|
+
require 'itunes_receipt_mock/subscription'
|
7
|
+
|
8
|
+
##
|
9
|
+
# ItunesReceiptMock
|
10
|
+
module ItunesReceiptMock
|
11
|
+
class MissingArgumentError < StandardError; end
|
12
|
+
|
13
|
+
@transaction_id = 1_000_000_000
|
14
|
+
|
15
|
+
##
|
16
|
+
# Creates a new iTunes receipt
|
17
|
+
#
|
18
|
+
# Returns: rdoc-ref:ItunesReceiptMock::Validation
|
19
|
+
#
|
20
|
+
# Params:
|
21
|
+
# +options+:: rdoc-ref:ItunesReceiptMock
|
22
|
+
def self.new(options = {})
|
23
|
+
Validation.new(options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.next_transaction_id
|
27
|
+
@transaction_id += 1
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
##
|
2
|
+
# ItunesReceiptMock
|
3
|
+
module ItunesReceiptMock
|
4
|
+
##
|
5
|
+
# ItunesReceiptMock::Mixins
|
6
|
+
module Mixins
|
7
|
+
private
|
8
|
+
|
9
|
+
def date_attrs(prefix, date)
|
10
|
+
{
|
11
|
+
"#{prefix}_date" => date.utc.strftime('%F %T') + ' Etc/GMT',
|
12
|
+
"#{prefix}_date_ms" => date.utc.strftime('%s%L').to_i,
|
13
|
+
"#{prefix}_date_pst" => date.getlocal('-08:00').strftime('%F %T') +
|
14
|
+
' America/Los_Angeles'
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
##
|
2
|
+
# ItunesReceiptMock
|
3
|
+
module ItunesReceiptMock
|
4
|
+
##
|
5
|
+
# ItunesReceiptMock::Purchase
|
6
|
+
class Purchase
|
7
|
+
include ItunesReceiptMock::Mixins
|
8
|
+
|
9
|
+
attr_accessor :quantity, :product_id, :transaction_id,
|
10
|
+
:original_transaction_id, :purchase_date,
|
11
|
+
:original_purchase_date
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
@product_id = options.fetch :product_id, nil
|
15
|
+
fail ItunesReceiptMock::MissingArgumentError,
|
16
|
+
'product_id is required' unless @product_id
|
17
|
+
@quantity = options.fetch :quantity, 1
|
18
|
+
@transaction_id =
|
19
|
+
options.fetch :transaction_id,
|
20
|
+
ItunesReceiptMock.next_transaction_id.to_s
|
21
|
+
@original_transaction_id =
|
22
|
+
options.fetch :original_transaction_id, @transaction_id
|
23
|
+
@purchase_date = options.fetch :purchase_date, Time.now
|
24
|
+
@original_purchase_date =
|
25
|
+
options.fetch :original_purchase_date, @purchase_date
|
26
|
+
end
|
27
|
+
|
28
|
+
def result(_options = {})
|
29
|
+
{
|
30
|
+
'quantity' => quantity,
|
31
|
+
'product_id' => product_id,
|
32
|
+
'transaction_id' => transaction_id,
|
33
|
+
'original_transaction_id' => original_transaction_id
|
34
|
+
}
|
35
|
+
.merge(date_attrs('purchase', purchase_date))
|
36
|
+
.merge(date_attrs('original_purchase', original_purchase_date))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
##
|
2
|
+
# ItunesReceiptMock
|
3
|
+
module ItunesReceiptMock
|
4
|
+
##
|
5
|
+
# ItunesReceiptMock::Receipt
|
6
|
+
class Receipt
|
7
|
+
include ItunesReceiptMock::Mixins
|
8
|
+
|
9
|
+
attr_reader :in_app
|
10
|
+
attr_accessor :environment, :adam_id, :app_item_id, :bundle_id,
|
11
|
+
:application_version, :download_id,
|
12
|
+
:version_external_identifier, :original_purchase_date,
|
13
|
+
:original_application_version
|
14
|
+
|
15
|
+
def initialize(options = {})
|
16
|
+
@in_app = {}
|
17
|
+
@bundle_id = options.fetch :bundle_id, nil
|
18
|
+
@environment = options.fetch :environment, 'Production'
|
19
|
+
@adam_id = options.fetch :adam_id, 0
|
20
|
+
@app_item_id = options.fetch :app_item_id, 0
|
21
|
+
@application_version = options.fetch :application_version, '1'
|
22
|
+
@download_id = options.fetch :download_id, 0
|
23
|
+
@version_external_identifier =
|
24
|
+
options.fetch :version_external_identifier, 0
|
25
|
+
@original_purchase_date = options.fetch :original_purchase_date, Time.now
|
26
|
+
@original_application_version =
|
27
|
+
options.fetch :original_application_version, 0
|
28
|
+
|
29
|
+
fail MissingArgumentError, 'bundle_id is required' unless @bundle_id
|
30
|
+
end
|
31
|
+
|
32
|
+
def result(options = {})
|
33
|
+
request_date = options[:request_date] = Time.now
|
34
|
+
{
|
35
|
+
'receipt_type' => environment,
|
36
|
+
'adam_id' => adam_id,
|
37
|
+
'app_item_id' => app_item_id,
|
38
|
+
'bundle_id' => bundle_id,
|
39
|
+
'application_version' => application_version,
|
40
|
+
'download_id' => download_id,
|
41
|
+
'version_external_identifier' => version_external_identifier,
|
42
|
+
'original_application_version' => original_application_version,
|
43
|
+
'in_app' => in_app_result(options)
|
44
|
+
}
|
45
|
+
.merge(date_attrs('request', request_date))
|
46
|
+
.merge(date_attrs('original_purchase', original_purchase_date))
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_purchase(options = {})
|
50
|
+
purchase = Purchase.new(options)
|
51
|
+
@in_app[purchase.transaction_id] = purchase
|
52
|
+
purchase
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_subscription(options = {})
|
56
|
+
purchase = Subscription.new(options)
|
57
|
+
@in_app[purchase.transaction_id] = purchase
|
58
|
+
purchase
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def in_app_result(options)
|
64
|
+
in_app.map { |_, v| v.result(options) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
##
|
2
|
+
# ItunesReceiptMock
|
3
|
+
module ItunesReceiptMock
|
4
|
+
##
|
5
|
+
# ItunesReceiptMock::Subscription
|
6
|
+
class Subscription < Purchase
|
7
|
+
attr_accessor :expires_date, :web_order_line_item_id, :is_trial_period
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
super
|
11
|
+
@expires_date = options.fetch :expires_date, nil
|
12
|
+
@web_order_line_item_id =
|
13
|
+
options.fetch :web_order_line_item_id,
|
14
|
+
rand(1_000_000_000..9_999_999_999).to_s
|
15
|
+
@is_trial_period = options.fetch :is_trial_period, false
|
16
|
+
|
17
|
+
fail MissingArgumentError, 'expires_date is required' unless @expires_date
|
18
|
+
end
|
19
|
+
|
20
|
+
def result(_options = {})
|
21
|
+
super.merge(
|
22
|
+
'web_order_line_item_id' => web_order_line_item_id,
|
23
|
+
'is_trial_period' => is_trial_period
|
24
|
+
).merge(date_attrs('expires_date', expires_date))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
##
|
2
|
+
# ItunesReceiptMock
|
3
|
+
module ItunesReceiptMock
|
4
|
+
##
|
5
|
+
# ItunesReceiptMock::Validation
|
6
|
+
class Validation
|
7
|
+
include ItunesReceiptMock::Mixins
|
8
|
+
|
9
|
+
STATUS_CODES = [0, 21_000] + (21_002..21_008).to_a
|
10
|
+
|
11
|
+
attr_reader :receipt, :latest_receipt_info
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
@latest_receipt_info = {}
|
15
|
+
@receipt = Receipt.new(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def result(options = {})
|
19
|
+
status = options.fetch(:status, 0)
|
20
|
+
result = { 'status' => status }
|
21
|
+
if status == 0
|
22
|
+
result.merge!(
|
23
|
+
'status' => status,
|
24
|
+
'environment' => receipt.environment,
|
25
|
+
'receipt' => receipt.result(options),
|
26
|
+
'latest_receipt_info' => latest_receipt_info_result(options)
|
27
|
+
)
|
28
|
+
result.merge!(
|
29
|
+
'latest_receipt' => Base64.strict_encode64(result.to_json)
|
30
|
+
)
|
31
|
+
end
|
32
|
+
result
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_purchase(options = {})
|
36
|
+
purchase = receipt.add_purchase(options)
|
37
|
+
@latest_receipt_info[purchase.transaction_id] = purchase
|
38
|
+
purchase
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_subscription(options = {})
|
42
|
+
purchase = receipt.add_subscription(options)
|
43
|
+
@latest_receipt_info[purchase.transaction_id] = purchase
|
44
|
+
purchase
|
45
|
+
end
|
46
|
+
|
47
|
+
def renew_subscription(purchase, options = {})
|
48
|
+
expires_date = options.fetch(:expires_date, nil)
|
49
|
+
fail MissingArgumentError, 'expires_date is required' unless expires_date
|
50
|
+
|
51
|
+
attrs = {
|
52
|
+
quantity: purchase.quantity,
|
53
|
+
product_id: purchase.product_id,
|
54
|
+
original_transaction_id: purchase.original_transaction_id,
|
55
|
+
original_purchase_date: purchase.original_purchase_date,
|
56
|
+
web_order_line_item_id: purchase.web_order_line_item_id,
|
57
|
+
is_trial_period: purchase.is_trial_period
|
58
|
+
}.merge(expires_date: expires_date).merge(options)
|
59
|
+
|
60
|
+
receipt.in_app.delete(purchase.original_transaction_id)
|
61
|
+
add_subscription(attrs)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def latest_receipt_info_result(options)
|
67
|
+
latest_receipt_info.map { |_, v| v.result(options) }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/spec/module_spec.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ItunesReceiptMock do
|
4
|
+
describe '.new' do
|
5
|
+
subject { described_class.new(options) }
|
6
|
+
|
7
|
+
context 'with minimal options' do
|
8
|
+
let(:options) { { bundle_id: 'foobar' } }
|
9
|
+
|
10
|
+
it 'creates an instance of Validation' do
|
11
|
+
expect(subject).to be_a(described_class::Validation)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when bundle_id is not present' do
|
16
|
+
let(:options) { {} }
|
17
|
+
|
18
|
+
it 'raises an MissingArgumentError' do
|
19
|
+
expect { subject }.to raise_error(
|
20
|
+
described_class::MissingArgumentError,
|
21
|
+
'bundle_id is required'
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'full integration' do
|
28
|
+
let(:validation) { described_class.new(bundle_id: 'com.example') }
|
29
|
+
let!(:purchase) { validation.add_purchase(product_id: 'foobar') }
|
30
|
+
let!(:subscription) do
|
31
|
+
validation.add_subscription product_id: 'premium',
|
32
|
+
purchase_date: 1.month.ago,
|
33
|
+
expires_date: Time.now
|
34
|
+
end
|
35
|
+
|
36
|
+
subject { validation.result }
|
37
|
+
|
38
|
+
it 'contains the purchases in the receipt.in_app object' do
|
39
|
+
expect(validation.receipt.in_app.length).to eq(2)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'contains the purchases in the latest_receipt_info object' do
|
43
|
+
expect(validation.latest_receipt_info.length).to eq(2)
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'renewing the subscription' do
|
47
|
+
let!(:renewal) do
|
48
|
+
validation.renew_subscription subscription,
|
49
|
+
expires_date: 1.month.from_now
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'contains two subscription transactions in latest_receipt_info' do
|
53
|
+
expect(validation.latest_receipt_info.length).to eq(3)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ItunesReceiptMock::Receipt do
|
4
|
+
before do
|
5
|
+
Timecop.freeze
|
6
|
+
end
|
7
|
+
|
8
|
+
after do
|
9
|
+
Timecop.return
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.new' do
|
13
|
+
subject { described_class.new(options) }
|
14
|
+
|
15
|
+
context 'with minimal options' do
|
16
|
+
let(:options) { { bundle_id: 'foobar' } }
|
17
|
+
|
18
|
+
it 'sets "bundle_id" to the option value' do
|
19
|
+
expect(subject.bundle_id).to eq(options[:bundle_id])
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'defaults everything else' do
|
23
|
+
expect(subject.environment).to eq('Production')
|
24
|
+
expect(subject.adam_id).to eq(0)
|
25
|
+
expect(subject.app_item_id).to eq(0)
|
26
|
+
expect(subject.application_version).to eq('1')
|
27
|
+
expect(subject.download_id).to eq(0)
|
28
|
+
expect(subject.version_external_identifier).to eq(0)
|
29
|
+
expect(subject.original_purchase_date).to eq(Time.now)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when options are complete' do
|
34
|
+
let(:options) do
|
35
|
+
{
|
36
|
+
bundle_id: 'foobar',
|
37
|
+
environment: 'Sandbox',
|
38
|
+
adam_id: rand(1..5),
|
39
|
+
app_item_id: rand(1..5),
|
40
|
+
application_version: rand(1..5).to_s,
|
41
|
+
download_id: rand(1..5),
|
42
|
+
version_external_identifier: rand(1..5),
|
43
|
+
original_purchase_date: Time.new(2015, 06, 20, 8, 16, 32)
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'sets all the things' do
|
48
|
+
expect(subject.environment).to eq(options[:environment])
|
49
|
+
expect(subject.adam_id).to eq(options[:adam_id])
|
50
|
+
expect(subject.app_item_id).to eq(options[:app_item_id])
|
51
|
+
expect(subject.application_version).to eq(options[:application_version])
|
52
|
+
expect(subject.download_id).to eq(options[:download_id])
|
53
|
+
expect(subject.version_external_identifier).to eq(
|
54
|
+
options[:version_external_identifier]
|
55
|
+
)
|
56
|
+
expect(subject.original_purchase_date).to eq(
|
57
|
+
options[:original_purchase_date]
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#add_purchase' do
|
64
|
+
let(:receipt) { described_class.new(bundle_id: 'foobar') }
|
65
|
+
|
66
|
+
subject { receipt.add_purchase(options) }
|
67
|
+
|
68
|
+
context 'with minimal options' do
|
69
|
+
let(:options) { { product_id: 'whatever' } }
|
70
|
+
|
71
|
+
it 'creates an instance of Purchase' do
|
72
|
+
expect(subject).to be_a(ItunesReceiptMock::Purchase)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'adds the purchase to the #in_app object' do
|
76
|
+
expect(receipt.in_app[subject.transaction_id]).to eq(subject)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when product_id is not present' do
|
81
|
+
let(:options) { {} }
|
82
|
+
|
83
|
+
it 'raises an MissingArgumentError' do
|
84
|
+
expect { subject }.to raise_error(
|
85
|
+
ItunesReceiptMock::MissingArgumentError,
|
86
|
+
'product_id is required'
|
87
|
+
)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#add_subscription' do
|
93
|
+
let(:receipt) { described_class.new(bundle_id: 'foobar') }
|
94
|
+
|
95
|
+
subject { receipt.add_subscription(options) }
|
96
|
+
|
97
|
+
context 'with minimal options' do
|
98
|
+
let(:options) do
|
99
|
+
{
|
100
|
+
product_id: 'whatever',
|
101
|
+
expires_date: 1.month.from_now
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'creates an instance of Subscription' do
|
106
|
+
expect(subject).to be_a(ItunesReceiptMock::Subscription)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'adds the subscription to the #in_app object' do
|
110
|
+
expect(receipt.in_app[subject.transaction_id]).to eq(subject)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'when expires_date is not present' do
|
115
|
+
let(:options) { { product_id: 'whatever' } }
|
116
|
+
|
117
|
+
it 'raises an MissingArgumentError' do
|
118
|
+
expect { subject }.to raise_error(
|
119
|
+
ItunesReceiptMock::MissingArgumentError,
|
120
|
+
'expires_date is required'
|
121
|
+
)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '#result' do
|
127
|
+
let(:receipt) { described_class.new(bundle_id: 'foobar') }
|
128
|
+
let(:options) { {} }
|
129
|
+
|
130
|
+
subject { receipt.result(options) }
|
131
|
+
|
132
|
+
it 'returns everything' do
|
133
|
+
expect(subject['receipt_type']).to eq(receipt.environment)
|
134
|
+
expect(subject['adam_id']).to eq(receipt.adam_id)
|
135
|
+
expect(subject['app_item_id']).to eq(receipt.app_item_id)
|
136
|
+
expect(subject['bundle_id']).to eq(receipt.bundle_id)
|
137
|
+
expect(subject['application_version']).to eq(receipt.application_version)
|
138
|
+
expect(subject['download_id']).to eq(receipt.download_id)
|
139
|
+
expect(subject['version_external_identifier']).to eq(
|
140
|
+
receipt.version_external_identifier
|
141
|
+
)
|
142
|
+
expect(subject['original_application_version']).to eq(
|
143
|
+
receipt.original_application_version
|
144
|
+
)
|
145
|
+
expect(subject['in_app']).to be_a(Array)
|
146
|
+
expect(subject['request_date']).to eq(
|
147
|
+
Time.now.utc.strftime('%F %T') + ' Etc/GMT'
|
148
|
+
)
|
149
|
+
expect(subject['original_purchase_date']).to eq(
|
150
|
+
receipt.original_purchase_date.utc.strftime('%F %T') + ' Etc/GMT'
|
151
|
+
)
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'when "request_date" is in options' do
|
155
|
+
let(:options) { { request_date: rand(1..5).hours.ago } }
|
156
|
+
|
157
|
+
it 'returns the request_date as specified' do
|
158
|
+
expect(subject['request_date']).to eq(
|
159
|
+
options[:request_date].utc.strftime('%F %T') + ' Etc/GMT'
|
160
|
+
)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
if ENV['CODECLIMATE_REPO_TOKEN']
|
2
|
+
require 'codeclimate-test-reporter'
|
3
|
+
CodeClimate::TestReporter.start
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'active_support/all'
|
7
|
+
require 'timecop'
|
8
|
+
require 'itunes_receipt_mock'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.expect_with :rspec do |expectations|
|
12
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
13
|
+
end
|
14
|
+
config.mock_with :rspec do |mocks|
|
15
|
+
mocks.verify_partial_doubles = true
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ItunesReceiptMock::Validation do
|
4
|
+
describe '.new' do
|
5
|
+
let(:options) { { bundle_id: 'foobar' } }
|
6
|
+
|
7
|
+
subject { described_class.new(options) }
|
8
|
+
|
9
|
+
it 'creates an instance of Receipt' do
|
10
|
+
expect(subject.receipt).to be_a(ItunesReceiptMock::Receipt)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#result' do
|
15
|
+
let(:validation) { described_class.new(bundle_id: 'foobar') }
|
16
|
+
|
17
|
+
subject { validation.result(options) }
|
18
|
+
|
19
|
+
context 'when status is 0' do
|
20
|
+
let(:options) { { status: 0 } }
|
21
|
+
|
22
|
+
it 'returns everything' do
|
23
|
+
expect(subject['status']).to eq(0)
|
24
|
+
expect(subject['environment']).to_not be_nil
|
25
|
+
expect(subject['receipt']).to_not be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when status is not 0' do
|
30
|
+
let(:options) { { status: 1 } }
|
31
|
+
|
32
|
+
it 'returns just the status' do
|
33
|
+
expect(subject).to eq('status' => options[:status])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#add_purchase' do
|
39
|
+
let(:validation) { described_class.new(bundle_id: 'foobar') }
|
40
|
+
|
41
|
+
subject { validation.add_purchase(product_id: 'foobar') }
|
42
|
+
|
43
|
+
it 'adds the purchase to the #latest_receipt_info object' do
|
44
|
+
expect(validation.latest_receipt_info[subject.transaction_id])
|
45
|
+
.to eq(subject)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#add_subscription' do
|
50
|
+
let(:validation) { described_class.new(bundle_id: 'foobar') }
|
51
|
+
|
52
|
+
subject do
|
53
|
+
validation.add_subscription product_id: 'foobar',
|
54
|
+
expires_date: 1.month.from_now
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'adds the subscription to the #latest_receipt_info object' do
|
58
|
+
expect(validation.latest_receipt_info[subject.transaction_id])
|
59
|
+
.to eq(subject)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#renew_subscription' do
|
64
|
+
let(:validation) { described_class.new(bundle_id: 'foobar') }
|
65
|
+
let(:subscription) do
|
66
|
+
validation.add_subscription product_id: 'foobar',
|
67
|
+
purchase_date: 1.month.ago,
|
68
|
+
expires_date: Time.now
|
69
|
+
end
|
70
|
+
|
71
|
+
subject do
|
72
|
+
validation.renew_subscription subscription,
|
73
|
+
expires_date: 1.month.from_now
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'removes the old transaction from #receipt#in_app' do
|
77
|
+
expect(validation.receipt.in_app[subscription.transaction_id])
|
78
|
+
.to eq(subscription)
|
79
|
+
subject
|
80
|
+
expect(validation.receipt.in_app[subscription.transaction_id])
|
81
|
+
.to be_nil
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'adds the new transaction to #receipt#in_app' do
|
85
|
+
expect(validation.receipt.in_app[subject.transaction_id]).to eq(subject)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'adds the new tranaction to #latest_receipt_info' do
|
89
|
+
expect(validation.latest_receipt_info[subject.transaction_id])
|
90
|
+
.to eq(subject)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'preserves both transactions in #latest_receipt_info' do
|
94
|
+
subject
|
95
|
+
expect(validation.latest_receipt_info.values)
|
96
|
+
.to match_array([subscription, subject])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: itunes-receipt-mock
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- mbaasy.com
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '10.4'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '10.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.2'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubygems-tasks
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: timecop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.8'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.8'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: codeclimate-test-reporter
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.4'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.4'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.33'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.33'
|
111
|
+
description: Mock iTunes receipt validation responses for testing
|
112
|
+
email: hello@mbaasy.com
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- lib/itunes_receipt_mock.rb
|
118
|
+
- lib/itunes_receipt_mock/mixins.rb
|
119
|
+
- lib/itunes_receipt_mock/purchase.rb
|
120
|
+
- lib/itunes_receipt_mock/receipt.rb
|
121
|
+
- lib/itunes_receipt_mock/subscription.rb
|
122
|
+
- lib/itunes_receipt_mock/validation.rb
|
123
|
+
- lib/itunes_receipt_mock/version.rb
|
124
|
+
- spec/module_spec.rb
|
125
|
+
- spec/receipt_spec.rb
|
126
|
+
- spec/spec_helper.rb
|
127
|
+
- spec/validation_spec.rb
|
128
|
+
homepage: https://github.com/mbaasy/itunes-receipt-mock-ruby
|
129
|
+
licenses:
|
130
|
+
- MIT
|
131
|
+
metadata: {}
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 2.4.6
|
149
|
+
signing_key:
|
150
|
+
specification_version: 4
|
151
|
+
summary: Mock iTunes Connect receipts
|
152
|
+
test_files: []
|
153
|
+
has_rdoc:
|