saasy 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.
- data/CHANGELOG.md +114 -0
- data/Gemfile +26 -0
- data/README.md +118 -0
- data/Rakefile +38 -0
- data/app/controllers/accounts_controller.rb +68 -0
- data/app/controllers/billings_controller.rb +25 -0
- data/app/controllers/invitations_controller.rb +65 -0
- data/app/controllers/memberships_controller.rb +45 -0
- data/app/controllers/plans_controller.rb +24 -0
- data/app/controllers/profiles_controller.rb +19 -0
- data/app/helpers/limits_helper.rb +13 -0
- data/app/mailers/billing_mailer.rb +53 -0
- data/app/mailers/invitation_mailer.rb +18 -0
- data/app/models/invitation.rb +113 -0
- data/app/models/limit.rb +49 -0
- data/app/models/membership.rb +26 -0
- data/app/models/permission.rb +19 -0
- data/app/models/signup.rb +163 -0
- data/app/views/accounts/_account.html.erb +9 -0
- data/app/views/accounts/_blank_slate.html.erb +6 -0
- data/app/views/accounts/_projects.html.erb +12 -0
- data/app/views/accounts/_subnav.html.erb +10 -0
- data/app/views/accounts/edit.html.erb +34 -0
- data/app/views/accounts/index.html.erb +9 -0
- data/app/views/accounts/new.html.erb +36 -0
- data/app/views/billing_mailer/completed_trial.text.erb +13 -0
- data/app/views/billing_mailer/expiring_trial.text.erb +15 -0
- data/app/views/billing_mailer/new_unactivated.text.erb +1 -0
- data/app/views/billing_mailer/problem.html.erb +13 -0
- data/app/views/billing_mailer/problem.text.erb +14 -0
- data/app/views/billing_mailer/receipt.html.erb +41 -0
- data/app/views/billing_mailer/receipt.text.erb +25 -0
- data/app/views/billings/_form.html.erb +8 -0
- data/app/views/billings/edit.html.erb +13 -0
- data/app/views/billings/show.html.erb +29 -0
- data/app/views/invitation_mailer/invitation.text.erb +6 -0
- data/app/views/invitations/new.html.erb +17 -0
- data/app/views/invitations/show.html.erb +22 -0
- data/app/views/layouts/saucy.html.erb +36 -0
- data/app/views/limits/_meter.html.erb +13 -0
- data/app/views/memberships/edit.html.erb +21 -0
- data/app/views/memberships/index.html.erb +17 -0
- data/app/views/plans/_plan.html.erb +32 -0
- data/app/views/plans/_terms.html.erb +15 -0
- data/app/views/plans/edit.html.erb +33 -0
- data/app/views/plans/index.html.erb +12 -0
- data/app/views/profiles/_inputs.html.erb +5 -0
- data/app/views/profiles/edit.html.erb +36 -0
- data/app/views/projects/_form.html.erb +36 -0
- data/app/views/projects/edit.html.erb +22 -0
- data/app/views/projects/index.html.erb +28 -0
- data/app/views/projects/new.html.erb +13 -0
- data/app/views/projects/show.html.erb +0 -0
- data/app/views/shared/_project_dropdown.html.erb +55 -0
- data/app/views/shared/_saucy_javascript.html.erb +33 -0
- data/config/locales/en.yml +37 -0
- data/config/routes.rb +19 -0
- data/features/run_features.feature +83 -0
- data/features/step_definitions/clearance_steps.rb +45 -0
- data/features/step_definitions/rails_steps.rb +73 -0
- data/features/step_definitions/saucy_steps.rb +8 -0
- data/features/support/env.rb +4 -0
- data/features/support/file.rb +11 -0
- data/lib/generators/saucy/base.rb +18 -0
- data/lib/generators/saucy/features/features_generator.rb +91 -0
- data/lib/generators/saucy/features/templates/README +3 -0
- data/lib/generators/saucy/features/templates/factories.rb +71 -0
- data/lib/generators/saucy/features/templates/features/edit_profile.feature +9 -0
- data/lib/generators/saucy/features/templates/features/edit_project_permissions.feature +37 -0
- data/lib/generators/saucy/features/templates/features/edit_user_permissions.feature +47 -0
- data/lib/generators/saucy/features/templates/features/manage_account.feature +35 -0
- data/lib/generators/saucy/features/templates/features/manage_billing.feature +93 -0
- data/lib/generators/saucy/features/templates/features/manage_plan.feature +143 -0
- data/lib/generators/saucy/features/templates/features/manage_projects.feature +139 -0
- data/lib/generators/saucy/features/templates/features/manage_users.feature +142 -0
- data/lib/generators/saucy/features/templates/features/new_account.feature +33 -0
- data/lib/generators/saucy/features/templates/features/project_dropdown.feature +77 -0
- data/lib/generators/saucy/features/templates/features/sign_up.feature +32 -0
- data/lib/generators/saucy/features/templates/features/sign_up_paid.feature +65 -0
- data/lib/generators/saucy/features/templates/features/trial_plans.feature +82 -0
- data/lib/generators/saucy/features/templates/step_definitions/account_steps.rb +30 -0
- data/lib/generators/saucy/features/templates/step_definitions/braintree_steps.rb +25 -0
- data/lib/generators/saucy/features/templates/step_definitions/cron_steps.rb +23 -0
- data/lib/generators/saucy/features/templates/step_definitions/email_steps.rb +40 -0
- data/lib/generators/saucy/features/templates/step_definitions/factory_girl_steps.rb +1 -0
- data/lib/generators/saucy/features/templates/step_definitions/html_steps.rb +51 -0
- data/lib/generators/saucy/features/templates/step_definitions/plan_steps.rb +16 -0
- data/lib/generators/saucy/features/templates/step_definitions/project_steps.rb +4 -0
- data/lib/generators/saucy/features/templates/step_definitions/session_steps.rb +37 -0
- data/lib/generators/saucy/features/templates/step_definitions/user_steps.rb +100 -0
- data/lib/generators/saucy/features/templates/support/braintree.rb +5 -0
- data/lib/generators/saucy/install/install_generator.rb +40 -0
- data/lib/generators/saucy/install/templates/controllers/projects_controller.rb +3 -0
- data/lib/generators/saucy/install/templates/create_saucy_tables.rb +115 -0
- data/lib/generators/saucy/install/templates/models/account.rb +3 -0
- data/lib/generators/saucy/install/templates/models/plan.rb +3 -0
- data/lib/generators/saucy/install/templates/models/project.rb +3 -0
- data/lib/generators/saucy/specs/specs_generator.rb +20 -0
- data/lib/generators/saucy/specs/templates/support/braintree.rb +5 -0
- data/lib/generators/saucy/views/views_generator.rb +23 -0
- data/lib/saucy.rb +10 -0
- data/lib/saucy/account.rb +132 -0
- data/lib/saucy/account_authorization.rb +67 -0
- data/lib/saucy/configuration.rb +29 -0
- data/lib/saucy/engine.rb +35 -0
- data/lib/saucy/fake_braintree.rb +134 -0
- data/lib/saucy/layouts.rb +36 -0
- data/lib/saucy/plan.rb +54 -0
- data/lib/saucy/project.rb +125 -0
- data/lib/saucy/projects_controller.rb +94 -0
- data/lib/saucy/railties/tasks.rake +28 -0
- data/lib/saucy/routing_extensions.rb +121 -0
- data/lib/saucy/subscription.rb +237 -0
- data/lib/saucy/user.rb +30 -0
- data/spec/controllers/accounts_controller_spec.rb +228 -0
- data/spec/controllers/application_controller_spec.rb +32 -0
- data/spec/controllers/invitations_controller_spec.rb +215 -0
- data/spec/controllers/memberships_controller_spec.rb +117 -0
- data/spec/controllers/plans_controller_spec.rb +13 -0
- data/spec/controllers/profiles_controller_spec.rb +48 -0
- data/spec/controllers/projects_controller_spec.rb +216 -0
- data/spec/environment.rb +95 -0
- data/spec/layouts_spec.rb +21 -0
- data/spec/mailers/billing_mailer_spec.rb +68 -0
- data/spec/mailers/invitiation_mailer_spec.rb +19 -0
- data/spec/models/account_spec.rb +218 -0
- data/spec/models/invitation_spec.rb +320 -0
- data/spec/models/limit_spec.rb +70 -0
- data/spec/models/membership_spec.rb +37 -0
- data/spec/models/permission_spec.rb +30 -0
- data/spec/models/plan_spec.rb +81 -0
- data/spec/models/project_spec.rb +223 -0
- data/spec/models/signup_spec.rb +177 -0
- data/spec/models/subscription_spec.rb +481 -0
- data/spec/models/user_spec.rb +72 -0
- data/spec/route_extensions_spec.rb +51 -0
- data/spec/saucy_spec.rb +62 -0
- data/spec/scaffold/config/routes.rb +5 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/support/authentication_helpers.rb +81 -0
- data/spec/support/authorization_helpers.rb +56 -0
- data/spec/support/braintree.rb +7 -0
- data/spec/support/clearance_matchers.rb +55 -0
- data/spec/support/notifications.rb +57 -0
- data/spec/views/accounts/_account.html.erb_spec.rb +37 -0
- metadata +325 -0
data/lib/saucy/user.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Saucy
|
|
2
|
+
module User
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
attr_accessible :name, :project_ids, :email, :password
|
|
7
|
+
has_many :memberships
|
|
8
|
+
has_many :accounts, :through => :memberships
|
|
9
|
+
has_many :permissions
|
|
10
|
+
has_many :projects, :through => :permissions
|
|
11
|
+
validates_presence_of :name
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module InstanceMethods
|
|
15
|
+
def admin_of?(account)
|
|
16
|
+
memberships.exists?(:account_id => account.id, :admin => true)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def member_of?(account_or_project)
|
|
20
|
+
account_or_project.has_member?(self)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module ClassMethods
|
|
25
|
+
def by_name
|
|
26
|
+
order('users.name')
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe AccountsController, "routes" do
|
|
4
|
+
it { should route(:get, "/plans/abc/accounts/new").
|
|
5
|
+
to(:action => :new, :plan_id => :abc) }
|
|
6
|
+
it { should route(:get, "/accounts").to(:action => :index) }
|
|
7
|
+
it { should route(:post, "/plans/abc/accounts").
|
|
8
|
+
to(:action => :create, :plan_id => :abc) }
|
|
9
|
+
it { should route(:put, "/accounts/1").to(:action => :update, :id => 1) }
|
|
10
|
+
it { should route(:get, "/accounts/1/edit").to(:action => :edit, :id => 1) }
|
|
11
|
+
it { should route(:delete, "/accounts/1").to(:action => :destroy, :id => 1) }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe AccountsController, "new" do
|
|
15
|
+
let(:signup) { stub('signup') }
|
|
16
|
+
let(:plan) { Factory(:plan) }
|
|
17
|
+
|
|
18
|
+
before do
|
|
19
|
+
Signup.stubs(:new => signup)
|
|
20
|
+
get :new, :plan_id => plan.to_param
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "renders the new account form" do
|
|
24
|
+
should respond_with(:success)
|
|
25
|
+
should render_template(:new)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "assigns a new signup" do
|
|
29
|
+
Signup.should have_received(:new)
|
|
30
|
+
should assign_to(:signup).with(signup)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "notifies observers" do
|
|
34
|
+
should notify_observers("plan_viewed", :plan => plan, :request => request)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe AccountsController, "successful create for a confirmed user" do
|
|
39
|
+
let(:user) { Factory.stub(:user) }
|
|
40
|
+
let(:account) { Factory.stub(:account) }
|
|
41
|
+
let(:signup) { stub('signup', :user => user,
|
|
42
|
+
:user= => nil,
|
|
43
|
+
:plan= => plan,
|
|
44
|
+
:account => account) }
|
|
45
|
+
let(:signup_attributes) { "attributes" }
|
|
46
|
+
let(:plan) { Factory(:plan) }
|
|
47
|
+
|
|
48
|
+
before do
|
|
49
|
+
Signup.stubs(:new => signup)
|
|
50
|
+
signup.stubs(:save => true)
|
|
51
|
+
sign_in_as user
|
|
52
|
+
post :create, :signup => signup_attributes, :plan_id => plan.to_param
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "creates an signup" do
|
|
56
|
+
Signup.should have_received(:new).with(signup_attributes)
|
|
57
|
+
signup.should have_received(:save)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "redirects to the root" do
|
|
61
|
+
should redirect_to(new_account_project_url(signup.account))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "sets the current user" do
|
|
65
|
+
signup.should have_received(:user=).with(user)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it { should set_the_flash.to(/created/i) }
|
|
69
|
+
it { should_not set_the_flash.to(/confirm/i) }
|
|
70
|
+
it { should be_signed_in.as(user) }
|
|
71
|
+
|
|
72
|
+
it "notifies observers" do
|
|
73
|
+
should notify_observers("account_created", :account => signup.account,
|
|
74
|
+
:request => request)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe AccountsController, "failed create" do
|
|
79
|
+
let(:signup) { stub('signup', :user= => nil, :plan= => plan) }
|
|
80
|
+
let(:signup_attributes) { "attributes" }
|
|
81
|
+
let(:plan) { Factory(:plan) }
|
|
82
|
+
|
|
83
|
+
before do
|
|
84
|
+
Signup.stubs(:new => signup)
|
|
85
|
+
signup.stubs(:save => false)
|
|
86
|
+
post :create, :signup => signup_attributes, :plan_id => plan.to_param
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "creates an signup" do
|
|
90
|
+
Signup.should have_received(:new).with(signup_attributes)
|
|
91
|
+
signup.should have_received(:save)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "renders the new signup form" do
|
|
95
|
+
should respond_with(:success)
|
|
96
|
+
should render_template(:new)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "assigns a new signup" do
|
|
100
|
+
Signup.should have_received(:new)
|
|
101
|
+
should assign_to(:signup).with(signup)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
describe AccountsController, "index with multiple projects" do
|
|
106
|
+
let(:user) { Factory.stub(:user) }
|
|
107
|
+
let(:accounts) { %w(one two) }
|
|
108
|
+
let(:projects) { %w(one two) }
|
|
109
|
+
|
|
110
|
+
before do
|
|
111
|
+
user.stubs(:accounts => accounts)
|
|
112
|
+
user.stubs(:projects => projects)
|
|
113
|
+
sign_in_as user
|
|
114
|
+
get :index
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "renders the dashboard page" do
|
|
118
|
+
should respond_with(:success)
|
|
119
|
+
should render_template(:index)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "assigns the user's accounts" do
|
|
123
|
+
user.should have_received(:accounts)
|
|
124
|
+
should assign_to(:accounts).with(accounts)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
describe AccountsController, "signed out" do
|
|
129
|
+
it "redirects to sign_in on index" do
|
|
130
|
+
get :index
|
|
131
|
+
should redirect_to(sign_in_path)
|
|
132
|
+
end
|
|
133
|
+
it "redirects to sign_in on edit" do
|
|
134
|
+
get :edit, :id => 1
|
|
135
|
+
should redirect_to(sign_in_path)
|
|
136
|
+
end
|
|
137
|
+
it "redirects to sign_in on update" do
|
|
138
|
+
put :update, :id => 1, :account => {}
|
|
139
|
+
should redirect_to(sign_in_path)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
describe AccountsController, "index with one project" do
|
|
144
|
+
let(:user) { Factory.stub(:user) }
|
|
145
|
+
let(:accounts) { %w(one two) }
|
|
146
|
+
let(:projects) { [Factory.stub(:project)] }
|
|
147
|
+
|
|
148
|
+
before do
|
|
149
|
+
user.stubs(:accounts => accounts)
|
|
150
|
+
user.stubs(:projects => projects)
|
|
151
|
+
sign_in_as user
|
|
152
|
+
get :index
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "redirects to the project" do
|
|
156
|
+
should redirect_to(controller.project_url(projects.first))
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
describe AccountsController, "valid update", :as => :account_admin do
|
|
161
|
+
before do
|
|
162
|
+
put :update,
|
|
163
|
+
:account => Factory.attributes_for(:account),
|
|
164
|
+
:id => account.to_param
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "redirects to settings" do
|
|
168
|
+
should redirect_to(edit_profile_url)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it { should set_the_flash.to(/updated/) }
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
describe AccountsController, "invalid update", :as => :account_admin do
|
|
175
|
+
before do
|
|
176
|
+
put :update,
|
|
177
|
+
:account => {:name => ""},
|
|
178
|
+
:id => account.to_param
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it { should respond_with(:success) }
|
|
182
|
+
it { should render_template(:edit) }
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
describe AccountsController, "edit", :as => :account_admin do
|
|
186
|
+
before do
|
|
187
|
+
get :edit, :id => account.to_param
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "renders the edit template" do
|
|
191
|
+
should respond_with(:success)
|
|
192
|
+
should render_template(:edit)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "assigns the account" do
|
|
196
|
+
should assign_to(:account).with(account)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
describe AccountsController, "destroy", :as => :account_admin do
|
|
201
|
+
before do
|
|
202
|
+
Account.stubs(:find_by_keyword! => account)
|
|
203
|
+
account.stubs(:destroy)
|
|
204
|
+
delete :destroy, :id => account.to_param
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it "redirects to the root url" do
|
|
208
|
+
should redirect_to("/")
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "sets the flash" do
|
|
212
|
+
should set_the_flash.to(/deleted/i)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
it "deletes the account" do
|
|
216
|
+
account.should have_received(:destroy)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
describe AccountsController, "permissions", :as => :account_member do
|
|
221
|
+
it { should deny_access.
|
|
222
|
+
on(:get, :edit, :id => account.to_param).
|
|
223
|
+
flash(/admin/) }
|
|
224
|
+
it { should deny_access.
|
|
225
|
+
on(:put, :update, :id => account.to_param).
|
|
226
|
+
flash(/admin/) }
|
|
227
|
+
end
|
|
228
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ApplicationController do
|
|
4
|
+
|
|
5
|
+
describe "with a valid account id in the params" do
|
|
6
|
+
before do
|
|
7
|
+
@account = Factory(:account)
|
|
8
|
+
@controller.stubs(:params).returns(:account_id => @account.to_param)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should return the corresponding account from current_account" do
|
|
12
|
+
@controller.__send__(:current_account).should == @account
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "with an invalid account id in the params" do
|
|
17
|
+
before do
|
|
18
|
+
@controller.stubs(:params).returns(:account_id => "invalid")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should return the corresponding account from current_account" do
|
|
22
|
+
expect { @controller.__send__(:current_account) }.
|
|
23
|
+
to raise_error(ActiveRecord::RecordNotFound)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it { should filter_param(:card_number) }
|
|
28
|
+
it { should filter_param(:cardholder_name) }
|
|
29
|
+
it { should filter_param(:verification_code) }
|
|
30
|
+
it { should filter_param(:expiration_month) }
|
|
31
|
+
it { should filter_param(:expiration_year) }
|
|
32
|
+
end
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe InvitationsController, "routes" do
|
|
4
|
+
it { should route(:get, "/accounts/abc/invitations/new").
|
|
5
|
+
to(:action => :new, :account_id => 'abc') }
|
|
6
|
+
it { should route(:post, "/accounts/abc/invitations").
|
|
7
|
+
to(:action => :create, :account_id => 'abc') }
|
|
8
|
+
it { should route(:get, "/accounts/abc/invitations/xyz").
|
|
9
|
+
to(:action => :show, :account_id => 'abc', :id => 'xyz') }
|
|
10
|
+
it { should route(:put, "/accounts/abc/invitations/xyz").
|
|
11
|
+
to(:action => :update, :account_id => 'abc', :id => 'xyz') }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe InvitationsController, "permissions" do
|
|
15
|
+
let(:account) { Factory(:account) }
|
|
16
|
+
before { sign_in }
|
|
17
|
+
it { should deny_access.
|
|
18
|
+
on(:get, :new, :account_id => account.to_param).
|
|
19
|
+
flash(/admin/) }
|
|
20
|
+
it { should deny_access.
|
|
21
|
+
on(:post, :create, :account_id => account.to_param).
|
|
22
|
+
flash(/admin/) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe InvitationsController, "new", :as => :account_admin do
|
|
26
|
+
let(:invitation) { Invitation.new }
|
|
27
|
+
let(:projects) { ['one', 'two'] }
|
|
28
|
+
|
|
29
|
+
before do
|
|
30
|
+
Account.stubs(:find_by_keyword! => account)
|
|
31
|
+
account.stubs(:projects_by_name => projects)
|
|
32
|
+
Invitation.stubs(:new => invitation)
|
|
33
|
+
get :new, :account_id => account.to_param
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "renders the new template" do
|
|
37
|
+
should respond_with(:success)
|
|
38
|
+
should render_template(:new)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "assigns an invitation" do
|
|
42
|
+
Invitation.should have_received(:new)
|
|
43
|
+
should assign_to(:invitation).with(invitation)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "assigns projects" do
|
|
47
|
+
should assign_to(:projects).with(projects)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe InvitationsController, "valid create", :as => :account_admin do
|
|
52
|
+
let(:invitation) { Factory.stub(:invitation) }
|
|
53
|
+
let(:attributes) { 'attributes' }
|
|
54
|
+
|
|
55
|
+
before do
|
|
56
|
+
Invitation.stubs(:new => invitation)
|
|
57
|
+
invitation.stubs(:account=)
|
|
58
|
+
invitation.stubs(:sender=)
|
|
59
|
+
invitation.stubs(:save => true)
|
|
60
|
+
post :create, :account_id => account.to_param, :invitation => attributes
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "redirects to the membership index" do
|
|
64
|
+
should redirect_to(account_memberships_url(account))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "saves an invitation" do
|
|
68
|
+
Invitation.should have_received(:new).with(attributes)
|
|
69
|
+
invitation.should have_received(:account=).with(account)
|
|
70
|
+
invitation.should have_received(:sender=).with(current_user)
|
|
71
|
+
invitation.should have_received(:save)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "sets a flash message" do
|
|
75
|
+
should set_the_flash.to(/invited/i)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe InvitationsController, "invalid create", :as => :account_admin do
|
|
80
|
+
let(:invitation) { Factory.stub(:invitation) }
|
|
81
|
+
let(:projects) { ['one', 'two'] }
|
|
82
|
+
|
|
83
|
+
before do
|
|
84
|
+
Invitation.stubs(:new => invitation)
|
|
85
|
+
invitation.stubs(:save => false)
|
|
86
|
+
Account.stubs(:find_by_keyword! => account)
|
|
87
|
+
account.stubs(:projects_by_name => projects)
|
|
88
|
+
post :create, :account_id => account.to_param, :invitation => {}
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "renders the new template" do
|
|
92
|
+
should respond_with(:success)
|
|
93
|
+
should render_template(:new)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "doesn't set a flash message" do
|
|
97
|
+
should_not set_the_flash
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "assigns projects" do
|
|
101
|
+
should assign_to(:projects).with(projects)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
describe InvitationsController, "show" do
|
|
106
|
+
let(:invitation) { Factory.stub(:invitation, :code => 'abc') }
|
|
107
|
+
let(:account) { invitation.account }
|
|
108
|
+
|
|
109
|
+
before do
|
|
110
|
+
Invitation.stubs(:find_by_code! => invitation)
|
|
111
|
+
get :show, :id => invitation.to_param, :account_id => account.to_param
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "renders the show template" do
|
|
115
|
+
should respond_with(:success)
|
|
116
|
+
should render_template(:show)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "assigns the invitation" do
|
|
120
|
+
Invitation.should have_received(:find_by_code!).with(invitation.to_param)
|
|
121
|
+
should assign_to(:invitation).with(invitation)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
describe InvitationsController, "show for a used invitation" do
|
|
126
|
+
let(:invitation) { Factory.stub(:invitation, :code => 'abc', :used => true) }
|
|
127
|
+
let(:account) { invitation.account }
|
|
128
|
+
|
|
129
|
+
before do
|
|
130
|
+
Invitation.stubs(:find_by_code! => invitation)
|
|
131
|
+
get :show, :id => invitation.to_param, :account_id => account.to_param
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "redirects to the root url" do
|
|
135
|
+
should redirect_to("/")
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "sets a flash message" do
|
|
139
|
+
should set_the_flash.to(/used/i)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
describe InvitationsController, "valid update" do
|
|
144
|
+
let(:invitation) { Factory.stub(:invitation, :code => 'abc') }
|
|
145
|
+
let(:account) { invitation.account }
|
|
146
|
+
let(:attributes) { 'attributes' }
|
|
147
|
+
let(:user) { Factory.stub(:user) }
|
|
148
|
+
|
|
149
|
+
before do
|
|
150
|
+
Invitation.stubs(:find_by_code! => invitation)
|
|
151
|
+
invitation.stubs(:accept => true)
|
|
152
|
+
invitation.stubs(:user => user)
|
|
153
|
+
put :update, :id => invitation.to_param,
|
|
154
|
+
:account_id => account.to_param,
|
|
155
|
+
:invitation => attributes
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "signs the user in" do
|
|
159
|
+
should be_signed_in.as(user)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "accepts the invitation" do
|
|
163
|
+
Invitation.should have_received(:find_by_code!).with(invitation.to_param)
|
|
164
|
+
invitation.should have_received(:accept).with(attributes)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "redirects to the root page" do
|
|
168
|
+
should redirect_to(root_url)
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
describe InvitationsController, "invalid update" do
|
|
173
|
+
let(:invitation) { Factory.stub(:invitation, :code => 'abc') }
|
|
174
|
+
let(:account) { invitation.account }
|
|
175
|
+
|
|
176
|
+
before do
|
|
177
|
+
Invitation.stubs(:find_by_code! => invitation)
|
|
178
|
+
invitation.stubs(:accept => false)
|
|
179
|
+
put :update, :id => invitation.to_param,
|
|
180
|
+
:account_id => account.to_param,
|
|
181
|
+
:invitation => {}
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "doesn't sign in" do
|
|
185
|
+
should_not be_signed_in
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it "renders the show template" do
|
|
189
|
+
should respond_with(:success)
|
|
190
|
+
should render_template(:show)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "assigns the invitation" do
|
|
194
|
+
should assign_to(:invitation).with(invitation)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
describe InvitationsController, "update for a used invitation" do
|
|
199
|
+
let(:invitation) { Factory.stub(:invitation, :code => 'abc', :used => true) }
|
|
200
|
+
let(:account) { invitation.account }
|
|
201
|
+
|
|
202
|
+
before do
|
|
203
|
+
Invitation.stubs(:find_by_code! => invitation)
|
|
204
|
+
put :update, :id => invitation.to_param, :account_id => account.to_param
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it "redirects to the root url" do
|
|
208
|
+
should redirect_to("/")
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "sets a flash message" do
|
|
212
|
+
should set_the_flash.to(/used/i)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|