ashmont 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,204 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ashmont::Subscription do
4
+ %w(transactions).each do |delegated_method|
5
+ it "delegates ##{delegated_method} to the remote subscription" do
6
+ remote_subscription = stub_remote_subscription(delegated_method => "expected")
7
+ subscription = Ashmont::Subscription.new(remote_subscription.id)
8
+ result = subscription.send(delegated_method)
9
+ Braintree::Subscription.should have_received(:find).with(remote_subscription.id)
10
+ result.should == "expected"
11
+ end
12
+ end
13
+
14
+ it "converts the next billing date into the configured timezone" do
15
+ unconverted_date = "2011-01-20"
16
+ remote_subscription = stub_remote_subscription(:next_billing_date => unconverted_date)
17
+ subscription = Ashmont::Subscription.new("xyz")
18
+ result = subscription.next_billing_date
19
+ result.utc_offset.should == ActiveSupport::TimeZone[Ashmont.merchant_account_time_zone].utc_offset
20
+ result.strftime("%Y-%m-%d").should == unconverted_date
21
+ end
22
+
23
+ it "doesn't have a next billing date without a remote subscription" do
24
+ Ashmont::Subscription.new.next_billing_date.should be_nil
25
+ end
26
+
27
+ it "returns the token" do
28
+ subscription = Ashmont::Subscription.new('abc')
29
+ subscription.token.should == 'abc'
30
+ end
31
+
32
+ it "retries a subscription" do
33
+ subscription_token = 'xyz'
34
+ transaction_token = 'abc'
35
+ transaction = stub("transaction", :id => transaction_token)
36
+ retry_result = stub("retry-result", :transaction => transaction)
37
+ settlement_result = stub("settlement-result", :success? => true)
38
+ Braintree::Subscription.stubs(:retry_charge => retry_result)
39
+ Braintree::Transaction.stubs(:submit_for_settlement => settlement_result)
40
+
41
+ subscription = Ashmont::Subscription.new(subscription_token)
42
+ subscription.retry_charge.should be_true
43
+ subscription.errors.should be_empty
44
+
45
+ Braintree::Subscription.should have_received(:retry_charge).with(subscription_token)
46
+ Braintree::Transaction.should have_received(:submit_for_settlement).with(transaction_token)
47
+ end
48
+
49
+ it "has errors after a failed subscription retry" do
50
+ subscription_token = 'xyz'
51
+ transaction_token = 'abc'
52
+ transaction = stub("transaction", :id => transaction_token)
53
+ error_messages = "failure"
54
+ errors = "errors"
55
+ retry_result = stub("retry-result", :transaction => transaction)
56
+ settlement_result = stub("settlement-result", :success? => false, :errors => error_messages)
57
+ Braintree::Subscription.stubs(:retry_charge => retry_result)
58
+ Braintree::Transaction.stubs(:submit_for_settlement => settlement_result)
59
+ Ashmont::Errors.stubs(:new => errors)
60
+
61
+ subscription = Ashmont::Subscription.new(subscription_token)
62
+ subscription.retry_charge.should be_false
63
+ subscription.errors.should == errors
64
+
65
+ Braintree::Subscription.should have_received(:retry_charge).with(subscription_token)
66
+ Braintree::Transaction.should have_received(:submit_for_settlement).with(transaction_token)
67
+ Ashmont::Errors.should have_received(:new).with(transaction, error_messages)
68
+ end
69
+
70
+ it "reloads the subscription after retrying a charge" do
71
+ transaction = stub("transaction", :id => 'abc')
72
+ retry_result = stub("retry-result", :transaction => transaction)
73
+ settlement_result = stub("settlement-result", :success? => true)
74
+ past_due_subscription = stub("subscription", :status => "past_due")
75
+ active_subscription = stub("subscription", :status => "active")
76
+ Braintree::Subscription.stubs(:retry_charge => retry_result)
77
+ Braintree::Transaction.stubs(:submit_for_settlement => settlement_result)
78
+ Braintree::Subscription.stubs(:find).returns(past_due_subscription).then.returns(active_subscription)
79
+
80
+ subscription = Ashmont::Subscription.new('xyz')
81
+ expect { subscription.retry_charge }.to change { subscription.status }.from("past_due").to("active")
82
+ end
83
+
84
+ it "updates a subscription" do
85
+ token = 'xyz'
86
+ Braintree::Subscription.stubs(:update => 'expected')
87
+
88
+ subscription = Ashmont::Subscription.new(token)
89
+ result = subscription.save(:name => "Billy")
90
+
91
+ Braintree::Subscription.should have_received(:update).with(token, has_entries(:name => "Billy"))
92
+ result.should == "expected"
93
+ end
94
+
95
+ it "creates a successful subscription" do
96
+ attributes = { "test" => "hello" }
97
+ remote_subscription = stub_remote_subscription(:status => "fine")
98
+ result = stub("result", :subscription => remote_subscription, :success? => true)
99
+ Braintree::Subscription.stubs(:create => result)
100
+
101
+ subscription = Ashmont::Subscription.new
102
+ subscription.save(attributes).should be_true
103
+
104
+ Braintree::Subscription.should have_received(:create).with(has_entries(attributes))
105
+ subscription.token.should == remote_subscription.id
106
+ subscription.status.should == "fine"
107
+ end
108
+
109
+ it "passes a configured merchant account id" do
110
+ remote_subscription = stub_remote_subscription(:id => "xyz", :status => "fine")
111
+ result = stub("result", :subscription => remote_subscription, :success? => true)
112
+ Braintree::Subscription.stubs(:create => result)
113
+
114
+ with_configured_merchant_acount_id do |merchant_account_id|
115
+ subscription = Ashmont::Subscription.new
116
+ subscription.save({})
117
+
118
+ Braintree::Subscription.should have_received(:create).with(has_entries(:merchant_account_id => merchant_account_id))
119
+ end
120
+ end
121
+
122
+ it "doesn't pass a merchant account id when not is configured" do
123
+ remote_subscription = stub_remote_subscription(:id => "xyz", :status => "fine")
124
+ result = stub("result", :subscription => remote_subscription, :success? => true)
125
+ Braintree::Subscription.stubs(:create => result)
126
+
127
+ subscription = Ashmont::Subscription.new
128
+ subscription.save({})
129
+
130
+ Braintree::Subscription.should have_received(:create).with(has_entries(:merchant_account_id => nil)).never
131
+ end
132
+
133
+ it "returns the most recent transaction" do
134
+ Timecop.freeze(Time.now) do
135
+ dates = [2.days.ago, 3.days.ago, 1.day.ago]
136
+ transactions = dates.map { |date| stub("transaction", :created_at => date) }
137
+ remote_subscription = stub_remote_subscription(:transactions => transactions)
138
+
139
+ subscription = Ashmont::Subscription.new("xyz")
140
+
141
+ subscription.most_recent_transaction.created_at.should == 1.day.ago
142
+ end
143
+ end
144
+
145
+ it "reloads remote data" do
146
+ old_remote_subscription = stub_remote_subscription(:status => "old")
147
+ new_remote_subscription = stub_remote_subscription(:status => "new")
148
+ Braintree::Subscription.stubs(:find).returns(old_remote_subscription).then.returns(new_remote_subscription)
149
+ subscription = Ashmont::Subscription.new(old_remote_subscription.id)
150
+ subscription.status.should == "old"
151
+ subscription.reload.status.should == "new"
152
+ end
153
+
154
+ it "finds status from the remote subscription" do
155
+ remote_subscription = stub_remote_subscription(:status => "a-ok")
156
+ subscription = Ashmont::Subscription.new("xyz")
157
+ subscription.status.should == "a-ok"
158
+ end
159
+
160
+ it "doesn't have status without a remote subscription" do
161
+ subscription = Ashmont::Subscription.new(nil)
162
+ subscription.status.should be_nil
163
+ end
164
+
165
+ it "uses a cached status when provided" do
166
+ remote_subscription = stub_remote_subscription(:status => "past-due")
167
+ subscription = Ashmont::Subscription.new("xyz", :status => "a-ok")
168
+ subscription.status.should == "a-ok"
169
+ end
170
+
171
+ it "updates the cached status when reloading" do
172
+ remote_subscription = stub_remote_subscription(:status => "active")
173
+ subscription = Ashmont::Subscription.new("xyz", :status => "past-due")
174
+ subscription.reload
175
+ subscription.status.should == "active"
176
+ end
177
+
178
+ it "is past due with a past due status" do
179
+ Ashmont::Subscription.new("xyz", :status => Braintree::Subscription::Status::PastDue).should be_past_due
180
+ end
181
+
182
+ it "isn't past due with an active status" do
183
+ Ashmont::Subscription.new("xyz", :status => Braintree::Subscription::Status::Active).should_not be_past_due
184
+ end
185
+
186
+ def with_configured_merchant_acount_id
187
+ merchant_account_id = "jkl"
188
+ Ashmont.merchant_account_id = merchant_account_id
189
+ yield merchant_account_id
190
+ ensure
191
+ Ashmont.merchant_account_id = nil
192
+ end
193
+
194
+ def stub_remote_subscription(options = {})
195
+ stub(
196
+ "remote_subscription",
197
+ {
198
+ :transactions => [],
199
+ :status => "active",
200
+ :id => "abcdef"
201
+ }.update(options)
202
+ ).tap { |subscription| Braintree::Subscription.stubs(:find => subscription) }
203
+ end
204
+ end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Ashmont do
4
+ it "has a version number" do
5
+ expect(Ashmont::VERSION).not_to be nil
6
+ end
7
+
8
+ it "does something useful" do
9
+ expect(false).to eq(true)
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ require 'rspec'
2
+ require 'ashmont'
3
+ require 'bourne'
4
+ require 'timecop'
5
+
6
+ RSpec.configure do |config|
7
+ config.mock_with :mocha
8
+ end
metadata ADDED
@@ -0,0 +1,187 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ashmont
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.12
5
+ platform: ruby
6
+ authors:
7
+ - thoughtbot
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: braintree
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.74.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.74.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: i18n
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: tzinfo
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0.3'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bourne
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: timecop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: ActiveModel-like objects and helpers for interacting with Braintree.
126
+ email:
127
+ - jferris@thoughtbot.com
128
+ executables:
129
+ - console
130
+ - setup
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - ".gitignore"
135
+ - ".rspec"
136
+ - ".travis.yml"
137
+ - CHANGELOG.md
138
+ - CODE_OF_CONDUCT.md
139
+ - Gemfile
140
+ - LICENSE.txt
141
+ - README.md
142
+ - Rakefile
143
+ - ashmont.gemspec
144
+ - bin/console
145
+ - bin/setup
146
+ - lib/ashmont.rb
147
+ - lib/ashmont/customer.rb
148
+ - lib/ashmont/errors.rb
149
+ - lib/ashmont/subscribed_customer.rb
150
+ - lib/ashmont/subscription.rb
151
+ - lib/ashmont/version.rb
152
+ - spec/ashmont/customer_spec.rb
153
+ - spec/ashmont/errors_spec.rb
154
+ - spec/ashmont/subscribed_customer_spec.rb
155
+ - spec/ashmont/subscription_spec.rb
156
+ - spec/ashmont_spec.rb
157
+ - spec/spec_helper.rb
158
+ homepage: ''
159
+ licenses: []
160
+ metadata: {}
161
+ post_install_message:
162
+ rdoc_options: []
163
+ require_paths:
164
+ - lib
165
+ required_ruby_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ requirements: []
176
+ rubyforge_project: ashmont
177
+ rubygems_version: 2.6.10
178
+ signing_key:
179
+ specification_version: 4
180
+ summary: ActiveModel-like objects and helpers for interacting with Braintree.
181
+ test_files:
182
+ - spec/ashmont/customer_spec.rb
183
+ - spec/ashmont/errors_spec.rb
184
+ - spec/ashmont/subscribed_customer_spec.rb
185
+ - spec/ashmont/subscription_spec.rb
186
+ - spec/ashmont_spec.rb
187
+ - spec/spec_helper.rb