saasy 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,45 @@
|
|
1
|
+
When /^I bootstrap the application for clearance$/ do
|
2
|
+
steps %{
|
3
|
+
When I remove the file "public/index.html"
|
4
|
+
And I successfully run "rails generate cucumber:install"
|
5
|
+
And I successfully run "rails generate clearance:install"
|
6
|
+
And I successfully run "rails generate clearance:features"
|
7
|
+
And I configure ActionMailer to use "www.example.com" as a host
|
8
|
+
And I add flash messages to the layout
|
9
|
+
And I add session links to the layout
|
10
|
+
And I configure "clearance/sessions#new" as the root route
|
11
|
+
And I disable Capybara Javascript emulation
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
When /^I add flash messages to the layout$/ do
|
16
|
+
flashes = %{
|
17
|
+
<% flash.each do |key, value| -%>
|
18
|
+
<%= value %>
|
19
|
+
<% end -%>
|
20
|
+
}
|
21
|
+
|
22
|
+
replace_in_file "app/views/layouts/application.html.erb",
|
23
|
+
/(<body>)/,
|
24
|
+
"\\1\n#{flashes}"
|
25
|
+
end
|
26
|
+
|
27
|
+
When /^I add session links to the layout$/ do
|
28
|
+
links = %{
|
29
|
+
<% if signed_in? -%>
|
30
|
+
<%= link_to 'Sign out', sign_out_path, :method => :delete %>
|
31
|
+
<% else -%>
|
32
|
+
<%= link_to 'Sign in', sign_in_path %>
|
33
|
+
<% end -%>
|
34
|
+
}
|
35
|
+
|
36
|
+
replace_in_file "app/views/layouts/application.html.erb",
|
37
|
+
/(<body>)/,
|
38
|
+
"\\1\n#{links}"
|
39
|
+
end
|
40
|
+
|
41
|
+
When /^I configure "([^"]*)" as the root route$/ do |action|
|
42
|
+
replace_in_file "config/routes.rb",
|
43
|
+
/(routes\.draw do)/,
|
44
|
+
"\\1\nroot :to => '#{action}'"
|
45
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
When /^I configure ActionMailer to use "([^"]+)" as a host$/ do |host|
|
2
|
+
mailer_config = "config.action_mailer.default_url_options = { :host => '#{host}' }"
|
3
|
+
replace_in_file "config/application.rb",
|
4
|
+
/(class .* < Rails::Application)/,
|
5
|
+
"\\1\n#{mailer_config}"
|
6
|
+
end
|
7
|
+
|
8
|
+
When /^I add the "([^"]*)" gem from this project as a dependency$/ do |gem_name|
|
9
|
+
append_to_file('Gemfile', %{\ngem "#{gem_name}", :path => "#{PROJECT_ROOT}"})
|
10
|
+
end
|
11
|
+
|
12
|
+
When /^I disable Capybara Javascript emulation$/ do
|
13
|
+
replace_in_file "features/support/env.rb",
|
14
|
+
%{require 'cucumber/rails/capybara_javascript_emulation'},
|
15
|
+
"# Disabled"
|
16
|
+
end
|
17
|
+
|
18
|
+
When /^I give a more detailed new account message$/ do
|
19
|
+
account_message = "Please sign up now."
|
20
|
+
replace_in_file 'app/views/accounts/new.html.erb',
|
21
|
+
%r{(</h2>)},
|
22
|
+
"\\1\n#{account_message}"
|
23
|
+
|
24
|
+
scenario = <<-HERE
|
25
|
+
Feature: The new account page should have a desperate message
|
26
|
+
Scenario: New account message
|
27
|
+
Given a plan exists with a name of "Free"
|
28
|
+
When I go to the sign up page for the "Free" plan
|
29
|
+
Then I should see "Please sign up now"
|
30
|
+
HERE
|
31
|
+
create_file('features/new_account_message.feature', scenario)
|
32
|
+
end
|
33
|
+
|
34
|
+
When /^I add a custom layout to the accounts index$/ do
|
35
|
+
in_current_dir do
|
36
|
+
FileUtils.cp("app/views/layouts/application.html.erb",
|
37
|
+
"app/views/layouts/custom.html.erb")
|
38
|
+
end
|
39
|
+
replace_in_file 'app/views/layouts/custom.html.erb',
|
40
|
+
%r{(<body>)},
|
41
|
+
"\\1\nCustom Layout Content"
|
42
|
+
layout_config = "config.saucy.layouts.accounts.index = 'custom'"
|
43
|
+
replace_in_file "config/application.rb",
|
44
|
+
/(class .* < Rails::Application)/,
|
45
|
+
"\\1\n#{layout_config}"
|
46
|
+
|
47
|
+
create_file('features/custom_accounts_index_layout.feature', <<-SCENARIO)
|
48
|
+
Feature: The accounts index should have a custom layout
|
49
|
+
Scenario: Custom layout
|
50
|
+
Given I am signed up as "email@person.com/password"
|
51
|
+
And the following projects exist:
|
52
|
+
| name | account |
|
53
|
+
| ClothesPin | name: One |
|
54
|
+
| Talkr | name: Two |
|
55
|
+
| Fabio | name: One |
|
56
|
+
And "email@person.com" is a member of the "ClothesPin" project
|
57
|
+
And "email@person.com" is a member of the "Talkr" project
|
58
|
+
When I go to the sign in page
|
59
|
+
And I sign in as "email@person.com/password"
|
60
|
+
And I go to the dashboard page
|
61
|
+
Then I should see "Custom Layout Content"
|
62
|
+
SCENARIO
|
63
|
+
end
|
64
|
+
|
65
|
+
When /^I copy the specs for this project$/ do
|
66
|
+
in_current_dir do
|
67
|
+
FileUtils.cp_r(File.join(PROJECT_ROOT, 'spec'), '.')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
Then /^at least one example should have run$/ do
|
72
|
+
Then %{the output should match /[1-9]0* examples/}
|
73
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/base'
|
3
|
+
|
4
|
+
module Saucy
|
5
|
+
module Generators
|
6
|
+
# Base generator for Saucy generators. Setups up the source root.
|
7
|
+
class Base < ::Rails::Generators::Base
|
8
|
+
# @return [String] source root for tempates within a saucy generator
|
9
|
+
def self.source_root
|
10
|
+
@_saucy_source_root ||=
|
11
|
+
File.expand_path(File.join(File.dirname(__FILE__),
|
12
|
+
generator_name,
|
13
|
+
'templates'))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'generators/saucy/base'
|
2
|
+
|
3
|
+
module Saucy
|
4
|
+
module Generators
|
5
|
+
class FeaturesGenerator < Base
|
6
|
+
|
7
|
+
desc <<DESC
|
8
|
+
Description:
|
9
|
+
Copy saucy cucumber features files to your application.
|
10
|
+
DESC
|
11
|
+
|
12
|
+
def copy_feature_files
|
13
|
+
directory "features", "features/saucy"
|
14
|
+
directory "step_definitions", "features/step_definitions/saucy"
|
15
|
+
directory "support", "features/support/saucy"
|
16
|
+
template "README", "features/saucy/README"
|
17
|
+
template "README", "features/step_definitions/saucy/README"
|
18
|
+
empty_directory "spec"
|
19
|
+
empty_directory "spec/factories"
|
20
|
+
template "factories.rb", "spec/factories/saucy_factories.rb"
|
21
|
+
end
|
22
|
+
|
23
|
+
def remove_conflicting_files
|
24
|
+
remove_file "features/clearance/visitor_signs_up.feature"
|
25
|
+
remove_file "spec/factories/clearance.rb"
|
26
|
+
remove_file "test/factories/clearance.rb"
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_paths
|
30
|
+
paths = <<-PATHS
|
31
|
+
when 'the list of accounts'
|
32
|
+
accounts_path
|
33
|
+
when 'the list of plans page'
|
34
|
+
plans_path
|
35
|
+
when /^the memberships page for the "([^"]+)" account$/
|
36
|
+
account = Account.find_by_name!($1)
|
37
|
+
account_memberships_path(account)
|
38
|
+
when /^the projects page for the "([^"]+)" account$/
|
39
|
+
account = Account.find_by_name!($1)
|
40
|
+
account_projects_path(account)
|
41
|
+
when /settings page for the "([^"]+)" account$/i
|
42
|
+
account = Account.find_by_name!($1)
|
43
|
+
edit_account_path(account)
|
44
|
+
when /settings page$/
|
45
|
+
edit_profile_path
|
46
|
+
when /dashboard page$/
|
47
|
+
accounts_path
|
48
|
+
when /sign up page for the "([^"]+)" plan$/i
|
49
|
+
plan = Plan.find_by_name!($1)
|
50
|
+
new_plan_account_path(plan)
|
51
|
+
when /^the billing page for the "([^"]+)" account$/
|
52
|
+
account = Account.find_by_name!($1)
|
53
|
+
account_billing_path(account)
|
54
|
+
when /^the upgrade plan page for the "([^"]+)" account$/
|
55
|
+
account = Account.find_by_name!($1)
|
56
|
+
edit_account_plan_path(account)
|
57
|
+
when /^the new project page for the newest account by "([^"]*)"$/
|
58
|
+
user = User.find_by_email!($1)
|
59
|
+
account = user.accounts.order("id desc").first
|
60
|
+
new_account_project_path(account)
|
61
|
+
when /^the "([^"]*)" project page$/
|
62
|
+
project = Project.find_by_name!($1)
|
63
|
+
account_project_path(project.account, project)
|
64
|
+
when /^the new project page for the "([^"]+)" account$/
|
65
|
+
account = Account.find_by_name!($1)
|
66
|
+
new_account_project_path(account)
|
67
|
+
|
68
|
+
|
69
|
+
PATHS
|
70
|
+
|
71
|
+
replace_in_file "features/support/paths.rb",
|
72
|
+
"case page_name",
|
73
|
+
"case page_name\n#{paths}"
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def replace_in_file(relative_path, find, replace)
|
79
|
+
path = File.join(destination_root, relative_path)
|
80
|
+
contents = IO.read(path)
|
81
|
+
unless contents.gsub!(find, replace)
|
82
|
+
raise "#{find.inspect} not found in #{relative_path}"
|
83
|
+
end
|
84
|
+
File.open(path, "w") { |file| file.write(contents) }
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
@@ -0,0 +1,71 @@
|
|
1
|
+
Factory.sequence :email do |n|
|
2
|
+
"user#{n}@example.com"
|
3
|
+
end
|
4
|
+
|
5
|
+
Factory.sequence :name do |n|
|
6
|
+
"name#{n}"
|
7
|
+
end
|
8
|
+
|
9
|
+
Factory.define :user do |user|
|
10
|
+
user.name { "test user" }
|
11
|
+
user.email { Factory.next :email }
|
12
|
+
user.password { "password" }
|
13
|
+
end
|
14
|
+
|
15
|
+
Factory.define :account do |f|
|
16
|
+
f.name { Factory.next(:name) }
|
17
|
+
f.keyword { Factory.next(:name) }
|
18
|
+
f.association :plan
|
19
|
+
end
|
20
|
+
|
21
|
+
Factory.define :paid_account, :parent => :account do |f|
|
22
|
+
f.cardholder_name { "Ralph Robot" }
|
23
|
+
f.billing_email { "ralph@example.com" }
|
24
|
+
f.card_number { "4111111111111111" }
|
25
|
+
f.verification_code { "123" }
|
26
|
+
f.expiration_month { 5 }
|
27
|
+
f.expiration_year { 2012 }
|
28
|
+
f.association :plan, :factory => :paid_plan
|
29
|
+
end
|
30
|
+
|
31
|
+
Factory.define :membership do |f|
|
32
|
+
f.association :user
|
33
|
+
f.association :account
|
34
|
+
end
|
35
|
+
|
36
|
+
Factory.define :signup do |f|
|
37
|
+
f.email { Factory.next :email }
|
38
|
+
f.password { "password" }
|
39
|
+
f.association :plan
|
40
|
+
end
|
41
|
+
|
42
|
+
Factory.define :project do |f|
|
43
|
+
f.association :account
|
44
|
+
f.name { Factory.next(:name) }
|
45
|
+
f.keyword { Factory.next(:name) }
|
46
|
+
end
|
47
|
+
|
48
|
+
Factory.define :permission do |f|
|
49
|
+
f.association :membership
|
50
|
+
f.project {|a| a.association(:project, :account => a.membership.account)}
|
51
|
+
end
|
52
|
+
|
53
|
+
Factory.define :invitation do |f|
|
54
|
+
f.email { Factory.next(:email) }
|
55
|
+
f.association :account
|
56
|
+
f.association :sender, :factory => :user
|
57
|
+
end
|
58
|
+
|
59
|
+
Factory.define :plan do |f|
|
60
|
+
f.name 'Free'
|
61
|
+
end
|
62
|
+
|
63
|
+
Factory.define :paid_plan, :parent => :plan do |f|
|
64
|
+
f.name 'Paid'
|
65
|
+
f.price 1
|
66
|
+
end
|
67
|
+
|
68
|
+
Factory.define :limit do |f|
|
69
|
+
f.name { Factory.next(:name) }
|
70
|
+
f.association :plan
|
71
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Feature: edit profile
|
2
|
+
|
3
|
+
Scenario: Normal users can edit themselves
|
4
|
+
Given I am signed in
|
5
|
+
When I go to the settings page
|
6
|
+
And I fill in "Name" with "Name Change"
|
7
|
+
And I press "Update"
|
8
|
+
And I go to the settings page
|
9
|
+
Then the "Name" field should contain "Name Change"
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Feature: edit permissions for a project
|
2
|
+
|
3
|
+
As an admin,
|
4
|
+
I can manage permissions for each project in my account, so only project
|
5
|
+
members can edit blurbs.
|
6
|
+
|
7
|
+
Scenario: edit permissions for a project
|
8
|
+
Given the following project exists:
|
9
|
+
| name | account |
|
10
|
+
| Stocknames | name: thoughtbot |
|
11
|
+
And the following users exist:
|
12
|
+
| name | email |
|
13
|
+
| Bill | bill@example.com |
|
14
|
+
| Jane | jane@example.com |
|
15
|
+
| Jeff | jeff@example.com |
|
16
|
+
| Hank | hank@example.com |
|
17
|
+
And I am signed in as an admin of the "Stocknames" project
|
18
|
+
And "bill@example.com" is a member of the "Stocknames" project
|
19
|
+
And "jane@example.com" is a member of the "thoughtbot" account
|
20
|
+
And "hank@example.com" is an admin of the "Stocknames" project
|
21
|
+
When I go to the settings page for the "thoughtbot" account
|
22
|
+
And I follow "Projects" within ".subnav"
|
23
|
+
And I follow "Stocknames" within "ul.projects"
|
24
|
+
Then "Bill" should be listed as a member
|
25
|
+
And "Hank" should be listed as an admin
|
26
|
+
And "Jane" should be listed as a non-member
|
27
|
+
And I should not see "Jeff"
|
28
|
+
When I check "Jane"
|
29
|
+
And I uncheck "Bill"
|
30
|
+
And I press "Update"
|
31
|
+
Then I should see "Project was updated"
|
32
|
+
When I follow "Stocknames" within "ul.projects"
|
33
|
+
Then the "Bill" checkbox should not be checked
|
34
|
+
And the "Jane" checkbox should be checked
|
35
|
+
And the "Hank" checkbox should be checked
|
36
|
+
And I should not see "Jeff"
|
37
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
Feature: edit permissions for a user
|
2
|
+
|
3
|
+
As an admin,
|
4
|
+
I can edit permissions for which users are on which projects and vice versa.
|
5
|
+
|
6
|
+
Scenario: edit permissions for a user
|
7
|
+
Given the following projects exists:
|
8
|
+
| name | account |
|
9
|
+
| Alpha | name: thoughtbot |
|
10
|
+
| Beta | name: thoughtbot |
|
11
|
+
| Delta | name: other |
|
12
|
+
Given the following user exists:
|
13
|
+
| name | email |
|
14
|
+
| Sam | sam@example.com |
|
15
|
+
And I am signed in as an admin of the "thoughtbot" account
|
16
|
+
And "sam@example.com" is a member of the "Alpha" project
|
17
|
+
When I go to the settings page for the "thoughtbot" account
|
18
|
+
And I follow "Users"
|
19
|
+
And I follow "Sam"
|
20
|
+
Then the "Alpha" checkbox should be checked
|
21
|
+
And the "Beta" checkbox should not be checked
|
22
|
+
And I should not see "Delta"
|
23
|
+
When I check "Beta"
|
24
|
+
And I uncheck "Alpha"
|
25
|
+
And I press "Update"
|
26
|
+
Then I should see "Permissions updated"
|
27
|
+
When I follow "Sam"
|
28
|
+
Then the "Alpha" checkbox should not be checked
|
29
|
+
And the "Beta" checkbox should be checked
|
30
|
+
And I should not see "Delta"
|
31
|
+
|
32
|
+
Scenario: promote a user to an admin
|
33
|
+
Given an account exists with a name of "Test"
|
34
|
+
And I am signed in as an admin of the "Test" account
|
35
|
+
And an user exists with a name of "Frank"
|
36
|
+
And the following memberships exist:
|
37
|
+
| account | user | admin |
|
38
|
+
| name: Test | name: Frank | false |
|
39
|
+
When I go to the memberships page for the "Test" account
|
40
|
+
And I follow "Frank"
|
41
|
+
And I check "Admin"
|
42
|
+
And I press "Update"
|
43
|
+
Then I should see "Permissions updated"
|
44
|
+
When I go to the memberships page for the "Test" account
|
45
|
+
And I follow "Frank"
|
46
|
+
Then the "Admin" checkbox should be checked
|
47
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Feature: Manage account
|
2
|
+
As a user
|
3
|
+
In order to properly represent my organization
|
4
|
+
I want to be able to edit account details
|
5
|
+
|
6
|
+
Scenario: Edit account details
|
7
|
+
Given an account exists with a name of "Test"
|
8
|
+
And I am signed in as an admin of the "Test" account
|
9
|
+
When I go to the settings page
|
10
|
+
And I follow "Test"
|
11
|
+
When I fill in "Account name" with "Name Change"
|
12
|
+
And I press "Update"
|
13
|
+
When I follow "Name Change"
|
14
|
+
Then the "Account name" field should contain "Name Change"
|
15
|
+
|
16
|
+
Scenario: Account Settings Tab Bar
|
17
|
+
Given an account exists with a name of "Test"
|
18
|
+
And I am signed in as an admin of the "Test" account
|
19
|
+
And a project named "Projection" exists under the "Test" account
|
20
|
+
And the user "captain@awesome.com" exists under the "Test" account
|
21
|
+
When I go to the settings page for the "Test" account
|
22
|
+
And I follow "Projects" within ".subnav"
|
23
|
+
Then I should see "Projection"
|
24
|
+
When I follow "Users"
|
25
|
+
Then I should see "captain@awesome.com"
|
26
|
+
|
27
|
+
Scenario: Delete account
|
28
|
+
Given an account exists with a name of "Chocolate"
|
29
|
+
And I am signed in as an admin of the "Chocolate" account
|
30
|
+
When I go to the settings page for the "Chocolate" account
|
31
|
+
And I follow "Delete"
|
32
|
+
Then I should see "Your account has been deleted"
|
33
|
+
When I go to the dashboard page
|
34
|
+
Then I should not see "Chocolate"
|
35
|
+
|