Skip to content

Commit e6d629f

Browse files
committed
test nullifying backlog bucket on moving work package to a different project
1 parent 3402366 commit e6d629f

2 files changed

Lines changed: 125 additions & 3 deletions

File tree

modules/backlogs/lib/open_project/backlogs/patches/set_attributes_service_patch.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,25 @@ module InstanceMethods
3737
def set_attributes(attributes)
3838
super
3939

40+
if moved_to_another_project? && model.backlog_bucket_id
41+
model.change_by_system do
42+
model.backlog_bucket = nil
43+
end
44+
end
45+
4046
if moved_to_project_that_has_no_access_to_sprint?
4147
model.change_by_system do
4248
model.sprint = nil
4349
end
4450
end
4551
end
4652

53+
def moved_to_another_project?
54+
work_package.persisted? && work_package.project_id_changed?
55+
end
56+
4757
def moved_to_project_that_has_no_access_to_sprint?
48-
!work_package.new_record? &&
49-
work_package.project_id &&
50-
work_package.project_id_changed? &&
58+
moved_to_another_project? &&
5159
work_package.sprint_id &&
5260
!work_package.sprint.visible_to?(work_package.project)
5361
end
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
require "spec_helper"
32+
33+
RSpec.describe WorkPackages::UpdateService, "backlog bucket nullification on project change", type: :model do
34+
let(:source_project) { create(:project) }
35+
let(:target_project) { create(:project) }
36+
37+
let(:project_permissions) do
38+
# manage_sprint_items permission is intentionally excluded: nullifying the
39+
# backlog bucket when a work package is moved to a different project is an
40+
# consistency measure (backlog buckets are project-scoped), not a
41+
# user-initiated sprint management action
42+
%i[
43+
edit_work_packages
44+
move_work_packages
45+
view_work_packages
46+
]
47+
end
48+
49+
let(:user) do
50+
create(
51+
:user,
52+
member_with_permissions: {
53+
source_project => project_permissions,
54+
target_project => project_permissions
55+
}
56+
)
57+
end
58+
59+
let(:work_package) do
60+
create(:work_package,
61+
project: source_project,
62+
author: user,
63+
backlog_bucket: backlog_bucket_in_source_project)
64+
end
65+
66+
let(:instance) { described_class.new(user:, model: work_package) }
67+
68+
current_user { user }
69+
70+
describe "when changing the project" do
71+
context "when the work package has a backlog bucket" do
72+
let(:backlog_bucket_in_source_project) do
73+
create(:backlog_bucket, project: source_project)
74+
end
75+
76+
context "when moving to another project" do
77+
it "nullifies the backlog_bucket_id" do
78+
result = instance.call(project: target_project)
79+
80+
expect(result).to be_success
81+
expect(work_package.reload).to have_attributes(backlog_bucket_id: nil, project: target_project)
82+
end
83+
end
84+
85+
context "when the work package project is NOT changing" do
86+
it "preserves the backlog_bucket_id" do
87+
result = instance.call(subject: "Updated Subject")
88+
89+
expect(result).to be_success
90+
expect(work_package.reload)
91+
.to have_attributes(
92+
backlog_bucket: backlog_bucket_in_source_project,
93+
project: source_project
94+
)
95+
end
96+
end
97+
end
98+
99+
context "when the work package does NOT have a backlog bucket" do
100+
let(:backlog_bucket_in_source_project) { nil }
101+
102+
it "keeps backlog_bucket_id nil when moving to another project" do
103+
result = instance.call(project: target_project)
104+
105+
expect(result).to be_success
106+
expect(work_package.reload)
107+
.to have_attributes(
108+
backlog_bucket_id: nil,
109+
project: target_project
110+
)
111+
end
112+
end
113+
end
114+
end

0 commit comments

Comments
 (0)