saucy 0.1.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.
Files changed (86) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +106 -0
  3. data/README +9 -0
  4. data/app/controllers/accounts_controller.rb +57 -0
  5. data/app/controllers/invitations_controller.rb +36 -0
  6. data/app/controllers/memberships_controller.rb +9 -0
  7. data/app/controllers/permissions_controller.rb +17 -0
  8. data/app/controllers/plans_controller.rb +7 -0
  9. data/app/controllers/profiles_controller.rb +17 -0
  10. data/app/controllers/projects_controller.rb +56 -0
  11. data/app/models/account_membership.rb +8 -0
  12. data/app/models/invitation.rb +86 -0
  13. data/app/models/project_membership.rb +16 -0
  14. data/app/models/signup.rb +134 -0
  15. data/app/views/accounts/_account.html.erb +12 -0
  16. data/app/views/accounts/_blank_slate.html.erb +6 -0
  17. data/app/views/accounts/_projects.html.erb +12 -0
  18. data/app/views/accounts/_tab_bar.html.erb +8 -0
  19. data/app/views/accounts/edit.html.erb +17 -0
  20. data/app/views/accounts/index.html.erb +3 -0
  21. data/app/views/accounts/new.html.erb +26 -0
  22. data/app/views/invitation_mailer/invitation.text.erb +6 -0
  23. data/app/views/invitations/new.html.erb +11 -0
  24. data/app/views/invitations/show.html.erb +20 -0
  25. data/app/views/memberships/index.html.erb +16 -0
  26. data/app/views/permissions/edit.html.erb +15 -0
  27. data/app/views/plans/index.html.erb +3 -0
  28. data/app/views/profiles/_inputs.html.erb +6 -0
  29. data/app/views/profiles/edit.html.erb +35 -0
  30. data/app/views/projects/_form.html.erb +4 -0
  31. data/app/views/projects/edit.html.erb +18 -0
  32. data/app/views/projects/index.html.erb +13 -0
  33. data/app/views/projects/new.html.erb +11 -0
  34. data/config/routes.rb +18 -0
  35. data/features/run_features.feature +73 -0
  36. data/features/step_definitions/clearance_steps.rb +45 -0
  37. data/features/step_definitions/rails_steps.rb +70 -0
  38. data/features/support/env.rb +4 -0
  39. data/features/support/file.rb +11 -0
  40. data/lib/generators/saucy/base.rb +18 -0
  41. data/lib/generators/saucy/features/features_generator.rb +68 -0
  42. data/lib/generators/saucy/features/templates/factories.rb +55 -0
  43. data/lib/generators/saucy/features/templates/step_definitions/email_steps.rb +13 -0
  44. data/lib/generators/saucy/features/templates/step_definitions/factory_girl_steps.rb +1 -0
  45. data/lib/generators/saucy/features/templates/step_definitions/html_steps.rb +3 -0
  46. data/lib/generators/saucy/features/templates/step_definitions/project_steps.rb +4 -0
  47. data/lib/generators/saucy/features/templates/step_definitions/session_steps.rb +27 -0
  48. data/lib/generators/saucy/features/templates/step_definitions/user_steps.rb +54 -0
  49. data/lib/generators/saucy/install/install_generator.rb +36 -0
  50. data/lib/generators/saucy/install/templates/create_saucy_tables.rb +72 -0
  51. data/lib/generators/saucy/install/templates/models/account.rb +3 -0
  52. data/lib/generators/saucy/install/templates/models/invitation_mailer.rb +9 -0
  53. data/lib/generators/saucy/install/templates/models/plan.rb +3 -0
  54. data/lib/generators/saucy/install/templates/models/project.rb +3 -0
  55. data/lib/generators/saucy/views/views_generator.rb +23 -0
  56. data/lib/saucy.rb +7 -0
  57. data/lib/saucy/account.rb +50 -0
  58. data/lib/saucy/account_authorization.rb +34 -0
  59. data/lib/saucy/configuration.rb +12 -0
  60. data/lib/saucy/engine.rb +9 -0
  61. data/lib/saucy/layouts.rb +36 -0
  62. data/lib/saucy/plan.rb +11 -0
  63. data/lib/saucy/project.rb +39 -0
  64. data/lib/saucy/user.rb +37 -0
  65. data/spec/controllers/accounts_controller_spec.rb +204 -0
  66. data/spec/controllers/application_controller_spec.rb +27 -0
  67. data/spec/controllers/invitations_controller_spec.rb +155 -0
  68. data/spec/controllers/memberships_controller_spec.rb +33 -0
  69. data/spec/controllers/permissions_controller_spec.rb +69 -0
  70. data/spec/controllers/profiles_controller_spec.rb +43 -0
  71. data/spec/controllers/projects_controller_spec.rb +123 -0
  72. data/spec/layouts_spec.rb +21 -0
  73. data/spec/models/account_membership_spec.rb +13 -0
  74. data/spec/models/account_spec.rb +61 -0
  75. data/spec/models/invitation_spec.rb +160 -0
  76. data/spec/models/project_membership_spec.rb +26 -0
  77. data/spec/models/project_spec.rb +80 -0
  78. data/spec/models/signup_spec.rb +175 -0
  79. data/spec/models/user_spec.rb +96 -0
  80. data/spec/saucy_spec.rb +7 -0
  81. data/spec/spec_helper.rb +31 -0
  82. data/spec/support/authentication_helpers.rb +71 -0
  83. data/spec/support/authorization_helpers.rb +56 -0
  84. data/spec/support/clearance_matchers.rb +55 -0
  85. data/spec/views/accounts/_account.html.erb_spec.rb +66 -0
  86. metadata +203 -0
