saucy 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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