-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
221 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
require 'candy_check/app_store/receipt' | ||
|
||
module CandyCheck | ||
# Module to request and verify a AppStore receipt | ||
module AppStore | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
module CandyCheck | ||
module AppStore | ||
# Describes a successful response from the AppStore verification server | ||
class Receipt | ||
attr_reader :attributes | ||
|
||
# Initializes a new instance which bases on a JSON result | ||
# from Apple's verification server | ||
# @param attributes [Hash] | ||
def initialize(attributes) | ||
@attributes = attributes | ||
end | ||
|
||
# In most cases a receipt is a valid transaction except when the | ||
# transaction was canceled. | ||
# @return [Boolean] | ||
def valid? | ||
!has?('cancellation_date') | ||
end | ||
|
||
# The receipt's transaction id | ||
# @return [String] | ||
def transaction_id | ||
read('transaction_id') | ||
end | ||
|
||
# The receipt's original transaction id which might differ from | ||
# the transaction id for restored products | ||
# @return [String] | ||
def original_transaction_id | ||
read('original_transaction_id') | ||
end | ||
|
||
# The version number for the app | ||
# @return [String] | ||
def app_version | ||
read('bvrs') | ||
end | ||
|
||
# The app's bundle identifier | ||
# @return [String] | ||
def bundle_identifier | ||
read('bid') | ||
end | ||
|
||
# The app's item id of the product | ||
# @return [String] | ||
def item_id | ||
read('item_id') | ||
end | ||
|
||
# The quantity of the product | ||
# @return [Fixnum] | ||
def quantity | ||
read('quantity').to_i | ||
end | ||
|
||
# The purchase date | ||
# @return [DateTime] | ||
def purchase_date | ||
read_date('purchase_date') | ||
end | ||
|
||
# The original purchase date which might differ from the | ||
# actual purchase date for restored products | ||
# @return [DateTime] | ||
def original_purchase_date | ||
read_date('original_purchase_date') | ||
end | ||
|
||
# The date of when Apple has canceled this transaction. | ||
# From Apple's documentation: "Treat a canceled receipt | ||
# the same as if no purchase had ever been made." | ||
# @return [DateTime] | ||
def cancellation_date | ||
read_date('cancellation_date') | ||
end | ||
|
||
private | ||
|
||
def read(field) | ||
attributes[field] | ||
end | ||
|
||
def has?(field) | ||
attributes.key?(field) | ||
end | ||
|
||
def read_date(field) | ||
(val = read(field)) && DateTime.parse(val) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
require 'spec_helper' | ||
|
||
describe CandyCheck::AppStore::Receipt do | ||
subject { CandyCheck::AppStore::Receipt.new(attributes) } | ||
|
||
let(:attributes) do | ||
{ | ||
'original_purchase_date_pst' => '2015-01-08 03:40:46' \ | ||
' America/Los_Angeles', | ||
'purchase_date_ms' => '1420803646868', | ||
'unique_identifier' => 'some_uniq_identifier_from_apple' \ | ||
'_for_this', | ||
'original_transaction_id' => 'some_original_transaction_id', | ||
'bvrs' => '2.0', | ||
'transaction_id' => 'some_transaction_id', | ||
'quantity' => '1', | ||
'unique_vendor_identifier' => '00000000-1111-2222-3333-' \ | ||
'444444444444', | ||
'item_id' => 'some_item_id', | ||
'product_id' => 'some_product', | ||
'purchase_date' => '2015-01-09 11:40:46 Etc/GMT', | ||
'original_purchase_date' => '2015-01-08 11:40:46 Etc/GMT', | ||
'purchase_date_pst' => '2015-01-09 03:40:46' \ | ||
' America/Los_Angeles', | ||
'bid' => 'some.test.app', | ||
'original_purchase_date_ms' => '1420717246868' | ||
} | ||
end | ||
|
||
describe 'valid transaction' do | ||
it 'is valid' do | ||
subject.valid?.must_be_true | ||
end | ||
|
||
it 'returns the item\'s id' do | ||
subject.item_id.must_equal 'some_item_id' | ||
end | ||
|
||
it 'returns the quantity' do | ||
subject.quantity.must_equal 1 | ||
end | ||
|
||
it 'returns the app version' do | ||
subject.app_version.must_equal '2.0' | ||
end | ||
|
||
it 'returns the bundle identifier' do | ||
subject.bundle_identifier.must_equal 'some.test.app' | ||
end | ||
|
||
it 'returns the purchase date' do | ||
expected = DateTime.new(2015, 1, 9, 11, 40, 46) | ||
subject.purchase_date.must_equal expected | ||
end | ||
|
||
it 'returns the original purchase date' do | ||
expected = DateTime.new(2015, 1, 8, 11, 40, 46) | ||
subject.original_purchase_date.must_equal expected | ||
end | ||
|
||
it 'returns the transaction id' do | ||
subject.transaction_id.must_equal 'some_transaction_id' | ||
end | ||
|
||
it 'returns the original transaction id' do | ||
subject.original_transaction_id.must_equal 'some_original_transaction_id' | ||
end | ||
|
||
it 'return nil for cancellation date' do | ||
subject.cancellation_date.must_be_nil | ||
end | ||
|
||
it 'returns raw attributes' do | ||
subject.attributes.must_be_same_as attributes | ||
end | ||
end | ||
|
||
describe 'valid transaction' do | ||
before do | ||
attributes['cancellation_date'] = '2015-01-12 11:40:46 Etc/GMT' | ||
end | ||
|
||
it 'isn\'t valid' do | ||
subject.valid?.must_be_false | ||
end | ||
|
||
it 'return nil for cancellation date' do | ||
expected = DateTime.new(2015, 1, 12, 11, 40, 46) | ||
subject.cancellation_date.must_equal expected | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters