diff --git a/modules/costs/spec/factories/journal/time_entry_journal_factory.rb b/modules/costs/spec/factories/journal/time_entry_journal_factory.rb
index af78e1d5a27..3f028d05e73 100644
--- a/modules/costs/spec/factories/journal/time_entry_journal_factory.rb
+++ b/modules/costs/spec/factories/journal/time_entry_journal_factory.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
@@ -27,6 +29,5 @@
#++
FactoryBot.define do
- factory :journal_time_entry_journal, class: "Journal::TimeEntryJournal" do
- end
+ factory :journal_time_entry_journal, class: "Journal::TimeEntryJournal"
end
diff --git a/spec/factories/journal_factory.rb b/spec/factories/journal_factory.rb
index 200480577c1..f9f2718a074 100644
--- a/spec/factories/journal_factory.rb
+++ b/spec/factories/journal_factory.rb
@@ -68,21 +68,37 @@ FactoryBot.define do
factory :message_journal, class: "Journal" do
journable_type { "Message" }
data { build(:journal_message_journal) }
+
+ callback(:after_stub) do |journal, options|
+ journal.journable ||= options.journable || build_stubbed(:message)
+ end
end
factory :news_journal, class: "Journal" do
journable_type { "News" }
data { build(:journal_message_journal) }
+
+ callback(:after_stub) do |journal, options|
+ journal.journable ||= options.journable || build_stubbed(:news)
+ end
end
factory :project_journal, class: "Journal" do
journable factory: :project
data { build(:journal_project_journal) }
+
+ callback(:after_stub) do |journal, options|
+ journal.journable ||= options.journable || build_stubbed(:project)
+ end
end
factory :time_entry_journal, class: "Journal" do
journable_type { "TimeEntry" }
data { association(:journal_time_entry_journal) }
+
+ callback(:after_stub) do |journal, options|
+ journal.journable ||= options.journable || build_stubbed(:time_entry)
+ end
end
end
end
diff --git a/spec/lib/open_project/journal_formatter/polymorphic_association_spec.rb b/spec/lib/open_project/journal_formatter/polymorphic_association_spec.rb
new file mode 100644
index 00000000000..41b5b615e6d
--- /dev/null
+++ b/spec/lib/open_project/journal_formatter/polymorphic_association_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+require "spec_helper"
+
+RSpec.describe JournalFormatter::PolymorphicAssociation do
+ describe ".render" do
+ let(:journal) { build_stubbed(:time_entry_journal) }
+ let(:instance) { described_class.new(journal) }
+
+ let(:old_wp) { create(:work_package) }
+ let(:new_wp) { create(:work_package) }
+ let(:old_value) { old_wp&.to_gid }
+ let(:new_value) { new_wp&.to_gid }
+
+ context "when setting new value" do
+ let(:old_wp) { nil }
+
+ it "renders the new value" do
+ expect(instance.render("entity_gid", [old_value, new_value]))
+ .to eq(I18n.t(:text_journal_set_to,
+ label: "Logged for",
+ value: "#{new_wp.subject}"))
+
+ expect(instance.render("entity_gid", [old_value, new_value], html: false))
+ .to eq(I18n.t(:text_journal_set_to,
+ label: "Logged for",
+ value: new_wp.subject))
+ end
+ end
+
+ context "when changing value" do
+ it "renders the change from old to new value" do
+ expect(instance.render("entity_gid", [old_value, new_value]))
+ .to eq(I18n.t(:text_journal_changed_plain,
+ label: "Logged for",
+ linebreak: nil,
+ old: "#{old_wp.subject}",
+ new: "#{new_wp.subject}"))
+
+ expect(instance.render("entity_gid", [old_value, new_value], html: false))
+ .to eq(I18n.t(:text_journal_changed_plain,
+ label: "Logged for",
+ linebreak: nil,
+ old: old_wp.subject,
+ new: new_wp.subject))
+ end
+ end
+
+ context "when removing the value" do
+ let(:new_value) { nil }
+
+ it "renders as removed" do
+ expect(instance.render("entity_gid", [old_value, new_value]))
+ .to eq(I18n.t(:text_journal_deleted,
+ label: "Logged for",
+ old: "#{old_wp.subject}"))
+
+ expect(instance.render("entity_gid", [old_value, new_value], html: false))
+ .to eq(I18n.t(:text_journal_deleted,
+ label: "Logged for",
+ old: old_wp.subject))
+ end
+ end
+ end
+end