stuff_to_do_plugin 0.4.0

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