saucy 0.7.0 → 0.7.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.
@@ -1,3 +1,15 @@
1
+ 0.7.1
2
+
3
+ Introduce a project dropdown, include it with:
4
+
5
+ render :partial => "shared/project_dropdown"
6
+
7
+ Saucy provides the javascript for this dropdown, but not the CSS or the image
8
+ for the dropdown. The Javascript depends on jQuery.
9
+
10
+ Also, adds the ability to move a project to another project that you are an
11
+ admin on.
12
+
1
13
  0.7.0
2
14
 
3
15
  Split Saucy::Configuration.mailer_sender into support_email_address and manager_email_address.
@@ -8,6 +8,10 @@ class Membership < ActiveRecord::Base
8
8
  validates_presence_of :account_id
9
9
  validates_uniqueness_of :user_id, :scope => :account_id
10
10
 
11
+ def self.admin
12
+ where(:admin => true)
13
+ end
14
+
11
15
  def name
12
16
  user.name
13
17
  end
@@ -11,14 +11,26 @@
11
11
  <%= value %>
12
12
  <% end -%>
13
13
 
14
+ <% if signed_in? -%>
15
+ <%= render :partial => 'shared/project_dropdown' %>
16
+ <% else %>
17
+ <%= link_to root_url do %>
18
+ <h1><%= t("app_name") %></h1>
19
+ <% end %>
20
+ <% end %>
21
+
14
22
  <% if signed_in? -%>
15
23
  <%= link_to 'Sign out', sign_out_path, :method => :delete %>
16
24
  <% else -%>
17
25
  <%= link_to 'Sign in', sign_in_path %>
18
26
  <% end -%>
19
27
 
20
- <%= yield(:subnav) %>
21
- <%= yield(:header) %>
28
+ <%= yield :subnav %>
29
+ <%= yield :header %>
30
+
22
31
  <%= yield %>
32
+
33
+ <%= javascript_include_tag 'jquery' %>
34
+ <%= yield :javascript %>
23
35
  </body>
24
36
  </html>
@@ -1,15 +1,32 @@
1
1
  <%= form.inputs do %>
2
- <%= form.input :name, :hint => project_url(Project.new(:account => current_account, :keyword => 'keyword')).html_safe %>
2
+ <%= form.input :account, :collection => current_user.memberships.admin.collect(&:account) %>
3
+ <%= form.input :name, :hint => project_url(form.object).html_safe %>
3
4
  <%= form.input :keyword, :wrapper_html => { :style => 'display: none' } %>
4
5
  <% if form.object.persisted? -%>
5
6
  <%= form.input :archived, :hint => t('project.archived.hint', :default => "Archived project don't count against your project total. You cannot create or edit stories or discussions.") %>
6
7
  <% end -%>
7
8
  <%= form.input :users, :label => "Admins",
8
9
  :as => :check_boxes,
9
- :collection => admins,
10
+ :collection => form.object.account.admins,
10
11
  :wrapper_html => { :id => "project_admins_input" },
11
12
  :input_html => { :disabled => true } %>
12
- <%= form.input :users, :as => :check_boxes, :collection => non_admins %>
13
+ <% if form.object.account.non_admins.any? -%>
14
+ <%= form.input :users, :as => :check_boxes, :collection => form.object.account.non_admins %>
15
+ <% end -%>
13
16
  <% end %>
14
17
 
18
+ <%= content_for :javascript do -%>
19
+ <%= javascript_tag do %>
20
+ $(function() {
21
+ $('#project_account_id').change(function() {
22
+ if($('#project_account_id').val() != "") {
23
+ console.log(window.location);
24
+ window.location.href = window.location.pathname + '?project[account_id]=' + $('#project_account_id').val();
25
+ return false;
26
+ }
27
+ });
28
+ });
29
+ <% end %>
30
+ <% end -%>
31
+
15
32
  <%= render :partial => "shared/saucy_javascript" %>
@@ -11,10 +11,8 @@
11
11
 
12
12
  <%= render :partial => 'accounts/subnav' %>
13
13
 
14
- <%= semantic_form_for @project do |form| %>
15
- <%= render 'form', :form => form,
16
- :non_admins => current_account.non_admins,
17
- :admins => current_account.admins %>
14
+ <%= semantic_form_for @project, :url => account_project_url(current_account, @project) do |form| %>
15
+ <%= render 'form', :form => form %>
18
16
 
19
17
  <%= form.buttons do %>
20
18
  <%= form.commit_button %>
@@ -5,9 +5,7 @@
5
5
  <%= render :partial => 'accounts/subnav' %>
6
6
 
7
7
  <%= semantic_form_for(@project, :url => account_projects_url(current_account)) do |form| %>
8
- <%= render 'form', :form => form,
9
- :non_admins => current_account.non_admins,
10
- :admins => current_account.admins %>
8
+ <%= render 'form', :form => form %>
11
9
  <%= form.buttons do -%>
12
10
  <%= form.commit_button %>
13
11
  <li><%= link_to 'Cancel', account_projects_path(current_account) %></li>
@@ -0,0 +1,55 @@
1
+ <% if current_user.projects.active.any? -%>
2
+ <ul id="project-selection">
3
+ <li>
4
+ <h1>
5
+ <%= link_to current_project? ? project_path(current_project) : root_url do -%>
6
+ <% if current_project? -%>
7
+ <span><%= current_project.name %></span>
8
+ <% else %>
9
+ <span>Projects</span>
10
+ <% end -%>
11
+ <% if current_user.memberships.admin.any? || current_user.projects.active.any? -%>
12
+ <img src="/images/arrow-down.png" alt="arrow down" />
13
+ <% end -%>
14
+ <% end %>
15
+ </h1>
16
+ <ul>
17
+ <% current_user.projects.active.each do |project| %>
18
+ <li><%= link_to project.name, project_path(project) -%></li>
19
+ <% end %>
20
+ <% if current_user.memberships.admin.any? -%>
21
+ <li>
22
+ <%= link_to current_account? && current_user.admin_of?(current_account) ? new_project_path(current_account) : new_project_path(current_user.memberships.admin.first.account) do %>
23
+ &#43; Create a new project
24
+ <% end %>
25
+ </li>
26
+ <% end -%>
27
+ </ul>
28
+ </li>
29
+ </ul>
30
+ <% end -%>
31
+
32
+ <%= content_for :javascript do -%>
33
+ <%= javascript_tag do %>
34
+ $(function() {
35
+ $('#project-selection h1 a').click(function() {
36
+ var dropdownbutton = $('#project-selection h1 a');
37
+ var dropdownlist = $('#project-selection li ul');
38
+ if(dropdownbutton.hasClass("expanded")) {
39
+ dropdownbutton.removeClass("expanded");
40
+ dropdownlist.removeClass("expanded");
41
+ } else {
42
+ dropdownbutton.addClass("expanded");
43
+ dropdownlist.addClass("expanded");
44
+ }
45
+ return false;
46
+ });
47
+
48
+ $('html *').live('click', function() {
49
+ if($(this).parents('.expanded').length == 0) {
50
+ $('.expanded').removeClass('expanded');
51
+ }
52
+ });
53
+ });
54
+ <% end %>
55
+ <% end -%>
@@ -19,9 +19,11 @@ Feature: generate a saucy application and run rake
19
19
  gem "shoulda"
20
20
  gem "launchy"
21
21
  gem "timecop"
