saucy 0.2.21 → 0.2.24

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.
@@ -1,20 +1,30 @@
1
1
  <p class="name"><%= plan.name %></p>
2
- <p class="price"><% if plan.billed? %>$<%= plan.price %>/month<% else %>Free<% end %></p>
3
- <ul class="features">
4
- <% plan.limits.numbered.each do |limit| %>
5
- <%= content_tag_for :li, limit, :class => limit.name do %>
6
- <%= pluralize(limit.value, limit.name.singularize) %>
7
- <% end %>
8
- <% end %>
9
- <% plan.limits.boolean.each do |limit| %>
10
- <% if limit.allowed? -%>
11
- <%= content_tag_for :li, limit, :class => limit.name do %>
12
- <%= limit.name %>
13
- <% end %>
14
- <% end -%>
2
+ <p class="price">
3
+ <% if plan.billed? %>
4
+ $<%= plan.price %>/month
5
+ <% else %>
6
+ Free
15
7
  <% end %>
8
+ <% if plan.trial? %>
9
+ Trial
10
+ <% end -%>
11
+ </p>
12
+ <ul class="features">
16
13
  <% if plan.trial? -%>
17
14
  <li class="trial"><%= t(".trial_will_expire",
18
15
  :default => "Your trial will expire after 30 days.") %></li>
16
+ <% else -%>
17
+ <% plan.limits.numbered.each do |limit| %>
18
+ <%= content_tag_for :li, limit, :class => limit.name do %>
19
+ <%= pluralize(limit.value, limit.name.singularize) %>
20
+ <% end %>
21
+ <% end %>
22
+ <% plan.limits.boolean.each do |limit| %>
23
+ <% if limit.allowed? -%>
24
+ <%= content_tag_for :li, limit, :class => limit.name do %>
25
+ <%= limit.name %>
26
+ <% end %>
27
+ <% end -%>
28
+ <% end %>
19
29
  <% end -%>
20
30
  </ul>
@@ -8,6 +8,9 @@
8
8
  <%= content_tag_for :li, plan, :class => "#{plan.name.parameterize} #{'disabled' if !@account.can_change_plan_to?(plan)}" do %>
9
9
  <%= form.label :plan_id, render(plan), :value => plan.id %>
10
10
  <%= form.radio_button :plan_id, plan.id, :disabled => !@account.can_change_plan_to?(plan), "data-free" => plan.free? %>
11
+ <% if !@account.can_change_plan_to?(plan) -%>
12
+ <p class="disabled"><%= t(".plan-disabled", :default => "Too big for %{name}.", :name => plan.name) %></p>
13
+ <% end -%>
11
14
  <% end %>
12
15
  <% end -%>
13
16
  <% end %>
@@ -116,6 +116,7 @@ Feature: Manage Plan
116
116
  And I follow "Upgrade"
117
117
  Then I should see "Upgrade Your Plan"
118
118
  And the "Free" plan should be disabled
119
+ And I should see "Too big for Free."
119
120
  And I should see "1 user" within ".basic"
120
121
  And I should see "0 users" within ".free"
121
122
  And I should see "1 project" within ".free"
@@ -3,14 +3,21 @@ Feature: Trial plans
3
3
  Background:
4
4
  Given the following plan exists:
5
5
  | name | price | trial |
6
- | Trial | 0 | true |
6
+ | Temp | 0 | true |
7
7
  | Eternal | 0 | false |
8
+ And the following limits exist:
9
+ | plan | name | value | value_type |
10
+ | name: Temp | users | 2 | number |
11
+ | name: Eternal | users | 2 | number |
8
12
 
9
13
  Scenario: Sign up for a trial plan
10
14
  When I go to the list of plans page
11
- And I follow "Trial"
15
+ And I follow "Temp"
16
+ Then I should see "Free"
17
+ And I should see "Trial"
12
18
  And I should see "Your trial will expire after 30 days"
13
- And I fill in "Email" with "email@person.com"
19
+ But I should not see "users"
20
+ When I fill in "Email" with "email@person.com"
14
21
  And I fill in "Password" with "password"
15
22
  And I fill in "Confirm password" with "password"
16
23
  And I fill in "Your name" with "Robot"
@@ -20,24 +27,26 @@ Feature: Trial plans
20
27
  Then I should see "created"
21
28
 
22
29
  Scenario: use an account during the trial
23
- Given a "Trial" account exists with a name of "Test" created 29 days ago
30
+ Given a "Temp" account exists with a name of "Test" created 29 days ago
24
31
  And I am signed in as an admin of the "Test" account
