saucy 0.1.9 → 0.1.11
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/Gemfile +1 -1
- data/Gemfile.lock +9 -3
- data/app/controllers/accounts_controller.rb +3 -9
- data/app/models/invitation.rb +1 -3
- data/app/views/accounts/_account.html.erb +1 -1
- data/app/views/memberships/index.html.erb +1 -2
- data/app/views/projects/_form.html.erb +1 -0
- data/app/views/projects/edit.html.erb +1 -1
- data/features/run_features.feature +1 -1
- data/features/step_definitions/rails_steps.rb +1 -1
- data/lib/generators/saucy/features/templates/factories.rb +2 -4
- data/lib/generators/saucy/features/templates/features/edit_user_permissions.feature +1 -1
- data/lib/generators/saucy/features/templates/features/manage_projects.feature +1 -0
- data/lib/generators/saucy/features/templates/features/manage_users.feature +4 -4
- data/lib/generators/saucy/features/templates/features/new_account.feature +2 -4
- data/lib/generators/saucy/features/templates/features/sign_up.feature +1 -26
- data/lib/generators/saucy/features/templates/step_definitions/session_steps.rb +3 -3
- data/lib/generators/saucy/install/templates/create_saucy_tables.rb +1 -0
- data/lib/saucy/account_authorization.rb +1 -1
- data/lib/saucy/project.rb +11 -1
- data/lib/saucy/projects_controller.rb +3 -13
- data/spec/controllers/accounts_controller_spec.rb +3 -28
- data/spec/models/invitation_spec.rb +3 -4
- data/spec/models/project_spec.rb +20 -0
- data/spec/support/authorization_helpers.rb +1 -1
- metadata +4 -4
data/Gemfile
CHANGED
@@ -5,7 +5,7 @@ gem "rake"
|
|
5
5
|
gem "rspec-rails", :require => false
|
6
6
|
gem "rails", ">= 3.0.3"
|
7
7
|
gem "thin"
|
8
|
-
gem "clearance", "
|
8
|
+
gem "clearance", :ref => '71d7c7f7a29ea757cf84fcc497cbc8ecf6cac211', :git => "git://github.com/thoughtbot/clearance.git", :require => false
|
9
9
|
gem "shoulda", :require => false
|
10
10
|
gem "bourne", :require => false
|
11
11
|
gem "sqlite3-ruby", :require => false
|
data/Gemfile.lock
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/thoughtbot/clearance.git
|
3
|
+
revision: 71d7c7f7a29ea757cf84fcc497cbc8ecf6cac211
|
4
|
+
ref: 71d7c7f7a29ea757cf84fcc497cbc8ecf6cac211
|
5
|
+
specs:
|
6
|
+
clearance (0.9.1)
|
7
|
+
rails (~> 3.0.0)
|
8
|
+
|
1
9
|
GEM
|
2
10
|
remote: http://rubygems.org/
|
3
11
|
specs:
|
@@ -48,8 +56,6 @@ GEM
|
|
48
56
|
celerity (0.8.5)
|
49
57
|
childprocess (0.1.4)
|
50
58
|
ffi (~> 0.6.3)
|
51
|
-
clearance (0.9.0.rc9)
|
52
|
-
rails (~> 3.0.0)
|
53
59
|
configuration (1.2.0)
|
54
60
|
cucumber (0.9.4)
|
55
61
|
builder (~> 2.1.2)
|
@@ -155,7 +161,7 @@ DEPENDENCIES
|
|
155
161
|
aruba
|
156
162
|
bourne
|
157
163
|
capybara
|
158
|
-
clearance
|
164
|
+
clearance!
|
159
165
|
cucumber
|
160
166
|
cucumber-rails
|
161
167
|
database_cleaner
|
@@ -12,15 +12,9 @@ class AccountsController < ApplicationController
|
|
12
12
|
@signup = Signup.new(params[:signup])
|
13
13
|
@signup.user = current_user
|
14
14
|
if @signup.save
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
redirect_to root_url
|
19
|
-
else
|
20
|
-
flash[:success] = "Account was created. Instructions for confirming your " +
|
21
|
-
"account have been sent to the email address you provided."
|
22
|
-
redirect_to sign_in_url
|
23
|
-
end
|
15
|
+
flash[:success] = "Account was created."
|
16
|
+
sign_in @signup.user
|
17
|
+
redirect_to root_url
|
24
18
|
else
|
25
19
|
render :action => 'new'
|
26
20
|
end
|
data/app/models/invitation.rb
CHANGED
@@ -59,9 +59,7 @@ class Invitation < ActiveRecord::Base
|
|
59
59
|
:password => new_user_password,
|
60
60
|
:password_confirmation => new_user_password_confirmation,
|
61
61
|
:name => new_user_name
|
62
|
-
)
|
63
|
-
user.email_confirmed = true
|
64
|
-
end
|
62
|
+
)
|
65
63
|
end
|
66
64
|
|
67
65
|
def validate_accepting_user
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<%= content_tag_for :div, account do -%>
|
2
2
|
<div class="account-header">
|
3
|
-
<
|
3
|
+
<h3><%= account.name %></h3>
|
4
4
|
<% if current_user.admin_of?(account) -%>
|
5
5
|
<%= link_to 'Settings', edit_account_path(account), :class => 'project-settings' %>
|
6
6
|
<% end -%>
|
@@ -6,11 +6,10 @@
|
|
6
6
|
<% @memberships.each do |membership| -%>
|
7
7
|
<%= content_tag_for :li, membership.user do -%>
|
8
8
|
<%= link_to [:edit, membership] do %>
|
9
|
-
<%= membership.name %> (<%= membership.email %>)
|
9
|
+
<%= membership.name %> <span>(<%= membership.email %>)</span>
|
10
10
|
<% end -%>
|
11
11
|
<% end -%>
|
12
12
|
<% end -%>
|
13
13
|
</ul>
|
14
14
|
|
15
15
|
<%= link_to 'Invite user', new_account_invitation_path(current_account), :class => "button"%>
|
16
|
-
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<h2>Edit project: <%= @project.name %></h2>
|
2
2
|
<div class="actions">
|
3
|
-
<%= link_to project_path(@project), :method => 'delete', :confirm => 'Are you sure you want to delete this project and all associated content?' do %>
|
3
|
+
<%= link_to project_path(@project), :method => 'delete', :confirm => 'Are you sure you want to delete this project and all associated content?', :class => 'action' do %>
|
4
4
|
<span class="delete_item">Remove this project</span>
|
5
5
|
<% end -%>
|
6
6
|
</div>
|
@@ -6,7 +6,7 @@ Feature: generate a saucy application and run rake
|
|
6
6
|
And I cd to "testapp"
|
7
7
|
And I append to "Gemfile" with:
|
8
8
|
"""
|
9
|
-
gem "clearance", "
|
9
|
+
gem "clearance", :git => "git://github.com/thoughtbot/clearance.git"
|
10
10
|
gem "cucumber-rails"
|
11
11
|
gem "capybara"
|
12
12
|
gem "factory_girl_rails"
|
@@ -47,7 +47,7 @@ When /^I add a custom layout to the accounts index$/ do
|
|
47
47
|
create_file('features/custom_accounts_index_layout.feature', <<-SCENARIO)
|
48
48
|
Feature: The accounts index should have a custom layout
|
49
49
|
Scenario: Custom layout
|
50
|
-
Given I am signed up
|
50
|
+
Given I am signed up as "email@person.com/password"
|
51
51
|
And the following projects exist:
|
52
52
|
| name | account |
|
53
53
|
| ClothesPin | name: One |
|
@@ -13,10 +13,6 @@ Factory.define :user do |user|
|
|
13
13
|
user.password_confirmation { "password" }
|
14
14
|
end
|
15
15
|
|
16
|
-
Factory.define :email_confirmed_user, :parent => :user do |user|
|
17
|
-
user.email_confirmed { true }
|
18
|
-
end
|
19
|
-
|
20
16
|
Factory.define :account do |f|
|
21
17
|
f.name { Factory.next(:name) }
|
22
18
|
f.url { Factory.next(:name) }
|
@@ -38,6 +34,8 @@ end
|
|
38
34
|
|
39
35
|
Factory.define :project do |f|
|
40
36
|
f.association :account
|
37
|
+
f.name { Factory.next(:name) }
|
38
|
+
f.url { Factory.next(:name) }
|
41
39
|
end
|
42
40
|
|
43
41
|
Factory.define :permission do |f|
|
@@ -32,7 +32,7 @@ Feature: edit permissions for a user
|
|
32
32
|
Scenario: promote a user to an admin
|
33
33
|
Given an account exists with a name of "Test"
|
34
34
|
And I am signed in as an admin of the "Test" account
|
35
|
-
And an
|
35
|
+
And an user exists with a name of "Frank"
|
36
36
|
And the following memberships exist:
|
37
37
|
| account | user | admin |
|
38
38
|
| name: Test | name: Frank | false |
|
@@ -12,6 +12,7 @@ Feature: Manage Projects
|
|
12
12
|
When I go to the projects page for the "Test" account
|
13
13
|
And I follow "New Project"
|
14
14
|
And I fill in "Name" with "Project 1"
|
15
|
+
And I fill in "Url" with "project1"
|
15
16
|
And I press "Create"
|
16
17
|
And I go to the projects page for the "Test" account
|
17
18
|
Then I should see "Project 1" within "ul.projects"
|
@@ -33,7 +33,7 @@ Feature: Managing users
|
|
33
33
|
Then the "Name" field should contain "Billy"
|
34
34
|
|
35
35
|
Scenario: Invite existing users
|
36
|
-
Given the following
|
36
|
+
Given the following user exists:
|
37
37
|
| email | password | password confirmation |
|
38
38
|
| invitee@example.com | secret | secret |
|
39
39
|
When I follow "Invite user"
|
@@ -57,7 +57,7 @@ Feature: Managing users
|
|
57
57
|
Then the form should have inline error messages
|
58
58
|
|
59
59
|
Scenario: Invite admin users
|
60
|
-
Given the following
|
60
|
+
Given the following user exists:
|
61
61
|
| email | password | password confirmation |
|
62
62
|
| invitee@example.com | secret | secret |
|
63
63
|
When I follow "Invite user"
|
@@ -78,7 +78,7 @@ Feature: Managing users
|
|
78
78
|
Then the form should have inline error messages
|
79
79
|
|
80
80
|
Scenario: view account members
|
81
|
-
Given the following
|
81
|
+
Given the following users exist:
|
82
82
|
| name |
|
83
83
|
| Bill |
|
84
84
|
| John |
|
@@ -93,7 +93,7 @@ Feature: Managing users
|
|
93
93
|
And I should not see "John"
|
94
94
|
|
95
95
|
Scenario: remove a user from an account
|
96
|
-
Given an
|
96
|
+
Given an user exists with a name of "Frank"
|
97
97
|
And the following memberships exist:
|
98
98
|
| account | user |
|
99
99
|
| name: Test | name: Frank |
|
@@ -4,7 +4,7 @@ Feature: user adds a new account
|
|
4
4
|
Given a plan exists with a name of "Free"
|
5
5
|
|
6
6
|
Scenario: existing user adds an account
|
7
|
-
Given I am signed up
|
7
|
+
Given I am signed up as "user@example.com/test"
|
8
8
|
When I go to the sign up page for the "Free" plan
|
9
9
|
And I fill in "Email" with "user@example.com"
|
10
10
|
And I fill in "Password" with "test"
|
@@ -27,9 +27,7 @@ Feature: user adds a new account
|
|
27
27
|
And I fill in "Account URL" with "robots"
|
28
28
|
And I press "Sign up"
|
29
29
|
Then I should see "created"
|
30
|
-
|
31
|
-
When I follow the confirmation link sent to "email@person.com"
|
32
|
-
And I go to the settings page
|
30
|
+
When I go to the settings page
|
33
31
|
And I follow "Robots, Inc"
|
34
32
|
Then the "Url" field should contain "robots"
|
35
33
|
When I go to the settings page
|
@@ -24,29 +24,4 @@ Feature: Sign up
|
|
24
24
|
And I fill in "Company Name" with "Robots, Inc"
|
25
25
|
And I fill in "Account URL" with "robotsinc"
|
26
26
|
And I press "Sign up"
|
27
|
-
Then I should see "
|
28
|
-
And a confirmation message should be sent to "email@person.com"
|
29
|
-
And the user "email@person.com" should be an admin of "Robots, Inc"
|
30
|
-
|
31
|
-
Scenario: User confirms his account
|
32
|
-
Given I signed up with "email@person.com/password"
|
33
|
-
When I follow the confirmation link sent to "email@person.com"
|
34
|
-
Then I should see "Confirmed email and signed in"
|
35
|
-
And I should be signed in
|
36
|
-
|
37
|
-
Scenario: Signed in user clicks confirmation link again
|
38
|
-
Given I signed up with "email@person.com/password"
|
39
|
-
When I follow the confirmation link sent to "email@person.com"
|
40
|
-
Then I should be signed in
|
41
|
-
When I follow the confirmation link sent to "email@person.com"
|
42
|
-
Then I should see "Confirmed email and signed in"
|
43
|
-
And I should be signed in
|
44
|
-
|
45
|
-
Scenario: Signed out user clicks confirmation link again
|
46
|
-
Given I signed up with "email@person.com/password"
|
47
|
-
When I follow the confirmation link sent to "email@person.com"
|
48
|
-
Then I should be signed in
|
49
|
-
When I sign out
|
50
|
-
And I follow the confirmation link sent to "email@person.com"
|
51
|
-
Then I should see "Already confirmed email. Please sign in."
|
52
|
-
And I should be signed out
|
27
|
+
Then I should see "created"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Given /^I (?:am signed in|sign in) as an admin of the "([^"]+)" project$/ do |project_name|
|
2
2
|
project = Project.find_by_name!(project_name)
|
3
|
-
user = Factory(:
|
3
|
+
user = Factory(:user)
|
4
4
|
membership = Factory(:membership, :user => user,
|
5
5
|
:account => project.account,
|
6
6
|
:admin => true)
|
@@ -11,7 +11,7 @@ end
|
|
11
11
|
|
12
12
|
Given /^I am signed in as an admin of the "([^"]*)" account$/ do |account_name|
|
13
13
|
account = Account.find_by_name!(account_name)
|
14
|
-
user = Factory(:
|
14
|
+
user = Factory(:user)
|
15
15
|
Factory(:membership, :user => user,
|
16
16
|
:account => account,
|
17
17
|
:admin => true)
|
@@ -25,6 +25,6 @@ When /^I sign in as "([^"\/]*)"$/ do |email|
|
|
25
25
|
end
|
26
26
|
|
27
27
|
Given /^I am signed in$/ do
|
28
|
-
user = Factory(:
|
28
|
+
user = Factory(:user)
|
29
29
|
When %{I sign in as "#{user.email}"}
|
30
30
|
end
|
data/lib/saucy/project.rb
CHANGED
@@ -7,7 +7,13 @@ module Saucy
|
|
7
7
|
has_many :permissions, :dependent => :destroy
|
8
8
|
has_many :users, :through => :permissions
|
9
9
|
|
10
|
-
validates_presence_of :account_id
|
10
|
+
validates_presence_of :account_id, :url, :name
|
11
|
+
|
12
|
+
validates_uniqueness_of :url, :scope => :account_id
|
13
|
+
|
14
|
+
validates_format_of :url,
|
15
|
+
:with => %r{^[a-z0-9]+$},
|
16
|
+
:message => "must be only lower case letters."
|
11
17
|
|
12
18
|
after_create :assign_default_memberships
|
13
19
|
after_save :update_memberships
|
@@ -30,6 +36,10 @@ module Saucy
|
|
30
36
|
end
|
31
37
|
|
32
38
|
module InstanceMethods
|
39
|
+
def to_param
|
40
|
+
url
|
41
|
+
end
|
42
|
+
|
33
43
|
def has_member?(user)
|
34
44
|
permissions.
|
35
45
|
joins(:membership).
|
@@ -23,11 +23,11 @@ module Saucy
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def edit
|
26
|
-
@project = ::Project.
|
26
|
+
@project = ::Project.find_by_url!(params[:id])
|
27
27
|
end
|
28
28
|
|
29
29
|
def update
|
30
|
-
@project = ::Project.
|
30
|
+
@project = ::Project.find_by_url!(params[:id])
|
31
31
|
if @project.update_attributes params[:project]
|
32
32
|
flash[:success] = 'Project was updated.'
|
33
33
|
redirect_to account_projects_url(current_account)
|
@@ -37,7 +37,7 @@ module Saucy
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def destroy
|
40
|
-
@project = ::Project.
|
40
|
+
@project = ::Project.find_by_url!(params[:id])
|
41
41
|
@project.destroy
|
42
42
|
flash[:success] = "Project has been deleted"
|
43
43
|
redirect_to account_projects_url(@project.account)
|
@@ -46,16 +46,6 @@ module Saucy
|
|
46
46
|
def index
|
47
47
|
@projects = current_account.projects
|
48
48
|
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
def current_account
|
53
|
-
if params[:id]
|
54
|
-
::Project.find(params[:id]).account
|
55
|
-
else
|
56
|
-
super
|
57
|
-
end
|
58
|
-
end
|
59
49
|
end
|
60
50
|
end
|
61
51
|
end
|
@@ -31,8 +31,8 @@ describe AccountsController, "new" do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
describe AccountsController, "successful create for a confirmed user" do
|
34
|
-
let(:user) { Factory.stub(:
|
35
|
-
let(:signup) { stub('signup', :user => user, :
|
34
|
+
let(:user) { Factory.stub(:user) }
|
35
|
+
let(:signup) { stub('signup', :user => user, :user= => nil) }
|
36
36
|
let(:signup_attributes) { "attributes" }
|
37
37
|
let(:plan) { Factory(:plan) }
|
38
38
|
|
@@ -61,33 +61,8 @@ describe AccountsController, "successful create for a confirmed user" do
|
|
61
61
|
it { should be_signed_in.as(user) }
|
62
62
|
end
|
63
63
|
|
64
|
-
describe AccountsController, "successful create for an unconfirmed user" do
|
65
|
-
let(:user) { Factory.stub(:user) }
|
66
|
-
let(:signup) { stub('signup', :user => user, :email_confirmed? => false, :user= => nil) }
|
67
|
-
let(:signup_attributes) { "attributes" }
|
68
|
-
let(:plan) { Factory(:plan) }
|
69
|
-
|
70
|
-
before do
|
71
|
-
Signup.stubs(:new => signup)
|
72
|
-
signup.stubs(:save => true)
|
73
|
-
post :create, :signup => signup_attributes, :plan_id => plan.to_param
|
74
|
-
end
|
75
|
-
|
76
|
-
it "creates an signup" do
|
77
|
-
Signup.should have_received(:new).with(signup_attributes)
|
78
|
-
signup.should have_received(:save)
|
79
|
-
end
|
80
|
-
|
81
|
-
it "redirects to the sign in url" do
|
82
|
-
should redirect_to(sign_in_url)
|
83
|
-
end
|
84
|
-
|
85
|
-
it { should set_the_flash.to(/created/i) }
|
86
|
-
it { should set_the_flash.to(/confirm/i) }
|
87
|
-
end
|
88
|
-
|
89
64
|
describe AccountsController, "failed create" do
|
90
|
-
let(:signup) { stub('signup', :
|
65
|
+
let(:signup) { stub('signup', :user= => nil) }
|
91
66
|
let(:signup_attributes) { "attributes" }
|
92
67
|
let(:plan) { Factory(:plan) }
|
93
68
|
|
@@ -63,7 +63,6 @@ describe Invitation, "valid accept for a new user" do
|
|
63
63
|
it "creates a saved, confirmed user" do
|
64
64
|
user.should_not be_nil
|
65
65
|
user.should be_persisted
|
66
|
-
user.should be_email_confirmed
|
67
66
|
user.name.should == name
|
68
67
|
end
|
69
68
|
|
@@ -99,7 +98,7 @@ end
|
|
99
98
|
|
100
99
|
describe Invitation, "valid accept for an existing user" do
|
101
100
|
let(:password) { 'secret' }
|
102
|
-
let(:user) { Factory(:
|
101
|
+
let(:user) { Factory(:user,
|
103
102
|
:password => password,
|
104
103
|
:password_confirmation => password) }
|
105
104
|
subject { Factory(:invitation, :email => user.email) }
|
@@ -119,7 +118,7 @@ describe Invitation, "valid accept for an existing user" do
|
|
119
118
|
end
|
120
119
|
|
121
120
|
describe Invitation, "accepting with an invalid password" do
|
122
|
-
let(:user) { Factory(:
|
121
|
+
let(:user) { Factory(:user) }
|
123
122
|
subject { Factory(:invitation, :email => user.email) }
|
124
123
|
let(:account) { subject.account }
|
125
124
|
let!(:result) { subject.accept(:existing_user_password => 'wrong') }
|
@@ -153,7 +152,7 @@ end
|
|
153
152
|
|
154
153
|
describe Invitation, "accepting an admin invite" do
|
155
154
|
let(:password) { 'secret' }
|
156
|
-
let(:user) { Factory(:
|
155
|
+
let(:user) { Factory(:user,
|
157
156
|
:password => password,
|
158
157
|
:password_confirmation => password) }
|
159
158
|
subject { Factory(:invitation, :email => user.email, :admin => true) }
|
data/spec/models/project_spec.rb
CHANGED
@@ -5,6 +5,8 @@ describe Project do
|
|
5
5
|
it { should validate_presence_of(:account_id) }
|
6
6
|
it { should have_many(:permissions) }
|
7
7
|
it { should have_many(:users).through(:permissions) }
|
8
|
+
it { should validate_presence_of(:url) }
|
9
|
+
it { should validate_presence_of(:name) }
|
8
10
|
|
9
11
|
it "finds projects visible to a user" do
|
10
12
|
account = Factory(:account)
|
@@ -28,6 +30,24 @@ describe Project do
|
|
28
30
|
|
29
31
|
Project.by_name.map(&:name).should == %w(abc def ghi)
|
30
32
|
end
|
33
|
+
|
34
|
+
it "should give its url for to_param" do
|
35
|
+
project = Factory(:project)
|
36
|
+
project.to_param.should == project.url
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe Project, "url uniqueness" do
|
41
|
+
let(:project) { Factory(:project) }
|
42
|
+
subject do
|
43
|
+
Factory.build(:project, :account => project.account)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "validates uniqueness of it's url" do
|
47
|
+
subject.url = project.url
|
48
|
+
subject.save
|
49
|
+
subject.errors[:url].should include("has already been taken")
|
50
|
+
end
|
31
51
|
end
|
32
52
|
|
33
53
|
describe Project, "for an account with admin and non-admin users" do
|
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:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 11
|
10
|
+
version: 0.1.11
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- thoughtbot, inc.
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2010-12-
|
20
|
+
date: 2010-12-22 00:00:00 -05:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|