tinypass 0.0.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 +15 -0
- data/.DS_Store +0 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +19 -0
- data/lib/.DS_Store +0 -0
- data/lib/tinypass.rb +48 -0
- data/lib/tinypass/.DS_Store +0 -0
- data/lib/tinypass/builder.rb +7 -0
- data/lib/tinypass/builder/client_builder.rb +40 -0
- data/lib/tinypass/builder/client_parser.rb +48 -0
- data/lib/tinypass/builder/cookie_parser.rb +25 -0
- data/lib/tinypass/builder/json_msg_builder.rb +115 -0
- data/lib/tinypass/builder/open_encoder.rb +11 -0
- data/lib/tinypass/builder/secure_encoder.rb +15 -0
- data/lib/tinypass/builder/security_utils.rb +67 -0
- data/lib/tinypass/gateway.rb +104 -0
- data/lib/tinypass/offer.rb +23 -0
- data/lib/tinypass/policies.rb +5 -0
- data/lib/tinypass/policies/discount_policy.rb +25 -0
- data/lib/tinypass/policies/policy.rb +25 -0
- data/lib/tinypass/policies/pricing_policy.rb +13 -0
- data/lib/tinypass/policies/restriction_policy.rb +14 -0
- data/lib/tinypass/price_option.rb +66 -0
- data/lib/tinypass/resource.rb +17 -0
- data/lib/tinypass/token.rb +6 -0
- data/lib/tinypass/token/access_token.rb +163 -0
- data/lib/tinypass/token/access_token_list.rb +71 -0
- data/lib/tinypass/token/access_token_store.rb +59 -0
- data/lib/tinypass/token/meter.rb +76 -0
- data/lib/tinypass/token/meter_helper.rb +82 -0
- data/lib/tinypass/token/token_data.rb +72 -0
- data/lib/tinypass/ui.rb +2 -0
- data/lib/tinypass/ui/html_widget.rb +29 -0
- data/lib/tinypass/ui/purchase_request.rb +34 -0
- data/lib/tinypass/utils.rb +34 -0
- data/lib/tinypass/version.rb +3 -0
- data/spec/.DS_Store +0 -0
- data/spec/acceptance/basic_workflow_spec.rb +81 -0
- data/spec/integration/.DS_Store +0 -0
- data/spec/integration/cases/.DS_Store +0 -0
- data/spec/integration/cases/basic_spec.rb +53 -0
- data/spec/integration/cases/combo_spec.rb +43 -0
- data/spec/integration/cases/metered_reminder_spec.rb +42 -0
- data/spec/integration/cases/metered_strict_spec.rb +54 -0
- data/spec/integration/cases/metered_views_spec.rb +92 -0
- data/spec/integration/client_builder_and_parser_spec.rb +21 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/support/.DS_Store +0 -0
- data/spec/support/acceptance.rb +13 -0
- data/spec/support/tinypass_factories.rb +25 -0
- data/spec/unit/.DS_Store +0 -0
- data/spec/unit/builder/.DS_Store +0 -0
- data/spec/unit/builder/client_builder_spec.rb +23 -0
- data/spec/unit/builder/client_parser_spec.rb +27 -0
- data/spec/unit/builder/cookie_parser_spec.rb +39 -0
- data/spec/unit/builder/json_msg_builder_spec.rb +73 -0
- data/spec/unit/builder/open_encoder_spec.rb +15 -0
- data/spec/unit/builder/secure_encoder_spec.rb +23 -0
- data/spec/unit/builder/security_utils_spec.rb +42 -0
- data/spec/unit/gateway_spec.rb +80 -0
- data/spec/unit/offer_spec.rb +31 -0
- data/spec/unit/policies/.DS_Store +0 -0
- data/spec/unit/policies/discount_policy_spec.rb +40 -0
- data/spec/unit/policies/pricing_policy_spec.rb +23 -0
- data/spec/unit/policies/restriction_policy_spec.rb +35 -0
- data/spec/unit/price_option_spec.rb +109 -0
- data/spec/unit/resource_spec.rb +24 -0
- data/spec/unit/tinypass_spec.rb +51 -0
- data/spec/unit/token/.DS_Store +0 -0
- data/spec/unit/token/access_token_list_spec.rb +94 -0
- data/spec/unit/token/access_token_spec.rb +267 -0
- data/spec/unit/token/access_token_store_spec.rb +93 -0
- data/spec/unit/token/meter_helper_spec.rb +103 -0
- data/spec/unit/token/meter_spec.rb +66 -0
- data/spec/unit/token/token_data_spec.rb +66 -0
- data/spec/unit/ui/.DS_Store +0 -0
- data/spec/unit/ui/html_widget_spec.rb +89 -0
- data/spec/unit/ui/purchase_request_spec.rb +46 -0
- data/spec/unit/utils_spec.rb +57 -0
- data/tinypass.gemspec +35 -0
- metadata +330 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module TinypassFactories
|
2
|
+
def build_tinypass_cookie(tokens, name = nil)
|
3
|
+
name ||= Tinypass::Config.token_cookie_name(Tinypass.aid)
|
4
|
+
list = Tinypass::AccessTokenList.new(tokens)
|
5
|
+
value = Tinypass::ClientBuilder.new.build_access_tokens(list)
|
6
|
+
|
7
|
+
{ name => value }
|
8
|
+
end
|
9
|
+
|
10
|
+
def build_expired_trial_access_token(rid)
|
11
|
+
token = Tinypass::AccessToken.new(rid, 0)
|
12
|
+
token.token_data[Tinypass::TokenData::METER_TYPE] = Tinypass::TokenData::METER_STRICT
|
13
|
+
token.token_data[Tinypass::TokenData::METER_TRIAL_ENDTIME] = Time.now.to_i - 1
|
14
|
+
|
15
|
+
token
|
16
|
+
end
|
17
|
+
|
18
|
+
def build_active_trial_access_token(rid)
|
19
|
+
token = Tinypass::AccessToken.new(rid, 0)
|
20
|
+
token.token_data[Tinypass::TokenData::METER_TYPE] = Tinypass::TokenData::METER_STRICT
|
21
|
+
token.token_data[Tinypass::TokenData::METER_TRIAL_ENDTIME] = Time.now.to_i + 24 * 60 * 60
|
22
|
+
|
23
|
+
token
|
24
|
+
end
|
25
|
+
end
|
data/spec/unit/.DS_Store
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tinypass::ClientBuilder do
|
4
|
+
describe "#initialize" do
|
5
|
+
it "uses a JsonMsgBuilder and SecureEncoder by default" do
|
6
|
+
Tinypass::JsonMsgBuilder.should_receive(:new)
|
7
|
+
Tinypass::SecureEncoder.should_receive(:new)
|
8
|
+
|
9
|
+
Tinypass::OpenEncoder.should_not_receive(:new)
|
10
|
+
|
11
|
+
Tinypass::ClientBuilder.new
|
12
|
+
end
|
13
|
+
|
14
|
+
it "uses the OpenEncoder if specified" do
|
15
|
+
Tinypass::JsonMsgBuilder.should_receive(:new)
|
16
|
+
Tinypass::OpenEncoder.should_receive(:new)
|
17
|
+
|
18
|
+
Tinypass::SecureEncoder.should_not_receive(:new)
|
19
|
+
|
20
|
+
Tinypass::ClientBuilder.new('_?o')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tinypass::ClientParser do
|
4
|
+
describe "#parse_access_tokens" do
|
5
|
+
let(:fake_builder) { double }
|
6
|
+
let(:fake_encoder) { double }
|
7
|
+
|
8
|
+
before do
|
9
|
+
Tinypass::JsonMsgBuilder.should_receive(:new).twice.and_return(fake_builder)
|
10
|
+
|
11
|
+
fake_encoder.should_receive(:decode).twice.with('payload').and_return('decoded payload')
|
12
|
+
fake_builder.should_receive(:parse_access_tokens).twice.with('decoded payload').and_return(OpenStruct.new(tokens: []))
|
13
|
+
end
|
14
|
+
|
15
|
+
it "uses the JsonMsgBuilder and SecureEncoder by default" do
|
16
|
+
Tinypass::SecureEncoder.should_receive(:new).twice.and_return(fake_encoder)
|
17
|
+
|
18
|
+
Tinypass::ClientParser.new.parse_access_tokens("???{QQQ}payload{QQQ}payload") # QQQ is intended to be unkonwn, triggering defaults
|
19
|
+
end
|
20
|
+
|
21
|
+
it "uses the OpenEncoder if specified" do
|
22
|
+
Tinypass::OpenEncoder.should_receive(:new).twice.and_return(fake_encoder)
|
23
|
+
|
24
|
+
Tinypass::ClientParser.new.parse_access_tokens("???{QoQ}payload{QoQ}payload") # the Qs are intended to be unknown, triggering defaults
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tinypass::CookieParser do
|
4
|
+
describe '#extract_cookie_value' do
|
5
|
+
it "returns the value when only key found" do
|
6
|
+
expect(Tinypass::CookieParser.extract_cookie_value('key', 'key=value')).to eq 'value'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns the value when not formatted" do
|
10
|
+
expect(Tinypass::CookieParser.extract_cookie_value('key', 'value')).to eq 'value'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "treats empty strings as nil" do
|
14
|
+
expect(Tinypass::CookieParser.extract_cookie_value('key', '')).to be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns nil when key not found" do
|
18
|
+
expect(Tinypass::CookieParser.extract_cookie_value('unknown_key', 'key=value')).to be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns the value when first key" do
|
22
|
+
expect(Tinypass::CookieParser.extract_cookie_value('key',
|
23
|
+
'key=value; other_key=21; third_key=[CS|v1|27A5]wasdf[C3]; ')).
|
24
|
+
to eq 'value'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns the value when middle key" do
|
28
|
+
expect(Tinypass::CookieParser.extract_cookie_value('key',
|
29
|
+
'other_key=21; key=value; third_key=[CS|v1|27A5]wasdf[C3]; ')).
|
30
|
+
to eq 'value'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns the value when last key" do
|
34
|
+
expect(Tinypass::CookieParser.extract_cookie_value('key',
|
35
|
+
'other_key=21; third_key=[CS|v1|27A5]wasdf[C3]; key=value;')).
|
36
|
+
to eq 'value'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tinypass::JsonMsgBuilder do
|
4
|
+
describe "#build_purchase_requests" do
|
5
|
+
let(:resource) { Tinypass::Resource.new('Premium-Content', 'Site wide premium content access', 'http://resource.com') }
|
6
|
+
let(:price_option_1) do
|
7
|
+
Tinypass::PriceOption.new('.50', '24 hours').tap do |option|
|
8
|
+
option.caption = 'Special offer!'
|
9
|
+
option.start_date_in_secs = 123456789
|
10
|
+
option.end_date_in_secs = 987654321
|
11
|
+
option.add_split_pay('taavo@dd9.com', '50%')
|
12
|
+
option.add_split_pay('bob@example.org', '.10')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
let(:price_option_2) { Tinypass::PriceOption.new('.99', '1 week') }
|
16
|
+
let(:offer) do
|
17
|
+
Tinypass::Offer.new(resource, price_option_1, price_option_2).tap do |offer|
|
18
|
+
offer.tags.push('tag', 'another tag', 'a third tag')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
let(:other_offer) { Tinypass::Offer.new(resource, price_option_2, price_option_1) }
|
22
|
+
let(:purchase_request) do
|
23
|
+
Tinypass::PurchaseRequest.new(offer).tap do |request|
|
24
|
+
request.client_ip = '1.2.3.4'
|
25
|
+
request.user_ref = 'steve'
|
26
|
+
request.options = { 'key' => 'value' }
|
27
|
+
request.secondary_offer = other_offer
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:builder) { Tinypass::JsonMsgBuilder.new }
|
32
|
+
|
33
|
+
context "with a single purchase request" do
|
34
|
+
let(:result) { MultiJson.load(builder.build_purchase_requests([purchase_request])).first }
|
35
|
+
|
36
|
+
it "encodes the purchase request correctly" do
|
37
|
+
%w(o1 o2 t v).each do |field|
|
38
|
+
expect(result[field]).not_to be_nil
|
39
|
+
end
|
40
|
+
|
41
|
+
expect(result['ip']).to eq '1.2.3.4'
|
42
|
+
expect(result['uref']).to eq 'steve'
|
43
|
+
expect(result['opts']).to eq({ 'key' => 'value' })
|
44
|
+
end
|
45
|
+
|
46
|
+
it "encodes the offers correctly" do
|
47
|
+
%w(pos pol).each do |field|
|
48
|
+
expect(result['o1'][field]).not_to be_nil # yes, we're only currently testing the primary offer
|
49
|
+
end
|
50
|
+
|
51
|
+
expect(result['o1']['rid']).to eq 'Premium-Content'
|
52
|
+
expect(result['o1']['rnm']).to eq 'Site wide premium content access'
|
53
|
+
expect(result['o1']['rurl']).to eq 'http://resource.com'
|
54
|
+
expect(result['o1']['tags']).to eq ['tag', 'another tag', 'a third tag']
|
55
|
+
end
|
56
|
+
|
57
|
+
it "encodes price options correctly" do
|
58
|
+
%w(opt0 opt1).each do |field|
|
59
|
+
expect(result['o1']['pos'][field]).not_to be_nil
|
60
|
+
end
|
61
|
+
|
62
|
+
po_result_1 = result['o1']['pos']['opt0'] # yes, we're only currently testing the first price option
|
63
|
+
|
64
|
+
expect(po_result_1['price']).to eq '.50'
|
65
|
+
expect(po_result_1['exp']).to eq '24 hours'
|
66
|
+
expect(po_result_1['caption']).to eq 'Special offer!'
|
67
|
+
expect(po_result_1['sd']).to eq 123456789
|
68
|
+
expect(po_result_1['ed']).to eq 987654321
|
69
|
+
expect(po_result_1['splits']).to eq ["taavo@dd9.com=0.5", "bob@example.org=0.1"]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tinypass::OpenEncoder do
|
4
|
+
describe '#encode' do
|
5
|
+
it "is a passthrough" do
|
6
|
+
expect(Tinypass::OpenEncoder.new.encode('the original string')).to eq 'the original string'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#decode' do
|
11
|
+
it "is a passthrough" do
|
12
|
+
expect(Tinypass::OpenEncoder.new.decode('the original string')).to eq 'the original string'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tinypass::SecureEncoder do
|
4
|
+
let(:encoder) { Tinypass::SecureEncoder.new(private_key) }
|
5
|
+
let(:private_key) { 'private key' }
|
6
|
+
let(:message) { 'a string'}
|
7
|
+
|
8
|
+
describe '#encode' do
|
9
|
+
it 'passes through to SecurityUtils' do
|
10
|
+
Tinypass::SecurityUtils.should_receive(:encrypt).with(private_key, message).and_return 'encrypted'
|
11
|
+
|
12
|
+
expect(encoder.encode(message)).to eq 'encrypted'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#decode' do
|
17
|
+
it 'passes through to SecurityUtils' do
|
18
|
+
Tinypass::SecurityUtils.should_receive(:decrypt).with(private_key, message).and_return 'decrypted'
|
19
|
+
|
20
|
+
expect(encoder.decode(message)).to eq 'decrypted'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Tinypass::SecurityUtils do
|
5
|
+
let(:private_key) { "thestringliteralisexactlyfortych" }
|
6
|
+
|
7
|
+
let(:java_data) { "JavaIsSoFun" }
|
8
|
+
let(:encrypted_java_data) { "V3IqZVBH2dQh4uxOMy9BAg~~~mB3lhC3FscKs7p18-N2vtvy6pSDsIyicy77lydm-UGk" }
|
9
|
+
|
10
|
+
let(:json_data) { "{\"aid\":\"MICMICMICX\",\"uid\":\"kjkxrNWUyD\",\"tokens\":[\"{\"ex\":1299043304,\"rid\":53530}\"],\"built\":1298957391760}" }
|
11
|
+
let(:encrypted_json_data) { "H1PgAu3LPBqwxFnnIEqG1N70CCRXrYsWL_audQvn1kYcbWEf9RQrA4rKX7qmFDvY_zQq61S8qBTWurpxtMLGPl7aEK86hD6Xkf6K2HxvOmHSKdN7iZ6mEJwyqB9X8b76wHA61qb-5eiERNBp3Nkjmw~~~WvbljkqdoCfCj-U-qjCAdyASh8sIajDSyk0pzkPZlBY" }
|
12
|
+
|
13
|
+
describe "#encrypt" do
|
14
|
+
it "produces the expected result for 'java' data" do
|
15
|
+
expect(Tinypass::SecurityUtils.encrypt(private_key, java_data)).to eq encrypted_java_data
|
16
|
+
end
|
17
|
+
|
18
|
+
it "produces the expected result for json data" do
|
19
|
+
expect(Tinypass::SecurityUtils.encrypt(private_key, json_data)).to eq encrypted_json_data
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#decrypt" do
|
24
|
+
it "produces the expected result for 'java' data" do
|
25
|
+
expect(Tinypass::SecurityUtils.decrypt(private_key, encrypted_java_data)).to eq java_data
|
26
|
+
end
|
27
|
+
|
28
|
+
it "produces the expected result for json data" do
|
29
|
+
expect(Tinypass::SecurityUtils.decrypt(private_key, encrypted_json_data)).to eq json_data
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#hash_hmac_sha256" do
|
34
|
+
it 'produces the expected results' do
|
35
|
+
expect(Tinypass::SecurityUtils::hash_hmac_sha256(private_key, '')).to eq "Y8MfdiTQSuLQGAW2aCXvAucxnYCmQGQSr780zffAka0"
|
36
|
+
expect(Tinypass::SecurityUtils::hash_hmac_sha256(private_key, 'a')).to eq "QSD2YcjAs_V3Z_-SBWmz3AFQ0jPFJi-j45gcgJMFRQ8"
|
37
|
+
expect(Tinypass::SecurityUtils::hash_hmac_sha256(private_key, 'tinypass')).to eq "AxJ7i3CxUPOF0q53YCpNzoewP4hRbqSOhqfQRoRFRF4"
|
38
|
+
expect(Tinypass::SecurityUtils::hash_hmac_sha256(private_key, '!@#$%^&*()_+{}|:<>?')).to eq "xRdalr1ZhbUYMBxmYJmhjSZi0D4Z-eTKyt-eGFnQPUY"
|
39
|
+
expect(Tinypass::SecurityUtils::hash_hmac_sha256(private_key, 'кирилл')).to eq "iPBDZnvNX0YSy10m6JUoItYZ83nXfPgCQXS76yS7Xo4"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tinypass::Gateway do
|
4
|
+
describe "#fetch_access_detail" do
|
5
|
+
it "returns nil when server returns 404" do
|
6
|
+
stub_request(:get, 'https://sandbox.tinypass.com/r2/access?rid=my_rid&user_ref=my_user_ref').to_return(status: 404)
|
7
|
+
expect(Tinypass.fetch_access_detail('my_rid', 'my_user_ref')).to be_nil
|
8
|
+
end
|
9
|
+
|
10
|
+
context "when server returns data" do
|
11
|
+
it "returns an AccessDetails" do
|
12
|
+
stub_request(:get, 'https://sandbox.tinypass.com/r2/access?rid=my_rid&user_ref=my_user_ref').
|
13
|
+
to_return(status: 200, body: "{}")
|
14
|
+
expect(Tinypass.fetch_access_detail('my_rid', 'my_user_ref')).to be_kind_of Tinypass::Gateway::AccessDetails
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#fetch_access_details" do
|
20
|
+
it "returns nil when server returns 404" do
|
21
|
+
stub_request(:get, "https://sandbox.tinypass.com/r2/access/search?pagesize=500&user_ref=my_user_ref").to_return(status: 404)
|
22
|
+
expect(Tinypass.fetch_access_details(user_ref: 'my_user_ref')).to be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when server returns data" do
|
26
|
+
it "returns an array of AccessDetails" do
|
27
|
+
stub_request(:get, "https://sandbox.tinypass.com/r2/access/search?pagesize=500&user_ref=my_user_ref").
|
28
|
+
to_return(status: 200, body: MultiJson.dump(data: [{}]))
|
29
|
+
details_array = Tinypass.fetch_access_details(user_ref: 'my_user_ref')
|
30
|
+
expect(details_array).not_to be_empty
|
31
|
+
expect(details_array.first).to be_kind_of Tinypass::Gateway::AccessDetails
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#fetch_subscription_details" do
|
37
|
+
it "returns the json" do
|
38
|
+
fake_result = [{ 'key' => 'value' }]
|
39
|
+
|
40
|
+
stub_request(:get, "https://sandbox.tinypass.com/r2/subscription/search?rid=my_rid&user_ref=my_user_ref").
|
41
|
+
to_return(status: 200, body: MultiJson.dump(fake_result))
|
42
|
+
|
43
|
+
expect(Tinypass.fetch_subscription_details({user_ref: 'my_user_ref', rid: 'my_rid'})).to eq fake_result
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#cancel_subscription" do
|
48
|
+
it "produces the expected request" do
|
49
|
+
cancel_request = stub_request(:post, "https://sandbox.tinypass.com/r2/subscription/cancel?rid=my_rid&user_ref=my_user_ref")
|
50
|
+
|
51
|
+
Tinypass.cancel_subscription({user_ref: 'my_user_ref', rid: 'my_rid'})
|
52
|
+
expect(cancel_request).to have_been_requested
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#revoke_access" do
|
57
|
+
it "produces the expected request" do
|
58
|
+
revoke_request = stub_request(:post, "https://sandbox.tinypass.com/r2/access/revoke?refund=true&rid=my_rid&user_ref=my_user_ref")
|
59
|
+
|
60
|
+
Tinypass.revoke_access({user_ref: 'my_user_ref', rid: 'my_rid', refund: true})
|
61
|
+
expect(revoke_request).to have_been_requested
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe Tinypass::Gateway::AccessDetails do
|
67
|
+
describe "#access_granted?" do
|
68
|
+
it "returns true when expires not set" do
|
69
|
+
expect(Tinypass::Gateway::AccessDetails.new.access_granted?).to be_true
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns true when expires in the future" do
|
73
|
+
expect(Tinypass::Gateway::AccessDetails.new(expires: Time.now.to_i + 1000).access_granted?).to be_true
|
74
|
+
end
|
75
|
+
|
76
|
+
it "returns false when expires in the past" do
|
77
|
+
expect(Tinypass::Gateway::AccessDetails.new(expires: Time.now.to_i - 1).access_granted?).to be_false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Tinypass::Offer do
|
4
|
+
let(:resource) { Tinypass::Resource.new('RID1', 0) }
|
5
|
+
let(:price_option) { Tinypass::PriceOption.new('.50', '24 hours') }
|
6
|
+
let(:other_price_option) { Tinypass::PriceOption.new('.50', '1 week') }
|
7
|
+
|
8
|
+
describe "#initialize" do
|
9
|
+
it "accepts a resource and two price options" do
|
10
|
+
offer = Tinypass::Offer.new(resource, price_option, other_price_option)
|
11
|
+
expect(offer.resource).to eq resource
|
12
|
+
expect(offer.pricing.price_options.length).to eq 2
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "delegates has_active_prices? to pricing" do
|
17
|
+
offer = Tinypass::Offer.new(resource, price_option, other_price_option)
|
18
|
+
fake_pricing = double(has_active_options?: 'it was delegated')
|
19
|
+
|
20
|
+
offer.stub(:pricing).and_return(fake_pricing)
|
21
|
+
expect(offer.has_active_prices?).to eq 'it was delegated'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can set tags" do
|
25
|
+
offer = Tinypass::Offer.new(resource, price_option, other_price_option)
|
26
|
+
offer.tags << 'one' << 'two' << 'three'
|
27
|
+
expect(offer.tags).to include('one')
|
28
|
+
expect(offer.tags).to include('two')
|
29
|
+
expect(offer.tags).to include('three')
|
30
|
+
end
|
31
|
+
end
|
Binary file
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tinypass::DiscountPolicy do
|
4
|
+
describe '#on_total_spend_in_period' do
|
5
|
+
let(:data) { Tinypass::DiscountPolicy.on_total_spend_in_period('100', '1 week', '50%') }
|
6
|
+
let(:hash) { data.to_hash }
|
7
|
+
|
8
|
+
it 'returns a DiscountPolicy' do
|
9
|
+
expect(data).to be_kind_of Tinypass::DiscountPolicy
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'sets the type' do
|
13
|
+
expect(hash[Tinypass::Policy::POLICY_TYPE]).to eq Tinypass::Policy::DISCOUNT_TOTAL_IN_PERIOD
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'sets the values' do
|
17
|
+
expect(hash['amount']).to eq '100'
|
18
|
+
expect(hash['withinPeriod']).to eq '1 week'
|
19
|
+
expect(hash['discount']).to eq '50%'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#previous_purchased' do
|
24
|
+
let(:data) { Tinypass::DiscountPolicy.previous_purchased(['RID1'], '50%') }
|
25
|
+
let(:hash) { data.to_hash }
|
26
|
+
|
27
|
+
it 'returns a DiscountPolicy' do
|
28
|
+
expect(data).to be_kind_of Tinypass::DiscountPolicy
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'sets the type' do
|
32
|
+
expect(hash[Tinypass::Policy::POLICY_TYPE]).to eq Tinypass::Policy::DISCOUNT_PREVIOUS_PURCHASE
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'sets the values' do
|
36
|
+
expect(hash['rids']).to eq ['RID1']
|
37
|
+
expect(hash['discount']).to eq '50%'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tinypass::PricingPolicy do
|
4
|
+
describe 'has_active_options?' do
|
5
|
+
it "returns true when it should" do
|
6
|
+
policy = Tinypass::PricingPolicy.new([double(active?: true)])
|
7
|
+
|
8
|
+
expect(policy.has_active_options?).to be_true
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns false when it should" do
|
12
|
+
policy = Tinypass::PricingPolicy.new(double(active?: false))
|
13
|
+
|
14
|
+
expect(policy.has_active_options?).to be_false
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns false when no options" do
|
18
|
+
policy = Tinypass::PricingPolicy.new([])
|
19
|
+
|
20
|
+
expect(policy.has_active_options?).to be_false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|