Skip to content

Commit de82f9f

Browse files
authored
Merge pull request #22908 from opf/bug/74351-move-down-link-shown-incorrectly-for-1-backlog-bucket-item
Bug/74351 move down link shown incorrectly for 1 backlog bucket item
2 parents 48aeb70 + d648dfa commit de82f9f

2 files changed

Lines changed: 142 additions & 22 deletions

File tree

modules/backlogs/app/controllers/backlogs/inbox_controller.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ class InboxController < BaseController
3737

3838
# Deferred ActionMenu items (Primer include-fragment).
3939
def menu
40-
max_position = Backlog.inbox_for(project: @project).maximum(:position) || 0
40+
backlog_items_scope = if OpenProject::FeatureDecisions.backlog_buckets_active? && @work_package.backlog_bucket_id
41+
@work_package.backlog_bucket.work_packages
42+
else
43+
Backlog.inbox_for(project: @project)
44+
end
45+
46+
max_position = backlog_items_scope.maximum(:position) || 0
4147
open_sprints_exist = Agile::Sprint.for_project(@project).visible.not_completed.exists?
4248

4349
render(Backlogs::InboxMenuComponent.new(

modules/backlogs/spec/controllers/backlogs/inbox_controller_spec.rb

Lines changed: 135 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -257,42 +257,156 @@
257257
get :menu, params: { project_id: project.id, id: work_package.id }, format: :html
258258
end
259259

260-
it "returns deferred action menu list HTML", :aggregate_failures do
261-
subject
262-
expect(response).to have_http_status :ok
263-
expect(response.body).to include(I18n.t(:"js.button_open_details"))
260+
shared_examples "it renders the menu" do
261+
it "returns deferred action menu list HTML", :aggregate_failures do
262+
subject
263+
expect(response).to have_http_status :ok
264+
expect(response.body).to include(I18n.t(:"js.button_open_details"))
265+
end
266+
267+
context "when all=1 is in params" do
268+
subject do
269+
get :menu, params: { project_id: project.id, id: work_package.id, all: "1" }, format: :html
270+
end
271+
272+
it "embeds the all query in deferred action URLs" do
273+
subject
274+
expect(response.body).to match(/all=1/)
275+
end
276+
end
277+
278+
context "when the work package belongs to another project" do
279+
let(:other_project) { create(:project) }
280+
let(:work_package) { create(:work_package, project: other_project) }
281+
282+
it "responds with 404" do
283+
expect(response).to have_http_status :not_found
284+
end
285+
end
286+
287+
context "with a user lacking project permission" do
288+
let(:user) { create(:user) }
289+
290+
it "responds with 404" do
291+
subject
292+
expect(response).to have_http_status :not_found
293+
end
294+
end
264295
end
265296

266-
context "when all=1 is in params" do
267-
subject do
268-
get :menu, params: { project_id: project.id, id: work_package.id, all: "1" }, format: :html
297+
shared_examples "renders actions to move in both directions" do
298+
it "renders actions to move in both directions", :aggregate_failures do
299+
expect(response.body).to include(I18n.t(:label_sort_highest))
300+
expect(response.body).to include(I18n.t(:label_sort_higher))
301+
expect(response.body).to include(I18n.t(:label_sort_lower))
302+
expect(response.body).to include(I18n.t(:label_sort_lowest))
269303
end
304+
end
270305

271-
it "embeds the all query in deferred action URLs" do
272-
subject
273-
expect(response.body).to match(/all=1/)
306+
shared_examples "renders only actions to move to bottom" do
307+
it "renders only actions to move to bottom", :aggregate_failures do
308+
expect(response.body).not_to include(I18n.t(:label_sort_highest))
309+
expect(response.body).not_to include(I18n.t(:label_sort_higher))
310+
expect(response.body).to include(I18n.t(:label_sort_lower))
311+
expect(response.body).to include(I18n.t(:label_sort_lowest))
274312
end
275313
end
276314

277-
context "when the work package belongs to another project" do
278-
let(:other_project) { create(:project) }
279-
let(:work_package) { create(:work_package, project: other_project) }
315+
shared_examples "renders only actions to move to top" do
316+
it "renders only actions to move to top", :aggregate_failures do
317+
expect(response.body).to include(I18n.t(:label_sort_highest))
318+
expect(response.body).to include(I18n.t(:label_sort_higher))
319+
expect(response.body).not_to include(I18n.t(:label_sort_lower))
320+
expect(response.body).not_to include(I18n.t(:label_sort_lowest))
321+
end
322+
end
280323

281-
it "responds with 404" do
282-
expect(response).to have_http_status :not_found
324+
shared_examples "renders no actions to move" do
325+
it "renders no actions to move", :aggregate_failures do
326+
expect(response.body).not_to include(I18n.t(:label_sort_highest))
327+
expect(response.body).not_to include(I18n.t(:label_sort_higher))
328+
expect(response.body).not_to include(I18n.t(:label_sort_lower))
329+
expect(response.body).not_to include(I18n.t(:label_sort_lowest))
283330
end
284331
end
285332

286-
context "with a user lacking project permission" do
287-
let(:user) { create(:user) }
333+
context "with backlog buckets enabled", with_flag: { backlog_buckets: true } do
334+
let!(:bucket1) { create(:backlog_bucket, project:) }
335+
let!(:bucket2) { create(:backlog_bucket, project:) }
288336

289-
it "responds with 404" do
290-
subject
291-
expect(response).to have_http_status :not_found
337+
let!(:bucket1_lone_work_package) { create(:work_package, project:, backlog_bucket: bucket1) }
338+
let!(:bucket2_work_packages) { create_list(:work_package, 5, project:, backlog_bucket: bucket2) }
339+
340+
it_behaves_like "checks permissions for private projects"
341+
342+
it_behaves_like "it renders the menu"
343+
344+
context "for work package at the top of inbox" do
345+
let(:work_package) { work_packages.first }
346+
347+
it_behaves_like "renders only actions to move to bottom"
348+
end
349+
350+
context "for work package at the bottom of inbox" do
351+
let(:work_package) { work_packages.last }
352+
353+
it_behaves_like "renders only actions to move to top"
354+
end
355+
356+
context "for work package in the middle of inbox" do
357+
let(:work_package) { work_packages.third }
358+
359+
it_behaves_like "renders actions to move in both directions"
360+
end
361+
362+
context "for a work package alone in the bucket" do
363+
let(:work_package) { bucket1_lone_work_package }
364+
365+
it_behaves_like "renders no actions to move"
366+
end
367+
368+
context "for work package at the top of bucket with multiple" do
369+
let(:work_package) { bucket2_work_packages.first }
370+
371+
it_behaves_like "renders only actions to move to bottom"
372+
end
373+
374+
context "for work package in the middle of bucket with multiple" do
375+
let(:work_package) { bucket2_work_packages.third }
376+
377+
it_behaves_like "renders actions to move in both directions"
378+
end
379+
380+
context "for work package at the bottom of bucket with multiple" do
381+
let(:work_package) { bucket2_work_packages.last }
382+
383+
it_behaves_like "renders only actions to move to top"
292384
end
293385
end
294386

295-
it_behaves_like "checks permissions for private projects"
387+
context "with backlog buckets disabled", with_flag: { backlog_buckets: false } do
388+
it_behaves_like "checks permissions for private projects"
389+
390+
it_behaves_like "it renders the menu"
391+
392+
context "for work package at the top" do
393+
let(:work_package) { work_packages.first }
394+
395+
it_behaves_like "renders only actions to move to bottom"
396+
end
397+
398+
context "for work package in the middle" do
399+
let(:work_package) { work_packages.third }
400+
401+
it_behaves_like "renders actions to move in both directions"
402+
end
403+
404+
context "for work package at the bottom" do
405+
let(:work_package) { work_packages.last }
406+
407+
it_behaves_like "renders only actions to move to top"
408+
end
409+
end
296410
end
297411

298412
describe "GET #move_to_sprint_dialog" do

0 commit comments

Comments
 (0)