|
31 | 31 | require "spec_helper" |
32 | 32 |
|
33 | 33 | RSpec.describe CopyProjectJob, type: :model, with_good_job_batches: [CopyProjectJob, SendCopyProjectStatusEmailJob] do |
| 34 | + shared_let(:admin) { create(:admin) } |
| 35 | + shared_let(:user_de) { create(:admin, language: :de) } |
34 | 36 | let(:params) { { name: "Copy", identifier: "copy" } } |
35 | | - let(:user_de) { create(:admin, language: :de) } |
36 | 37 | let(:mail_double) { double("Mail::Message", deliver: true) } # rubocop:disable RSpec/VerifiedDoubles |
37 | 38 |
|
38 | 39 | before { allow(mail_double).to receive(:deliver_later) } |
39 | 40 |
|
40 | 41 | describe "copy project succeeds with errors" do |
41 | | - let(:admin) { create(:admin) } |
42 | 42 | let(:source_project) { create(:project, types: [type]) } |
43 | 43 |
|
44 | | - let!(:work_package) { create(:work_package, project: source_project, type:) } |
| 44 | + let!(:work_package) { create(:work_package, :skip_validations, done_ratio: 101, project: source_project, type:) } |
45 | 45 |
|
46 | 46 | let(:type) { create(:type_bug) } |
47 | | - let(:custom_field) do |
48 | | - create(:work_package_custom_field, name: "required_field", field_format: "text", is_required: true, is_for_all: true) |
49 | | - end |
50 | | - |
51 | 47 | let(:job_args) do |
52 | 48 | { |
53 | 49 | target_project_params: params, |
54 | 50 | associations_to_copy: [:work_packages] |
55 | 51 | } |
56 | 52 | end |
57 | 53 |
|
58 | | - let(:params) { { name: "Copy", identifier: "copy", type_ids: [type.id], work_package_custom_field_ids: [custom_field.id] } } |
| 54 | + let(:params) { { name: "Copy", identifier: "copy", type_ids: [type.id] } } |
59 | 55 | let(:expected_error_message) do |
60 | | - "#{WorkPackage.model_name.human} '#{work_package.type.name} ##{work_package.id}: #{work_package.subject}': #{custom_field.name} #{I18n.t('errors.messages.blank')}." |
61 | | - end |
62 | | - |
63 | | - before do |
64 | | - source_project.work_package_custom_fields << custom_field |
65 | | - type.custom_fields << custom_field |
| 56 | + "#{WorkPackage.model_name.human} '#{work_package.type.name} ##{work_package.id}: " \ |
| 57 | + "#{work_package.subject}': % Complete " \ |
| 58 | + "#{I18n.t('activerecord.errors.models.work_package.attributes.done_ratio.inclusion')}" |
66 | 59 | end |
67 | 60 |
|
68 | 61 | it "copies the project", :aggregate_failures do |
|
94 | 87 | GoodJob.perform_inline |
95 | 88 | batch.reload |
96 | 89 |
|
97 | | - msg = /Arbeitspaket 'Bug #\d+: WorkPackage No. \d+': required_field muss ausgefüllt werden\./ |
| 90 | + msg = /Arbeitspaket 'Bug #\d+: WorkPackage No. \d+': % abgeschlossen muss zwischen 0 und 100 liegen\./ |
98 | 91 | expect(batch.properties[:errors].first).to match(msg) |
99 | 92 | end |
100 | 93 | end |
101 | 94 |
|
| 95 | + describe "copy project succeeds with invalid custom fields" do |
| 96 | + let(:source_project) { create(:project, types: [type]) } |
| 97 | + |
| 98 | + let!(:work_package) { create(:work_package, project: source_project, type:) } |
| 99 | + |
| 100 | + let(:type) { create(:type_bug) } |
| 101 | + let(:custom_field) do |
| 102 | + create(:work_package_custom_field, name: "required_field", field_format: "text", is_required: true, is_for_all: true) |
| 103 | + end |
| 104 | + |
| 105 | + let(:job_args) do |
| 106 | + { |
| 107 | + target_project_params: params, |
| 108 | + associations_to_copy: [:work_packages] |
| 109 | + } |
| 110 | + end |
| 111 | + |
| 112 | + let(:params) { { name: "Copy", identifier: "copy", type_ids: [type.id], work_package_custom_field_ids: [custom_field.id] } } |
| 113 | + |
| 114 | + before do |
| 115 | + source_project.work_package_custom_fields << custom_field |
| 116 | + type.custom_fields << custom_field |
| 117 | + end |
| 118 | + |
| 119 | + it "copies the project", :aggregate_failures do |
| 120 | + copy_job = nil |
| 121 | + batch = GoodJob::Batch.enqueue(user: admin, source_project:) do |
| 122 | + copy_job = described_class.perform_later(**job_args) |
| 123 | + end |
| 124 | + GoodJob.perform_inline |
| 125 | + batch.reload |
| 126 | + |
| 127 | + copied_project = Project.find_by(identifier: params[:identifier]) |
| 128 | + |
| 129 | + expect(copied_project).to eq(batch.properties[:target_project]) |
| 130 | + expect(batch.properties[:errors]).to be_empty |
| 131 | + |
| 132 | + # expect to create a status |
| 133 | + expect(copy_job.job_status).to be_present |
| 134 | + expect(copy_job.job_status[:status]).to eq "success" |
| 135 | + expect(copy_job.job_status[:payload]["redirect"]).to include "/projects/copy" |
| 136 | + |
| 137 | + expected_link = { "href" => "/api/v3/projects/#{copied_project.id}", "title" => copied_project.name } |
| 138 | + expect(copy_job.job_status[:payload]["_links"]["project"]).to eq(expected_link) |
| 139 | + end |
| 140 | + end |
| 141 | + |
102 | 142 | describe "project has an invalid repository" do |
103 | | - let(:admin) { create(:admin) } |
104 | 143 | let(:source_project) do |
105 | 144 | project = create(:project) |
106 | 145 |
|
|
136 | 175 | end |
137 | 176 |
|
138 | 177 | describe "copy project fails with internal error" do |
139 | | - let(:admin) { create(:admin) } |
140 | 178 | let(:source_project) { create(:project) } |
141 | | - let(:params) { { name: "Copy", identifier: "copy" } } |
142 | 179 |
|
143 | 180 | before do |
144 | 181 | allow(User).to receive(:current).and_return(admin) |
|
174 | 211 | set_factory_default(:project_with_types, source_project) |
175 | 212 | end |
176 | 213 |
|
177 | | - let(:admin) { create(:admin) } |
178 | | - let(:params) { { name: "Copy", identifier: "copy" } } |
179 | | - |
180 | 214 | let_work_packages(<<~TABLE) |
181 | 215 | hierarchy | work | remaining work | start date | end date | scheduling mode |
182 | 216 | parent | 1h | 0h | 2024-01-23 | 2024-01-26 | automatic |
|
235 | 269 | end |
236 | 270 |
|
237 | 271 | describe "subproject" do |
238 | | - let(:params) { { name: "Copy", identifier: "copy" } } |
239 | 272 | let(:subproject) do |
240 | 273 | create(:project, parent: project).tap do |p| |
241 | 274 | create(:member, principal: user, roles: [role], project: p) |
|
328 | 361 | set_factory_default(:project_with_types, source_project) |
329 | 362 | end |
330 | 363 |
|
331 | | - let(:admin) { create(:admin) } |
332 | | - let(:params) { { name: "Copy", identifier: "copy" } } |
333 | | - |
334 | 364 | let_work_packages(<<~TABLE) |
335 | 365 | hierarchy | start date | end date | scheduling mode |
336 | 366 | automatic_parent | 2024-01-23 | 2024-01-26 | automatic |
|
362 | 392 | # do it. |
363 | 393 | describe "sending notifications" do |
364 | 394 | shared_let(:project) { create(:project) } |
365 | | - shared_let(:admin) { create(:admin) } |
366 | 395 | shared_let(:user) { create(:user) } |
367 | 396 | shared_let(:roles) { [create(:project_role)] } |
368 | 397 | shared_let(:member) { create(:member, user:, project:, roles:) } |
369 | 398 |
|
370 | | - let(:params) { { name: "Copy", identifier: "copy" } } |
371 | | - |
372 | 399 | def perform_the_job |
373 | 400 | batch = GoodJob::Batch.enqueue(user: admin, source_project: project) do |
374 | 401 | described_class.perform_later(target_project_params: params, associations_to_copy: [:members]) |
|
0 commit comments