ashmont 0.0.12

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.
@@ -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