saucy 0.1.3 → 0.1.4
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 +15 -1
- data/Gemfile.lock +67 -1
- data/Rakefile +26 -0
- data/app/controllers/memberships_controller.rb +33 -1
- data/app/models/invitation.rb +1 -1
- data/app/models/membership.rb +22 -0
- data/app/models/permission.rb +17 -0
- data/app/models/signup.rb +3 -3
- data/app/views/memberships/edit.html.erb +18 -0
- data/app/views/memberships/index.html.erb +4 -4
- data/config/routes.rb +2 -3
- data/features/run_features.feature +4 -3
- data/features/step_definitions/rails_steps.rb +3 -0
- data/lib/generators/saucy/features/templates/factories.rb +4 -4
- data/lib/generators/saucy/features/templates/step_definitions/session_steps.rb +6 -3
- data/lib/generators/saucy/features/templates/step_definitions/user_steps.rb +6 -4
- data/lib/generators/saucy/install/templates/create_saucy_tables.rb +8 -6
- data/lib/saucy/account.rb +9 -5
- data/lib/saucy/project.rb +28 -5
- data/lib/saucy/user.rb +5 -12
- data/spec/controllers/memberships_controller_spec.rb +87 -5
- data/spec/environment.rb +91 -0
- data/spec/models/account_spec.rb +17 -6
- data/spec/models/membership_spec.rb +37 -0
- data/spec/models/permission_spec.rb +19 -0
- data/spec/models/project_spec.rb +39 -9
- data/spec/models/user_spec.rb +16 -42
- data/spec/scaffold/config/routes.rb +5 -0
- data/spec/spec_helper.rb +8 -1
- data/spec/support/authentication_helpers.rb +16 -6
- metadata +75 -74
- data/app/controllers/permissions_controller.rb +0 -17
- data/app/models/account_membership.rb +0 -8
- data/app/models/project_membership.rb +0 -14
- data/app/views/permissions/edit.html.erb +0 -15
- data/spec/controllers/permissions_controller_spec.rb +0 -69
- data/spec/models/account_membership_spec.rb +0 -13
- data/spec/models/project_membership_spec.rb +0 -22
data/Gemfile
CHANGED
@@ -2,7 +2,21 @@ source "http://rubygems.org"
|
|
2
2
|
gem "cucumber"
|
3
3
|
gem "aruba"
|
4
4
|
gem "rake"
|
5
|
-
gem "rspec", :require => false
|
5
|
+
gem "rspec-rails", :require => false
|
6
6
|
gem "rails", ">= 3.0.3"
|
7
7
|
gem "thin"
|
8
|
+
gem "clearance", "0.9.0.rc9", :require => false
|
9
|
+
gem "shoulda", :require => false
|
10
|
+
gem "bourne", :require => false
|
11
|
+
gem "sqlite3-ruby", :require => false
|
12
|
+
gem "factory_girl", :require => false
|
13
|
+
|
14
|
+
# used by the rails app in cucumber
|
15
|
+
gem "cucumber-rails", :require => false
|
16
|
+
gem "capybara", :require => false
|
17
|
+
gem "factory_girl_rails", :require => false
|
18
|
+
gem "formtastic", :require => false
|
19
|
+
gem "database_cleaner", :require => false
|
20
|
+
gem "dynamic_form", :require => false
|
21
|
+
gem "launchy", :require => false
|
8
22
|
|
data/Gemfile.lock
CHANGED
@@ -33,29 +33,68 @@ GEM
|
|
33
33
|
background_process
|
34
34
|
cucumber (~> 0.9.4)
|
35
35
|
background_process (1.2)
|
36
|
+
bourne (1.0)
|
37
|
+
mocha (= 0.9.8)
|
36
38
|
builder (2.1.2)
|
39
|
+
capybara (0.4.0)
|
40
|
+
celerity (>= 0.7.9)
|
41
|
+
culerity (>= 0.2.4)
|
42
|
+
mime-types (>= 1.16)
|
43
|
+
nokogiri (>= 1.3.3)
|
44
|
+
rack (>= 1.0.0)
|
45
|
+
rack-test (>= 0.5.4)
|
46
|
+
selenium-webdriver (>= 0.0.27)
|
47
|
+
xpath (~> 0.1.2)
|
48
|
+
celerity (0.8.5)
|
49
|
+
childprocess (0.1.4)
|
50
|
+
ffi (~> 0.6.3)
|
51
|
+
clearance (0.9.0.rc9)
|
52
|
+
rails (~> 3.0.0)
|
53
|
+
configuration (1.2.0)
|
37
54
|
cucumber (0.9.4)
|
38
55
|
builder (~> 2.1.2)
|
39
56
|
diff-lcs (~> 1.1.2)
|
40
57
|
gherkin (~> 2.2.9)
|
41
58
|
json (~> 1.4.6)
|
42
59
|
term-ansicolor (~> 1.0.5)
|
60
|
+
cucumber-rails (0.3.2)
|
61
|
+
cucumber (>= 0.8.0)
|
62
|
+
culerity (0.2.12)
|
43
63
|
daemons (1.1.0)
|
64
|
+
database_cleaner (0.6.0)
|
44
65
|
diff-lcs (1.1.2)
|
66
|
+
dynamic_form (1.1.3)
|
45
67
|
erubis (2.6.6)
|
46
68
|
abstract (>= 1.0.0)
|
47
69
|
eventmachine (0.12.10)
|
70
|
+
factory_girl (1.3.2)
|
71
|
+
factory_girl_rails (1.0)
|
72
|
+
factory_girl (~> 1.3)
|
73
|
+
rails (>= 3.0.0.beta4)
|
74
|
+
ffi (0.6.3)
|
75
|
+
rake (>= 0.8.7)
|
76
|
+
formtastic (1.2.2)
|
77
|
+
actionpack (>= 2.3.7)
|
78
|
+
activesupport (>= 2.3.7)
|
79
|
+
i18n (>= 0.4.0)
|
48
80
|
gherkin (2.2.9)
|
49
81
|
json (~> 1.4.6)
|
50
82
|
term-ansicolor (~> 1.0.5)
|
51
83
|
i18n (0.5.0)
|
52
84
|
json (1.4.6)
|
85
|
+
json_pure (1.4.6)
|
86
|
+
launchy (0.3.7)
|
87
|
+
configuration (>= 0.0.5)
|
88
|
+
rake (>= 0.8.1)
|
53
89
|
mail (2.2.11)
|
54
90
|
activesupport (>= 2.3.6)
|
55
91
|
i18n (~> 0.5.0)
|
56
92
|
mime-types (~> 1.16)
|
57
93
|
treetop (~> 1.4.8)
|
58
94
|
mime-types (1.16)
|
95
|
+
mocha (0.9.8)
|
96
|
+
rake
|
97
|
+
nokogiri (1.4.4)
|
59
98
|
polyglot (0.3.1)
|
60
99
|
rack (1.2.1)
|
61
100
|
rack-mount (0.6.13)
|
@@ -84,6 +123,19 @@ GEM
|
|
84
123
|
rspec-expectations (2.2.0)
|
85
124
|
diff-lcs (~> 1.1.2)
|
86
125
|
rspec-mocks (2.2.0)
|
126
|
+
rspec-rails (2.2.1)
|
127
|
+
actionpack (~> 3.0)
|
128
|
+
activesupport (~> 3.0)
|
129
|
+
railties (~> 3.0)
|
130
|
+
rspec (~> 2.2.0)
|
131
|
+
rubyzip (0.9.4)
|
132
|
+
selenium-webdriver (0.1.1)
|
133
|
+
childprocess (= 0.1.4)
|
134
|
+
ffi (~> 0.6.3)
|
135
|
+
json_pure
|
136
|
+
rubyzip
|
137
|
+
shoulda (2.11.3)
|
138
|
+
sqlite3-ruby (1.3.2)
|
87
139
|
term-ansicolor (1.0.5)
|
88
140
|
thin (1.2.7)
|
89
141
|
daemons (>= 1.0.9)
|
@@ -93,14 +145,28 @@ GEM
|
|
93
145
|
treetop (1.4.9)
|
94
146
|
polyglot (>= 0.3.1)
|
95
147
|
tzinfo (0.3.23)
|
148
|
+
xpath (0.1.2)
|
149
|
+
nokogiri (~> 1.3)
|
96
150
|
|
97
151
|
PLATFORMS
|
98
152
|
ruby
|
99
153
|
|
100
154
|
DEPENDENCIES
|
101
155
|
aruba
|
156
|
+
bourne
|
157
|
+
capybara
|
158
|
+
clearance (= 0.9.0.rc9)
|
102
159
|
cucumber
|
160
|
+
cucumber-rails
|
161
|
+
database_cleaner
|
162
|
+
dynamic_form
|
163
|
+
factory_girl
|
164
|
+
factory_girl_rails
|
165
|
+
formtastic
|
166
|
+
launchy
|
103
167
|
rails (>= 3.0.3)
|
104
168
|
rake
|
105
|
-
rspec
|
169
|
+
rspec-rails
|
170
|
+
shoulda
|
171
|
+
sqlite3-ruby
|
106
172
|
thin
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'cucumber/rake/task'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
desc 'Default: run all tests'
|
9
|
+
task :default => [:spec, :cucumber]
|
10
|
+
|
11
|
+
Cucumber::Rake::Task.new(:cucumber) do |t|
|
12
|
+
t.fork = true
|
13
|
+
t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'progress')]
|
14
|
+
end
|
15
|
+
|
16
|
+
RSpec::Core::RakeTask.new do |t|
|
17
|
+
t.pattern = "spec/**/*_spec.rb"
|
18
|
+
t.rspec_opts = "--format progress"
|
19
|
+
end
|
20
|
+
|
21
|
+
eval("$specification = begin; #{IO.read('saucy.gemspec')}; end")
|
22
|
+
Rake::GemPackageTask.new($specification) do |package|
|
23
|
+
package.need_zip = true
|
24
|
+
package.need_tar = true
|
25
|
+
end
|
26
|
+
|
@@ -3,7 +3,39 @@ class MembershipsController < ApplicationController
|
|
3
3
|
layout Saucy::Layouts.to_proc
|
4
4
|
|
5
5
|
def index
|
6
|
-
@
|
6
|
+
@memberships = current_account.memberships_by_name
|
7
7
|
render
|
8
8
|
end
|
9
|
+
|
10
|
+
def edit
|
11
|
+
find_membership
|
12
|
+
@projects = current_account.projects_by_name
|
13
|
+
render
|
14
|
+
end
|
15
|
+
|
16
|
+
def update
|
17
|
+
find_membership.update_attributes!(params[:membership])
|
18
|
+
flash[:success] = "Permissions updated."
|
19
|
+
redirect_to account_memberships_url(current_account)
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy
|
23
|
+
find_membership.destroy
|
24
|
+
flash[:success] = "User removed."
|
25
|
+
redirect_to account_memberships_url(current_account)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def find_membership
|
31
|
+
@membership ||= Membership.find(params[:id], :include => :account)
|
32
|
+
end
|
33
|
+
|
34
|
+
def current_account
|
35
|
+
if params[:id]
|
36
|
+
find_membership.account
|
37
|
+
else
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end
|
9
41
|
end
|
data/app/models/invitation.rb
CHANGED
@@ -22,7 +22,7 @@ class Invitation < ActiveRecord::Base
|
|
22
22
|
@user = existing_user || new_user
|
23
23
|
if valid?
|
24
24
|
@user.save!
|
25
|
-
@user.
|
25
|
+
@user.memberships.create!(:account => account, :admin => admin)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Membership < ActiveRecord::Base
|
2
|
+
belongs_to :user
|
3
|
+
belongs_to :account
|
4
|
+
has_many :permissions
|
5
|
+
has_many :projects, :through => :permissions
|
6
|
+
|
7
|
+
validates_presence_of :user_id
|
8
|
+
validates_presence_of :account_id
|
9
|
+
validates_uniqueness_of :user_id, :scope => :account_id
|
10
|
+
|
11
|
+
def name
|
12
|
+
user.name
|
13
|
+
end
|
14
|
+
|
15
|
+
def email
|
16
|
+
user.email
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.by_name
|
20
|
+
joins(:user).order('users.name')
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Permission < ActiveRecord::Base
|
2
|
+
belongs_to :membership
|
3
|
+
belongs_to :project
|
4
|
+
belongs_to :user
|
5
|
+
|
6
|
+
before_validation :assign_user_id_from_membership
|
7
|
+
|
8
|
+
def user=(ignored)
|
9
|
+
raise NotImplementedError, "Use Permission#membership= instead"
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def assign_user_id_from_membership
|
15
|
+
self.user_id = membership.user_id
|
16
|
+
end
|
17
|
+
end
|
data/app/models/signup.rb
CHANGED
@@ -66,8 +66,8 @@ class Signup
|
|
66
66
|
@existing_user ||= User.find_by_email(email)
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
70
|
-
@
|
69
|
+
def membership
|
70
|
+
@membership ||= Membership.new(:user => user,
|
71
71
|
:account => account,
|
72
72
|
:admin => true)
|
73
73
|
end
|
@@ -128,7 +128,7 @@ class Signup
|
|
128
128
|
Account.transaction do
|
129
129
|
account.save!
|
130
130
|
user.save!
|
131
|
-
|
131
|
+
membership.save!
|
132
132
|
end
|
133
133
|
end
|
134
134
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<h2>Permissions for <span><%= @membership.name %></span> on <%= current_account.name %></h2>
|
2
|
+
|
3
|
+
<%= render :partial => 'accounts/tab_bar' %>
|
4
|
+
|
5
|
+
<%= semantic_form_for @membership do |form| -%>
|
6
|
+
<%= form.inputs do -%>
|
7
|
+
<%= form.input :admin %>
|
8
|
+
<%= form.input :projects, :as => :check_boxes, :collection => @projects %>
|
9
|
+
<% end -%>
|
10
|
+
<%= form.buttons do -%>
|
11
|
+
<%= form.commit_button "Update" %>
|
12
|
+
<li><%= link_to "Remove from account",
|
13
|
+
@membership,
|
14
|
+
:method => :delete,
|
15
|
+
:confirm => "Are you sure?" %></li>
|
16
|
+
<% end -%>
|
17
|
+
<% end -%>
|
18
|
+
|
@@ -3,10 +3,10 @@
|
|
3
3
|
<%= render :partial => 'accounts/tab_bar' %>
|
4
4
|
|
5
5
|
<ul class="users">
|
6
|
-
<% @
|
7
|
-
<%= content_tag_for :li, user do -%>
|
8
|
-
<%= link_to
|
9
|
-
<%=
|
6
|
+
<% @memberships.each do |membership| -%>
|
7
|
+
<%= content_tag_for :li, membership.user do -%>
|
8
|
+
<%= link_to [:edit, membership] do %>
|
9
|
+
<%= membership.name %> (<%= membership.email %>)
|
10
10
|
<% end -%>
|
11
11
|
<% end -%>
|
12
12
|
<% end -%>
|
data/config/routes.rb
CHANGED
@@ -3,11 +3,10 @@ Rails.application.routes.draw do
|
|
3
3
|
resources :projects, :only => [:new, :create, :index, :show]
|
4
4
|
resources :memberships, :only => [:index]
|
5
5
|
resources :invitations, :only => [:new, :create]
|
6
|
-
resources :users, :only => [] do
|
7
|
-
resource :permissions, :only => [:edit, :update]
|
8
|
-
end
|
9
6
|
end
|
10
7
|
|
8
|
+
resources :memberships, :only => [:edit, :update, :destroy]
|
9
|
+
|
11
10
|
resources :plans, :only => [:index] do
|
12
11
|
resources :accounts, :only => [:new, :create]
|
13
12
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
@puts @announce
|
1
|
+
@disable-bundler @puts @announce
|
2
2
|
Feature: generate a saucy application and run rake
|
3
3
|
|
4
4
|
Background:
|
@@ -16,9 +16,10 @@ Feature: generate a saucy application and run rake
|
|
16
16
|
gem "rspec-rails"
|
17
17
|
gem "bourne"
|
18
18
|
gem "shoulda"
|
19
|
+
gem "launchy"
|
19
20
|
"""
|
20
21
|
When I add the "saucy" gem from this project as a dependency
|
21
|
-
And I successfully run "bundle install"
|
22
|
+
And I successfully run "bundle install --local"
|
22
23
|
And I bootstrap the application for clearance
|
23
24
|
|
24
25
|
Scenario: generate a saucy application and run rake
|
@@ -70,4 +71,4 @@ Feature: generate a saucy application and run rake
|
|
70
71
|
"""
|
71
72
|
0 failures
|
72
73
|
"""
|
73
|
-
Then
|
74
|
+
Then at least one example should have run
|
@@ -22,7 +22,7 @@ Factory.define :account do |f|
|
|
22
22
|
f.url { Factory.next(:name) }
|
23
23
|
end
|
24
24
|
|
25
|
-
Factory.define :
|
25
|
+
Factory.define :membership do |f|
|
26
26
|
f.association :user
|
27
27
|
f.association :account
|
28
28
|
end
|
@@ -40,9 +40,9 @@ Factory.define :project do |f|
|
|
40
40
|
f.association :account
|
41
41
|
end
|
42
42
|
|
43
|
-
Factory.define :
|
44
|
-
f.association :
|
45
|
-
f.project {|a| a.association(:project, :account => a.
|
43
|
+
Factory.define :permission do |f|
|
44
|
+
f.association :membership
|
45
|
+
f.project {|a| a.association(:project, :account => a.membership.account)}
|
46
46
|
end
|
47
47
|
|
48
48
|
Factory.define :invitation do |f|
|
@@ -1,15 +1,18 @@
|
|
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
3
|
user = Factory(:email_confirmed_user)
|
4
|
-
Factory(:
|
5
|
-
|
4
|
+
membership = Factory(:membership, :user => user,
|
5
|
+
:account => project.account,
|
6
|
+
:admin => true)
|
7
|
+
Factory(:permission, :membership => membership,
|
8
|
+
:project => project)
|
6
9
|
When %{I sign in as "#{user.email}"}
|
7
10
|
end
|
8
11
|
|
9
12
|
Given /^I am signed in as an admin of the "([^"]*)" account$/ do |account_name|
|
10
13
|
account = Account.find_by_name!(account_name)
|
11
14
|
user = Factory(:email_confirmed_user)
|
12
|
-
Factory(:
|
15
|
+
Factory(:membership, :user => user,
|
13
16
|
:account => account,
|
14
17
|
:admin => true)
|
15
18
|
When %{I sign in as "#{user.email}"}
|
@@ -1,20 +1,22 @@
|
|
1
1
|
Given /^"([^"]*)" is a member of the "([^"]*)" project$/ do |email, project_name|
|
2
2
|
user = User.find_by_email!(email)
|
3
3
|
project = Project.find_by_name!(project_name)
|
4
|
-
Factory(:
|
5
|
-
|
4
|
+
membership = Factory(:membership, :user => user,
|
5
|
+
:account => project.account)
|
6
|
+
Factory(:permission, :membership => membership,
|
7
|
+
:project => project)
|
6
8
|
end
|
7
9
|
|
8
10
|
Given /^"([^"]*)" is a member of the "([^"]*)" account/ do |email, account_name|
|
9
11
|
user = User.find_by_email!(email)
|
10
12
|
account = Account.find_by_name!(account_name)
|
11
|
-
Factory(:
|
13
|
+
Factory(:membership, :user => user, :account => account)
|
12
14
|
end
|
13
15
|
|
14
16
|
Given /^"([^"]*)" is an admin of the "([^"]*)" account/ do |email, account_name|
|
15
17
|
user = User.find_by_email!(email)
|
16
18
|
account = Account.find_by_name!(account_name)
|
17
|
-
Factory(:
|
19
|
+
Factory(:membership, :user => user, :account => account, :admin => true)
|
18
20
|
end
|
19
21
|
|
20
22
|
Then /^the user "([^"]*)" should be an admin of "([^"]*)"$/ do |email, account_name|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class CreateSaucyTables < ActiveRecord::Migration
|
2
2
|
def self.up
|
3
|
-
create_table :
|
3
|
+
create_table :memberships do |table|
|
4
4
|
table.integer :account_id
|
5
5
|
table.integer :user_id
|
6
6
|
table.boolean :admin
|
@@ -8,7 +8,7 @@ class CreateSaucyTables < ActiveRecord::Migration
|
|
8
8
|
table.datetime :updated_at
|
9
9
|
end
|
10
10
|
|
11
|
-
add_index :
|
11
|
+
add_index :memberships, [:account_id, :user_id], :unique => true
|
12
12
|
|
13
13
|
create_table :accounts do |table|
|
14
14
|
table.belongs_to :plan
|
@@ -29,14 +29,16 @@ class CreateSaucyTables < ActiveRecord::Migration
|
|
29
29
|
|
30
30
|
add_index :invitations, [:account_id]
|
31
31
|
|
32
|
-
create_table :
|
32
|
+
create_table :permissions do |table|
|
33
|
+
table.integer :membership_id
|
33
34
|
table.integer :user_id
|
34
35
|
table.integer :project_id
|
35
36
|
table.datetime :created_at
|
36
37
|
table.datetime :updated_at
|
37
38
|
end
|
38
39
|
|
39
|
-
add_index :
|
40
|
+
add_index :permissions, [:user_id, :project_id]
|
41
|
+
add_index :permissions, [:membership_id, :project_id], :name => [:membership_and_project]
|
40
42
|
|
41
43
|
create_table :projects do |table|
|
42
44
|
table.string :name
|
@@ -63,10 +65,10 @@ class CreateSaucyTables < ActiveRecord::Migration
|
|
63
65
|
remove_column :users, :name
|
64
66
|
drop_table :plans
|
65
67
|
drop_table :projects
|
66
|
-
drop_table :
|
68
|
+
drop_table :permissions
|
67
69
|
drop_table :invitations
|
68
70
|
drop_table :accounts
|
69
|
-
drop_table :
|
71
|
+
drop_table :memberships
|
70
72
|
end
|
71
73
|
end
|
72
74
|
|