Skip to content

Commit 0c8178c

Browse files
committed
fix creation of work packages on shared sprints
1 parent 48e4b69 commit 0c8178c

File tree

9 files changed

+213
-8
lines changed

9 files changed

+213
-8
lines changed

modules/backlogs/app/components/backlogs/sprint_component.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ See COPYRIGHT and LICENSE files for more details.
3030
<%= component_wrapper(tag: :section) do %>
3131
<%= render(Primer::Beta::BorderBox.new(**@system_arguments)) do |border_box| %>
3232
<% border_box.with_header(id: dom_target(sprint, :header)) do %>
33-
<%= render(Backlogs::SprintHeaderComponent.new(sprint:, folded: folded?)) %>
33+
<%= render(Backlogs::SprintHeaderComponent.new(sprint:, project:, folded: folded?)) %>
3434
<% end %>
3535
<% if stories.empty? %>
3636
<% border_box.with_row(data: { empty_list_item: true }) do %>

modules/backlogs/app/components/backlogs/sprint_component.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def initialize(sprint:, project:, current_user: User.current, **system_arguments
5555
end
5656

5757
def stories
58-
sprint.work_packages.where(project: @project).order(:position)
58+
sprint.work_packages.where(project:).order(:position)
5959
end
6060

6161
def wrapper_uniq_by

modules/backlogs/app/components/backlogs/sprint_header_component.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,20 @@ class SprintHeaderComponent < ApplicationComponent
3636
include Redmine::I18n
3737
include RbCommonHelper
3838

39-
attr_reader :sprint, :collapsed, :current_user
39+
attr_reader :sprint, :project, :collapsed, :current_user
4040

41-
delegate :project, to: :sprint
4241
delegate :name, to: :sprint, prefix: :sprint
4342

4443
def initialize(
4544
sprint:,
45+
project:,
4646
folded: false,
4747
current_user: User.current
4848
)
4949
super()
5050

5151
@sprint = sprint
52+
@project = project
5253
@collapsed = folded
5354
@current_user = current_user
5455
end

modules/backlogs/app/controllers/rb_sprints_controller.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ def update_header_component_via_turbo_stream(state: :show)
155155

156156
def update_sprint_header_component_via_turbo_stream(sprint:)
157157
update_via_turbo_stream(
158-
component: Backlogs::SprintHeaderComponent.new(sprint:),
158+
component: Backlogs::SprintHeaderComponent.new(sprint:,
159+
project: @project),
159160
method: :morph
160161
)
161162
end

modules/backlogs/app/controllers/rb_stories_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class RbStoriesController < RbApplicationController
3636
skip_before_action :load_sprint_and_project, only: NEW_SPRINT_ACTIONS
3737

3838
before_action :legacy_load_story, except: NEW_SPRINT_ACTIONS
39-
prepend_before_action :load_sprint, :load_project, :load_story, only: NEW_SPRINT_ACTIONS
39+
before_action :load_project, :load_sprint, :load_story, only: NEW_SPRINT_ACTIONS
4040

4141
# Move a story from a Sprint to another Sprint or an Agile::Sprint.
4242
def move_legacy

modules/backlogs/spec/components/backlogs/sprint_component_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
end
5353

5454
def render_component
55-
render_inline(described_class.new(sprint:, current_user: user))
55+
render_inline(described_class.new(sprint:, project:, current_user: user))
5656
end
5757

5858
describe "rendering" do

modules/backlogs/spec/components/backlogs/sprint_header_component_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
end
5353

5454
def render_component(folded: false)
55-
render_inline(described_class.new(sprint:, folded:, current_user: user))
55+
render_inline(described_class.new(sprint:, project:, folded:, current_user: user))
5656
end
5757

5858
describe "show state (default)" do
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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+
require_relative "../../support/pages/backlogs"
33+
34+
RSpec.describe "Create work package in sprint", :js, with_flag: { scrum_projects: true } do
35+
let!(:project) do
36+
create(:project,
37+
types: [type, type2],
38+
enabled_module_names: %w(work_package_tracking backlogs))
39+
end
40+
let!(:project2) { create(:project) }
41+
let(:create_role) do
42+
create(:project_role,
43+
permissions: %i(view_sprints
44+
view_work_packages
45+
manage_sprint_items
46+
add_work_packages))
47+
end
48+
let(:non_create_role) do
49+
create(:project_role,
50+
permissions: %i(view_sprints
51+
view_work_packages))
52+
end
53+
54+
let(:type) { create(:type) }
55+
let(:type2) { create(:type) }
56+
57+
let!(:priority) { create(:default_priority) }
58+
let!(:status) { create(:default_status) }
59+
60+
let!(:sprint1) { create(:agile_sprint, project:) }
61+
let!(:sprint2) { create(:agile_sprint, project:) }
62+
63+
let!(:sprint1_wp1) { create(:work_package, sprint: sprint1, type:, project:) }
64+
let!(:sprint1_wp2) { create(:work_package, sprint: sprint1, type:, project:) }
65+
let!(:sprint1_other_project_wp1) { create(:work_package, sprint: sprint1, type:, project: project2) }
66+
67+
let(:backlogs_page) { Pages::Backlogs.new(project) }
68+
69+
current_user do
70+
create(:user,
71+
member_with_roles: {
72+
project => create_role,
73+
project2 => create_role
74+
})
75+
end
76+
77+
before do
78+
# Faulty and mostly irrelevant for the test. Only needed to make the sprints appear on the page.
79+
# To be removed once the setting is removed.
80+
Setting.plugin_openproject_backlogs = {
81+
"story_types" => [type.id.to_s],
82+
"task_type" => type.id.to_s
83+
}
84+
85+
backlogs_page.visit!
86+
end
87+
88+
context "in a non shared sprint" do
89+
it "allows creating a new story" do
90+
backlogs_page.click_in_sprint_menu(sprint1, "New story")
91+
92+
within_dialog "New work package" do
93+
fill_in "Subject", with: "The new item"
94+
# TODO: removed in OP #57688, to be reimplemented
95+
# fill_in "Story Points", with: "5"
96+
97+
select_combo_box_option type2.name, from: "Type"
98+
99+
# saving the new story
100+
click_on "Create"
101+
end
102+
103+
expect_and_dismiss_flash type: :success, message: "New work package created"
104+
105+
created_work_package = WorkPackage.last
106+
107+
# velocity should be summed up immediately
108+
# TODO: removed in OP #57688, to be reimplemented
109+
# xpect(page).to have_css(".velocity", text: "12")
110+
111+
# this will ensure that the page refresh is through before we check the order
112+
backlogs_page.click_in_sprint_menu(sprint1, "New story")
113+
114+
within_dialog "New work package" do
115+
fill_in "Subject", with: "Another story"
116+
end
117+
118+
# the order is kept even after a page refresh -> it is persisted in the db
119+
page.driver.refresh
120+
121+
expect(page)
122+
.to have_no_content "Another story"
123+
124+
backlogs_page
125+
.expect_work_packages_in_sprint_in_order(sprint1,
126+
work_packages: [sprint1_wp1,
127+
sprint1_wp2,
128+
created_work_package])
129+
130+
# created with the selected type (HighlightedTypeComponent renders type name in uppercase)
131+
backlogs_page.within_work_package_row(created_work_package) do
132+
expect(page).to have_text(type2.name.upcase)
133+
end
134+
end
135+
end
136+
137+
context "in an empty non shared sprint" do
138+
it "allows creating a new story" do
139+
backlogs_page.click_in_sprint_menu(sprint2, "New story")
140+
141+
within_dialog "New work package" do
142+
fill_in "Subject", with: "The new item"
143+
144+
click_on "Create"
145+
end
146+
147+
expect_and_dismiss_flash type: :success, message: "New work package created"
148+
149+
created_work_package = WorkPackage.last
150+
151+
backlogs_page
152+
.expect_work_packages_in_sprint_in_order(sprint2,
153+
work_packages: [created_work_package])
154+
end
155+
end
156+
157+
context "in a shared sprint" do
158+
let(:backlogs_page) { Pages::Backlogs.new(project2) }
159+
160+
it "allows creating a new story" do
161+
backlogs_page.click_in_sprint_menu(sprint1, "New story")
162+
163+
within_dialog "New work package" do
164+
fill_in "Subject", with: "The new item"
165+
166+
click_on "Create"
167+
end
168+
169+
expect_and_dismiss_flash type: :success, message: "New work package created"
170+
171+
created_work_package = WorkPackage.last
172+
173+
backlogs_page
174+
.expect_work_packages_in_sprint_in_order(sprint1,
175+
work_packages: [sprint1_other_project_wp1,
176+
created_work_package])
177+
end
178+
end
179+
180+
context "when lacking the permission to create work packages" do
181+
current_user do
182+
create(:user,
183+
member_with_roles: {
184+
project => non_create_role
185+
})
186+
end
187+
188+
it "does not show a menu item for creating a new work package" do
189+
backlogs_page.expect_no_sprint_menu_item(sprint1, "New story")
190+
end
191+
end
192+
end

modules/backlogs/spec/support/pages/backlogs.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,13 @@ def expect_and_dismiss_error(message)
217217
click_on "Cancel"
218218
end
219219

220+
def expect_no_sprint_menu_item(sprint, item_name)
221+
within_sprint_menu(sprint) do |_menu|
222+
expect(page)
223+
.to have_no_selector(:menuitem, text: item_name)
224+
end
225+
end
226+
220227
def path
221228
backlogs_project_backlogs_path(project)
222229
end
@@ -280,6 +287,10 @@ def within_sprint_menu(backlog, &)
280287
end
281288
end
282289

290+
def within_work_package_row(work_package, &)
291+
within(work_package_selector(work_package), &)
292+
end
293+
283294
private
284295

285296
def within_story(story, &)

0 commit comments

Comments
 (0)