saucy 0.4.10 → 0.5.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,26 @@
1
+ 0.5.0
2
+
3
+ Added the ability to archive projects. Archived projects are not included in
4
+ an accounts `projects_count`.
5
+
6
+ To upgrade to this version add the following column to the projects table:
7
+
8
+ add_column :projects, :archived, :default => false, :null => false
9
+
10
+ This version adds a list of archived projects to the projects index of an
11
+ account. An introduced headers to these two lists. Archived projects have
12
+ a "View Project" link, which is how the user can view an archived project.
13
+ You will probably want to style this list, headers, and link.
14
+
15
+ It also adds an Archive link on the project's edit page. You will probably
16
+ want to style this link.
17
+
18
+ It is up to your application to provide any additional logic about what
19
+ limitations are present for archived projects (for example, not being able to
20
+ create new comments on them).
21
+
22
+ 0.4.10
23
+
24
+ A user following an invite link who is already signed in and whose email
25
+ address matches the one in the invite automatically accepts the invite when
26
+ following the link.
@@ -0,0 +1,27 @@
1
+ class ArchivesController < ApplicationController
2
+ before_filter :authenticate
3
+ before_filter :authorize_admin
4
+ before_filter :ensure_account_within_projects_limit
5
+
6
+ def create
7
+ @project = current_project
8
+ @project.archived = true
9
+ @project.save
10
+ flash[:success] = "Project has been archived"
11
+ redirect_to account_projects_url(current_project.account)
12
+ end
13
+
14
+ def destroy
15
+ @project = current_project
16
+ @project.archived = false
17
+ @project.save
18
+ flash[:success] = "Project unarchived"
19
+ redirect_to account_projects_url(current_project.account)
20
+ end
21
+
22
+ private
23
+
24
+ def ensure_account_within_projects_limit
25
+ ensure_account_within_limit("projects")
26
+ end
27
+ end
@@ -3,6 +3,15 @@
3
3
  <% end -%>
4
4
 
5
5
  <div class="actions">
6
+ <% if !@project.archived? -%>
7
+ <%= link_to account_project_archive_path(@project.account, @project), :method => 'post', :confirm => 'Are you sure you want to archive this project?', :class => 'action' do %>
8
+ <span class="archive_item">Archive this project</span>
9
+ <% end -%>
10
+ <% else -%>
11
+ <%= link_to account_project_archive_path(@project.account, @project), :method => 'delete', :class => 'action' do %>
12
+ <span class="unarchive_item">Unarchive this project</span>
13
+ <% end -%>
14
+ <% end -%>
6
15
  <%= link_to project_path(@project), :method => 'delete', :confirm => 'Are you sure you want to delete this project and all associated content?', :class => 'action' do %>
7
16
  <span class="delete_item">Remove this project</span>
8
17
  <% end -%>
@@ -4,12 +4,25 @@
4
4
 
5
5
  <%= render :partial => 'accounts/subnav' %>
6
6
 
7
- <ul class="projects">
8
- <% @projects.each do |project| -%>
7
+ <h3>Active Projects</h3>
8
+ <ul class="projects active">
9
+ <% @active_projects.each do |project| -%>
9
10
  <%= content_tag_for :li, project do -%>
10
- <%= link_to h(project.name), edit_project_path(project) %>
11
+ <%= link_to h(project.name), edit_project_path(project), :class => "edit" %>
11
12
  <% end -%>
12
13
  <% end -%>
13
14
  </ul>
14
15
 
15
16
  <%= link_to 'New Project', new_account_project_path(current_account), :class => "button" %>
17
+
18
+ <% if @archived_projects.any? -%>
19
+ <h3>Archived Projects</h3>
20
+ <ul class="projects archived">
21
+ <% @archived_projects.each do |project| -%>
22
+ <%= content_tag_for :li, project do -%>
23
+ <%= link_to h(project.name), edit_project_path(project), :class => "edit" %>
24
+ <%= link_to "View Project", project_path(project), :class => "view" %>
25
+ <% end -%>
26
+ <% end -%>
27
+ </ul>
28
+ <% end -%>
data/config/routes.rb CHANGED
@@ -6,7 +6,9 @@ Rails.application.routes.draw do
6
6
  through :accounts do
7
7
  resource :billing
8
8
  resource :plan
9
- resources :projects
9
+ resources :projects do
10
+ resource :archive, :only => [:create, :destroy]
11
+ end
10
12
  resources :memberships, :only => [:index, :edit, :update, :destroy]
11
13
  resources :invitations, :only => [:show, :update, :new, :create]
