saucy 0.13.3 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ 0.14.0
2
+
3
+ * Accept user billing address.
4
+
1
5
  0.13.2
2
6
 
3
7
  * Follow-up to 0.13.1: Actually work irrespective of system TZ
@@ -12,6 +12,13 @@ class BillingsController < ApplicationController
12
12
  @account.billing_email = @account.customer.email
13
13
  @account.expiration_month = @account.credit_card.expiration_month
14
14
  @account.expiration_year = @account.credit_card.expiration_year
15
+
16
+ @account.street_address = @account.billing_address.street_address
17
+ @account.extended_address = @account.billing_address.extended_address
18
+ @account.locality = @account.billing_address.locality
19
+ @account.region = @account.billing_address.region
20
+ @account.postal_code = @account.billing_address.postal_code
21
+ @account.country_name = @account.billing_address.country_name
15
22
  end
16
23
 
17
24
  def update
data/app/models/signup.rb CHANGED
@@ -13,7 +13,13 @@ class Signup
13
13
  :expiration_month => :expiration_month,
14
14
  :expiration_year => :expiration_year,
15
15
  :verification_code => :verification_code,
16
- :plan => :plan
16
+ :plan => :plan,
17
+ :street_address => :street_address,
18
+ :extended_address => :extended_address,
19
+ :locality => :locality,
20
+ :region => :region,
21
+ :postal_code => :postal_code,
22
+ :country_name => :country_name
17
23
  },
18
24
  :user => {
19
25
  :email => :email,
@@ -22,7 +28,8 @@ class Signup
22
28
  }.freeze
23
29
 
24
30
  attr_accessor :billing_email, :password, :cardholder_name, :email,
25
- :card_number, :expiration_month, :expiration_year, :plan, :verification_code, :coupon
31
+ :card_number, :expiration_month, :expiration_year, :plan, :verification_code, :coupon,
32
+ :street_address, :extended_address, :locality, :region, :postal_code, :country_name
26
33
 
27
34
  def initialize(attributes = {})
28
35
  if attributes
@@ -1,8 +1,18 @@
1
1
  <%= form.inputs do %>
2
- <%= form.input :cardholder_name, :required => true %>
3
- <%= form.input :billing_email, :required => true, :hint => "We'll send receipts and billing issues to this address." %>
4
2
  <%= form.input :card_number, :required => true, :input_html => { :autocomplete => "off" } %>
5
3
  <%= form.input :verification_code, :required => true, :input_html => { :autocomplete => "off" } %>
6
4
  <%= form.input :expiration_month, :collection => [['January', '01'], ['February', '02'], ['March', '03'], ['April', '04'], ['May', '05'], ['June', '06'], ['July', '07'], ['August', '08'], ['September', '09'], ['October', '10'], ['November', '11'], ['December', '12']], :required => true %>
7
5
  <%= form.input :expiration_year, :collection => (Date.today.year..(Date.today.year+10)).to_a, :required => true %>
6
+ <%= form.input :cardholder_name, :required => true %>
7
+ <%= form.input :billing_email, :required => true, :hint => "We'll send receipts and billing issues to this address." %>
8
+
9
+ <%= form.input :street_address, :label => "Address Line 1", :required => true %>
10
+ <%= form.input :extended_address, :label => "Address Line 2", :required => true %>
11
+ <%= form.input :locality, :label => "City", :required => true %>
12
+ <%= form.input :region, :label => "State or Province", :required => true %>
13
+ <%= form.input :postal_code, :label => "ZIP or Postal Code", :required => true %>
14
+ <%= form.input :country_name, :label => "Country",
15
+ :required => true,
16
+ :collection => ["United States of America", "Canada", "---",
17
+ *Braintree::Address::CountryNames.map(&:first)] %>
8
18
  <% end -%>
@@ -20,6 +20,7 @@ Feature: generate a saucy application and run rake
20
20
  gem "launchy"
21
21
  gem "timecop"
22
22
  gem "jquery-rails"
