From 0c3540b040407fc50bc2c38693544f7d6b64a3ce Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Fri, 12 Jun 2026 13:29:57 +0300 Subject: [PATCH] Cover blank work-package journal values in meeting activity formatter A work-package association journal stores a blank value for the absent side when the link is added or removed. Rendering it through the meeting formatter must resolve to the undisclosed label rather than tripping the find_by semantic-identifier guard, which previously surfaced as an UnsupportedLookup on the activities page. --- .../meeting_work_package_id_spec.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/modules/meeting/spec/lib/open_project/journal_formatter/meeting_work_package_id_spec.rb b/modules/meeting/spec/lib/open_project/journal_formatter/meeting_work_package_id_spec.rb index 05984fb0fb2..952df029c2a 100644 --- a/modules/meeting/spec/lib/open_project/journal_formatter/meeting_work_package_id_spec.rb +++ b/modules/meeting/spec/lib/open_project/journal_formatter/meeting_work_package_id_spec.rb @@ -73,6 +73,22 @@ RSpec.describe OpenProject::JournalFormatter::MeetingWorkPackageId do end end + context "when one side of the change is blank" do + # Regression for an activities-page crash: a work-package association + # journal holds a blank value for the absent side when the link is added + # or removed, and resolving it must not trip the find_by semantic-id guard. + before do + allow(WorkPackage).to receive(:visible).and_return(WorkPackage.where(id: new_work_package.id)) + end + + it "renders the visible side and an undisclosed label for the blank side" do + result = instance.render("work_package_id", ["", new_work_package.id], html: true) + + expect(result).to include("New task") + expect(result).to include(I18n.t(:label_agenda_item_undisclosed_wp, id: "")) + end + end + context "when work package names contain HTML" do let(:old_work_package) { create(:work_package, project:, subject: "Safe task") } let(:new_work_package) { create(:work_package, project:, subject: "") }