12
14
  end
@@ -34,17 +34,53 @@ Feature: Manage Projects
34
34
  And I press "Update"
35
35
  Then I should see "Name Change"
36
36
 
37
+ Scenario: Archive a project
38
+ Given the following project exists:
39
+ | account | name |
40
+ | name: Test | Project 1 |
41
+ When I go to the projects page for the "Test" account
42
+ And I follow "Project 1" within "ul.projects"
43
+ And I follow "Archive this project"
44
+ And I should see "Project 1" within "ul.projects.archived"
45
+
46
+ Scenario: Unarchive a project
47
+ Given the following project exists:
48
+ | account | name | archived |
49
+ | name: Test | Project 1 | true |
50
+ When I go to the projects page for the "Test" account
51
+ And I follow "Project 1" within "ul.projects.archived"
52
+ And I follow "Unarchive this project"
53
+ And I should see "Project 1" within "ul.projects.active"
54
+
55
+ Scenario: Unarchive a project when at the account limit
56
+ Given the following limit exists for the "Test" account:
57
+ | name | value |
58
+ | projects | 1 |
59
+ And the following projects exist:
60
+ | account | name | archived |
61
+ | name: Test | Project 1 | false |
62
+ | name: Test | Project 2 | true |
63
+ When I go to the projects page for the "Test" account
64
+ And I follow "Project 2"
65
+ And I follow "Unarchive this project"
66
+ Then I should see "at your limit"
67
+ When I go to the projects page for the "Test" account
68
+ And I should see "Project 1" within "ul.projects.active"
69
+ And I should see "Project 2" within "ul.projects.archived"
70
+
37
71
  Scenario: View all projects
38
72
  Given the following projects exist:
39
- | account | name |
40
- | name: Test | Project 1 |
41
- | name: Test | Project 2 |
42
- | name: Other | Project 3 |
43
- | name: Another | Project 4 |
73
+ | account | name | archived |
74
+ | name: Test | Project 1 | false |
75
+ | name: Test | Project 2 | false |
76
+ | name: Test | Project 3 | true |
77
+ | name: Other | Project 3 | false |
78
+ | name: Another | Project 4 | false |
44
79
  And "joe@example.com" is a member of the "Other" account
45
80
  When I go to the projects page for the "Test" account
46
- Then I should see "Project 1" within "ul.projects"
47
- And I should see "Project 2" within "ul.projects"
81
+ Then I should see "Project 1" within "ul.projects.active"
82
+ And I should see "Project 2" within "ul.projects.active"
83
+ And I should see "Project 3" within "ul.projects.archived"
48
84
  But I should not see "Project 3" within "ul.projects"
49
85
  And I should not see "Project 4" within "ul.projects"
50
86
 
@@ -59,6 +59,7 @@ class CreateSaucyTables < ActiveRecord::Migration
59
59
  table.string :name
60
60
  table.string :keyword
61
61
  table.integer :account_id
62
+ table.boolean :archived, :default => false, :null => false
62
63
  table.datetime :created_at
63
64
  table.datetime :updated_at
64
65
  end
data/lib/saucy/account.rb CHANGED
@@ -77,7 +77,7 @@ module Saucy
77
77
  end
78
78
 
79
79
  def projects_count
80
- projects.count
80
+ projects.active.count
81
81
  end
82
82
  end
83
83
 
data/lib/saucy/project.rb CHANGED
@@ -44,6 +44,14 @@ module Saucy
44
44
  where(['projects.id IN(?)', user.project_ids])
45
45
  end
46
46
 
47
+ def archived
48
+ where(:archived => true)
49
+ end
50
+
51
+ def active
52
+ where(:archived => false)
53
+ end
54
+
47
55
  def by_name
48
56
  order("projects.name")
49
57
  end
@@ -50,7 +50,8 @@ module Saucy
50
50
  end
51
51
 
52
52
  def index
53
- @projects = current_account.projects
53
+ @active_projects = current_account.projects.active
54
+ @archived_projects = current_account.projects.archived
54
55
  end
55
56
 