25
32
  When I go to the projects page for the "Test" account
26
33
  Then I should see "Test"
27
34
  And I should not see "expired"
28
35
 
29
36
  Scenario: Try to use an expired trial plan
30
- Given a "Trial" account exists with a name of "Test" created 30 days ago
37
+ Given a "Temp" account exists with a name of "Test" created 30 days ago
31
38
  And I am signed in as an admin of the "Test" account
32
39
  When I go to the projects page for the "Test" account
33
40
  Then I should be on the upgrade plan page for the "Test" account
34
41
  And I should see "expired"
35
- And the "Trial" plan should be disabled
42
+ And the "Temp" plan should be disabled
36
43
 
37
44
  Scenario: Sign up for a non-trial plan
38
45
  When I go to the list of plans page
39
46
  And I follow "Eternal"
40
- Then I should not see "trial"
47
+ Then I should see "users"
48
+ But I should not see "Trial"
49
+ And I should not see "expire"
41
50
 
42
51
  Scenario: Use a non-trial plan forever
43
52
  Given an "Eternal" account exists with a name of "Test" created 30 days ago
@@ -17,6 +17,9 @@ module Saucy
17
17
 
18
18
  attr_accessor *CUSTOMER_ATTRIBUTES.keys
19
19
 
20
+ CUSTOMER_ATTRIBUTES.keys.each do |attribute|
21
+ validates_presence_of attribute, :if => :switching_to_billed?
22
+ end
20
23
  before_create :create_customer
21
24
  before_create :create_subscription, :if => :billed?
22
25
  after_destroy :destroy_customer
@@ -104,16 +107,18 @@ module Saucy
104
107
 
105
108
  def update_customer(attributes)
106
109
  set_customer_attributes(attributes)
107
- result = Braintree::Customer.update(customer_token, customer_attributes)
108
- handle_customer_result(result)
109
- result.success?
110
+ if valid?
111
+ result = Braintree::Customer.update(customer_token, customer_attributes)
112
+ handle_customer_result(result)
113
+ result.success?
114
+ end
110
115
  end
111
116
 
112
117
  def save_subscription
113
- if subscription
118
+ if subscription
114
119
  Braintree::Subscription.update(subscription_token, :plan_id => plan_id)
115
120
  elsif plan.billed?
116
- create_subscription
121
+ valid? && create_subscription
117
122
  end
118
123
  end
119
124
 
@@ -200,6 +205,10 @@ module Saucy
200
205
  false
201
206
  end
202
207
  end
208
+
209
+ def switching_to_billed?
210
+ plan_id && plan.billed? && subscription_token.blank?
211
+ end
203
212
  end
204
213
 
205
214
  module ClassMethods
@@ -9,6 +9,7 @@ describe Account do
9
9
  :cardholder_name => "Ralph Robot",
10
10
  :billing_email => "ralph@example.com",
11
11
  :card_number => "4111111111111112",
12
+ :verification_code => "100",
12
13
  :expiration_month => 5,
13
14
  :expiration_year => 2012,
14
15
  :plan => Factory(:paid_plan))
@@ -51,6 +52,44 @@ describe Account do
51
52
  end
52
53
  end
53
54
 
55
+ describe Account, "given free and paid plans" do
56
+ let(:free) { Factory(:plan, :price => 0) }
57
+ let(:paid) { Factory(:plan, :price => 1) }
58
+
59
+ it "doesn't switch from free to paid without credit card info" do
60
+ account = Factory(:account, :plan => free)
61
+ account = Account.find(account.id)
62
+
63
+ result = account.save_customer_and_subscription!(:plan_id => paid.id)
64
+
65
+ result.should be_false
66
+ account.reload.plan.should == free
67
+ Saucy::Subscription::CUSTOMER_ATTRIBUTES.keys.each do |attribute|
68
+ account.errors[attribute].should_not be_blank
69
+ end
70
+ FakeBraintree.customers[account.customer_token].should_not be_nil
71
+ FakeBraintree.customers[account.customer_token]["credit_cards"].should be_blank
72
+ end
73
+
74
+ it "requires a billing email when upgrading to a paid plan" do
75
+ account = Factory(:account, :plan => free, :card_number => '123')
76
+ account.reload
77
+ account.plan = paid
78
+
79
+ account.should validate_presence_of(:billing_email)
80
+ end
81
+
82
+ it "requires a billing email for paid plans" do
83
+ account = Factory.build(:account, :plan => paid, :card_number => '123')
84
+ account.should validate_presence_of(:billing_email)
85
+ end
86
+
87
+ it "doesn't require a billing email for free plans" do
88
+ account = Factory.build(:account, :plan => free)
89
+ account.should_not validate_presence_of(:billing_email)
90
+ end
91
+ end
92
+
54
93
  describe Account, "with a paid plan" do