23
+ gem "minitest", "~> 2.6.1", :platforms => :ruby_19
23
24
  """
24
25
  When I add the "saucy" gem from this project as a dependency
25
26
  And I successfully run `bundle install`
@@ -25,6 +25,11 @@ Factory.define :paid_account, :parent => :account do |f|
25
25
  f.verification_code { "123" }
26
26
  f.expiration_month { 5 }
27
27
  f.expiration_year { 2012 }
28
+ f.street_address { "1 Robo Lane" }
29
+ f.locality { "Boston" }
30
+ f.region { "MA" }
31
+ f.postal_code { "02108" }
32
+ f.country_name { "United States of America" }
28
33
  f.association :plan, :factory => :paid_plan
29
34
  end
30
35
 
@@ -3,12 +3,14 @@ Feature: Manage Billing
3
3
  I want to be able to manage my billing information
4
4
  So that my account can stay up to date and in good standing
5
5
 
6
- Scenario: Update the billing information on an account with a paid plan
6
+ Background:
7
7
  Given a paid plan exists with a name of "Paid"
8
8
  And the following account exists:
9
- | name | keyword | plan | cardholder_name | billing_email | card_number | verification_code | expiration_month | expiration_year |
10
- | Test | test | name: Paid | Joe Smith | jsmith@example.com | 4111111111115555 | 122 | 01 | 2015 |
11
- And I have signed in with "joe@example.com"
9
+ | name | keyword | plan | cardholder_name | billing_email | card_number | verification_code | expiration_month | expiration_year | street_address | extended_address | locality | region | postal_code | country_name |
10
+ | Test | test | name: Paid | Joe Smith | jsmith@example.com | 4111111111115555 | 122 | 01 | 2015 | 1 Robo Lane | Suite 333 | Beverly Hills | CA | 90210 | United States of America |
11
+
12
+ Scenario: Update the billing information on an account with a paid plan
13
+ Given I have signed in with "joe@example.com"
12
14
  And "joe@example.com" is an admin of the "Test" account
13
15
  When I go to the billing page for the "Test" account
14
16
  Then I should see "card ending in 5555"
@@ -21,23 +23,39 @@ Feature: Manage Billing
21
23
  And the "Verification code" field should have nothing in it
22
24
  And the "Expiration month" field should contain "01"
23
25
  And the "Expiration year" field should contain "2015"
26
+ And the "Address Line 1" field should contain "1 Robo Lane"
27
+ And the "Address Line 2" field should contain "Suite 333"
28
+ And the "City" field should contain "Beverly Hills"
29
+ And the "State or Province" field should contain "CA"
30
+ And the "ZIP or Postal Code" field should contain "90210"
31
+ And the "Country" field should contain "United States of America"
24
32
 
25
- And I fill in "Cardholder name" with "Ralph Robot"
33
+ When I fill in "Cardholder name" with "Ralph Robot"
26
34
  And I fill in "Billing email" with "accounting@example.com"
27
35
  And I fill in "Card number" with "4111111111111111"
28
36
  And I fill in "Verification code" with "123"
29
37
  And I select "March" from "Expiration month"
30
38
  And I select "2020" from "Expiration year"
39
+ And I fill in "Address Line 1" with "41 Winter St"
40
+ And I fill in "Address Line 2" with "Floor 7"
41
+ And I fill in "City" with "Boston"
42
+ And I fill in "State or Province" with "MA"
43
+ And I fill in "ZIP or Postal Code" with "02108"
44
+ And I select "Uganda" from "Country"
31
45
  And I press "Update"
32
46
  Then I should see "updated successfully"
33
- Then I should see "card ending in 1111"
47
+ And I should see "card ending in 1111"
48
+
49
+ When I follow "Change"
50
+ Then the "Address Line 1" field should contain "41 Winter St"
51
+ And the "Address Line 2" field should contain "Floor 7"
52
+ And the "City" field should contain "Boston"
53
+ And the "State or Province" field should contain "MA"
54
+ And the "ZIP or Postal Code" field should contain "02108"
55
+ And the "Country" field should contain "Uganda"
34
56
 
35
57
  Scenario: Be forced to update the billing information on an account with a paid plan that is past due
36
- Given a paid plan exists with a name of "Paid"
37
- And the following account exists:
38
- | name | keyword | plan | cardholder_name | billing_email | card_number | verification_code | expiration_month | expiration_year |
39
- | Test | test | name: Paid | Joe Smith | jsmith@example.com | 4111111111115555 | 122 | 01 | 2015 |
40
- And the "Test" account is past due
58
+ Given the "Test" account is past due
41
59
  And I have signed in with "joe@example.com"
42
60
  And "joe@example.com" is an admin of the "Test" account
43
61
  When I go to the settings page for the "Test" account
@@ -45,11 +63,7 @@ Feature: Manage Billing
45
63
  And I should see "There was an issue processing the credit card you have on file. Please update your credit card information."
46
64
 
47
65
  Scenario: Be told to have an admin update the billing information on an account with a paid plan that is past due
48
- Given a paid plan exists with a name of "Paid"
49
- And the following account exists:
50
- | name | keyword | plan | cardholder_name | billing_email | card_number | verification_code | expiration_month | expiration_year |
51
- | Test | test | name: Paid | Joe Smith | jsmith@example.com | 4111111111115555 | 122 | 01 | 2015 |
52
- And the "Test" account is past due
66
+ Given the "Test" account is past due
53
67
  And the following projects exist:
54
68
  | name | account |
55
69
  | Project | name: Test |
@@ -64,11 +78,7 @@ Feature: Manage Billing
64
78
  Then I should be on the billing page for the "Test" account
65
79
 
66
80
  Scenario: View past credit card charges
67
- Given a paid plan exists with a name of "Paid"
68
- And the following account exists:
69
- | name | keyword | plan | cardholder_name | billing_email | card_number | verification_code | expiration_month | expiration_year |
70
- | Test | test | name: Paid | Joe Smith | jsmith@example.com | 4111111111115555 | 122 | 01 | 2015 |
71
- And the following transaction exist for the "Test" account:
81
+ Given the following transaction exist for the "Test" account:
72
82
  | status | amount | created_at |
73
83
  | Settled | 20.00 | July 1, 2010 |
74
84
  | Settled | 5.00 | August 1, 2010 |
@@ -80,14 +90,19 @@ Feature: Manage Billing
80
90
  And I should see "08/01/10 $5"
81
91
 
82
92
  Scenario: Navigate back to the main settings page
83
- Given a paid plan exists with a name of "Paid"
84
- And the following account exists:
85
- | name | keyword | plan | cardholder_name | billing_email | card_number | verification_code | expiration_month | expiration_year |
86
- | Test | test | name: Paid | Joe Smith | jsmith@example.com | 4111111111115555 | 122 | 01 | 2015 |
87
- And I have signed in with "joe@example.com"
93
+ Given I have signed in with "joe@example.com"
88
94
  And "joe@example.com" is an admin of the "Test" account
89
95
  When I go to the billing page for the "Test" account
90
96
  And I follow "Change"
91
97
  And I follow "Billing"
92
98
  And I follow "Account Info"
93
99
  Then I should be on the settings page for the "Test" account
100
+
101
+ Scenario: Billing countries
102
+ Given I have signed in with "joe@example.com"
103
+ And "joe@example.com" is an admin of the "Test" account
104
+ When I go to the billing page for the "Test" account
105
+ And I follow "Change"
106
+ Then I should see all the Braintree countries in the country select with the following at the top:
107
+ | United States of America |
108
+ | Canada |
@@ -6,7 +6,7 @@ Feature: Manage Plan
6
6
  Scenario: Change the plan to another paid plan on an account with a paid plan
7
7
  Given a paid plan exists with a name of "Basic"
8
8
  And a paid plan exists with a name of "Premium"
9
- And the following account exists:
9
+ And the following paid account exists:
10
10
  | name | keyword | plan | cardholder_name | billing_email | card_number | verification_code | expiration_month | expiration_year |
11
11
  | Test | test | name: Basic | Joe Smith | jsmith@example.com | 4111111111115555 | 122 | 01 | 2015 |
12
12
  And I have signed in with "joe@example.com"
@@ -37,13 +37,18 @@ Feature: Manage Plan
37
37
  Then I should see "Upgrade Your Plan"
38
38
  When I choose the "Basic" plan
39
39
  Then I should see "Billing Information"
40
- And I should not see "No thanks, just delete my account"
41
40
  And I fill in "Cardholder name" with "Ralph Robot"
42
41
  And I fill in "Billing email" with "accounting@example.com"
43
42
  And I fill in "Card number" with "4111111111111111"
44
43
  And I fill in "Verification code" with "123"
45
44
  And I select "March" from "Expiration month"
46
45
  And I select "2020" from "Expiration year"
46
+ And I fill in "Address Line 1" with "41 Winter St"
47
+ And I fill in "Address Line 2" with "Floor 7"
48
+ And I fill in "City" with "Boston"
49
+ And I fill in "State or Province" with "MA"
50
+ And I fill in "ZIP or Postal Code" with "02108"
51
+ And I select "United States of America" from "Country"
47
52
  When I press "Upgrade"
48
53
  Then I should see "Plan changed successfully"
49
54
  And I should see "Basic"
@@ -71,6 +76,12 @@ Feature: Manage Plan
71
76
  And I fill in "Verification code" with "123"
72
77
  And I select "March" from "Expiration month"
73
78
  And I select "2020" from "Expiration year"
79
+ And I fill in "Address Line 1" with "41 Winter St"
80
+ And I fill in "Address Line 2" with "Floor 7"
81
+ And I fill in "City" with "Boston"
82
+ And I fill in "State or Province" with "MA"
83
+ And I fill in "ZIP or Postal Code" with "02108"
84
+ And I select "United States of America" from "Country"
74
85
  When I press "Upgrade"
75
86
  Then I should not see "Plan changed successfully"
76
87
  And "Card number" should have the error "is invalid"
@@ -78,7 +89,7 @@ Feature: Manage Plan
78
89
  Scenario: Change the plan to a free on an account with a paid plan
79
90
  Given a paid plan exists with a name of "Basic"
80
91
  And a plan exists with a name of "Free"
81
- And the following account exists:
92
+ And the following paid account exists:
82
93
  | name | keyword | plan | cardholder_name | billing_email | card_number | verification_code | expiration_month | expiration_year |
83
94
  | Test | test | name: Basic | Joe Smith | jsmith@example.com | 4111111111115555 | 122 | 01 | 2015 |
84
95
  And I have signed in with "joe@example.com"
@@ -97,7 +108,7 @@ Feature: Manage Plan
97
108
  Scenario: Attempting to downgrade when beyond the limits
98
109
  Given a paid plan exists with a name of "Basic"
99
110
  And a plan exists with a name of "Free"
100
- And the following account exists:
111
+ And the following paid account exists:
101
112
  | name | keyword | plan | cardholder_name | billing_email | card_number | verification_code | expiration_month | expiration_year |
102
113
  | Test | test | name: Basic | Joe Smith | jsmith@example.com | 4111111111115555 | 122 | 01 | 2015 |
103
114
  And the following limits exist:
@@ -127,7 +138,7 @@ Feature: Manage Plan
127
138
 
128
139
  Scenario: Viewing current usage
129
140
  Given a paid plan exists with a name of "Basic"
130
- And the following account exists:
141
+ And the following paid account exists:
131
142
  | name | keyword | plan | cardholder_name | billing_email | card_number | verification_code | expiration_month | expiration_year |
132
143
  | Test | test | name: Basic | Joe Smith | jsmith@example.com | 4111111111115555 | 122 | 01 | 2015 |
133
144
  And the following limits exist:
@@ -31,6 +31,12 @@ Feature: Sign up
31
31
  And I fill in "Verification code" with "123"
32
32
  And I select "March" from "Expiration month"
33
33
  And I select "2020" from "Expiration year"
34
+ And I fill in "Address Line 1" with "123 Robo Lane"
35
+ And I fill in "Address Line 2" with "Suite 5"
36
+ And I fill in "City" with "Boston"
37
+ And I fill in "State or Province" with "MA"
38
+ And I fill in "ZIP or Postal Code" with "02110"
39
+ And I select "United States of America" from "Country"
34
40
  And I press "Sign up"
35
41
  Then I should see "created"
36
42
 
@@ -46,6 +52,12 @@ Feature: Sign up
46
52
  And I fill in "Verification code" with "123"
47
53
  And I select "March" from "Expiration month"
48
54
  And I select "2020" from "Expiration year"
55
+ And I fill in "Address Line 1" with "123 Robo Lane"
56
+ And I fill in "Address Line 2" with "Suite 5"
57
+ And I fill in "City" with "Boston"
58
+ And I fill in "State or Province" with "MA"
59
+ And I fill in "ZIP or Postal Code" with "02110"
60
+ And I select "United States of America" from "Country"
49
61
  And I press "Sign up"
50
62
  Then "Card number" should have the error "is invalid"
51
63
 
@@ -61,5 +73,11 @@ Feature: Sign up
61
73
  And I fill in "Verification code" with "123"
62
74
  And I select "March" from "Expiration month"
63
75
  And I select "2020" from "Expiration year"
76
+ And I fill in "Address Line 1" with "123 Robo Lane"
77
+ And I fill in "Address Line 2" with "Suite 5"
78
+ And I fill in "City" with "Boston"
79
+ And I fill in "State or Province" with "MA"
80
+ And I fill in "ZIP or Postal Code" with "02110"
81
+ And I select "United States of America" from "Country"
64
82
  And I press "Sign up"
65
83
  Then "Card number" should have the error "Do Not Honor"
@@ -37,15 +37,6 @@ Feature: Trial plans
37
37
  And I should see "expired"
38
38
  And the "Temp" plan should be disabled
39
39
 
40
- Scenario: Delete an account with an expired plan
41
- Given a "Temp" account exists with a name of "Test" created 30 days ago
42
- And I am signed in as an admin of the "Test" account
43
- When I go to the projects page for the "Test" account
44
- Then I should be on the upgrade plan page for the "Test" account
45
- And I should see "expired"
46
- When I follow "No thanks, just delete my account"
47
- Then I should see "Your account has been deleted"
48
-
49
40
  Scenario: Sign up for a non-trial plan
50
41
  When I go to the list of plans page
51
42
  And I follow "Eternal"
@@ -0,0 +1,8 @@
1
+ Then /^I should see all the Braintree countries in the country select with the following at the top:$/ do |table|
2
+ divider = "---"
3
+ top_country_names = table.raw.flatten
4
+ all_country_names = Braintree::Address::CountryNames.map(&:first)
5
+
6
+ expected_country_names = [top_country_names, divider, all_country_names].flatten
7
+ page.should have_select("Country", :options => expected_country_names)
8
+ end
@@ -10,16 +10,28 @@ module Saucy
10
10
 
11
11
  extend ActiveSupport::Memoizable
12
12
 
13
- CUSTOMER_ATTRIBUTES = { :cardholder_name => :cardholder_name,
14
- :billing_email => :email,
15
- :card_number => :number,
16
- :expiration_month => :expiration_month,
17
- :expiration_year => :expiration_year,
18
- :verification_code => :cvv }
19
-
20
- attr_accessor *CUSTOMER_ATTRIBUTES.keys
21
-
22
- CUSTOMER_ATTRIBUTES.keys.each do |attribute|
13
+ CUSTOMER_ATTRIBUTES = [ :cardholder_name,
14
+ :billing_email,
15
+ :card_number,
16
+ :expiration_month,
17
+ :expiration_year,
18
+ :verification_code,
19
+ :street_address,
20
+ :extended_address,
21
+ :locality,
22
+ :region,
23
+ :postal_code,
24
+ :country_name
25
+ ]
26
+
27
+ OPTIONAL_CUSTOMER_ATTRIBUTES = [:extended_address]
28
+
29
+ REQUIRED_CUSTOMER_ATTRIBUTES =
30
+ CUSTOMER_ATTRIBUTES - OPTIONAL_CUSTOMER_ATTRIBUTES
31
+
32
+ attr_accessor *CUSTOMER_ATTRIBUTES
33
+
34
+ REQUIRED_CUSTOMER_ATTRIBUTES.each do |attribute|
23
35
  validates_presence_of attribute, :if => :switching_to_billed?
24
36
  end
25
37
  before_create :create_customer
@@ -39,6 +51,10 @@ module Saucy
39
51
  customer.credit_cards[0] if customer && customer.credit_cards.any?
40
52
  end
41
53
 
54
+ def billing_address
55
+ credit_card.billing_address if credit_card
56
+ end
57
+
42
58
  def subscription
43
59
  Braintree::Subscription.find(subscription_token) if subscription_token
44
60
  end
@@ -103,11 +119,11 @@ module Saucy
103
119
  end
104
120
 
105
121
  def changing_customer_attributes?(attributes)
106
- CUSTOMER_ATTRIBUTES.keys.any? { |attribute| attributes[attribute].present? }
122
+ CUSTOMER_ATTRIBUTES.any? { |attribute| attributes[attribute].present? }
107
123
  end
108
124
 
109
125
  def set_customer_attributes(attributes)
110
- CUSTOMER_ATTRIBUTES.keys.each do |attribute|
126
+ CUSTOMER_ATTRIBUTES.each do |attribute|
111
127
  send("#{attribute}=", attributes[attribute]) if attributes[attribute].present?
112
128
  end
113
129
  end
@@ -144,7 +160,16 @@ module Saucy
144
160
  :number => card_number,
145
161
  :expiration_month => expiration_month,
146
162
  :expiration_year => expiration_year,
147
- :cvv => verification_code }
163
+ :cvv => verification_code,
164
+ :billing_address => {
165
+ :street_address => street_address,
166
+ :extended_address => extended_address,
167
+ :locality => locality,
168
+ :region => region,
169
+ :postal_code => postal_code,
170
+ :country_name => country_name
171
+ }
172
+ }
148
173
  if credit_card
149
174
  card_attributes.merge!(:options => credit_card_options)
150
175
  end
@@ -1,17 +1,22 @@
1
1
  require 'spec_helper'
2
2
 
3
+ describe Account, "factories" do
4
+ it "has a valid factory" do
5
+ Factory(:account).should be_valid
6
+ end
7
+
8
+ it "has a valid paid factory" do
9
+ Factory(:paid_account).should be_valid
10
+ end
11
+ end
12
+
3
13
  describe Account do
4
14
  subject { Factory(:account) }
5
15
 
6
16
  it "manifests braintree processor_declined errors as errors on number and doesn't save" do
7
17
  FakeBraintree.failures["4111111111111112"] = { "message" => "Do Not Honor", "code" => "2000", "status" => "processor_declined" }
8
- account = Factory.build(:account,
9
- :cardholder_name => "Ralph Robot",
10
- :billing_email => "ralph@example.com",
18
+ account = Factory.build(:paid_account,
11
19
  :card_number => "4111111111111112",
12
- :verification_code => "100",
13
- :expiration_month => 5,
14
- :expiration_year => 2012,
15
20
  :plan => Factory(:paid_plan))
16
21
  account.save.should_not be
17
22
  FakeBraintree.customers.should be_empty
@@ -21,13 +26,8 @@ describe Account do
21
26
 
22
27
  it "manifests braintree gateway_rejected errors as errors on number and doesn't save" do
23
28
  FakeBraintree.failures["4111111111111112"] = { "message" => "Gateway Rejected: cvv", "code" => "N", "status" => "gateway_rejected" }
24
- account = Factory.build(:account,
25
- :cardholder_name => "Ralph Robot",
26
- :billing_email => "ralph@example.com",
29
+ account = Factory.build(:paid_account,
27
30
  :card_number => "4111111111111112",
28
- :expiration_month => 5,
29
- :expiration_year => 2012,
30
- :verification_code => 200,
31
31
  :plan => Factory(:paid_plan))
32
32
  account.save.should_not be
33
33
  FakeBraintree.customers.should be_empty
@@ -36,14 +36,9 @@ describe Account do
36
36
  end
37
37
 
38
38
  it "manifests braintree gateway_rejected errors as errors on number and doesn't save" do
39
- FakeBraintree.failures["4111111111111111"] = { "message" => "Credit card number is invalid.", "errors" => { "customer" => { "errors" => [], "credit-card" => { "errors" => [{ "message" => "Credit card number is invalid.", "code" => 81715, "attribute" => :number }] }}}}
40
- account = Factory.build(:account,
41
- :cardholder_name => "Ralph Robot",
42
- :billing_email => "ralph@example.com",
43
- :card_number => "4111111111111111",
44
- :expiration_month => 5,
45
- :expiration_year => 2012,
46
- :verification_code => 123,
39
+ FakeBraintree.failures["4111111111111112"] = { "message" => "Credit card number is invalid.", "errors" => { "customer" => { "errors" => [], "credit-card" => { "errors" => [{ "message" => "Credit card number is invalid.", "code" => 81715, "attribute" => :number }] }}}}
40
+ account = Factory.build(:paid_account,
41
+ :card_number => "4111111111111112",
47
42
  :plan => Factory(:paid_plan))
48
43
  account.save.should_not be
49
44
  FakeBraintree.customers.should be_empty
@@ -64,7 +59,7 @@ describe Account, "given free and paid plans" do
64
59
 
65
60
  result.should be_false
66
61
  account.reload.plan.should == free
67
- Saucy::Subscription::CUSTOMER_ATTRIBUTES.keys.each do |attribute|
62
+ Saucy::Subscription::REQUIRED_CUSTOMER_ATTRIBUTES.each do |attribute|
68
63
  account.errors[attribute].should_not be_blank
69
64
  end
70
65
  FakeBraintree.customers[account.customer_token].should_not be_nil
@@ -92,14 +87,7 @@ end
92
87
 
93
88
  describe Account, "with a paid plan" do
94
89
  subject do
95
- Factory(:account,
96
- :cardholder_name => "Ralph Robot",
97
- :billing_email => "ralph@example.com",
98
- :card_number => "4111111111111111",
99
- :verification_code => "123",
100
- :expiration_month => 5,
101
- :expiration_year => 2012,
102
- :plan => Factory(:paid_plan))
90
+ Factory(:paid_account, :plan => Factory(:paid_plan))
103
91
  end
104
92
 
105
93
  it "has a customer_token" do
@@ -148,15 +136,76 @@ describe Account, "with a paid plan" do
148
136
  FakeBraintree.subscriptions[subject.subscription_token]["price"].should == "5"
149
137
  end
150
138
 
151
- it "updates the customer and credit card information when changed" do
152
- subject.save_customer_and_subscription!(:billing_email => "jrobot@example.com",
153
- :cardholder_name => "Jim Robot",
154
- :card_number => "4111111111111115",
155
- :verification_code => "123",
156
- :expiration_month => 5,
157
- :expiration_year => 2013)
158
- subject.customer.email.should == "jrobot@example.com"
159
- subject.credit_card.cardholder_name.should == "Jim Robot"
139
+ context "updating customer credit card information when changed" do
140
+ before do
141
+ subject.save_customer_and_subscription!(:billing_email => "jrobot@example.com",
142
+ :cardholder_name => "Jim Robot",
143
+ :card_number => "4111111111111115",
144
+ :verification_code => "123",
145
+ :expiration_month => 5,
146
+ :expiration_year => 2013)
147
+ end
148
+
149
+ it "updates the billing email" do
150
+ subject.customer.email.should == "jrobot@example.com"
151
+ end
152
+
153
+ it "updates the cardholder name" do
154
+ subject.credit_card.cardholder_name.should == "Jim Robot"
155
+ end
156
+
157
+ it "updates the card number" do
158
+ subject.credit_card.last_4.should == "1115"
159
+ end
160
+
161
+ it "updates the expiration year" do
162
+ subject.credit_card.expiration_year.should == 2013
163
+ end
164
+
165
+ it "updates the expiration month" do
166
+ subject.credit_card.expiration_month.should == 5
167
+ end
168
+ end
169
+
170
+ context "updating customer credit card billing address information when changed" do
171
+ before do
172
+ subject.save_customer_and_subscription!(:billing_email => "jrobot@example.com",
173
+ :cardholder_name => "Jim Robot",
174
+ :card_number => "4111111111111115",
175
+ :verification_code => "123",
176
+ :expiration_month => 5,
177
+ :expiration_year => 2013,
178
+ :street_address => "1 E Main St",
179
+ :extended_address => "Suite 3",
180
+ :locality => "Chicago",
181
+ :region => "Illinois",
182
+ :postal_code => "60622",
183
+ :country_name => "United States of America")
184
+ end
185
+
186
+ it "updates the street address" do
187
+ subject.billing_address.street_address.should == "1 E Main St"
188
+ end
189
+
190
+ it "updates the extended address" do
191
+ subject.billing_address.extended_address.should == "Suite 3"
192
+ end
193
+
194
+ it "updates the locality" do
195
+ subject.billing_address.locality.should == "Chicago"
196
+ end
197
+
198
+ it "updates the region" do
199
+ subject.billing_address.region.should == "Illinois"
200
+ end
201
+
202
+ it "updates the postal code" do
203
+ subject.billing_address.postal_code.should == "60622"
204
+ end
205
+
206
+ it "updates the country name" do
207
+ subject.billing_address.country_name.should == "United States of America"
208
+ end
160
209
  end
161
210
 
162
211
  it "deletes the customer when deleted" do
@@ -190,6 +239,10 @@ describe Account, "with a free plan" do
190
239
  subject.subscription.should be_nil
191
240
  end
192
241
 
242
+ it "doesn't have a billing address" do
243
+ subject.billing_address.should be_nil
244
+ end
245
+
193
246
  it "creates a braintree customer" do
194
247
  FakeBraintree.customers[subject.customer_token].should_not be_nil
195
248
  end
@@ -199,34 +252,23 @@ describe Account, "with a free plan" do
199
252
  FakeBraintree.subscriptions[subject.subscription_token].should be_nil
200
253
  end
201
254
 
202
- it "creates a credit card, and subscription when the plan is changed to a paid plan and the billing info is supplied" do
255
+ it "creates a credit card, subscription, and billing address when the plan is changed to a paid plan and the billing info is supplied" do
203
256
  new_plan = Factory(:paid_plan, :name => "New Plan")
204
- subject.save_customer_and_subscription!(:plan_id => new_plan.id,
205
- :cardholder_name => "Ralph Robot",
206
- :billing_email => "ralph@example.com",
207
- :card_number => "4111111111111111",
208
- :verification_code => "123",
209
- :expiration_month => 5,
210
- :expiration_year => 2012)
257
+ subject.save_customer_and_subscription!(Factory.attributes_for(:paid_account, :plan_id => new_plan.id))
211
258
 
212
259
  FakeBraintree.customers[subject.customer_token]["credit_cards"].first.should_not be_nil
213
260
  FakeBraintree.subscriptions[subject.subscription_token].should_not be_nil
214
261
  FakeBraintree.subscriptions[subject.subscription_token]["plan_id"].should == new_plan.id
215
262
  subject.credit_card.should_not be_nil
216
263
  subject.subscription.should_not be_nil
264
+ subject.billing_address.should_not be_nil
217
265
  end
218
266
 
219
267
  it "passes up the merchant_account_id on the subscription when it's configured" do
220
268
  begin
221
269
  Saucy::Configuration.merchant_account_id = 'test'
222
270
  new_plan = Factory(:paid_plan, :name => "New Plan")
223
- subject.save_customer_and_subscription!(:plan_id => new_plan.id,
224
- :cardholder_name => "Ralph Robot",
225
- :billing_email => "ralph@example.com",
226
- :card_number => "4111111111111111",
227
- :verification_code => "123",
228
- :expiration_month => 5,
229
- :expiration_year => 2012)
271
+ subject.save_customer_and_subscription!(Factory.attributes_for(:paid_account, :plan_id => new_plan.id))
230
272
 
231
273
  FakeBraintree.subscriptions[subject.subscription_token]["merchant_account_id"].should == 'test'
232
274
  ensure
@@ -237,23 +279,18 @@ describe Account, "with a free plan" do
237
279
  it "doesn't pass up the merchant_account_id on the subscription when it's not configured" do
238
280
  Saucy::Configuration.merchant_account_id = nil
239
281
  new_plan = Factory(:paid_plan, :name => "New Plan")
240
- subject.save_customer_and_subscription!(:plan_id => new_plan.id,
241
- :cardholder_name => "Ralph Robot",
242
- :billing_email => "ralph@example.com",
243
- :card_number => "4111111111111111",
244
- :verification_code => "123",
245
- :expiration_month => 5,
246
- :expiration_year => 2012)
282
+ subject.save_customer_and_subscription!(Factory.attributes_for(:paid_account, :plan_id => new_plan.id))
247
283
 
248
284
  FakeBraintree.subscriptions[subject.subscription_token].keys.should_not include("merchant_account_id")
249
285
  end
250
286
 
251
- it "doesn't create a credit card, and subscription when the plan is changed to a different free plan" do
287
+ it "doesn't create a credit card, subscription, and billing address when the plan is changed to a different free plan" do
252
288
  new_plan = Factory(:plan, :name => "New Plan")
253
289
  subject.save_customer_and_subscription!(:plan_id => new_plan.id)
254
290
 
255
291
  subject.credit_card.should be_nil
256
292
  subject.subscription.should be_nil
293
+ subject.billing_address.should be_nil
257
294
  end
258
295
  end
259
296
 
@@ -285,16 +322,12 @@ end
285
322
 
286
323
  describe Account, "with a paid subscription" do
287
324
  subject do
288
- Factory(:account,
289
- :cardholder_name => "Ralph Robot",
290
- :billing_email => "ralph@example.com",
291
- :card_number => "4111111111111111",
292
- :verification_code => "123",
293
- :expiration_month => 5,
294
- :expiration_year => 2012,
325
+ Factory(:paid_account,
295
326
  :plan => Factory(:paid_plan))
296
327
  end
297
328
 
329
+ let(:merchant_time_zone) { ActiveSupport::TimeZone[Saucy::Configuration.merchant_account_time_zone] }
330
+
298
331
  it "gets marked as past due and updates its next_billing_date when subscriptions are updated and it has been rejected by the gateway" do
299
332
  next_billing_date_string = 2.months.from_now.to_s(:braintree_date)
300
333
  subscription = FakeBraintree.subscriptions[subject.subscription_token]
@@ -304,8 +337,7 @@ describe Account, "with a paid subscription" do
304
337
  Timecop.travel(subject.next_billing_date + 1.day) do
305
338
  Account.update_subscriptions!
306
339
  subject.reload.subscription_status.should == Braintree::Subscription::Status::PastDue
307
- subject.next_billing_date.should == Time.parse(next_billing_date_string).in_time_zone(
308
- Saucy::Configuration.merchant_account_time_zone)
340
+ subject.next_billing_date.should == merchant_time_zone.parse(next_billing_date_string)
309
341
  subject.past_due?.should be
310
342
  end
311
343
  end
@@ -326,13 +358,7 @@ describe Account, "with a paid subscription" do
326
358
  end
327
359
 
328
360
  it "delivers the rest of the emails even if one fails" do
329
- Factory(:account,
330
- :cardholder_name => "Ralph Robot",
331
- :billing_email => "ralph@example.com",
332
- :card_number => "4111111111111111",
333
- :verification_code => "123",
334
- :expiration_month => 5,
335
- :expiration_year => 2012,
361
+ Factory(:paid_account,
336
362
  :plan => Factory(:paid_plan))
337
363
  Timecop.travel(subject.next_billing_date + 1.day) do
338
364
  Account.update_subscriptions!
@@ -519,13 +545,7 @@ end
519
545
 
520
546
  describe Account, "with a paid subscription that is past due" do
521
547
  subject do
522
- Factory(:account,
523
- :cardholder_name => "Ralph Robot",
524
- :billing_email => "ralph@example.com",
525
- :card_number => "4111111111111111",
526
- :verification_code => "123",
527
- :expiration_month => 5,
528
- :expiration_year => 2012,
548
+ Factory(:paid_account,
529
549
  :plan => Factory(:paid_plan))
530
550
  end
531
551
 
@@ -622,13 +642,7 @@ end
622
642
 
623
643
  describe Account, "that is activated" do
624
644
  subject do
625
- Factory(:account,
626
- :cardholder_name => "Ralph Robot",
627
- :billing_email => "ralph@example.com",
628
- :card_number => "4111111111111111",
629
- :verification_code => "123",
630
- :expiration_month => 5,
631
- :expiration_year => 2012,
645
+ Factory(:paid_account,
632
646
  :plan => Factory(:paid_plan))
633
647
  end
634
648
 
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saucy
3
3
  version: !ruby/object:Gem::Version
4
- hash: 45
5
4
  prerelease:
6
- segments:
7
- - 0
8
- - 13
9
- - 3
10
- version: 0.13.3
5
+ version: 0.14.0
11
6
  platform: ruby
12
7
  authors:
13
8
  - thoughtbot, inc.
@@ -20,7 +15,7 @@ autorequire:
20
15
  bindir: bin
21
16
  cert_chain: []
22
17
 
23
- date: 2011-10-18 00:00:00 Z
18
+ date: 2011-10-24 00:00:00 Z
24
19
  dependencies:
25
20
  - !ruby/object:Gem::Dependency
26
21
  name: clearance
@@ -30,11 +25,6 @@ dependencies:
30
25
  requirements:
31
26
  - - ~>
32
27
  - !ruby/object:Gem::Version
33
- hash: 55
34
- segments:
35
- - 0
36
- - 11
37
- - 2
38
28
  version: 0.11.2
39
29
  type: :runtime
40
30
  version_requirements: *id001
@@ -46,10 +36,6 @@ dependencies:
46
36
  requirements:
47
37
  - - ">="
48
38
  - !ruby/object:Gem::Version
49
- hash: 11
50
- segments:
51
- - 1
52
- - 2
53
39
  version: "1.2"
54
40
  type: :runtime
55
41
  version_requirements: *id002
@@ -61,11 +47,6 @@ dependencies:
61
47
  requirements:
62
48
  - - ">="
63
49
  - !ruby/object:Gem::Version
64
- hash: 1
65
- segments:
66
- - 3
67
- - 0
68
- - 3
69
50
  version: 3.0.3
70
51
  type: :runtime
71
52
  version_requirements: *id003
@@ -77,11 +58,6 @@ dependencies:
77
58
  requirements:
78
59
  - - ">="
79
60
  - !ruby/object:Gem::Version
80
- hash: 19
81
- segments:
82
- - 2
83
- - 6
84
- - 2
85
61
  version: 2.6.2
86
62
  type: :runtime
87
63
  version_requirements: *id004
@@ -93,11 +69,6 @@ dependencies:
93
69
  requirements:
94
70
  - - "="
95
71
  - !ruby/object:Gem::Version
96
- hash: 29
97
- segments:
98
- - 1
99
- - 3
100
- - 3
101
72
  version: 1.3.3
102
73
  type: :runtime
103
74
  version_requirements: *id005
@@ -109,11 +80,6 @@ dependencies:
109
80
  requirements:
110
81
  - - ">="
111
82
  - !ruby/object:Gem::Version
112
- hash: 23
113
- segments:
114
- - 1
115
- - 1
116
- - 2
117
83
  version: 1.1.2
118
84
  type: :runtime
119
85
  version_requirements: *id006
@@ -125,11 +91,6 @@ dependencies:
125
91
  requirements:
126
92
  - - ~>
127
93
  - !ruby/object:Gem::Version
128
- hash: 15
129
- segments:
130
- - 3
131
- - 0
132
- - 4
133
94
  version: 3.0.4
134
95
  type: :runtime
135
96
  version_requirements: *id007
@@ -141,11 +102,6 @@ dependencies:
141
102
  requirements:
142
103
  - - "="
143
104
  - !ruby/object:Gem::Version
144
- hash: 27
145
- segments:
146
- - 0
147
- - 2
148
- - 6
149
105
  version: 0.2.6
150
106
  type: :development
151
107
  version_requirements: *id008
@@ -238,6 +194,7 @@ files:
238
194
  - lib/generators/saucy/features/templates/factories.rb
239
195
  - lib/generators/saucy/features/templates/step_definitions/account_steps.rb
240
196
  - lib/generators/saucy/features/templates/step_definitions/braintree_steps.rb
197
+ - lib/generators/saucy/features/templates/step_definitions/country_steps.rb
241
198
  - lib/generators/saucy/features/templates/step_definitions/cron_steps.rb
242
199
  - lib/generators/saucy/features/templates/step_definitions/email_steps.rb
243
200
  - lib/generators/saucy/features/templates/step_definitions/factory_girl_steps.rb
@@ -345,23 +302,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
345
302
  requirements:
346
303
  - - ">="
347
304
  - !ruby/object:Gem::Version
348
- hash: 3
349
- segments:
350
- - 0
351
305
  version: "0"
352
306
  required_rubygems_version: !ruby/object:Gem::Requirement
353
307
  none: false
354
308
  requirements:
355
309
  - - ">="
356
310
  - !ruby/object:Gem::Version
357
- hash: 3
358
- segments:
359
- - 0
360
311
  version: "0"
361
312
  requirements: []
362
313
 
363
314
  rubyforge_project:
364
- rubygems_version: 1.8.11
315
+ rubygems_version: 1.8.10
365
316
  signing_key:
366
317
  specification_version: 3
367
318
  summary: Clearance-based Rails engine for SaaS