@@ -0,0 +1,27 @@
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.url)
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
+ end
@@ -0,0 +1,155 @@
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, "/invitations/xyz").
9
+ to(:action => :show, :id => 'xyz') }
10
+ it { should route(:put, "/invitations/xyz").
11
+ to(:action => :update, :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
+
28
+ before do
29
+ Invitation.stubs(:new => invitation)
30
+ get :new, :account_id => account.to_param
31
+ end
32
+
33
+ it "renders the new template" do
34
+ should respond_with(:success)
35
+ should render_template(:new)
36
+ end
37
+
38
+ it "assigns an invitation" do
39
+ Invitation.should have_received(:new)
40
+ should assign_to(:invitation).with(invitation)
41
+ end
42
+ end
43
+
44
+ describe InvitationsController, "valid create", :as => :account_admin do
45
+ let(:invitation) { Factory.stub(:invitation) }
46
+ let(:attributes) { 'attributes' }
47
+
48
+ before do
49
+ Invitation.stubs(:new => invitation)
50
+ invitation.stubs(:account=)
51
+ invitation.stubs(:save => true)
52
+ post :create, :account_id => account.to_param, :invitation => attributes
53
+ end
54
+
55
+ it "redirects to the membership index" do
56
+ should redirect_to(account_memberships_url(account))
57
+ end
58
+
59
+ it "saves an invitation" do
60
+ Invitation.should have_received(:new).with(attributes)
61
+ invitation.should have_received(:account=).with(account)
62
+ invitation.should have_received(:save)
63
+ end
64
+
65
+ it "sets a flash message" do
66
+ should set_the_flash.to(/invited/i)
67
+ end
68
+ end
69
+
70
+ describe InvitationsController, "invalid create", :as => :account_admin do
71
+ let(:invitation) { Factory.stub(:invitation) }
72
+
73
+ before do
74
+ Invitation.stubs(:new => invitation)
75
+ invitation.stubs(:save => false)
76
+ post :create, :account_id => account.to_param, :invitation => {}
77
+ end
78
+
79
+ it "renders the new template" do
80
+ should respond_with(:success)
81
+ should render_template(:new)
82
+ end
83
+
84
+ it "doesn't set a flash message" do
85
+ should_not set_the_flash
86
+ end
87
+ end
88
+
89
+ describe InvitationsController, "show" do
90
+ let(:invitation) { Factory.stub(:invitation) }
91
+
92
+ before do
93
+ Invitation.stubs(:find => invitation)
94
+ get :show, :id => invitation.to_param
95
+ end
96
+
97
+ it "renders the show template" do
98
+ should respond_with(:success)
99
+ should render_template(:show)
100
+ end
101
+
102
+ it "assigns the invitation" do
103
+ Invitation.should have_received(:find).with(invitation.to_param)
104
+ should assign_to(:invitation).with(invitation)
105
+ end
106
+ end
107
+
108
+ describe InvitationsController, "valid update" do
109
+ let(:invitation) { Factory.stub(:invitation) }
110
+ let(:attributes) { 'attributes' }
111
+ let(:user) { Factory.stub(:user) }
112
+
113
+ before do
114
+ Invitation.stubs(:find => invitation)
115
+ invitation.stubs(:accept => true)
116
+ invitation.stubs(:user => user)
117
+ put :update, :id => invitation.to_param, :invitation => attributes
118
+ end
119
+
120
+ it "signs the user in" do
121
+ should be_signed_in.as(user)
122
+ end
123
+
124
+ it "accepts the invitation" do
125
+ Invitation.should have_received(:find).with(invitation.to_param)
126
+ invitation.should have_received(:accept).with(attributes)
127
+ end
128
+
129
+ it "redirects to the root page" do
130
+ should redirect_to(root_url)
131
+ end
132
+ end
133
+
134
+ describe InvitationsController, "invalid update" do
135
+ let(:invitation) { Factory.stub(:invitation) }
136
+
137
+ before do
138
+ Invitation.stubs(:find => invitation)
139
+ invitation.stubs(:accept => false)
140
+ put :update, :id => invitation.to_param, :invitation => {}
141
+ end
142
+
143
+ it "doesn't sign in" do
144
+ should_not be_signed_in
145
+ end
146
+
147
+ it "renders the show template" do
148
+ should respond_with(:success)
149
+ should render_template(:show)
150
+ end
151
+
152
+ it "assigns the invitation" do
153
+ should assign_to(:invitation).with(invitation)
154
+ end
155
+ end
@@ -0,0 +1,33 @@
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
+ end
7
+
8
+ describe MembershipsController, "permissions", :as => :account_member do
9
+ it { should deny_access.
10
+ on(:get, :index, :account_id => account.to_param).
11
+ flash(/admin/) }
12
+ end
13
+
14
+ describe MembershipsController, "index", :as => :account_admin do
15
+ let(:users) { [Factory.stub(:user), Factory.stub(:user)] }
16
+
17
+ before do
18
+ Account.stubs(:find_by_url! => account)
19
+ account.stubs(:users_by_name => users)
20
+ get :index, :account_id => account.to_param
21
+ end
22
+
23
+ it "renders the index template" do
24
+ should respond_with(:success)
25
+ should render_template(:index)
26
+ end
27
+
28
+ it "assigns users by name" do
29
+ account.should have_received(:users_by_name)
30
+ should assign_to(:users).with(users)
31
+ end
32
+ end
33
+
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe PermissionsController, "routes" do
4
+ it { should route(:get, "/accounts/abc/users/def/permissions/edit").
5
+ to(:action => :edit, :account_id => 'abc', :user_id => 'def') }
6
+ it { should route(:put, "/accounts/abc/users/def/permissions").
7
+ to(:action => :update, :account_id => 'abc', :user_id => 'def') }
8
+ end
9
+
10
+ describe PermissionsController, "permissions", :as => :account_member do
11
+ let(:user) { Factory.stub(:user) }
12
+ it { should deny_access.
13
+ on(:get, :edit, :account_id => account.to_param,
14
+ :user_id => user.to_param).
15
+ flash(/admin/) }
16
+ end
17
+
18
+ describe PermissionsController, "edit", :as => :account_admin do
19
+ let(:edited_user) { Factory.stub(:user) }
20
+ let(:projects) { [Factory.stub(:project)] }
21
+
22
+ before do
23
+ Account.stubs(:find_by_url! => account)
24
+ User.stubs(:find => edited_user)
25
+ account.stubs(:projects_by_name => projects)
26
+ get :edit, :account_id => account.to_param, :user_id => edited_user.to_param
27
+ end
28
+
29
+ it "renders the edit template" do
30
+ should respond_with(:success)
31
+ should render_template(:edit)
32
+ end
33
+
34
+ it "assigns projects by name" do
35
+ account.should have_received(:projects_by_name)
36
+ should assign_to(:projects).with(projects)
37
+ end
38
+
39
+ it "assigns the user being edited" do
40
+ should assign_to(:user).with(edited_user)
41
+ end
42
+ end
43
+
44
+ describe PermissionsController, "update", :as => :account_admin do
45
+ let(:edited_user) { Factory.stub(:user) }
46
+ let(:project_ids) { [1, 2, 3] }
47
+
48
+ before do
49
+ Account.stubs(:find_by_url! => account)
50
+ User.stubs(:find => edited_user)
51
+ edited_user.stubs(:update_permissions_for)
52
+ put :update, :account_id => account.to_param,
53
+ :user_id => edited_user.to_param,
54
+ :permissions => { :project_ids => project_ids }
55
+ end
56
+
57
+ it "redirects to the memberships index" do
58
+ should redirect_to(account_memberships_url(account))
59
+ end
60
+
61
+ it "update permissions" do
62
+ edited_user.should have_received(:update_permissions_for).with(account, project_ids)
63
+ end
64
+
65
+ it "sets a flash message" do
66
+ should set_the_flash.to(/update/i)
67
+ end
68
+ end
69
+
@@ -0,0 +1,43 @@
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, "edit", :as => :user do
9
+ before { get :edit }
10
+ it { should respond_with(:success) }
11
+ it { should assign_to(:user).with(user) }
12
+ end
13
+
14
+ describe ProfilesController, "valid update", :as => :user do
15
+ let(:attributes) { 'attributes' }
16
+
17
+ before do
18
+ user.stubs(:update_attributes => true)
19
+ put :update, :user => attributes
20
+ end
21
+
22
+ it { should set_the_flash.to(/has been updated/) }
23
+
24
+ it "redirects to the user" do
25
+ should redirect_to(edit_profile_url)
26
+ end
27
+
28
+ it "updates the user" do
29
+ user.should have_received(:update_attributes).with(attributes)
30
+ end
31
+ end
32
+
33
+ describe ProfilesController, "invalid update", :as => :user do
34
+ before do
35
+ user.stubs(:update_attributes => false)
36
+ get :update, :user => { :email => "" }
37
+ end
38
+
39
+ it { should_not set_the_flash }
40
+ it { should render_template(:edit) }
41
+ it { should assign_to(:user).with(user) }
42
+ end
43
+
@@ -0,0 +1,123 @@
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, "/projects/def/edit").
9
+ to(:action => :edit, :id => 'def') }
10
+ it { should route(:put, "/projects/def").
11
+ to(:action => :update, :id => 'def') }
12
+ it { should route(:delete, "/projects/def").
13
+ to(:action => :destroy, :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, "create", :as => :account_admin do
34
+ before do
35
+ @project_count = Project.count
36
+ post :create,
37
+ :project => Factory.attributes_for(:project),
38
+ :account_id => account.to_param
39
+ end
40
+
41
+ it "should change Project count by 1" do
42
+ Project.count.should == @project_count + 1
43
+ end
44
+
45
+ it "should place the new project into the account" do
46
+ Project.last.account.should == account
47
+ end
48
+
49
+ it "should redirect to the edit page" do
50
+ should redirect_to(edit_project_url(assigns(:project)))
51
+ end
52
+ end
53
+
54
+ describe ProjectsController, "edit", :as => :project_admin do
55
+ before do
56
+ get :edit, :id => project.to_param
57
+ end
58
+
59
+ it { should respond_with(:success) }
60
+ it { should render_template(:edit) }
61
+ it { should_not set_the_flash }
62
+ it { should assign_to(:project) }
63
+ end
64
+
65
+ describe ProjectsController, "update", :as => :project_admin do
66
+ before do
67
+ put :update, :project => Factory.attributes_for(:project), :id => project.to_param
68
+ end
69
+
70
+ it "should redirect to account_projects_url" do
71
+ should redirect_to(account_projects_url(account))
72
+ end
73
+ end
74
+
75
+ describe ProjectsController, "destroy", :as => :project_admin do
76
+ before do
77
+ delete :destroy, :id => project.to_param
78
+ end
79
+
80
+ it { should set_the_flash.to(/deleted/) }
81
+ it { should assign_to( :project) }
82
+
83
+ it "should redirect to account_projects_url" do
84
+ should redirect_to(account_projects_url(account))
85
+ end
86
+ end
87
+
88
+ describe ProjectsController, "index", :as => :account_admin do
89
+ let(:projects) { ['one', 'two'] }
90
+
91
+ before do
92
+ Account.stubs(:find_by_url! => account)
93
+ account.stubs(:projects => projects)
94
+ get :index, :account_id => account.to_param
95
+ end
96
+
97
+ it "renders the index template" do
98
+ should respond_with(:success)
99
+ should render_template(:index)
100
+ end
101
+
102
+ it "assigns projects" do
103
+ account.should have_received(:projects)
104
+ should assign_to(:projects).with(projects)
105
+ end
106
+ end
107
+
108
+ describe ProjectsController, "as a non-admin", :as => :project_member do
109
+ it { should deny_access.on(:get, :edit, :id => project.to_param).
110
+ flash(/admin/) }
111
+
112
+ it { should deny_access.on(:put, :update, :id => project.to_param).
113
+ flash(/admin/) }
114
+
115
+ it { should deny_access.on(:delete, :destroy, :id => project.to_param).
116
+ flash(/admin/) }
117
+
118
+ it { should deny_access.on(:get, :new, :account_id => account.to_param).flash(/admin/) }
119
+
120
+ it { should deny_access.on(:post, :create, :account_id => account.to_param).
121
+ flash(/admin/) }
122
+ end
123
+