@@ -48,8 +48,8 class User < Principal | |||
|
48 | 48 | has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify |
|
49 | 49 | has_many :changesets, :dependent => :nullify |
|
50 | 50 | has_one :preference, :dependent => :destroy, :class_name => 'UserPreference' |
|
51 |
has_one :rss_token |
|
|
52 |
has_one :api_token |
|
|
51 | has_one :rss_token, :class_name => 'Token', :conditions => "action='feeds'" | |
|
52 | has_one :api_token, :class_name => 'Token', :conditions => "action='api'" | |
|
53 | 53 | belongs_to :auth_source |
|
54 | 54 | |
|
55 | 55 | # Active non-anonymous users scope |
@@ -74,6 +74,8 class User < Principal | |||
|
74 | 74 | validates_confirmation_of :password, :allow_nil => true |
|
75 | 75 | validates_inclusion_of :mail_notification, :in => MAIL_NOTIFICATION_OPTIONS.collect(&:first), :allow_blank => true |
|
76 | 76 | |
|
77 | before_destroy :remove_references_before_destroy | |
|
78 | ||
|
77 | 79 | def before_create |
|
78 | 80 | self.mail_notification = Setting.default_notification_option if self.mail_notification.blank? |
|
79 | 81 | true |
@@ -473,6 +475,31 class User < Principal | |||
|
473 | 475 | end |
|
474 | 476 | |
|
475 | 477 | private |
|
478 | ||
|
479 | # Removes references that are not handled by associations | |
|
480 | # Things that are not deleted are reassociated with the anonymous user | |
|
481 | def remove_references_before_destroy | |
|
482 | return if self.id.nil? | |
|
483 | ||
|
484 | substitute = User.anonymous | |
|
485 | Attachment.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] | |
|
486 | Comment.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] | |
|
487 | Issue.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] | |
|
488 | Issue.update_all 'assigned_to_id = NULL', ['assigned_to_id = ?', id] | |
|
489 | Journal.update_all ['user_id = ?', substitute.id], ['user_id = ?', id] | |
|
490 | JournalDetail.update_all ['old_value = ?', substitute.id.to_s], ["property = 'attr' AND prop_key = 'assigned_to_id' AND old_value = ?", id.to_s] | |
|
491 | JournalDetail.update_all ['value = ?', substitute.id.to_s], ["property = 'attr' AND prop_key = 'assigned_to_id' AND value = ?", id.to_s] | |
|
492 | Message.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] | |
|
493 | News.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] | |
|
494 | # Remove private queries and keep public ones | |
|
495 | Query.delete_all ['user_id = ? AND is_public = ?', id, false] | |
|
496 | Query.update_all ['user_id = ?', substitute.id], ['user_id = ?', id] | |
|
497 | TimeEntry.update_all ['user_id = ?', substitute.id], ['user_id = ?', id] | |
|
498 | Token.delete_all ['user_id = ?', id] | |
|
499 | Watcher.delete_all ['user_id = ?', id] | |
|
500 | WikiContent.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] | |
|
501 | WikiContent::Version.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] | |
|
502 | end | |
|
476 | 503 | |
|
477 | 504 | # Return password digest |
|
478 | 505 | def self.hash_password(clear_password) |
@@ -498,4 +525,9 class AnonymousUser < User | |||
|
498 | 525 | def mail; nil end |
|
499 | 526 | def time_zone; nil end |
|
500 | 527 | def rss_key; nil end |
|
528 | ||
|
529 | # Anonymous user can not be destroyed | |
|
530 | def destroy | |
|
531 | false | |
|
532 | end | |
|
501 | 533 | end |
@@ -62,12 +62,11 class RepositoryTest < ActiveSupport::TestCase | |||
|
62 | 62 | |
|
63 | 63 | def test_should_not_create_with_disabled_scm |
|
64 | 64 | # disable Subversion |
|
65 |
|
|
|
66 | repository = Repository::Subversion.new(:project => Project.find(3), :url => "svn://localhost") | |
|
67 | assert !repository.save | |
|
68 | assert_equal I18n.translate('activerecord.errors.messages.invalid'), repository.errors.on(:type) | |
|
69 | # re-enable Subversion for following tests | |
|
70 | Setting.delete_all | |
|
65 | with_settings :enabled_scm => ['Darcs', 'Git'] do | |
|
66 | repository = Repository::Subversion.new(:project => Project.find(3), :url => "svn://localhost") | |
|
67 | assert !repository.save | |
|
68 | assert_equal I18n.translate('activerecord.errors.messages.invalid'), repository.errors.on(:type) | |
|
69 | end | |
|
71 | 70 | end |
|
72 | 71 | |
|
73 | 72 | def test_scan_changesets_for_issue_ids |
@@ -109,12 +109,216 class UserTest < ActiveSupport::TestCase | |||
|
109 | 109 | assert_equal "john", @admin.login |
|
110 | 110 | end |
|
111 | 111 | |
|
112 | def test_destroy | |
|
113 | User.find(2).destroy | |
|
112 | def test_destroy_should_delete_members_and_roles | |
|
113 | members = Member.find_all_by_user_id(2) | |
|
114 | ms = members.size | |
|
115 | rs = members.collect(&:roles).flatten.size | |
|
116 | ||
|
117 | assert_difference 'Member.count', - ms do | |
|
118 | assert_difference 'MemberRole.count', - rs do | |
|
119 | User.find(2).destroy | |
|
120 | end | |
|
121 | end | |
|
122 | ||
|
114 | 123 | assert_nil User.find_by_id(2) |
|
115 | 124 | assert Member.find_all_by_user_id(2).empty? |
|
116 | 125 | end |
|
117 | 126 | |
|
127 | def test_destroy_should_update_attachments | |
|
128 | attachment = Attachment.create!(:container => Project.find(1), | |
|
129 | :file => uploaded_test_file("testfile.txt", "text/plain"), | |
|
130 | :author_id => 2) | |
|
131 | ||
|
132 | User.find(2).destroy | |
|
133 | assert_nil User.find_by_id(2) | |
|
134 | assert_equal User.anonymous, attachment.reload.author | |
|
135 | end | |
|
136 | ||
|
137 | def test_destroy_should_update_comments | |
|
138 | comment = Comment.create!( | |
|
139 | :commented => News.create!(:project_id => 1, :author_id => 1, :title => 'foo', :description => 'foo'), | |
|
140 | :author => User.find(2), | |
|
141 | :comments => 'foo' | |
|
142 | ) | |
|
143 | ||
|
144 | User.find(2).destroy | |
|
145 | assert_nil User.find_by_id(2) | |
|
146 | assert_equal User.anonymous, comment.reload.author | |
|
147 | end | |
|
148 | ||
|
149 | def test_destroy_should_update_issues | |
|
150 | issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo') | |
|
151 | ||
|
152 | User.find(2).destroy | |
|
153 | assert_nil User.find_by_id(2) | |
|
154 | assert_equal User.anonymous, issue.reload.author | |
|
155 | end | |
|
156 | ||
|
157 | def test_destroy_should_unassign_issues | |
|
158 | issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2) | |
|
159 | ||
|
160 | User.find(2).destroy | |
|
161 | assert_nil User.find_by_id(2) | |
|
162 | assert_nil issue.reload.assigned_to | |
|
163 | end | |
|
164 | ||
|
165 | def test_destroy_should_update_journals | |
|
166 | issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo') | |
|
167 | issue.init_journal(User.find(2), "update") | |
|
168 | issue.save! | |
|
169 | ||
|
170 | User.find(2).destroy | |
|
171 | assert_nil User.find_by_id(2) | |
|
172 | assert_equal User.anonymous, issue.journals.first.reload.user | |
|
173 | end | |
|
174 | ||
|
175 | def test_destroy_should_update_journal_details_old_value | |
|
176 | issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2) | |
|
177 | issue.init_journal(User.find(1), "update") | |
|
178 | issue.assigned_to_id = nil | |
|
179 | assert_difference 'JournalDetail.count' do | |
|
180 | issue.save! | |
|
181 | end | |
|
182 | journal_detail = JournalDetail.first(:order => 'id DESC') | |
|
183 | assert_equal '2', journal_detail.old_value | |
|
184 | ||
|
185 | User.find(2).destroy | |
|
186 | assert_nil User.find_by_id(2) | |
|
187 | assert_equal User.anonymous.id.to_s, journal_detail.reload.old_value | |
|
188 | end | |
|
189 | ||
|
190 | def test_destroy_should_update_journal_details_value | |
|
191 | issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo') | |
|
192 | issue.init_journal(User.find(1), "update") | |
|
193 | issue.assigned_to_id = 2 | |
|
194 | assert_difference 'JournalDetail.count' do | |
|
195 | issue.save! | |
|
196 | end | |
|
197 | journal_detail = JournalDetail.first(:order => 'id DESC') | |
|
198 | assert_equal '2', journal_detail.value | |
|
199 | ||
|
200 | User.find(2).destroy | |
|
201 | assert_nil User.find_by_id(2) | |
|
202 | assert_equal User.anonymous.id.to_s, journal_detail.reload.value | |
|
203 | end | |
|
204 | ||
|
205 | def test_destroy_should_update_messages | |
|
206 | board = Board.create!(:project_id => 1, :name => 'Board', :description => 'Board') | |
|
207 | message = Message.create!(:board_id => board.id, :author_id => 2, :subject => 'foo', :content => 'foo') | |
|
208 | ||
|
209 | User.find(2).destroy | |
|
210 | assert_nil User.find_by_id(2) | |
|
211 | assert_equal User.anonymous, message.reload.author | |
|
212 | end | |
|
213 | ||
|
214 | def test_destroy_should_update_news | |
|
215 | news = News.create!(:project_id => 1, :author_id => 2, :title => 'foo', :description => 'foo') | |
|
216 | ||
|
217 | User.find(2).destroy | |
|
218 | assert_nil User.find_by_id(2) | |
|
219 | assert_equal User.anonymous, news.reload.author | |
|
220 | end | |
|
221 | ||
|
222 | def test_destroy_should_delete_private_queries | |
|
223 | query = Query.new(:name => 'foo', :is_public => false) | |
|
224 | query.project_id = 1 | |
|
225 | query.user_id = 2 | |
|
226 | query.save! | |
|
227 | ||
|
228 | User.find(2).destroy | |
|
229 | assert_nil User.find_by_id(2) | |
|
230 | assert_nil Query.find_by_id(query.id) | |
|
231 | end | |
|
232 | ||
|
233 | def test_destroy_should_update_public_queries | |
|
234 | query = Query.new(:name => 'foo', :is_public => true) | |
|
235 | query.project_id = 1 | |
|
236 | query.user_id = 2 | |
|
237 | query.save! | |
|
238 | ||
|
239 | User.find(2).destroy | |
|
240 | assert_nil User.find_by_id(2) | |
|
241 | assert_equal User.anonymous, query.reload.user | |
|
242 | end | |
|
243 | ||
|
244 | def test_destroy_should_update_time_entries | |
|
245 | entry = TimeEntry.new(:hours => '2', :spent_on => Date.today, :activity => TimeEntryActivity.create!(:name => 'foo')) | |
|
246 | entry.project_id = 1 | |
|
247 | entry.user_id = 2 | |
|
248 | entry.save! | |
|
249 | ||
|
250 | User.find(2).destroy | |
|
251 | assert_nil User.find_by_id(2) | |
|
252 | assert_equal User.anonymous, entry.reload.user | |
|
253 | end | |
|
254 | ||
|
255 | def test_destroy_should_delete_tokens | |
|
256 | token = Token.create!(:user_id => 2, :value => 'foo') | |
|
257 | ||
|
258 | User.find(2).destroy | |
|
259 | assert_nil User.find_by_id(2) | |
|
260 | assert_nil Token.find_by_id(token.id) | |
|
261 | end | |
|
262 | ||
|
263 | def test_destroy_should_delete_watchers | |
|
264 | issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo') | |
|
265 | watcher = Watcher.create!(:user_id => 2, :watchable => issue) | |
|
266 | ||
|
267 | User.find(2).destroy | |
|
268 | assert_nil User.find_by_id(2) | |
|
269 | assert_nil Watcher.find_by_id(watcher.id) | |
|
270 | end | |
|
271 | ||
|
272 | def test_destroy_should_update_wiki_contents | |
|
273 | wiki_content = WikiContent.create!( | |
|
274 | :text => 'foo', | |
|
275 | :author_id => 2, | |
|
276 | :page => WikiPage.create!(:title => 'Foo', :wiki => Wiki.create!(:project_id => 1, :start_page => 'Start')) | |
|
277 | ) | |
|
278 | wiki_content.text = 'bar' | |
|
279 | assert_difference 'WikiContent::Version.count' do | |
|
280 | wiki_content.save! | |
|
281 | end | |
|
282 | ||
|
283 | User.find(2).destroy | |
|
284 | assert_nil User.find_by_id(2) | |
|
285 | assert_equal User.anonymous, wiki_content.reload.author | |
|
286 | wiki_content.versions.each do |version| | |
|
287 | assert_equal User.anonymous, version.reload.author | |
|
288 | end | |
|
289 | end | |
|
290 | ||
|
291 | def test_destroy_should_nullify_issue_categories | |
|
292 | category = IssueCategory.create!(:project_id => 1, :assigned_to_id => 2, :name => 'foo') | |
|
293 | ||
|
294 | User.find(2).destroy | |
|
295 | assert_nil User.find_by_id(2) | |
|
296 | assert_nil category.reload.assigned_to_id | |
|
297 | end | |
|
298 | ||
|
299 | def test_destroy_should_nullify_changesets | |
|
300 | changeset = Changeset.create!( | |
|
301 | :repository => Repository::Subversion.create!( | |
|
302 | :project_id => 1, | |
|
303 | :url => 'file:///var/svn' | |
|
304 | ), | |
|
305 | :revision => '12', | |
|
306 | :committed_on => Time.now, | |
|
307 | :committer => 'jsmith' | |
|
308 | ) | |
|
309 | assert_equal 2, changeset.user_id | |
|
310 | ||
|
311 | User.find(2).destroy | |
|
312 | assert_nil User.find_by_id(2) | |
|
313 | assert_nil changeset.reload.user_id | |
|
314 | end | |
|
315 | ||
|
316 | def test_anonymous_user_should_not_be_destroyable | |
|
317 | assert_no_difference 'User.count' do | |
|
318 | assert_equal false, User.anonymous.destroy | |
|
319 | end | |
|
320 | end | |
|
321 | ||
|
118 | 322 | def test_validate_login_presence |
|
119 | 323 | @admin.login = "" |
|
120 | 324 | assert !@admin.save |
General Comments 0
You need to be logged in to leave comments.
Login now