55
94
  subject do
56
95
  Factory(:account,
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saucy
3
3
  version: !ruby/object:Gem::Version
4
- hash: 61
4
+ hash: 39
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 21
10
- version: 0.2.21
9
+ - 24
10
+ version: 0.2.24
11
11
  platform: ruby
12
12
  authors:
13
13
  - thoughtbot, inc.
@@ -17,14 +17,13 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2011-02-14 00:00:00 -05:00
20
+ date: 2011-02-15 00:00:00 -05:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
24
- type: :runtime
25
- prerelease: false
26
24
  name: formtastic
27
- version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
28
27
  none: false
29
28
  requirements:
30
29
  - - ">="
@@ -34,12 +33,12 @@ dependencies:
34
33
  - 1
35
34
  - 2
36
35
  version: "1.2"
37
- requirement: *id001
38
- - !ruby/object:Gem::Dependency
39
36
  type: :runtime
40
- prerelease: false
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
41
39
  name: railties
42
- version_requirements: &id002 !ruby/object:Gem::Requirement
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
43
42
  none: false
44
43
  requirements:
45
44
  - - ">="
@@ -50,12 +49,12 @@ dependencies:
50
49
  - 0
51
50
  - 3
52
51
  version: 3.0.3
53
- requirement: *id002
54
- - !ruby/object:Gem::Dependency
55
52
  type: :runtime
56
- prerelease: false
53
+ version_requirements: *id002
54
+ - !ruby/object:Gem::Dependency
57
55
  name: braintree
58
- version_requirements: &id003 !ruby/object:Gem::Requirement
56
+ prerelease: false
57
+ requirement: &id003 !ruby/object:Gem::Requirement
59
58
  none: false
60
59
  requirements:
61
60
  - - ">="
@@ -66,12 +65,12 @@ dependencies:
66
65
  - 6
67
66
  - 2
68
67
  version: 2.6.2
69
- requirement: *id003
70
- - !ruby/object:Gem::Dependency
71
68
  type: :runtime
72
- prerelease: false
69
+ version_requirements: *id003
70
+ - !ruby/object:Gem::Dependency
73
71
  name: sham_rack
74
- version_requirements: &id004 !ruby/object:Gem::Requirement
72
+ prerelease: false
73
+ requirement: &id004 !ruby/object:Gem::Requirement
75
74
  none: false
76
75
  requirements:
77
76
  - - "="
@@ -82,12 +81,12 @@ dependencies:
82
81
  - 3
83
82
  - 3
84
83
  version: 1.3.3
85
- requirement: *id004
86
- - !ruby/object:Gem::Dependency
87
84
  type: :runtime
88
- prerelease: false
85
+ version_requirements: *id004
86
+ - !ruby/object:Gem::Dependency
89
87
  name: sinatra
90
- version_requirements: &id005 !ruby/object:Gem::Requirement
88
+ prerelease: false
89
+ requirement: &id005 !ruby/object:Gem::Requirement
91
90
  none: false
92
91
  requirements:
93
92
  - - "="
@@ -98,12 +97,12 @@ dependencies:
98
97
  - 1
99
98
  - 2
100
99
  version: 1.1.2
101
- requirement: *id005
100
+ type: :runtime
101
+ version_requirements: *id005
102
102
  - !ruby/object:Gem::Dependency
103
- type: :development
104
- prerelease: false
105
103
  name: aruba
106
- version_requirements: &id006 !ruby/object:Gem::Requirement
104
+ prerelease: false
105
+ requirement: &id006 !ruby/object:Gem::Requirement
107
106
  none: false
108
107
  requirements:
109
108
  - - "="
@@ -114,7 +113,8 @@ dependencies:
114
113
  - 2
115
114
  - 6
116
115
  version: 0.2.6
117
- requirement: *id006
116
+ type: :development
117
+ version_requirements: *id006
118
118
  description: Clearance-based Rails engine for Software as a Service (Saas) that provides account and project management
119
119
  email: support@thoughtbot.com
120
120
  executables: []