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
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe MembershipsController, "routes" do
|
|
4
|
+
it { should route(:get, "/accounts/abc/memberships").
|
|
5
|
+
to(:action => :index, :account_id => 'abc') }
|
|
6
|
+
it { should route(:get, "/accounts/xyz/memberships/abc/edit").
|
|
7
|
+
to(:action => :edit, :account_id => 'xyz', :id => 'abc') }
|
|
8
|
+
it { should route(:put, "/accounts/xyz/memberships/abc").
|
|
9
|
+
to(:action => :update, :account_id => 'xyz', :id => 'abc') }
|
|
10
|
+
it { should route(:delete, "/accounts/xyz/memberships/abc").
|
|
11
|
+
to(:action => :destroy, :account_id => 'xyz', :id => 'abc') }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe MembershipsController, "permissions", :as => :account_member do
|
|
15
|
+
let(:membership) { Factory(:membership, :account => account) }
|
|
16
|
+
it { should deny_access.
|
|
17
|
+
on(:get, :index, :account_id => account.to_param).
|
|
18
|
+
flash(/admin/) }
|
|
19
|
+
it { should deny_access.
|
|
20
|
+
on(:get, :edit, :id => membership.to_param,
|
|
21
|
+
:account_id => account.to_param).
|
|
22
|
+
flash(/admin/) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe MembershipsController, "index", :as => :account_admin do
|
|
26
|
+
let(:memberships) { [Factory.stub(:membership), Factory.stub(:membership)] }
|
|
27
|
+
|
|
28
|
+
before do
|
|
29
|
+
Account.stubs(:find_by_keyword! => account)
|
|
30
|
+
account.stubs(:memberships_by_name => memberships)
|
|
31
|
+
get :index, :account_id => account.to_param
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "renders the index template" do
|
|
35
|
+
should respond_with(:success)
|
|
36
|
+
should render_template(:index)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "assigns memberships by name" do
|
|
40
|
+
account.should have_received(:memberships_by_name)
|
|
41
|
+
should assign_to(:memberships).with(memberships)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe MembershipsController, "edit", :as => :account_admin do
|
|
46
|
+
let(:edited_membership) { Factory.stub(:membership, :account => account) }
|
|
47
|
+
let(:projects) { [Factory.stub(:project)] }
|
|
48
|
+
|
|
49
|
+
before do
|
|
50
|
+
Membership.stubs(:find => edited_membership)
|
|
51
|
+
account.stubs(:projects_by_name => projects)
|
|
52
|
+
get :edit, :id => edited_membership.to_param, :account_id => account.to_param
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "renders the edit template" do
|
|
56
|
+
should respond_with(:success)
|
|
57
|
+
should render_template(:edit)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "assigns projects by name" do
|
|
61
|
+
account.should have_received(:projects_by_name)
|
|
62
|
+
should assign_to(:projects).with(projects)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "assigns the membership being edited" do
|
|
66
|
+
Membership.should have_received(:find).with(edited_membership.to_param,
|
|
67
|
+
:include => :account)
|
|
68
|
+
should assign_to(:membership).with(edited_membership)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe MembershipsController, "update", :as => :account_admin do
|
|
73
|
+
let(:edited_membership) { Factory.stub(:membership, :account => account) }
|
|
74
|
+
let(:attributes) { 'some attributes' }
|
|
75
|
+
|
|
76
|
+
before do
|
|
77
|
+
Membership.stubs(:find => edited_membership)
|
|
78
|
+
edited_membership.stubs(:update_attributes!)
|
|
79
|
+
put :update, :id => edited_membership.to_param,
|
|
80
|
+
:account_id => account.to_param,
|
|
81
|
+
:membership => attributes
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "redirects to the account memberships index" do
|
|
85
|
+
should redirect_to(account_memberships_url(account))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "update the membership" do
|
|
89
|
+
edited_membership.should have_received(:update_attributes!).with(attributes)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "sets a flash message" do
|
|
93
|
+
should set_the_flash.to(/update/i)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe MembershipsController, "destroy", :as => :account_admin do
|
|
98
|
+
let(:removed_membership) { Factory.stub(:membership, :account => account) }
|
|
99
|
+
|
|
100
|
+
before do
|
|
101
|
+
Membership.stubs(:find => removed_membership)
|
|
102
|
+
removed_membership.stubs(:destroy)
|
|
103
|
+
delete :destroy, :id => removed_membership.to_param, :account_id => account.to_param
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "redirects to the account memberships index" do
|
|
107
|
+
should redirect_to(account_memberships_url(account))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "removes the membership" do
|
|
111
|
+
removed_membership.should have_received(:destroy)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "sets a flash message" do
|
|
115
|
+
should set_the_flash.to(/remove/i)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe PlansController, "successful update", :as => :account_admin do
|
|
4
|
+
before do
|
|
5
|
+
Account.stubs(:find_by_keyword! => account)
|
|
6
|
+
account.stubs(:save_customer_and_subscription! => true)
|
|
7
|
+
put :update, :account_id => account.to_param
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "notifies observers" do
|
|
11
|
+
should notify_observers("plan_upgraded", :account => account, :request => request)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ProfilesController, "routes" do
|
|
4
|
+
it { should route(:get, "/profile/edit").to(:action => :edit) }
|
|
5
|
+
it { should route(:put, "/profile").to(:action => :update) }
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
describe ProfilesController, "signed out" do
|
|
9
|
+
it { should deny_access.on(:get, :edit) }
|
|
10
|
+
it { should deny_access.on(:put, :update) }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe ProfilesController, "edit", :as => :user do
|
|
14
|
+
before { get :edit }
|
|
15
|
+
it { should respond_with(:success) }
|
|
16
|
+
it { should assign_to(:user).with(user) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe ProfilesController, "valid update", :as => :user do
|
|
20
|
+
let(:attributes) { 'attributes' }
|
|
21
|
+
|
|
22
|
+
before do
|
|
23
|
+
user.stubs(:update_attributes => true)
|
|
24
|
+
put :update, :user => attributes
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it { should set_the_flash.to(/has been updated/) }
|
|
28
|
+
|
|
29
|
+
it "redirects to the user" do
|
|
30
|
+
should redirect_to(edit_profile_url)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "updates the user" do
|
|
34
|
+
user.should have_received(:update_attributes).with(attributes)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe ProfilesController, "invalid update", :as => :user do
|
|
39
|
+
before do
|
|
40
|
+
user.stubs(:update_attributes => false)
|
|
41
|
+
get :update, :user => { :email => "" }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it { should_not set_the_flash }
|
|
45
|
+
it { should render_template(:edit) }
|
|
46
|
+
it { should assign_to(:user).with(user) }
|
|
47
|
+
end
|
|
48
|
+
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ProjectsController, "routes" do
|
|
4
|
+
it { should route(:get, "/accounts/abc/projects/new").
|
|
5
|
+
to(:action => :new, :account_id => 'abc') }
|
|
6
|
+
it { should route(:post, "/accounts/abc/projects").
|
|
7
|
+
to(:action => :create, :account_id => 'abc') }
|
|
8
|
+
it { should route(:get, "/accounts/abc/projects/def/edit").
|
|
9
|
+
to(:action => :edit, :account_id => 'abc', :id => 'def') }
|
|
10
|
+
it { should route(:put, "/accounts/abc/projects/def").
|
|
11
|
+
to(:action => :update, :account_id => 'abc', :id => 'def') }
|
|
12
|
+
it { should route(:delete, "/accounts/abc/projects/def").
|
|
13
|
+
to(:action => :destroy, :account_id => 'abc', :id => 'def') }
|
|
14
|
+
it { should route(:get, "/accounts/abc/projects").
|
|
15
|
+
to(:action => :index, :account_id => 'abc') }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe ProjectsController, "new", :as => :account_admin do
|
|
19
|
+
before do
|
|
20
|
+
get :new, :account_id => account.to_param
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it { should respond_with(:success) }
|
|
24
|
+
it { should render_template(:new) }
|
|
25
|
+
it { should_not set_the_flash }
|
|
26
|
+
it { should assign_to( :project) }
|
|
27
|
+
|
|
28
|
+
it "has a new project that belongs to account" do
|
|
29
|
+
assigns(:project).account.should == account
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe ProjectsController, "#show as another user" do
|
|
34
|
+
let(:account) { Factory(:account) }
|
|
35
|
+
let(:user) { Factory(:user) }
|
|
36
|
+
let(:project) { Factory(:project, :account => account) }
|
|
37
|
+
before do
|
|
38
|
+
sign_in_as(user)
|
|
39
|
+
get :show, :account_id => account.to_param, :id => project.to_param
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it { should respond_with(:redirect) }
|
|
43
|
+
it { should set_the_flash.to(/do not have permission/) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe ProjectsController, "create", :as => :account_admin do
|
|
47
|
+
before do
|
|
48
|
+
@project_count = Project.count
|
|
49
|
+
post :create,
|
|
50
|
+
:project => Factory.attributes_for(:project),
|
|
51
|
+
:account_id => account.to_param
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should change Project count by 1" do
|
|
55
|
+
Project.count.should == @project_count + 1
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should place the new project into the account" do
|
|
59
|
+
Project.last.account.should == account
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should redirect to the edit page" do
|
|
63
|
+
should redirect_to(controller.project_url(assigns(:project)))
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe ProjectsController, "edit", :as => :project_admin do
|
|
68
|
+
before do
|
|
69
|
+
get :edit, :id => project.to_param, :account_id => account.to_param
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it { should respond_with(:success) }
|
|
73
|
+
it { should render_template(:edit) }
|
|
74
|
+
it { should_not set_the_flash }
|
|
75
|
+
it { should assign_to(:project) }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe ProjectsController, "update", :as => :project_admin do
|
|
79
|
+
before do
|
|
80
|
+
put :update, :project => Factory.attributes_for(:project),
|
|
81
|
+
:id => project.to_param,
|
|
82
|
+
:account_id => account.to_param
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should redirect to account_projects_url" do
|
|
86
|
+
should redirect_to(account_projects_url(account))
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe ProjectsController, "update with account that you don't have access to", :as => :project_admin do
|
|
91
|
+
before do
|
|
92
|
+
put :update, :project => Factory.attributes_for(:project, :account_id => Factory(:account).id),
|
|
93
|
+
:id => project.to_param,
|
|
94
|
+
:account_id => account.to_param
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should show an error" do
|
|
98
|
+
should set_the_flash.to(/permission/i)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "should redirect to account_projects_url" do
|
|
102
|
+
should redirect_to(account_projects_url(account))
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
describe ProjectsController, "create with account that you don't have access to", :as => :account_admin do
|
|
107
|
+
before do
|
|
108
|
+
post :create,
|
|
109
|
+
:project => Factory.attributes_for(:project, :account_id => Factory(:account).id),
|
|
110
|
+
:account_id => account.to_param
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "should show an error" do
|
|
114
|
+
should set_the_flash.to(/permission/i)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "should redirect to account_projects_url" do
|
|
118
|
+
should redirect_to(account_projects_url(account))
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
describe ProjectsController, "edit with account that you don't have access to", :as => :project_admin do
|
|
123
|
+
before do
|
|
124
|
+
get :edit, :id => project.to_param, :account_id => account.to_param, :project => { :account_id => Factory(:account).id }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "should show an error" do
|
|
128
|
+
should set_the_flash.to(/permission/i)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "should redirect to account_projects_url" do
|
|
132
|
+
should redirect_to(account_projects_url(account))
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
describe ProjectsController, "edit with account that you have access to", :as => :project_admin do
|
|
137
|
+
before do
|
|
138
|
+
@other_account = Factory(:account)
|
|
139
|
+
Factory(:membership, :user => current_user, :account => @other_account, :admin => true)
|
|
140
|
+
get :edit, :id => project.to_param, :account_id => account.to_param, :project => { :account_id => @other_account.id }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it { should assign_to(:project) }
|
|
144
|
+
|
|
145
|
+
it "sets the new account on the project" do
|
|
146
|
+
assigns(:project).account.should == @other_account
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
describe ProjectsController, "destroy", :as => :project_admin do
|
|
151
|
+
before do
|
|
152
|
+
delete :destroy, :id => project.to_param, :account_id => account.to_param
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it { should set_the_flash.to(/deleted/) }
|
|
156
|
+
it { should assign_to(:project) }
|
|
157
|
+
|
|
158
|
+
it "should redirect to account_projects_url" do
|
|
159
|
+
should redirect_to(account_projects_url(account))
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
describe ProjectsController, "index", :as => :account_admin do
|
|
164
|
+
let(:projects) { ['one', 'two'] }
|
|
165
|
+
|
|
166
|
+
before do
|
|
167
|
+
projects.stubs(:archived => projects, :active => projects)
|
|
168
|
+
Account.stubs(:find_by_keyword! => account)
|
|
169
|
+
account.stubs(:projects => projects)
|
|
170
|
+
get :index, :account_id => account.to_param
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it "renders the index template" do
|
|
174
|
+
should respond_with(:success)
|
|
175
|
+
should render_template(:index)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "assigns projects" do
|
|
179
|
+
account.should have_received(:projects).times(2)
|
|
180
|
+
should assign_to(:active_projects).with(projects)
|
|
181
|
+
should assign_to(:archived_projects).with(projects)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
describe ProjectsController, "as a non-admin", :as => :project_member do
|
|
186
|
+
it { should deny_access.on(:get, :edit, :id => project.to_param,
|
|
187
|
+
:account_id => account.to_param).
|
|
188
|
+
flash(/admin/) }
|
|
189
|
+
|
|
190
|
+
it { should deny_access.on(:put, :update, :id => project.to_param,
|
|
191
|
+
:account_id => account.to_param).
|
|
192
|
+
flash(/admin/) }
|
|
193
|
+
|
|
194
|
+
it { should deny_access.on(:delete, :destroy, :id => project.to_param,
|
|
195
|
+
:account_id => account.to_param).
|
|
196
|
+
flash(/admin/) }
|
|
197
|
+
|
|
198
|
+
it { should deny_access.on(:get, :new, :account_id => account.to_param).flash(/admin/) }
|
|
199
|
+
|
|
200
|
+
it { should deny_access.on(:post, :create, :account_id => account.to_param).
|
|
201
|
+
flash(/admin/) }
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
describe ProjectsController, "show for a duplicate project keyword", :as => :project_admin do
|
|
205
|
+
before do
|
|
206
|
+
Factory(:project, :keyword => "test")
|
|
207
|
+
|
|
208
|
+
account = Factory(:account)
|
|
209
|
+
project = Factory(:project, :account => account, :keyword => "test")
|
|
210
|
+
sign_in_as_non_admin_of_project(project)
|
|
211
|
+
get :show, :id => "test", :account_id => account.to_param
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it { should respond_with(:success) }
|
|
215
|
+
it { should_not set_the_flash }
|
|
216
|
+
end
|
data/spec/environment.rb
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
PROJECT_ROOT = File.expand_path("../..", __FILE__)
|
|
2
|
+
$LOAD_PATH << File.join(PROJECT_ROOT, "lib")
|
|
3
|
+
|
|
4
|
+
require 'rails/all'
|
|
5
|
+
require 'saucy'
|
|
6
|
+
require 'clearance'
|
|
7
|
+
require 'factory_girl'
|
|
8
|
+
require 'bourne'
|
|
9
|
+
|
|
10
|
+
FileUtils.rm_f(File.join(PROJECT_ROOT, 'tmp', 'test.sqlite3'))
|
|
11
|
+
|
|
12
|
+
class ApplicationController < ActionController::Base
|
|
13
|
+
include Clearance::Authentication
|
|
14
|
+
include Saucy::AccountAuthorization
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class ProjectsController < ApplicationController
|
|
18
|
+
include Saucy::ProjectsController
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class User < ActiveRecord::Base
|
|
22
|
+
include Clearance::User
|
|
23
|
+
include Saucy::User
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class Plan < ActiveRecord::Base
|
|
27
|
+
include Saucy::Plan
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module Testapp
|
|
31
|
+
class Application < Rails::Application
|
|
32
|
+
config.action_mailer.default_url_options = { :host => 'localhost' }
|
|
33
|
+
config.encoding = "utf-8"
|
|
34
|
+
config.paths.config.database = "spec/scaffold/config/database.yml"
|
|
35
|
+
config.paths.app.models << "lib/generators/saucy/install/templates/models"
|
|
36
|
+
config.paths.config.routes << "spec/scaffold/config/routes.rb"
|
|
37
|
+
config.paths.app.views << "spec/scaffold/views"
|
|
38
|
+
config.paths.log = "tmp/log"
|
|
39
|
+
config.cache_classes = true
|
|
40
|
+
config.whiny_nils = true
|
|
41
|
+
config.consider_all_requests_local = true
|
|
42
|
+
config.action_controller.perform_caching = false
|
|
43
|
+
config.action_dispatch.show_exceptions = false
|
|
44
|
+
config.action_controller.allow_forgery_protection = false
|
|
45
|
+
config.action_mailer.delivery_method = :test
|
|
46
|
+
config.active_support.deprecation = :stderr
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Testapp::Application.initialize!
|
|
51
|
+
|
|
52
|
+
require "lib/generators/saucy/features/templates/factories"
|
|
53
|
+
require "lib/generators/saucy/install/templates/create_saucy_tables"
|
|
54
|
+
|
|
55
|
+
class ClearanceCreateUsers < ActiveRecord::Migration
|
|
56
|
+
def self.up
|
|
57
|
+
create_table(:users) do |t|
|
|
58
|
+
t.string :email
|
|
59
|
+
t.string :encrypted_password, :limit => 128
|
|
60
|
+
t.string :salt, :limit => 128
|
|
61
|
+
t.string :confirmation_token, :limit => 128
|
|
62
|
+
t.string :remember_token, :limit => 128
|
|
63
|
+
t.boolean :email_confirmed, :default => false, :null => false
|
|
64
|
+
t.timestamps
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
add_index :users, :email
|
|
68
|
+
add_index :users, :remember_token
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class ClearanceMailer
|
|
73
|
+
def self.change_password(user)
|
|
74
|
+
new
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.confirmation(user)
|
|
78
|
+
new
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.deliver_change_password(user)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def self.deliver_confirmation(user)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def deliver
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
Clearance.configure do |config|
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
ClearanceCreateUsers.suppress_messages { ClearanceCreateUsers.migrate(:up) }
|
|
95
|
+
CreateSaucyTables.suppress_messages { CreateSaucyTables.migrate(:up) }
|