56
57
  private
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArchivesController, "routes" do
4
+ it { should route(:delete, "/accounts/abc/projects/def/archive").
5
+ to(:action => :destroy, :account_id => 'abc', :project_id => 'def') }
6
+ it { should route(:post, "/accounts/abc/projects/def/archive").
7
+ to(:action => :create, :account_id => 'abc', :project_id => 'def') }
8
+ end
9
+
10
+ describe ArchivesController, "destroy", :as => :project_admin do
11
+ before do
12
+ delete :destroy, :project_id => project.to_param, :account_id => account.to_param
13
+ end
14
+
15
+ it { should set_the_flash.to(/unarchived/) }
16
+
17
+ it "should redirect to account_projects_url" do
18
+ should redirect_to(account_projects_url(account))
19
+ end
20
+ end
21
+
22
+ describe ArchivesController, "archive", :as => :project_admin do
23
+ before do
24
+ post :create, :project_id => project.to_param, :account_id => account.to_param
25
+ end
26
+
27
+ it { should set_the_flash.to(/archived/) }
28
+
29
+ it "should redirect to account_projects_url" do
30
+ should redirect_to(account_projects_url(account))
31
+ end
32
+ end
33
+
34
+ describe ArchivesController, "as a non-admin", :as => :project_member do
35
+ it { should deny_access.on(:delete, :destroy, :project_id => project.to_param,
36
+ :account_id => account.to_param).
37
+ flash(/admin/) }
38
+
39
+ it { should deny_access.on(:post, :create, :account_id => account.to_param, :project_id => project.to_param).
40
+ flash(/admin/) }
41
+ end
@@ -104,6 +104,7 @@ describe ProjectsController, "index", :as => :account_admin do
104
104
  let(:projects) { ['one', 'two'] }
105
105
 
106
106
  before do
107
+ projects.stubs(:archived => projects, :active => projects)
107
108
  Account.stubs(:find_by_keyword! => account)
108
109
  account.stubs(:projects => projects)
109
110
  get :index, :account_id => account.to_param
@@ -115,8 +116,9 @@ describe ProjectsController, "index", :as => :account_admin do
115
116
  end
116
117
 
117
118
  it "assigns projects" do
118
- account.should have_received(:projects)
119
- should assign_to(:projects).with(projects)
119
+ account.should have_received(:projects).times(2)
120
+ should assign_to(:active_projects).with(projects)
121
+ should assign_to(:archived_projects).with(projects)
120
122
  end
121
123
  end
122
124
 
@@ -87,8 +87,9 @@ describe Account do
87
87
  subject.users_count.should == 1
88
88
  end
89
89
 
90
- it "has a count of projects" do
91
- Factory(:project, :account => subject)
90
+ it "has a count of active projects" do
91
+ Factory(:project, :account => subject, :archived => false)
92
+ Factory(:project, :account => subject, :archived => true)
92
93
  subject.projects_count.should == 1
93
94
  end
94
95
 
@@ -36,6 +36,21 @@ describe Project do
36
36
  Project.by_name.map(&:name).should == %w(abc def ghi)
37
37
  end
38
38
 
39
+ context "archived and non-archived projects" do
40
+ before do
41
+ @archived = [Factory(:project, :archived => true), Factory(:project, :archived => true)]
42
+ @active = [Factory(:project, :archived => false)]
43
+ end
44
+
45
+ it "returns only archived projects with archived" do
46
+ Project.archived.all.should == @archived
47
+ end
48
+
49
+ it "returns only active projects with active" do
50
+ Project.active.all.should == @active
51
+ end
52
+ end
53
+
39
54
  it "should give its keyword for to_param" do
40
55
  project = Factory(:project)
41
56
  project.to_param.should == project.keyword
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: 27
4
+ hash: 11
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 4
9
- - 10
10
- version: 0.4.10
8
+ - 5
9
+ - 0
10
+ version: 0.5.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - thoughtbot, inc.
@@ -125,6 +125,7 @@ extensions: []
125
125
  extra_rdoc_files: []
126
126
 
127
127
  files:
128
+ - CHANGELOG.md
128
129
  - Gemfile
129
130
  - Gemfile.lock
130
131
  - Rakefile
@@ -132,6 +133,7 @@ files:
132
133
  - config/locales/en.yml
133
134
  - config/routes.rb
134
135
  - app/controllers/accounts_controller.rb
136
+ - app/controllers/archives_controller.rb
135
137
  - app/controllers/billings_controller.rb
136
138
  - app/controllers/invitations_controller.rb
137
139
  - app/controllers/memberships_controller.rb
@@ -238,6 +240,7 @@ files:
238
240
  - lib/generators/saucy/features/templates/README
239
241
  - spec/controllers/accounts_controller_spec.rb
240
242
  - spec/controllers/application_controller_spec.rb
243
+ - spec/controllers/archives_controller_spec.rb
241
244
  - spec/controllers/invitations_controller_spec.rb
242
245
  - spec/controllers/memberships_controller_spec.rb
243
246
  - spec/controllers/plans_controller_spec.rb