Chris@1295
|
1 # Redmine - project management software
|
Chris@1295
|
2 # Copyright (C) 2006-2013 Jean-Philippe Lang
|
Chris@1295
|
3 #
|
Chris@1295
|
4 # This program is free software; you can redistribute it and/or
|
Chris@1295
|
5 # modify it under the terms of the GNU General Public License
|
Chris@1295
|
6 # as published by the Free Software Foundation; either version 2
|
Chris@1295
|
7 # of the License, or (at your option) any later version.
|
Chris@1295
|
8 #
|
Chris@1295
|
9 # This program is distributed in the hope that it will be useful,
|
Chris@1295
|
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
Chris@1295
|
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
Chris@1295
|
12 # GNU General Public License for more details.
|
Chris@1295
|
13 #
|
Chris@1295
|
14 # You should have received a copy of the GNU General Public License
|
Chris@1295
|
15 # along with this program; if not, write to the Free Software
|
Chris@1295
|
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
Chris@1295
|
17
|
Chris@1295
|
18 require File.expand_path('../../test_helper', __FILE__)
|
Chris@1295
|
19
|
Chris@1295
|
20 class ProjectCopyTest < ActiveSupport::TestCase
|
Chris@1295
|
21 fixtures :projects, :trackers, :issue_statuses, :issues,
|
Chris@1295
|
22 :journals, :journal_details,
|
Chris@1295
|
23 :enumerations, :users, :issue_categories,
|
Chris@1295
|
24 :projects_trackers,
|
Chris@1295
|
25 :custom_fields,
|
Chris@1295
|
26 :custom_fields_projects,
|
Chris@1295
|
27 :custom_fields_trackers,
|
Chris@1295
|
28 :custom_values,
|
Chris@1295
|
29 :roles,
|
Chris@1295
|
30 :member_roles,
|
Chris@1295
|
31 :members,
|
Chris@1295
|
32 :enabled_modules,
|
Chris@1295
|
33 :versions,
|
Chris@1295
|
34 :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
|
Chris@1295
|
35 :groups_users,
|
Chris@1295
|
36 :boards, :messages,
|
Chris@1295
|
37 :repositories,
|
Chris@1295
|
38 :news, :comments,
|
Chris@1295
|
39 :documents
|
Chris@1295
|
40
|
Chris@1295
|
41 def setup
|
Chris@1295
|
42 ProjectCustomField.destroy_all
|
Chris@1295
|
43 @source_project = Project.find(2)
|
Chris@1295
|
44 @project = Project.new(:name => 'Copy Test', :identifier => 'copy-test')
|
Chris@1295
|
45 @project.trackers = @source_project.trackers
|
Chris@1295
|
46 @project.enabled_module_names = @source_project.enabled_modules.collect(&:name)
|
Chris@1295
|
47 end
|
Chris@1295
|
48
|
Chris@1295
|
49 test "#copy should copy issues" do
|
Chris@1295
|
50 @source_project.issues << Issue.generate!(:status => IssueStatus.find_by_name('Closed'),
|
Chris@1295
|
51 :subject => "copy issue status",
|
Chris@1295
|
52 :tracker_id => 1,
|
Chris@1295
|
53 :assigned_to_id => 2,
|
Chris@1295
|
54 :project_id => @source_project.id)
|
Chris@1295
|
55 assert @project.valid?
|
Chris@1295
|
56 assert @project.issues.empty?
|
Chris@1295
|
57 assert @project.copy(@source_project)
|
Chris@1295
|
58
|
Chris@1295
|
59 assert_equal @source_project.issues.size, @project.issues.size
|
Chris@1295
|
60 @project.issues.each do |issue|
|
Chris@1295
|
61 assert issue.valid?
|
Chris@1295
|
62 assert ! issue.assigned_to.blank?
|
Chris@1295
|
63 assert_equal @project, issue.project
|
Chris@1295
|
64 end
|
Chris@1295
|
65
|
Chris@1295
|
66 copied_issue = @project.issues.first(:conditions => {:subject => "copy issue status"})
|
Chris@1295
|
67 assert copied_issue
|
Chris@1295
|
68 assert copied_issue.status
|
Chris@1295
|
69 assert_equal "Closed", copied_issue.status.name
|
Chris@1295
|
70 end
|
Chris@1295
|
71
|
Chris@1295
|
72 test "#copy should copy issues custom values" do
|
Chris@1295
|
73 field = IssueCustomField.generate!(:is_for_all => true, :trackers => Tracker.all)
|
Chris@1295
|
74 issue = Issue.generate!(:project => @source_project, :subject => 'Custom field copy')
|
Chris@1295
|
75 issue.custom_field_values = {field.id => 'custom'}
|
Chris@1295
|
76 issue.save!
|
Chris@1295
|
77 assert_equal 'custom', issue.reload.custom_field_value(field)
|
Chris@1295
|
78
|
Chris@1295
|
79 assert @project.copy(@source_project)
|
Chris@1295
|
80 copy = @project.issues.find_by_subject('Custom field copy')
|
Chris@1295
|
81 assert copy
|
Chris@1295
|
82 assert_equal 'custom', copy.reload.custom_field_value(field)
|
Chris@1295
|
83 end
|
Chris@1295
|
84
|
Chris@1295
|
85 test "#copy should copy issues assigned to a locked version" do
|
Chris@1295
|
86 User.current = User.find(1)
|
Chris@1295
|
87 assigned_version = Version.generate!(:name => "Assigned Issues")
|
Chris@1295
|
88 @source_project.versions << assigned_version
|
Chris@1295
|
89 Issue.generate!(:project => @source_project,
|
Chris@1295
|
90 :fixed_version_id => assigned_version.id,
|
Chris@1295
|
91 :subject => "copy issues assigned to a locked version")
|
Chris@1295
|
92 assigned_version.update_attribute :status, 'locked'
|
Chris@1295
|
93
|
Chris@1295
|
94 assert @project.copy(@source_project)
|
Chris@1295
|
95 @project.reload
|
Chris@1295
|
96 copied_issue = @project.issues.first(:conditions => {:subject => "copy issues assigned to a locked version"})
|
Chris@1295
|
97
|
Chris@1295
|
98 assert copied_issue
|
Chris@1295
|
99 assert copied_issue.fixed_version
|
Chris@1295
|
100 assert_equal "Assigned Issues", copied_issue.fixed_version.name # Same name
|
Chris@1295
|
101 assert_equal 'locked', copied_issue.fixed_version.status
|
Chris@1295
|
102 end
|
Chris@1295
|
103
|
Chris@1295
|
104 test "#copy should change the new issues to use the copied version" do
|
Chris@1295
|
105 User.current = User.find(1)
|
Chris@1295
|
106 assigned_version = Version.generate!(:name => "Assigned Issues", :status => 'open')
|
Chris@1295
|
107 @source_project.versions << assigned_version
|
Chris@1295
|
108 assert_equal 3, @source_project.versions.size
|
Chris@1295
|
109 Issue.generate!(:project => @source_project,
|
Chris@1295
|
110 :fixed_version_id => assigned_version.id,
|
Chris@1295
|
111 :subject => "change the new issues to use the copied version")
|
Chris@1295
|
112
|
Chris@1295
|
113 assert @project.copy(@source_project)
|
Chris@1295
|
114 @project.reload
|
Chris@1295
|
115 copied_issue = @project.issues.first(:conditions => {:subject => "change the new issues to use the copied version"})
|
Chris@1295
|
116
|
Chris@1295
|
117 assert copied_issue
|
Chris@1295
|
118 assert copied_issue.fixed_version
|
Chris@1295
|
119 assert_equal "Assigned Issues", copied_issue.fixed_version.name # Same name
|
Chris@1295
|
120 assert_not_equal assigned_version.id, copied_issue.fixed_version.id # Different record
|
Chris@1295
|
121 end
|
Chris@1295
|
122
|
Chris@1295
|
123 test "#copy should keep target shared versions from other project" do
|
Chris@1295
|
124 assigned_version = Version.generate!(:name => "Assigned Issues", :status => 'open', :project_id => 1, :sharing => 'system')
|
Chris@1295
|
125 issue = Issue.generate!(:project => @source_project,
|
Chris@1295
|
126 :fixed_version => assigned_version,
|
Chris@1295
|
127 :subject => "keep target shared versions")
|
Chris@1295
|
128
|
Chris@1295
|
129 assert @project.copy(@source_project)
|
Chris@1295
|
130 @project.reload
|
Chris@1295
|
131 copied_issue = @project.issues.first(:conditions => {:subject => "keep target shared versions"})
|
Chris@1295
|
132
|
Chris@1295
|
133 assert copied_issue
|
Chris@1295
|
134 assert_equal assigned_version, copied_issue.fixed_version
|
Chris@1295
|
135 end
|
Chris@1295
|
136
|
Chris@1295
|
137 test "#copy should copy issue relations" do
|
Chris@1295
|
138 Setting.cross_project_issue_relations = '1'
|
Chris@1295
|
139
|
Chris@1295
|
140 second_issue = Issue.generate!(:status_id => 5,
|
Chris@1295
|
141 :subject => "copy issue relation",
|
Chris@1295
|
142 :tracker_id => 1,
|
Chris@1295
|
143 :assigned_to_id => 2,
|
Chris@1295
|
144 :project_id => @source_project.id)
|
Chris@1295
|
145 source_relation = IssueRelation.create!(:issue_from => Issue.find(4),
|
Chris@1295
|
146 :issue_to => second_issue,
|
Chris@1295
|
147 :relation_type => "relates")
|
Chris@1295
|
148 source_relation_cross_project = IssueRelation.create!(:issue_from => Issue.find(1),
|
Chris@1295
|
149 :issue_to => second_issue,
|
Chris@1295
|
150 :relation_type => "duplicates")
|
Chris@1295
|
151
|
Chris@1295
|
152 assert @project.copy(@source_project)
|
Chris@1295
|
153 assert_equal @source_project.issues.count, @project.issues.count
|
Chris@1295
|
154 copied_issue = @project.issues.find_by_subject("Issue on project 2") # Was #4
|
Chris@1295
|
155 copied_second_issue = @project.issues.find_by_subject("copy issue relation")
|
Chris@1295
|
156
|
Chris@1295
|
157 # First issue with a relation on project
|
Chris@1295
|
158 assert_equal 1, copied_issue.relations.size, "Relation not copied"
|
Chris@1295
|
159 copied_relation = copied_issue.relations.first
|
Chris@1295
|
160 assert_equal "relates", copied_relation.relation_type
|
Chris@1295
|
161 assert_equal copied_second_issue.id, copied_relation.issue_to_id
|
Chris@1295
|
162 assert_not_equal source_relation.id, copied_relation.id
|
Chris@1295
|
163
|
Chris@1295
|
164 # Second issue with a cross project relation
|
Chris@1295
|
165 assert_equal 2, copied_second_issue.relations.size, "Relation not copied"
|
Chris@1295
|
166 copied_relation = copied_second_issue.relations.select {|r| r.relation_type == 'duplicates'}.first
|
Chris@1295
|
167 assert_equal "duplicates", copied_relation.relation_type
|
Chris@1295
|
168 assert_equal 1, copied_relation.issue_from_id, "Cross project relation not kept"
|
Chris@1295
|
169 assert_not_equal source_relation_cross_project.id, copied_relation.id
|
Chris@1295
|
170 end
|
Chris@1295
|
171
|
Chris@1295
|
172 test "#copy should copy issue attachments" do
|
Chris@1295
|
173 issue = Issue.generate!(:subject => "copy with attachment", :tracker_id => 1, :project_id => @source_project.id)
|
Chris@1295
|
174 Attachment.create!(:container => issue, :file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 1)
|
Chris@1295
|
175 @source_project.issues << issue
|
Chris@1295
|
176 assert @project.copy(@source_project)
|
Chris@1295
|
177
|
Chris@1295
|
178 copied_issue = @project.issues.first(:conditions => {:subject => "copy with attachment"})
|
Chris@1295
|
179 assert_not_nil copied_issue
|
Chris@1295
|
180 assert_equal 1, copied_issue.attachments.count, "Attachment not copied"
|
Chris@1295
|
181 assert_equal "testfile.txt", copied_issue.attachments.first.filename
|
Chris@1295
|
182 end
|
Chris@1295
|
183
|
Chris@1295
|
184 test "#copy should copy memberships" do
|
Chris@1295
|
185 assert @project.valid?
|
Chris@1295
|
186 assert @project.members.empty?
|
Chris@1295
|
187 assert @project.copy(@source_project)
|
Chris@1295
|
188
|
Chris@1295
|
189 assert_equal @source_project.memberships.size, @project.memberships.size
|
Chris@1295
|
190 @project.memberships.each do |membership|
|
Chris@1295
|
191 assert membership
|
Chris@1295
|
192 assert_equal @project, membership.project
|
Chris@1295
|
193 end
|
Chris@1295
|
194 end
|
Chris@1295
|
195
|
Chris@1295
|
196 test "#copy should copy memberships with groups and additional roles" do
|
Chris@1295
|
197 group = Group.create!(:lastname => "Copy group")
|
Chris@1295
|
198 user = User.find(7)
|
Chris@1295
|
199 group.users << user
|
Chris@1295
|
200 # group role
|
Chris@1295
|
201 Member.create!(:project_id => @source_project.id, :principal => group, :role_ids => [2])
|
Chris@1295
|
202 member = Member.find_by_user_id_and_project_id(user.id, @source_project.id)
|
Chris@1295
|
203 # additional role
|
Chris@1295
|
204 member.role_ids = [1]
|
Chris@1295
|
205
|
Chris@1295
|
206 assert @project.copy(@source_project)
|
Chris@1295
|
207 member = Member.find_by_user_id_and_project_id(user.id, @project.id)
|
Chris@1295
|
208 assert_not_nil member
|
Chris@1295
|
209 assert_equal [1, 2], member.role_ids.sort
|
Chris@1295
|
210 end
|
Chris@1295
|
211
|
Chris@1295
|
212 test "#copy should copy project specific queries" do
|
Chris@1295
|
213 assert @project.valid?
|
Chris@1295
|
214 assert @project.queries.empty?
|
Chris@1295
|
215 assert @project.copy(@source_project)
|
Chris@1295
|
216
|
Chris@1295
|
217 assert_equal @source_project.queries.size, @project.queries.size
|
Chris@1295
|
218 @project.queries.each do |query|
|
Chris@1295
|
219 assert query
|
Chris@1295
|
220 assert_equal @project, query.project
|
Chris@1295
|
221 end
|
Chris@1295
|
222 assert_equal @source_project.queries.map(&:user_id).sort, @project.queries.map(&:user_id).sort
|
Chris@1295
|
223 end
|
Chris@1295
|
224
|
Chris@1295
|
225 test "#copy should copy versions" do
|
Chris@1295
|
226 @source_project.versions << Version.generate!
|
Chris@1295
|
227 @source_project.versions << Version.generate!
|
Chris@1295
|
228
|
Chris@1295
|
229 assert @project.versions.empty?
|
Chris@1295
|
230 assert @project.copy(@source_project)
|
Chris@1295
|
231
|
Chris@1295
|
232 assert_equal @source_project.versions.size, @project.versions.size
|
Chris@1295
|
233 @project.versions.each do |version|
|
Chris@1295
|
234 assert version
|
Chris@1295
|
235 assert_equal @project, version.project
|
Chris@1295
|
236 end
|
Chris@1295
|
237 end
|
Chris@1295
|
238
|
Chris@1295
|
239 test "#copy should copy wiki" do
|
Chris@1295
|
240 assert_difference 'Wiki.count' do
|
Chris@1295
|
241 assert @project.copy(@source_project)
|
Chris@1295
|
242 end
|
Chris@1295
|
243
|
Chris@1295
|
244 assert @project.wiki
|
Chris@1295
|
245 assert_not_equal @source_project.wiki, @project.wiki
|
Chris@1295
|
246 assert_equal "Start page", @project.wiki.start_page
|
Chris@1295
|
247 end
|
Chris@1295
|
248
|
Chris@1295
|
249 test "#copy should copy wiki without wiki module" do
|
Chris@1295
|
250 project = Project.new(:name => 'Copy Test', :identifier => 'copy-test', :enabled_module_names => [])
|
Chris@1295
|
251 assert_difference 'Wiki.count' do
|
Chris@1295
|
252 assert project.copy(@source_project)
|
Chris@1295
|
253 end
|
Chris@1295
|
254
|
Chris@1295
|
255 assert project.wiki
|
Chris@1295
|
256 end
|
Chris@1295
|
257
|
Chris@1295
|
258 test "#copy should copy wiki pages and content with hierarchy" do
|
Chris@1295
|
259 assert_difference 'WikiPage.count', @source_project.wiki.pages.size do
|
Chris@1295
|
260 assert @project.copy(@source_project)
|
Chris@1295
|
261 end
|
Chris@1295
|
262
|
Chris@1295
|
263 assert @project.wiki
|
Chris@1295
|
264 assert_equal @source_project.wiki.pages.size, @project.wiki.pages.size
|
Chris@1295
|
265
|
Chris@1295
|
266 @project.wiki.pages.each do |wiki_page|
|
Chris@1295
|
267 assert wiki_page.content
|
Chris@1295
|
268 assert !@source_project.wiki.pages.include?(wiki_page)
|
Chris@1295
|
269 end
|
Chris@1295
|
270
|
Chris@1295
|
271 parent = @project.wiki.find_page('Parent_page')
|
Chris@1295
|
272 child1 = @project.wiki.find_page('Child_page_1')
|
Chris@1295
|
273 child2 = @project.wiki.find_page('Child_page_2')
|
Chris@1295
|
274 assert_equal parent, child1.parent
|
Chris@1295
|
275 assert_equal parent, child2.parent
|
Chris@1295
|
276 end
|
Chris@1295
|
277
|
Chris@1295
|
278 test "#copy should copy issue categories" do
|
Chris@1295
|
279 assert @project.copy(@source_project)
|
Chris@1295
|
280
|
Chris@1295
|
281 assert_equal 2, @project.issue_categories.size
|
Chris@1295
|
282 @project.issue_categories.each do |issue_category|
|
Chris@1295
|
283 assert !@source_project.issue_categories.include?(issue_category)
|
Chris@1295
|
284 end
|
Chris@1295
|
285 end
|
Chris@1295
|
286
|
Chris@1295
|
287 test "#copy should copy boards" do
|
Chris@1295
|
288 assert @project.copy(@source_project)
|
Chris@1295
|
289
|
Chris@1295
|
290 assert_equal 1, @project.boards.size
|
Chris@1295
|
291 @project.boards.each do |board|
|
Chris@1295
|
292 assert !@source_project.boards.include?(board)
|
Chris@1295
|
293 end
|
Chris@1295
|
294 end
|
Chris@1295
|
295
|
Chris@1295
|
296 test "#copy should change the new issues to use the copied issue categories" do
|
Chris@1295
|
297 issue = Issue.find(4)
|
Chris@1295
|
298 issue.update_attribute(:category_id, 3)
|
Chris@1295
|
299
|
Chris@1295
|
300 assert @project.copy(@source_project)
|
Chris@1295
|
301
|
Chris@1295
|
302 @project.issues.each do |issue|
|
Chris@1295
|
303 assert issue.category
|
Chris@1295
|
304 assert_equal "Stock management", issue.category.name # Same name
|
Chris@1295
|
305 assert_not_equal IssueCategory.find(3), issue.category # Different record
|
Chris@1295
|
306 end
|
Chris@1295
|
307 end
|
Chris@1295
|
308
|
Chris@1295
|
309 test "#copy should limit copy with :only option" do
|
Chris@1295
|
310 assert @project.members.empty?
|
Chris@1295
|
311 assert @project.issue_categories.empty?
|
Chris@1295
|
312 assert @source_project.issues.any?
|
Chris@1295
|
313
|
Chris@1295
|
314 assert @project.copy(@source_project, :only => ['members', 'issue_categories'])
|
Chris@1295
|
315
|
Chris@1295
|
316 assert @project.members.any?
|
Chris@1295
|
317 assert @project.issue_categories.any?
|
Chris@1295
|
318 assert @project.issues.empty?
|
Chris@1295
|
319 end
|
Chris@1295
|
320
|
Chris@1295
|
321 test "#copy should copy subtasks" do
|
Chris@1295
|
322 source = Project.generate!(:tracker_ids => [1])
|
Chris@1295
|
323 issue = Issue.generate_with_descendants!(:project => source)
|
Chris@1295
|
324 project = Project.new(:name => 'Copy', :identifier => 'copy', :tracker_ids => [1])
|
Chris@1295
|
325
|
Chris@1295
|
326 assert_difference 'Project.count' do
|
Chris@1295
|
327 assert_difference 'Issue.count', 1+issue.descendants.count do
|
Chris@1295
|
328 assert project.copy(source.reload)
|
Chris@1295
|
329 end
|
Chris@1295
|
330 end
|
Chris@1295
|
331 copy = Issue.where(:parent_id => nil).order("id DESC").first
|
Chris@1295
|
332 assert_equal project, copy.project
|
Chris@1295
|
333 assert_equal issue.descendants.count, copy.descendants.count
|
Chris@1295
|
334 child_copy = copy.children.detect {|c| c.subject == 'Child1'}
|
Chris@1295
|
335 assert child_copy.descendants.any?
|
Chris@1295
|
336 end
|
Chris@1295
|
337 end
|