stuff_to_do_plugin 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYRIGHT.txt +18 -0
- data/CREDITS.txt +6 -0
- data/GPL.txt +339 -0
- data/README.rdoc +61 -0
- data/Rakefile +38 -0
- data/VERSION +1 -0
- data/app/controllers/stuff_to_do_controller.rb +161 -0
- data/app/helpers/stuff_to_do_helper.rb +88 -0
- data/app/models/stuff_to_do.rb +208 -0
- data/app/models/stuff_to_do_filter.rb +32 -0
- data/app/models/stuff_to_do_mailer.rb +16 -0
- data/app/views/settings/_stuff_to_do_settings.html.erb +27 -0
- data/app/views/stuff_to_do/_issue.html.erb +16 -0
- data/app/views/stuff_to_do/_item.html.erb +5 -0
- data/app/views/stuff_to_do/_left_panes.html.erb +51 -0
- data/app/views/stuff_to_do/_panes.html.erb +11 -0
- data/app/views/stuff_to_do/_project.html.erb +6 -0
- data/app/views/stuff_to_do/_right_panes.html.erb +25 -0
- data/app/views/stuff_to_do/_time_grid.html.erb +113 -0
- data/app/views/stuff_to_do/_time_grid_form.html.erb +32 -0
- data/app/views/stuff_to_do/index.html.erb +44 -0
- data/app/views/stuff_to_do_mailer/recommended_below_threshold.erb +3 -0
- data/app/views/stuff_to_do_mailer/recommended_below_threshold.text.html.rhtml +1 -0
- data/assets/images/b.png +0 -0
- data/assets/images/bl.png +0 -0
- data/assets/images/br.png +0 -0
- data/assets/images/closelabel.gif +0 -0
- data/assets/images/loading.gif +0 -0
- data/assets/images/tl.png +0 -0
- data/assets/images/tr.png +0 -0
- data/assets/javascripts/facebox.js +319 -0
- data/assets/javascripts/jquery-1.2.6.min.js +32 -0
- data/assets/javascripts/jquery-ui.js +2839 -0
- data/assets/javascripts/jquery.contextMenu.js +212 -0
- data/assets/javascripts/semantic.cache +15 -0
- data/assets/javascripts/stuff-to-do.js +270 -0
- data/assets/javascripts/ui/build.xml +24 -0
- data/assets/javascripts/ui/effects.blind.js +49 -0
- data/assets/javascripts/ui/effects.bounce.js +78 -0
- data/assets/javascripts/ui/effects.clip.js +54 -0
- data/assets/javascripts/ui/effects.core.js +510 -0
- data/assets/javascripts/ui/effects.drop.js +50 -0
- data/assets/javascripts/ui/effects.explode.js +79 -0
- data/assets/javascripts/ui/effects.fold.js +55 -0
- data/assets/javascripts/ui/effects.highlight.js +48 -0
- data/assets/javascripts/ui/effects.pulsate.js +55 -0
- data/assets/javascripts/ui/effects.scale.js +180 -0
- data/assets/javascripts/ui/effects.shake.js +57 -0
- data/assets/javascripts/ui/effects.slide.js +50 -0
- data/assets/javascripts/ui/effects.transfer.js +59 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-ar.js +26 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-bg.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-ca.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-cs.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-da.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-de.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-eo.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-es.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-fa.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-fi.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-fr.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-he.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-hr.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-hu.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-hy.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-id.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-is.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-it.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-ja.js +26 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-ko.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-lt.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-lv.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-nl.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-no.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-pl.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-pt-BR.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-ro.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-ru.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-sk.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-sl.js +26 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-sq.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-sv.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-th.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-tr.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-uk.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-zh-CN.js +25 -0
- data/assets/javascripts/ui/i18n/ui.datepicker-zh-TW.js +25 -0
- data/assets/javascripts/ui/svn.log +11 -0
- data/assets/javascripts/ui/ui.accordion.js +400 -0
- data/assets/javascripts/ui/ui.core.js +533 -0
- data/assets/javascripts/ui/ui.datepicker.js +1754 -0
- data/assets/javascripts/ui/ui.dialog.js +630 -0
- data/assets/javascripts/ui/ui.draggable.js +696 -0
- data/assets/javascripts/ui/ui.droppable.js +314 -0
- data/assets/javascripts/ui/ui.progressbar.js +114 -0
- data/assets/javascripts/ui/ui.resizable.js +805 -0
- data/assets/javascripts/ui/ui.selectable.js +266 -0
- data/assets/javascripts/ui/ui.slider.js +552 -0
- data/assets/javascripts/ui/ui.sortable.js +1012 -0
- data/assets/javascripts/ui/ui.tabs.js +572 -0
- data/assets/stylesheets/stuff_to_do.css +216 -0
- data/config/locales/bg.yml +18 -0
- data/config/locales/ca-fr.yml +18 -0
- data/config/locales/cs.yml +16 -0
- data/config/locales/da.yml +16 -0
- data/config/locales/de.yml +18 -0
- data/config/locales/en.yml +24 -0
- data/config/locales/es.yml +19 -0
- data/config/locales/fr.yml +17 -0
- data/config/locales/hu.yml +16 -0
- data/config/locales/it.yml +16 -0
- data/config/locales/ja.yml +18 -0
- data/config/locales/ko.yml +18 -0
- data/config/locales/lt.yml +18 -0
- data/config/locales/nl.yml +20 -0
- data/config/locales/pt-BR.yml +18 -0
- data/config/locales/ru.yml +19 -0
- data/config/locales/sv.yml +19 -0
- data/config/locales/tr.yml +18 -0
- data/config/routes.rb +3 -0
- data/init.rb +54 -0
- data/lang/bg.yml +17 -0
- data/lang/ca-fr.yml +17 -0
- data/lang/cs.yml +15 -0
- data/lang/da.yml +15 -0
- data/lang/de.yml +17 -0
- data/lang/en.yml +21 -0
- data/lang/es.yml +18 -0
- data/lang/fr.yml +16 -0
- data/lang/hu.yml +15 -0
- data/lang/it.yml +15 -0
- data/lang/ja.yml +17 -0
- data/lang/ko.yml +17 -0
- data/lang/lt.yml +17 -0
- data/lang/pt-br.yml +17 -0
- data/lang/ru.yml +15 -0
- data/lang/sv.yml +18 -0
- data/lang/tr.yml +17 -0
- data/lib/redmine_stuff_to_do/stuff_to_do_compatibility.rb +15 -0
- data/lib/stuff_to_do_array_patch.rb +8 -0
- data/lib/stuff_to_do_issue_patch.rb +57 -0
- data/lib/stuff_to_do_project_patch.rb +31 -0
- data/lib/stuff_to_do_user_patch.rb +10 -0
- data/rails/init.rb +1 -0
- data/spec/controllers/stuff_to_do_controller_add_to_time_grid_spec.rb +58 -0
- data/spec/controllers/stuff_to_do_controller_index_spec.rb +155 -0
- data/spec/controllers/stuff_to_do_controller_remove_from_time_grid_spec.rb +56 -0
- data/spec/controllers/stuff_to_do_controller_reorder_spec.rb +179 -0
- data/spec/controllers/stuff_to_do_controller_save_time_entries_spec.rb +56 -0
- data/spec/controllers/stuff_to_do_private_methods_spec.rb +82 -0
- data/spec/lib/stuff_to_do_issue_patch_spec.rb +60 -0
- data/spec/lib/stuff_to_do_project_patch_spec.rb +50 -0
- data/spec/lib/stuff_to_do_user_patch_spec.rb +8 -0
- data/spec/models/stuff_to_do_filter_spec.rb +3 -0
- data/spec/models/stuff_to_do_mailer_spec.rb +42 -0
- data/spec/models/stuff_to_do_spec.rb +426 -0
- data/spec/sanity_spec.rb +7 -0
- data/spec/spec_helper.rb +130 -0
- metadata +211 -0
data/lang/sv.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
stuff_to_do_title: Att göra
|
2
|
+
stuff_to_do_what_im_doing_now: "Det jag gör nu"
|
3
|
+
stuff_to_do_what_is_recommended: "Vad jag ska göra härnäst"
|
4
|
+
stuff_to_do_what_is_available: "Tillgängliga uppgifter"
|
5
|
+
stuff_to_do_text_order_im_doing_it: "I den ordning jag ska göra det"
|
6
|
+
stuff_to_do_text_by_project_manager: "Av projektledaren"
|
7
|
+
stuff_to_do_label_view_user_list: "Se en annan användares lista:"
|
8
|
+
stuff_to_do_text_total_progress: "Totalt"
|
9
|
+
stuff_to_do_text_total_estimates: "Uppskattningar"
|
10
|
+
stuff_to_do_label_project_manager_emails: "Projektledarens e-post"
|
11
|
+
stuff_to_do_label_threshold: Gräns
|
12
|
+
stuff_to_do_label_email_to: E-postadresser
|
13
|
+
stuff_to_do_text_settings: "Ett meddelande skickas när användarens kvarvarande uppgifter når gränsen. Ange en eller flera e-postadresser separerade med kommatecken."
|
14
|
+
stuff_to_do_label_filter: Filtrera
|
15
|
+
stuff_to_do_label_filter_by: Filtrera efter ...
|
16
|
+
stuff_to_do_drag_issue_create_list: Drag ett ärende hit för att skapa en ny lista.
|
17
|
+
stuff_to_do_drag_issue_remove_list: Drag ett ärende hit för att ta bort dem från listan
|
18
|
+
stuff_to_do_use_as_stuff_to_do: Lägg till i Att göra-listan
|
data/lang/tr.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
stuff_to_do_title: Yapılacaklar
|
2
|
+
stuff_to_do_what_im_doing_now: "Şimdi ne yapıyorum"
|
3
|
+
stuff_to_do_what_is_recommended: "Tavsiye edilenler"
|
4
|
+
stuff_to_do_what_is_available: "Uygun olanlar"
|
5
|
+
stuff_to_do_text_order_im_doing_it: "Yaptığım sırada"
|
6
|
+
stuff_to_do_text_by_project_manager: Proje Yöneticisine göre
|
7
|
+
stuff_to_do_label_view_user_list: "Başka bir kullanıcının listesini izle:"
|
8
|
+
stuff_to_do_text_total_progress: "Toplam süreç"
|
9
|
+
stuff_to_do_text_total_estimates: "Toplam Tahmin"
|
10
|
+
stuff_to_do_label_project_manager_emails: Proje Yönetici Epostaları
|
11
|
+
stuff_to_do_label_threshold: Eşik değeri
|
12
|
+
stuff_to_do_label_email_to: Eposta adresleri
|
13
|
+
stuff_to_do_text_settings: "Kullanıcının tavsiye edilen öge sayısı aşağıdaki eşik değerine eriştiğinde Proje Yöneticisine bir e-posta gönderilir. Çoklu e-posta alıcıları, adresler virgül ile ayrılarak tanımlanabilir."
|
14
|
+
stuff_to_do_label_filter: Filtre
|
15
|
+
stuff_to_do_label_filter_by: Filtre tercihi...
|
16
|
+
stuff_to_do_drag_issue_create_list: Yeni bir liste oluşturmak için iletileri buraya sürükleyin.
|
17
|
+
stuff_to_do_drag_issue_remove_list: Listeden kaldırmak için iletileri buraya sürükleyin.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RedmineStuffToDo
|
2
|
+
module StuffToDoCompatibility
|
3
|
+
class IssuePriority
|
4
|
+
def self.all
|
5
|
+
if Object.const_defined?('IssuePriority')
|
6
|
+
::IssuePriority.all
|
7
|
+
elsif Enumeration.respond_to?(:priorities)
|
8
|
+
return ::Enumeration.priorities
|
9
|
+
else
|
10
|
+
return ::Enumeration::get_values('IPRI')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Patches Redmine's Issues dynamically. Adds a +after_save+ filter.
|
2
|
+
module StuffToDoIssuePatch
|
3
|
+
def self.included(base) # :nodoc:
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
|
6
|
+
base.send(:include, InstanceMethods)
|
7
|
+
|
8
|
+
# Same as typing in the class
|
9
|
+
base.class_eval do
|
10
|
+
unloadable # Send unloadable so it will not be unloaded in development
|
11
|
+
|
12
|
+
after_save :update_next_issues
|
13
|
+
has_many :stuff_to_dos, :as => :stuff
|
14
|
+
has_and_belongs_to_many :time_grid_users, :class_name => 'User', :join_table => 'time_grid_issues_users'
|
15
|
+
|
16
|
+
named_scope :with_time_entries_for_user, lambda {|user_id|
|
17
|
+
{
|
18
|
+
:include => :time_entries,
|
19
|
+
:conditions => ["#{TimeEntry.table_name}.user_id = (?)", user_id]
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
named_scope :with_time_entries_within_date, lambda {|date_from, date_to,|
|
24
|
+
{
|
25
|
+
:include => :time_entries,
|
26
|
+
:conditions => ["#{TimeEntry.table_name}.spent_on > (:from) AND #{TimeEntry.table_name}.spent_on < (:to)",
|
27
|
+
{:from => date_from, :to => date_to}]
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
# Redmine 0.8.x compatibility method
|
32
|
+
unless ::Issue.respond_to?(:visible)
|
33
|
+
named_scope :visible, lambda {|*args| { :include => :project,
|
34
|
+
:conditions => Project.allowed_to_condition(args.first || User.current, :view_issues) } }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
module ClassMethods
|
41
|
+
end
|
42
|
+
|
43
|
+
module InstanceMethods
|
44
|
+
# This will update all NextIssues assigned to the Issue
|
45
|
+
#
|
46
|
+
# * When an issue is closed, NextIssue#remove_associations_to will be called to
|
47
|
+
# update the set of NextIssues
|
48
|
+
# * When an issue is reassigned, any previous (stale) NextIssues will
|
49
|
+
# be removed
|
50
|
+
def update_next_issues
|
51
|
+
self.reload
|
52
|
+
StuffToDo.remove_associations_to(self) if self.closed?
|
53
|
+
StuffToDo.remove_stale_assignments(self)
|
54
|
+
return true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module StuffToDoProjectPatch
|
2
|
+
def self.included(base) # :nodoc:
|
3
|
+
base.extend(ClassMethods)
|
4
|
+
base.send(:include, InstanceMethods)
|
5
|
+
|
6
|
+
# Same as typing in the class
|
7
|
+
base.class_eval do
|
8
|
+
unloadable # Send unloadable so it will not be unloaded in development
|
9
|
+
|
10
|
+
after_save :update_stuff_to_do
|
11
|
+
has_many :stuff_to_dos, :as => :stuff
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
end
|
18
|
+
|
19
|
+
module InstanceMethods
|
20
|
+
# This will update all StuffToDos assigned to the Project
|
21
|
+
#
|
22
|
+
# * When a project is archived, StuffToDo#remove_associations_to will be
|
23
|
+
# called to update the set of StuffToDos
|
24
|
+
def update_stuff_to_do
|
25
|
+
StuffToDo.remove_associations_to(self) unless self.active?
|
26
|
+
return true
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Patches Redmine's Users dynamically.
|
2
|
+
module StuffToDoUserPatch
|
3
|
+
def self.included(base) # :nodoc:
|
4
|
+
base.class_eval do
|
5
|
+
unloadable
|
6
|
+
has_and_belongs_to_many :time_grid_issues, :class_name => 'Issue', :join_table => 'time_grid_issues_users'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../init"
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe StuffToDoController, '#add_to_time_grid' do
|
4
|
+
include Redmine::I18n
|
5
|
+
integrate_views
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@current_user = mock_model(User, :admin? => false, :logged? => true, :language => :en, :memberships => [], :anonymous? => false, :name => "A Test User", :projects => Project)
|
9
|
+
@current_user.stub!(:time_grid_issues).and_return(Issue)
|
10
|
+
User.stub!(:current).and_return(@current_user)
|
11
|
+
end
|
12
|
+
|
13
|
+
def do_request
|
14
|
+
post :add_to_time_grid, {}
|
15
|
+
end
|
16
|
+
|
17
|
+
it_should_behave_like 'get_time_grid_data'
|
18
|
+
|
19
|
+
it 'should add the issue_id to the time grid issues for the user' do
|
20
|
+
issue101 = mock_model(Issue, :id => 101)
|
21
|
+
Issue.should_receive(:find_by_id).with('101').and_return(issue101)
|
22
|
+
Issue.should_receive(:exists?).with(issue101).and_return(false)
|
23
|
+
Issue.should_receive(:<<).with(issue101).and_return(true)
|
24
|
+
|
25
|
+
post :add_to_time_grid, {:issue_id => '101'}
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should not add the issue_id to the time grid issues for the user if the user already has the issue' do
|
29
|
+
issue101 = mock_model(Issue, :id => 101)
|
30
|
+
Issue.should_receive(:find_by_id).with('101').and_return(issue101)
|
31
|
+
Issue.should_receive(:exists?).with(issue101).and_return(true)
|
32
|
+
Issue.should_not_receive(:<<)
|
33
|
+
|
34
|
+
post :add_to_time_grid, {:issue_id => '101'}
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should render the time_grid partial for js' do
|
38
|
+
post :add_to_time_grid, {:format => 'js'}
|
39
|
+
response.should render_template('_time_grid')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
describe StuffToDoController, '#add_to_time_grid with an unauthenticated user' do
|
45
|
+
it 'should not be successful' do
|
46
|
+
post :add_to_time_grid, {}
|
47
|
+
response.should_not be_success
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should return a 403 status code' do
|
51
|
+
post :add_to_time_grid, {}
|
52
|
+
response.code.should eql("403")
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should display the standard unauthorized page'
|
56
|
+
end
|
57
|
+
|
58
|
+
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe StuffToDoController, '#index' do
|
4
|
+
include Redmine::I18n
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@current_user = mock_model(User, :admin? => false, :logged? => true, :language => :en, :memberships => [])
|
8
|
+
@current_user.stub!(:time_grid_issues).and_return(Issue)
|
9
|
+
User.stub!(:current).and_return(@current_user)
|
10
|
+
StuffToDo.stub!(:available)
|
11
|
+
StuffToDo.stub!(:using_issues_as_items?).and_return(true)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should be successful' do
|
15
|
+
get :index
|
16
|
+
response.should be_success
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should render the index template' do
|
20
|
+
get :index
|
21
|
+
response.should render_template('index')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should set @doing_now to the top 5 issues for the current user' do
|
25
|
+
stuff = []
|
26
|
+
5.times { stuff << mock('stuff') }
|
27
|
+
StuffToDo.should_receive(:doing_now).with(@current_user).and_return(stuff)
|
28
|
+
get :index
|
29
|
+
assigns[:doing_now].should have(5).things
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should set @recommended to the next 10 issues for the current user' do
|
33
|
+
stuff = []
|
34
|
+
10.times { stuff << mock('stuff') }
|
35
|
+
StuffToDo.should_receive(:recommended).with(@current_user).and_return(stuff)
|
36
|
+
get :index
|
37
|
+
assigns[:recommended].should have(10).things
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should set @available to the assigned issues that are not next issues for the current user' do
|
41
|
+
stuff = []
|
42
|
+
6.times { stuff << mock('stuff') }
|
43
|
+
StuffToDo.should_receive(:available).with(@current_user, @current_user ).and_return(stuff)
|
44
|
+
get :index
|
45
|
+
assigns[:available].should have(6).things
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should set @filters to for the view' do
|
49
|
+
get :index
|
50
|
+
assigns[:filters].should_not be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should build the filters using filters_for_view' do
|
54
|
+
controller.should_receive(:filters_for_view)
|
55
|
+
get :index
|
56
|
+
end
|
57
|
+
|
58
|
+
def do_request
|
59
|
+
get :index
|
60
|
+
end
|
61
|
+
|
62
|
+
it_should_behave_like 'get_time_grid_data'
|
63
|
+
end
|
64
|
+
|
65
|
+
describe StuffToDoController, '#index for another user as an administrator' do
|
66
|
+
def get_index
|
67
|
+
get :index, :user_id => @viewed_user.id
|
68
|
+
end
|
69
|
+
|
70
|
+
before(:each) do
|
71
|
+
@current_user = mock_model(User, :admin? => true, :logged? => true, :language => :en)
|
72
|
+
@current_user.stub!(:time_grid_issues).and_return(Issue)
|
73
|
+
User.stub!(:current).and_return(@current_user)
|
74
|
+
controller.stub!(:find_current_user).and_return(@current_user)
|
75
|
+
@viewed_user = mock_model(User)
|
76
|
+
User.stub!(:find).with(@viewed_user.id.to_s).and_return(@viewed_user)
|
77
|
+
StuffToDo.stub!(:available)
|
78
|
+
StuffToDo.stub!(:using_issues_as_items?).and_return(true)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should be successful' do
|
82
|
+
get_index
|
83
|
+
response.should be_success
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should render the index template' do
|
87
|
+
get_index
|
88
|
+
response.should render_template('index')
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should set @doing_now to the top 5 issues for the current user' do
|
92
|
+
stuff = []
|
93
|
+
5.times { stuff << mock('stuff') }
|
94
|
+
StuffToDo.should_receive(:doing_now).with(@viewed_user).and_return(stuff)
|
95
|
+
get_index
|
96
|
+
assigns[:doing_now].should have(5).things
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should set @recommended to the next 10 issues for the current user' do
|
100
|
+
stuff = []
|
101
|
+
10.times { stuff << mock('stuff') }
|
102
|
+
StuffToDo.should_receive(:recommended).with(@viewed_user).and_return(stuff)
|
103
|
+
get_index
|
104
|
+
assigns[:recommended].should have(10).things
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should set @available to the assigned issues that are not next issues for the current user' do
|
108
|
+
stuff = []
|
109
|
+
6.times { stuff << mock('stuff') }
|
110
|
+
StuffToDo.should_receive(:available).with(@viewed_user, @viewed_user).and_return(stuff)
|
111
|
+
get_index
|
112
|
+
assigns[:available].should have(6).things
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
describe StuffToDoController, '#index for another user as a user' do
|
118
|
+
def get_index
|
119
|
+
get :index, :user_id => @viewed_user.id
|
120
|
+
end
|
121
|
+
|
122
|
+
before(:each) do
|
123
|
+
@current_user = mock_model(User, :admin? => false, :logged? => true, :language => :en, :memberships => [], :anonymous? => false, :name => "A Test User", :projects => Project)
|
124
|
+
@current_user.stub!(:time_grid_issues).and_return(Issue)
|
125
|
+
User.stub!(:current).and_return(@current_user)
|
126
|
+
@viewed_user = mock_model(User)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should not be successful' do
|
130
|
+
get_index
|
131
|
+
response.should_not be_success
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should return a 403 status code' do
|
135
|
+
get_index
|
136
|
+
response.code.should eql("403")
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should display the standard unauthorized page'
|
140
|
+
end
|
141
|
+
|
142
|
+
describe StuffToDoController, '#index with an unauthenticated user' do
|
143
|
+
it 'should not be successful' do
|
144
|
+
get :index
|
145
|
+
response.should_not be_success
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should return a 403 status code' do
|
149
|
+
get :index
|
150
|
+
response.code.should eql("403")
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should display the standard unauthorized page'
|
154
|
+
end
|
155
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe StuffToDoController, '#remove_from_time_grid' do
|
4
|
+
include Redmine::I18n
|
5
|
+
integrate_views
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@current_user = mock_model(User, :admin? => false, :logged? => true, :language => :en, :memberships => [], :anonymous? => false, :name => "A Test User", :projects => Project)
|
9
|
+
@current_user.stub!(:time_grid_issues).and_return(Issue)
|
10
|
+
User.stub!(:current).and_return(@current_user)
|
11
|
+
end
|
12
|
+
|
13
|
+
def do_request
|
14
|
+
post :remove_from_time_grid, {}
|
15
|
+
end
|
16
|
+
|
17
|
+
it_should_behave_like 'get_time_grid_data'
|
18
|
+
|
19
|
+
it "should remove the issue_id from the user's time grid issues" do
|
20
|
+
issue101 = mock_model(Issue, :id => 101)
|
21
|
+
Issue.should_receive(:find_by_id).with('101').and_return(issue101)
|
22
|
+
Issue.should_receive(:delete).with(issue101).and_return(true)
|
23
|
+
|
24
|
+
post :remove_from_time_grid, {:issue_id => '101'}
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should not remove anything if the issue_id isn't assigned to the user" do
|
28
|
+
issue101 = mock_model(Issue, :id => 101)
|
29
|
+
Issue.should_receive(:find_by_id).with('101').and_return(nil)
|
30
|
+
Issue.should_not_receive(:delete)
|
31
|
+
|
32
|
+
post :remove_from_time_grid, {:issue_id => '101'}
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should render the time_grid partial for js' do
|
36
|
+
post :remove_from_time_grid, {:format => 'js'}
|
37
|
+
response.should render_template('_time_grid')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
describe StuffToDoController, '#remove_from_time_grid with an unauthenticated user' do
|
43
|
+
it 'should not be successful' do
|
44
|
+
post :remove_from_time_grid, {}
|
45
|
+
response.should_not be_success
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should return a 403 status code' do
|
49
|
+
post :remove_from_time_grid, {}
|
50
|
+
response.code.should eql("403")
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should display the standard unauthorized page'
|
54
|
+
end
|
55
|
+
|
56
|
+
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe StuffToDoController, '#reorder' do
|
4
|
+
def post_reorder
|
5
|
+
post :reorder, :stuff => @ordered_list
|
6
|
+
end
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
@current_user = mock_model(User, :admin? => false, :logged? => true, :language => :en)
|
10
|
+
User.stub!(:current).and_return(@current_user)
|
11
|
+
@ordered_list = ["500", "100", "300"]
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should redirect' do
|
15
|
+
post_reorder
|
16
|
+
response.should be_redirect
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should be redirect to the index action' do
|
20
|
+
post_reorder
|
21
|
+
response.should redirect_to(:action => 'index')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should reorder the Next Issues' do
|
25
|
+
StuffToDo.should_receive(:reorder_list).with(@current_user, @ordered_list)
|
26
|
+
post_reorder
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# These intregrate the partial view
|
31
|
+
describe StuffToDoController, '#reorder with the js format' do
|
32
|
+
def post_reorder
|
33
|
+
post :reorder, :stuff => @ordered_list, :format => 'js'
|
34
|
+
end
|
35
|
+
|
36
|
+
before(:each) do
|
37
|
+
@current_user = mock_model(User, :admin? => false, :logged? => true, :language => :en)
|
38
|
+
User.stub!(:current).and_return(@current_user)
|
39
|
+
@ordered_list = ["500", "100", "300"]
|
40
|
+
StuffToDo.stub!(:doing_now).and_return([])
|
41
|
+
StuffToDo.stub!(:recommended).and_return([])
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should be successful' do
|
45
|
+
post_reorder
|
46
|
+
response.should be_success
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should be render the panes' do
|
50
|
+
post_reorder
|
51
|
+
response.should render_template('stuff_to_do/_panes')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should reorder the Next Issues' do
|
55
|
+
StuffToDo.should_receive(:reorder_list).with(@current_user, @ordered_list)
|
56
|
+
post_reorder
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should assign the doing now issues for the view' do
|
60
|
+
post_reorder
|
61
|
+
assigns[:doing_now].should_not be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should assign the recommended next issues for the view' do
|
65
|
+
post_reorder
|
66
|
+
assigns[:recommended].should_not be_nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe StuffToDoController, '#reorder for another user as an administrator' do
|
71
|
+
def post_reorder
|
72
|
+
post :reorder, :stuff => @ordered_list, :user_id => @viewed_user.id
|
73
|
+
end
|
74
|
+
|
75
|
+
before(:each) do
|
76
|
+
@current_user = mock_model(User, :admin? => true, :logged? => true, :language => :en)
|
77
|
+
User.stub!(:current).and_return(@current_user)
|
78
|
+
controller.stub!(:find_current_user).and_return(@current_user)
|
79
|
+
@viewed_user = mock_model(User)
|
80
|
+
User.stub!(:find).with(@viewed_user.id.to_s).and_return(@viewed_user)
|
81
|
+
@ordered_list = ["500", "100", "300"]
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should redirect' do
|
85
|
+
post_reorder
|
86
|
+
response.should be_redirect
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should be redirect to the index action' do
|
90
|
+
post_reorder
|
91
|
+
response.should redirect_to(:action => 'index')
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should reorder the Next Issues' do
|
95
|
+
StuffToDo.should_receive(:reorder_list).with(@viewed_user, @ordered_list)
|
96
|
+
post_reorder
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# These intregrate the partial view
|
101
|
+
describe StuffToDoController, '#reorder for another user as an administrator with the js format' do
|
102
|
+
def post_reorder
|
103
|
+
post :reorder, :stuff => @ordered_list, :user_id => @viewed_user.id, :format => 'js'
|
104
|
+
end
|
105
|
+
|
106
|
+
before(:each) do
|
107
|
+
@current_user = mock_model(User, :admin? => true, :logged? => true, :language => :en)
|
108
|
+
User.stub!(:current).and_return(@current_user)
|
109
|
+
controller.stub!(:find_current_user).and_return(@current_user)
|
110
|
+
@viewed_user = mock_model(User)
|
111
|
+
User.stub!(:find).with(@viewed_user.id.to_s).and_return(@viewed_user)
|
112
|
+
@ordered_list = ["500", "100", "300"]
|
113
|
+
StuffToDo.stub!(:doing_now).and_return([])
|
114
|
+
StuffToDo.stub!(:recommended).and_return([])
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should be successful' do
|
118
|
+
post_reorder
|
119
|
+
response.should be_success
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should be render the panes' do
|
123
|
+
post_reorder
|
124
|
+
response.should render_template('stuff_to_do/_panes')
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should reorder the Next Issues' do
|
128
|
+
StuffToDo.should_receive(:reorder_list).with(@viewed_user, @ordered_list)
|
129
|
+
post_reorder
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should assign the doing now issues for the view' do
|
133
|
+
post_reorder
|
134
|
+
assigns[:doing_now].should_not be_nil
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should assign the recommended next issues for the view' do
|
138
|
+
post_reorder
|
139
|
+
assigns[:recommended].should_not be_nil
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe StuffToDoController, '#reorder for another user as a user' do
|
144
|
+
def post_reorder
|
145
|
+
post :reorder, :user_id => @viewed_user.id
|
146
|
+
end
|
147
|
+
|
148
|
+
before(:each) do
|
149
|
+
@current_user = mock_model(User, :admin? => false, :logged? => true, :language => :en)
|
150
|
+
User.stub!(:current).and_return(@current_user)
|
151
|
+
@viewed_user = mock_model(User)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should not be successful' do
|
155
|
+
post_reorder
|
156
|
+
response.should_not be_success
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should return a 403 status code' do
|
160
|
+
post_reorder
|
161
|
+
response.code.should eql("403")
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should display the standard unauthorized page'
|
165
|
+
end
|
166
|
+
|
167
|
+
describe StuffToDoController, '#reorder with an unauthenticated user' do
|
168
|
+
it 'should not be successful' do
|
169
|
+
post :reorder
|
170
|
+
response.should_not be_success
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should return a 403 status code' do
|
174
|
+
post :reorder
|
175
|
+
response.code.should eql("403")
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should display the standard unauthorized page'
|
179
|
+
end
|