stuff_to_do_plugin 0.4.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.
Files changed (159) hide show
  1. data/COPYRIGHT.txt +18 -0
  2. data/CREDITS.txt +6 -0
  3. data/GPL.txt +339 -0
  4. data/README.rdoc +61 -0
  5. data/Rakefile +38 -0
  6. data/VERSION +1 -0
  7. data/app/controllers/stuff_to_do_controller.rb +161 -0
  8. data/app/helpers/stuff_to_do_helper.rb +88 -0
  9. data/app/models/stuff_to_do.rb +208 -0
  10. data/app/models/stuff_to_do_filter.rb +32 -0
  11. data/app/models/stuff_to_do_mailer.rb +16 -0
  12. data/app/views/settings/_stuff_to_do_settings.html.erb +27 -0
  13. data/app/views/stuff_to_do/_issue.html.erb +16 -0
  14. data/app/views/stuff_to_do/_item.html.erb +5 -0
  15. data/app/views/stuff_to_do/_left_panes.html.erb +51 -0
  16. data/app/views/stuff_to_do/_panes.html.erb +11 -0
  17. data/app/views/stuff_to_do/_project.html.erb +6 -0
  18. data/app/views/stuff_to_do/_right_panes.html.erb +25 -0
  19. data/app/views/stuff_to_do/_time_grid.html.erb +113 -0
  20. data/app/views/stuff_to_do/_time_grid_form.html.erb +32 -0
  21. data/app/views/stuff_to_do/index.html.erb +44 -0
  22. data/app/views/stuff_to_do_mailer/recommended_below_threshold.erb +3 -0
  23. data/app/views/stuff_to_do_mailer/recommended_below_threshold.text.html.rhtml +1 -0
  24. data/assets/images/b.png +0 -0
  25. data/assets/images/bl.png +0 -0
  26. data/assets/images/br.png +0 -0
  27. data/assets/images/closelabel.gif +0 -0
  28. data/assets/images/loading.gif +0 -0
  29. data/assets/images/tl.png +0 -0
  30. data/assets/images/tr.png +0 -0
  31. data/assets/javascripts/facebox.js +319 -0
  32. data/assets/javascripts/jquery-1.2.6.min.js +32 -0
  33. data/assets/javascripts/jquery-ui.js +2839 -0
  34. data/assets/javascripts/jquery.contextMenu.js +212 -0
  35. data/assets/javascripts/semantic.cache +15 -0
  36. data/assets/javascripts/stuff-to-do.js +270 -0
  37. data/assets/javascripts/ui/build.xml +24 -0
  38. data/assets/javascripts/ui/effects.blind.js +49 -0
  39. data/assets/javascripts/ui/effects.bounce.js +78 -0
  40. data/assets/javascripts/ui/effects.clip.js +54 -0
  41. data/assets/javascripts/ui/effects.core.js +510 -0
  42. data/assets/javascripts/ui/effects.drop.js +50 -0
  43. data/assets/javascripts/ui/effects.explode.js +79 -0
  44. data/assets/javascripts/ui/effects.fold.js +55 -0
  45. data/assets/javascripts/ui/effects.highlight.js +48 -0
  46. data/assets/javascripts/ui/effects.pulsate.js +55 -0
  47. data/assets/javascripts/ui/effects.scale.js +180 -0
  48. data/assets/javascripts/ui/effects.shake.js +57 -0
  49. data/assets/javascripts/ui/effects.slide.js +50 -0
  50. data/assets/javascripts/ui/effects.transfer.js +59 -0
  51. data/assets/javascripts/ui/i18n/ui.datepicker-ar.js +26 -0
  52. data/assets/javascripts/ui/i18n/ui.datepicker-bg.js +25 -0
  53. data/assets/javascripts/ui/i18n/ui.datepicker-ca.js +25 -0
  54. data/assets/javascripts/ui/i18n/ui.datepicker-cs.js +25 -0
  55. data/assets/javascripts/ui/i18n/ui.datepicker-da.js +25 -0
  56. data/assets/javascripts/ui/i18n/ui.datepicker-de.js +25 -0
  57. data/assets/javascripts/ui/i18n/ui.datepicker-eo.js +25 -0
  58. data/assets/javascripts/ui/i18n/ui.datepicker-es.js +25 -0
  59. data/assets/javascripts/ui/i18n/ui.datepicker-fa.js +25 -0
  60. data/assets/javascripts/ui/i18n/ui.datepicker-fi.js +25 -0
  61. data/assets/javascripts/ui/i18n/ui.datepicker-fr.js +25 -0
  62. data/assets/javascripts/ui/i18n/ui.datepicker-he.js +25 -0
  63. data/assets/javascripts/ui/i18n/ui.datepicker-hr.js +25 -0
  64. data/assets/javascripts/ui/i18n/ui.datepicker-hu.js +25 -0
  65. data/assets/javascripts/ui/i18n/ui.datepicker-hy.js +25 -0
  66. data/assets/javascripts/ui/i18n/ui.datepicker-id.js +25 -0
  67. data/assets/javascripts/ui/i18n/ui.datepicker-is.js +25 -0
  68. data/assets/javascripts/ui/i18n/ui.datepicker-it.js +25 -0
  69. data/assets/javascripts/ui/i18n/ui.datepicker-ja.js +26 -0
  70. data/assets/javascripts/ui/i18n/ui.datepicker-ko.js +25 -0
  71. data/assets/javascripts/ui/i18n/ui.datepicker-lt.js +25 -0
  72. data/assets/javascripts/ui/i18n/ui.datepicker-lv.js +25 -0
  73. data/assets/javascripts/ui/i18n/ui.datepicker-nl.js +25 -0
  74. data/assets/javascripts/ui/i18n/ui.datepicker-no.js +25 -0
  75. data/assets/javascripts/ui/i18n/ui.datepicker-pl.js +25 -0
  76. data/assets/javascripts/ui/i18n/ui.datepicker-pt-BR.js +25 -0
  77. data/assets/javascripts/ui/i18n/ui.datepicker-ro.js +25 -0
  78. data/assets/javascripts/ui/i18n/ui.datepicker-ru.js +25 -0
  79. data/assets/javascripts/ui/i18n/ui.datepicker-sk.js +25 -0
  80. data/assets/javascripts/ui/i18n/ui.datepicker-sl.js +26 -0
  81. data/assets/javascripts/ui/i18n/ui.datepicker-sq.js +25 -0
  82. data/assets/javascripts/ui/i18n/ui.datepicker-sv.js +25 -0
  83. data/assets/javascripts/ui/i18n/ui.datepicker-th.js +25 -0
  84. data/assets/javascripts/ui/i18n/ui.datepicker-tr.js +25 -0
  85. data/assets/javascripts/ui/i18n/ui.datepicker-uk.js +25 -0
  86. data/assets/javascripts/ui/i18n/ui.datepicker-zh-CN.js +25 -0
  87. data/assets/javascripts/ui/i18n/ui.datepicker-zh-TW.js +25 -0
  88. data/assets/javascripts/ui/svn.log +11 -0
  89. data/assets/javascripts/ui/ui.accordion.js +400 -0
  90. data/assets/javascripts/ui/ui.core.js +533 -0
  91. data/assets/javascripts/ui/ui.datepicker.js +1754 -0
  92. data/assets/javascripts/ui/ui.dialog.js +630 -0
  93. data/assets/javascripts/ui/ui.draggable.js +696 -0
  94. data/assets/javascripts/ui/ui.droppable.js +314 -0
  95. data/assets/javascripts/ui/ui.progressbar.js +114 -0
  96. data/assets/javascripts/ui/ui.resizable.js +805 -0
  97. data/assets/javascripts/ui/ui.selectable.js +266 -0
  98. data/assets/javascripts/ui/ui.slider.js +552 -0
  99. data/assets/javascripts/ui/ui.sortable.js +1012 -0
  100. data/assets/javascripts/ui/ui.tabs.js +572 -0
  101. data/assets/stylesheets/stuff_to_do.css +216 -0
  102. data/config/locales/bg.yml +18 -0
  103. data/config/locales/ca-fr.yml +18 -0
  104. data/config/locales/cs.yml +16 -0
  105. data/config/locales/da.yml +16 -0
  106. data/config/locales/de.yml +18 -0
  107. data/config/locales/en.yml +24 -0
  108. data/config/locales/es.yml +19 -0
  109. data/config/locales/fr.yml +17 -0
  110. data/config/locales/hu.yml +16 -0
  111. data/config/locales/it.yml +16 -0
  112. data/config/locales/ja.yml +18 -0
  113. data/config/locales/ko.yml +18 -0
  114. data/config/locales/lt.yml +18 -0
  115. data/config/locales/nl.yml +20 -0
  116. data/config/locales/pt-BR.yml +18 -0
  117. data/config/locales/ru.yml +19 -0
  118. data/config/locales/sv.yml +19 -0
  119. data/config/locales/tr.yml +18 -0
  120. data/config/routes.rb +3 -0
  121. data/init.rb +54 -0
  122. data/lang/bg.yml +17 -0
  123. data/lang/ca-fr.yml +17 -0
  124. data/lang/cs.yml +15 -0
  125. data/lang/da.yml +15 -0
  126. data/lang/de.yml +17 -0
  127. data/lang/en.yml +21 -0
  128. data/lang/es.yml +18 -0
  129. data/lang/fr.yml +16 -0
  130. data/lang/hu.yml +15 -0
  131. data/lang/it.yml +15 -0
  132. data/lang/ja.yml +17 -0
  133. data/lang/ko.yml +17 -0
  134. data/lang/lt.yml +17 -0
  135. data/lang/pt-br.yml +17 -0
  136. data/lang/ru.yml +15 -0
  137. data/lang/sv.yml +18 -0
  138. data/lang/tr.yml +17 -0
  139. data/lib/redmine_stuff_to_do/stuff_to_do_compatibility.rb +15 -0
  140. data/lib/stuff_to_do_array_patch.rb +8 -0
  141. data/lib/stuff_to_do_issue_patch.rb +57 -0
  142. data/lib/stuff_to_do_project_patch.rb +31 -0
  143. data/lib/stuff_to_do_user_patch.rb +10 -0
  144. data/rails/init.rb +1 -0
  145. data/spec/controllers/stuff_to_do_controller_add_to_time_grid_spec.rb +58 -0
  146. data/spec/controllers/stuff_to_do_controller_index_spec.rb +155 -0
  147. data/spec/controllers/stuff_to_do_controller_remove_from_time_grid_spec.rb +56 -0
  148. data/spec/controllers/stuff_to_do_controller_reorder_spec.rb +179 -0
  149. data/spec/controllers/stuff_to_do_controller_save_time_entries_spec.rb +56 -0
  150. data/spec/controllers/stuff_to_do_private_methods_spec.rb +82 -0
  151. data/spec/lib/stuff_to_do_issue_patch_spec.rb +60 -0
  152. data/spec/lib/stuff_to_do_project_patch_spec.rb +50 -0
  153. data/spec/lib/stuff_to_do_user_patch_spec.rb +8 -0
  154. data/spec/models/stuff_to_do_filter_spec.rb +3 -0
  155. data/spec/models/stuff_to_do_mailer_spec.rb +42 -0
  156. data/spec/models/stuff_to_do_spec.rb +426 -0
  157. data/spec/sanity_spec.rb +7 -0
  158. data/spec/spec_helper.rb +130 -0
  159. metadata +211 -0
@@ -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
@@ -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,8 @@
1
+ class Array
2
+ # converts an array to a hash with the key = index in Array
3
+ def to_hash
4
+ Hash[*self.collect {|v|
5
+ [self.index(v),v]
6
+ }.flatten]
7
+ end unless respond_to?(:to_hash)
8
+ 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
+
@@ -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