22
+ gem "jquery-rails"
22
23
  """
23
24
  When I add the "saucy" gem from this project as a dependency
24
25
  And I successfully run "bundle install --local"
26
+ And I successfully run "rails generate jquery:install --force"
25
27
  And I bootstrap the application for clearance
26
28
  And I bootstrap the application for saucy
27
29
 
@@ -58,6 +58,14 @@ DESC
58
58
  user = User.find_by_email!($1)
59
59
  account = user.accounts.order("created_at desc").first
60
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
+
61
69
  PATHS
62
70
 
63
71
  replace_in_file "features/support/paths.rb",
@@ -4,13 +4,15 @@ Feature: Manage Projects
4
4
  In order to have a project for each of my software applications
5
5
 
6
6
  Background:
7
- Given the following account exists:
8
- | name | keyword |
9
- | Test | test |
7
+ Given the following accounts exist:
8
+ | name | keyword |
9
+ | Test | test |
10
+ | Another | another |
10
11
  And the following user exists:
11
12
  | name | email |
12
13
  | Joe User | joe@example.com |
13
14
  And "joe@example.com" is an admin of the "Test" account
15
+ And "joe@example.com" is an admin of the "Another" account
14
16
  And I sign in as "joe@example.com"
15
17
 
16
18
  Scenario: Create new project
@@ -34,6 +36,35 @@ Feature: Manage Projects
34
36
  And I press "Update"
35
37
  Then I should see "Name Change"
36
38
 
39
+ @javascript
40
+ Scenario: Move a project
41
+ Given the following projects exist:
42
+ | account | name |
43
+ | name: Test | Project 1 |
44
+ When I go to the projects page for the "Test" account
45
+ And I follow "Project 1" within "ul.projects"
46
+ And I select "Another" from "Account"
47
+ And I press "Update"
48
+ And I should see "Project 1" within "ul.projects"
49
+ Then I should be on the projects page for the "Another" account
50
+
51
+ @javascript
52
+ Scenario: Move a project when account being moved to is at the account limit
53
+ Given the following limit exists for the "Another" account:
54
+ | name | value |
55
+ | projects | 1 |
56
+ And the following projects exist:
57
+ | account | name |
58
+ | name: Test | Project 1 |
59
+ | name: Another | Project 2 |
60
+ When I go to the projects page for the "Test" account
61
+ And I follow "Project 1" within "ul.projects"
62
+ And I select "Another" from "Account"
63
+ And I press "Update"
64
+ Then I should see "at your limit"
65
+ When I go to the projects page for the "Test" account
66
+ Then I should see "Project 1"
67
+
37
68
  Scenario: Archive a project
38
69
  Given the following project exists:
39
70
  | account | name |
@@ -0,0 +1,77 @@
1
+ Feature: Project Dropdown
2
+ As a user
3
+ So that I can work on several projects
4
+ I can easily switch between projects
5
+
6
+ Background:
7
+ Given I am signed in as "user@example.com" under the "Werther's" account
8
+ And the following projects exist:
9
+ | name | account |
10
+ | Pacelog | name: Werther's |
11
+ | Narrator | name: Werther's |
12
+ | Flapper | name: Werther's |
13
+ And "user@example.com" is a member of the "Pacelog" project
14
+
15
+ @javascript
16
+ Scenario: Navigate from one project to another
17
+ Given "user@example.com" is a member of the "Narrator" project
18
+ When I go to the "Pacelog" project page
19
+ Then the page should not include "#project-selection ul.expanded"
20
+ When I click "#project-selection h1 a img"
21
+ Then the page should include "#project-selection ul.expanded"
22
+ And I should not see "Flapper"
23
+ When I follow "Narrator" within "#project-selection ul"
24
+ Then I should be on the "Narrator" project page
25
+
26
+ @javascript
27
+ Scenario: Click outside the projects dropdown to hide it
28
+ Given "user@example.com" is a member of the "Narrator" project
29
+ When I go to the "Narrator" project page
30
+ Then the page should not include "#project-selection ul.expanded"
31
+ When I click "#project-selection h1 a img"
32
+ Then the page should include "#project-selection ul.expanded"
33
+ When I click "body"
34
+ Then the page should not include "#project-selection ul.expanded"
35
+
36
+ Scenario: On project pages, the project name is rendered in the header
37
+ When I go to the "Pacelog" project page
38
+ Then I should see "Pacelog" within "#project-selection h1 a"
39
+
40
+ Scenario: On project pages with multiple projects, the project name and chooser are rendered in the header
41
+ Given "user@example.com" is a member of the "Narrator" project
42
+ When I go to the "Pacelog" project page
43
+ Then I should see "Pacelog" within "#project-selection h1 a"
44
+ And the page should include "#project-selection h1 a img"
45
+
46
+ Scenario: On non-project pages, the account name is rendered in the header with the project chooser
47
+ Given "user@example.com" is an admin of the "Narrator" project
48
+ When I am on the memberships page for the "Werther's" account
49
+ Then I should see "Projects" within "#project-selection h1 a"
50
+ And the page should include "#project-selection h1 a img"
51
+
52
+ When I am on the edit profile page
53
+ Then I should see "Projects" within "#project-selection h1 a"
54
+ And the page should include "#project-selection h1 a img"
55
+
56
+ Scenario: An admin on non-project pages, the new project link goes to the new project page for the right account
57
+ Given "user@example.com" is an admin of the "Narrator" project
58
+ When I am on the edit profile page
59
+ Then I should see "Create a new project" within "#project-selection"
60
+ When I follow "Create a new project"
61
+ Then I should be on the new project page for the "Werther's" account
62
+
63
+ Scenario: An admin on project pages, the new project link goes to the new project page for the right account
64
+ Given "user@example.com" is an admin of the "Narrator" project
65
+ When I go to the "Pacelog" project page
66
+ Then I should see "Create a new project" within "#project-selection"
67
+ When I follow "Create a new project"
68
+ Then I should be on the new project page for the "Werther's" account
69
+
70
+ Scenario: A non-admin on non-project pages, should not see the new project link
71
+ Given "user@example.com" is a member of the "Narrator" project
72
+ When I am on the edit profile page
73
+ Then I should not see "Create a new project" within "#project-selection"
74
+
75
+ Scenario: A non-admin on project pages, should not see the new project link
76
+ When I go to the "Pacelog" project page
77
+ Then I should not see "Create a new project" within "#project-selection"
@@ -27,3 +27,25 @@ end
27
27
  Then /^I there should be a link to the help site$/ do
28
28
  page.should have_css("a[href*='help.example.com']")
29
29
  end
30
+
31
+ Then /^"([^"]*)" should not be expanded$/ do |selector|
32
+ page.has_css?("#{selector}")
33
+ page.has_no_css?("#{selector}.expanded")
34
+ end
35
+
36
+ Then /^"([^"]*)" should be expanded/ do |selector|
37
+ page.has_css?("#{selector}")
38
+ page.has_css?("#{selector}.expanded")
39
+ end
40
+
41
+ When %r{^I click "([^"]*)"$} do |selector|
42
+ find(selector).click
43
+ end
44
+
45
+ Then /^the page should (not )?include "([^"]*)"$/ do |should_not_contain, selector|
46
+ if should_not_contain.present?
47
+ page.should have_no_css(selector)
48
+ else
49
+ page.should have_css(selector)
50
+ end
51
+ end
@@ -9,6 +9,13 @@ Given /^I (?:am signed in|sign in) as an admin of the "([^"]+)" project$/ do |pr
9
9
  When %{I sign in as "#{user.email}"}
10
10
  end
11
11
 
12
+ Given /^I am signed in as "([^"]*)" under the "([^"]*)" account$/ do |email, account_name|
13
+ account = Factory(:account, :name => account_name)
14
+ user = Factory(:user, :email => email)
15
+ membership = Factory(:membership, :user => user, :account => account)
16
+ When %{I sign in as "#{user.email}"}
17
+ end
18
+
12
19
  Given /^I am signed in as an admin of the "([^"]*)" account$/ do |account_name|
13
20
  account = Account.find_by_name!(account_name)
14
21
  user = Factory(:user)
@@ -21,6 +21,8 @@ module Saucy
21
21
  after_create :setup_memberships
22
22
  after_update :update_memberships
23
23
 
24
+ attr_protected :account, :account_id
25
+
24
26
  # We have to define these here instead of mixing them in,
25
27
  # because ActiveRecord does the same.
26
28
 
@@ -110,8 +112,12 @@ module Saucy
110
112
  end
111
113
 
112
114
  def ensure_account_within_limit
115
+ message = "You are at your limit of %{name} for your current plan."
113
116
  if archived_changed? && !archived? && !Limit.can_add_one?("projects", account)
114
- errors.add(:archived, I18n.t("saucy.errors.limited", :default => "You are at your limit of %{name} for your current plan.", :name => 'projects'))
117
+ errors.add(:archived, I18n.t("saucy.errors.limited", :default => message, :name => 'projects'))
118
+ end
119
+ if account_id_changed? && !Limit.can_add_one?("projects", account)
120
+ errors.add(:account_id, I18n.t("saucy.errors.limited", :default => message, :name => 'projects'))
115
121
  end
116
122
  end
117
123
  end
@@ -3,17 +3,22 @@ module Saucy
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
+ helper_method :current_project?
6
7
  before_filter :authorize
7
8
  before_filter :authorize_member, :only => :show
8
9
  before_filter :authorize_admin, :except => [:show]
9
10
  before_filter :ensure_active_account, :only => [:show, :destroy, :index]
10
11
  before_filter :ensure_account_within_projects_limit, :only => [:new, :create]
12
+ before_filter :ensure_admin_for_project_account, :only => [:edit, :create, :update]
11
13
  layout Saucy::Layouts.to_proc
12
14
  end
13
15
 
14
16
  module InstanceMethods
15
17
  def new
16
18
  @project = current_account.projects.build_with_default_permissions
19
+ if @project.keyword.blank?
20
+ @project.keyword = 'keyword'
21
+ end
17
22
  end
18
23
 
19
24
  def create
@@ -27,13 +32,16 @@ module Saucy
27
32
  end
28
33
 
29
34
  def edit
30
- current_project
35
+ @project = current_project
36
+ set_project_account_if_moving
31
37
  end
32
38
 
33
39
  def update
34
- if current_project.update_attributes params[:project]
40
+ @project = current_project
41
+ set_project_account_if_moving
42
+ if @project.update_attributes params[:project]
35
43
  flash[:success] = 'Project was updated.'
36
- redirect_to account_projects_url(current_account)
44
+ redirect_to account_projects_url(@project.account)
37
45
  else
38
46
  render :action => :edit
39
47
  end
@@ -56,13 +64,31 @@ module Saucy
56
64
 
57
65
  private
58
66
 
67
+ def set_project_account_if_moving
68
+ if params[:project] && params[:project][:account_id]
69
+ @project.account_id = params[:project][:account_id]
70
+ end
71
+ end
72
+
59
73
  def current_project
60
74
  @project ||= current_account.projects.find_by_keyword!(params[:id])
61
75
  end
62
76
 
77
+ def current_project?
78
+ params[:id].present?
79
+ end
80
+
63
81
  def ensure_account_within_projects_limit
64
82
  ensure_account_within_limit("projects")
65
83
  end
84
+
85
+ def ensure_admin_for_project_account
86
+ if params[:project] && params[:project][:account_id]
87
+ if !current_user.admin_of?(::Account.find(params[:project][:account_id]))
88
+ redirect_to account_projects_url(current_account), :alert => t('account.permission_denied', :default => "You do not have permission to this account.")
89
+ end
90
+ end
91
+ end
66
92
  end
67
93
  end
68
94
  end
@@ -87,13 +87,73 @@ describe ProjectsController, "update", :as => :project_admin do
87
87
  end
88
88
  end
89
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
+
90
150
  describe ProjectsController, "destroy", :as => :project_admin do
91
151
  before do
92
152
  delete :destroy, :id => project.to_param, :account_id => account.to_param
93
153
  end
94
154
 
95
155
  it { should set_the_flash.to(/deleted/) }
96
- it { should assign_to( :project) }
156
+ it { should assign_to(:project) }
97
157
 
98
158
  it "should redirect to account_projects_url" do
99
159
  should redirect_to(account_projects_url(account))
@@ -14,6 +14,9 @@ describe Project do
14
14
  it { should_not allow_value("HELLO").for(:keyword) }
15
15
  it { should_not allow_value("hello world").for(:keyword) }
16
16
 
17
+ it { should_not allow_mass_assignment_of(:account_id) }
18
+ it { should_not allow_mass_assignment_of(:account) }
19
+
17
20
  it "finds projects visible to a user" do
18
21
  account = Factory(:account)
19
22
  user = Factory(:user)
@@ -66,6 +69,20 @@ describe Project do
66
69
  end
67
70
  end
68
71
 
72
+ context "project moving to an account at its project limit" do
73
+ before do
74
+ @project = Factory(:project)
75
+ @account = Factory(:account)
76
+ Limit.stubs(:can_add_one?).with("projects", @account).returns(false)
77
+ end
78
+
79
+ it "cannot be moved" do
80
+ @project.account = @account
81
+ @project.save.should_not be
82
+ @project.errors[:account_id].first.should match(/at your limit/)
83
+ end
84
+ end
85
+
69
86
  it "should give its keyword for to_param" do
70
87
  project = Factory(:project)
71
88
  project.to_param.should == project.keyword
@@ -14,6 +14,8 @@ describe User, "valid" do
14
14
  account = Factory(:account)
15
15
  Factory(:membership, :user => subject, :admin => true, :account => account)
16
16
  subject.should be_admin_of(account)
17
+
18
+ subject.memberships.admin.first.account.should == account
17
19
  end
18
20
 
19
21
  it "isn't an admin of an account with a non admin membership" 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: 3
5
- prerelease:
4
+ hash: 1
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 7
9
- - 0
10
- version: 0.7.0
9
+ - 1
10
+ version: 0.7.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - thoughtbot, inc.
@@ -18,12 +18,12 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2011-05-05 00:00:00 -04:00
21
+ date: 2011-05-06 00:00:00 -04:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
25
+ name: clearance
25
26
  prerelease: false
26
- type: :runtime
27
27
  requirement: &id001 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
@@ -35,11 +35,11 @@ dependencies:
35
35
  - 11
36
36
  - 0
37
37
  version: 0.11.0
38
- name: clearance
38
+ type: :runtime
39
39
  version_requirements: *id001
40
40
  - !ruby/object:Gem::Dependency
41
+ name: formtastic
41
42
  prerelease: false
42
- type: :runtime
43
43
  requirement: &id002 !ruby/object:Gem::Requirement
44
44
  none: false
45
45
  requirements:
@@ -50,11 +50,11 @@ dependencies:
50
50
  - 1
51
51
  - 2
52
52
  version: "1.2"
53
- name: formtastic
53
+ type: :runtime
54
54
  version_requirements: *id002
55
55
  - !ruby/object:Gem::Dependency
56
+ name: railties
56
57
  prerelease: false
57
- type: :runtime
58
58
  requirement: &id003 !ruby/object:Gem::Requirement
59
59
  none: false
60
60
  requirements:
@@ -66,11 +66,11 @@ dependencies:
66
66
  - 0
67
67
  - 3
68
68
  version: 3.0.3
69
- name: railties
69
+ type: :runtime
70
70
  version_requirements: *id003
71
71
  - !ruby/object:Gem::Dependency
72
+ name: braintree
72
73
  prerelease: false
73
- type: :runtime
74
74
  requirement: &id004 !ruby/object:Gem::Requirement
75
75
  none: false
76
76
  requirements:
@@ -82,11 +82,11 @@ dependencies:
82
82
  - 6
83
83
  - 2
84
84
  version: 2.6.2
85
- name: braintree
85
+ type: :runtime
86
86
  version_requirements: *id004
87
87
  - !ruby/object:Gem::Dependency
88
+ name: sham_rack
88
89
  prerelease: false
89
- type: :runtime
90
90
  requirement: &id005 !ruby/object:Gem::Requirement
91
91
  none: false
92
92
  requirements:
@@ -98,11 +98,11 @@ dependencies:
98
98
  - 3
99
99
  - 3
100
100
  version: 1.3.3
101
- name: sham_rack
101
+ type: :runtime
102
102
  version_requirements: *id005
103
103
  - !ruby/object:Gem::Dependency
104
+ name: sinatra
104
105
  prerelease: false
105
- type: :runtime
106
106
  requirement: &id006 !ruby/object:Gem::Requirement
107
107
  none: false
108
108
  requirements:
@@ -114,11 +114,11 @@ dependencies:
114
114
  - 1
115
115
  - 2
116
116
  version: 1.1.2
117
- name: sinatra
117
+ type: :runtime
118
118
  version_requirements: *id006
119
119
  - !ruby/object:Gem::Dependency
120
+ name: aruba
120
121
  prerelease: false
121
- type: :development
122
122
  requirement: &id007 !ruby/object:Gem::Requirement
123
123
  none: false
124
124
  requirements:
@@ -130,7 +130,7 @@ dependencies:
130
130
  - 2
131
131
  - 6
132
132
  version: 0.2.6
133
- name: aruba
133
+ type: :development
134
134
  version_requirements: *id007
135
135
  description: Clearance-based Rails engine for Software as a Service (Saas) that provides account and project management
136
136
  email: support@thoughtbot.com
@@ -196,6 +196,7 @@ files:
196
196
  - app/views/projects/index.html.erb
197
197
  - app/views/projects/new.html.erb
198
198
  - app/views/projects/show.html.erb
199
+ - app/views/shared/_project_dropdown.html.erb
199
200
  - app/views/shared/_saucy_javascript.html.erb
200
201
  - lib/generators/saucy/base.rb
201
202
  - lib/generators/saucy/features/features_generator.rb
@@ -249,6 +250,7 @@ files:
249
250
  - lib/generators/saucy/features/templates/features/manage_projects.feature
250
251
  - lib/generators/saucy/features/templates/features/manage_users.feature
251
252
  - lib/generators/saucy/features/templates/features/new_account.feature
253
+ - lib/generators/saucy/features/templates/features/project_dropdown.feature
252
254
  - lib/generators/saucy/features/templates/features/sign_up.feature
253
255
  - lib/generators/saucy/features/templates/features/sign_up_paid.feature
254
256
  - lib/generators/saucy/features/templates/features/trial_plans.feature
@@ -314,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
314
316
  requirements: []
315
317
 
316
318
  rubyforge_project:
317
- rubygems_version: 1.6.2
319
+ rubygems_version: 1.3.7
318
320
  signing_key:
319
321
  specification_version: 3
320
322
  summary: Clearance-based Rails engine for SaaS