From 5019e82c396e65d84e36d630e739e035c65ba456 Mon Sep 17 00:00:00 2001 From: Mauro MSL Date: Thu, 2 Oct 2025 09:08:39 +0100 Subject: [PATCH 1/3] fix: call is method, not property #4991 --- src/submission/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/submission/models.py b/src/submission/models.py index dfab707e8..0834b686f 100755 --- a/src/submission/models.py +++ b/src/submission/models.py @@ -3374,7 +3374,7 @@ def backwards_compat_authors( for account in accounts: account.snapshot_as_author(instance) if action in ["post_remove", "post_clear"]: - instance.frozen_authors.filter(author__in=pk_set).delete() + instance.frozen_authors().filter(author__in=pk_set).delete() m2m_changed.connect(backwards_compat_authors, sender=Article.authors.through) From 7f532a3898c1319cbc1d0120b228e785c43d326f Mon Sep 17 00:00:00 2001 From: Mauro MSL Date: Wed, 22 Oct 2025 08:41:31 +0100 Subject: [PATCH 2/3] #4491: Adds signal test case --- src/submission/tests/test_signals.py | 42 ++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/submission/tests/test_signals.py diff --git a/src/submission/tests/test_signals.py b/src/submission/tests/test_signals.py new file mode 100644 index 000000000..8b2a4eca7 --- /dev/null +++ b/src/submission/tests/test_signals.py @@ -0,0 +1,42 @@ +from django.test import TestCase + +from submission.models import FrozenAuthor +from utils.testing import helpers + + +class TestBackwardsCompatAuthorsSignal(TestCase): + def setUp(self): + self.journal, _ = helpers.create_journals() + self.article = helpers.create_article( + title="Test Article", journal=self.journal + ) + self.account1 = helpers.create_user( + "author_one@email.com", ["author"], self.journal + ) + self.account2 = helpers.create_user( + "author_two@email.com", ["author"], self.journal + ) + + def test_signal_creates_frozen_author_on_add(self): + self.article.authors.add(self.account1) + self.assertTrue( + FrozenAuthor.objects.filter( + article=self.article, author=self.account1 + ).exists() + ) + + def test_signal_removes_frozen_author_on_remove(self): + frozen_author = FrozenAuthor.objects.create( + article=self.article, + author=self.account1, + ) + self.article.authors.add(self.account1) + self.article.authors.remove(self.account1) + self.assertFalse(FrozenAuthor.objects.filter(pk=frozen_author.pk).exists()) + + def test_signal_removes_all_frozen_authors_on_clear(self): + FrozenAuthor.objects.create(article=self.article, author=self.account1) + FrozenAuthor.objects.create(article=self.article, author=self.account2) + self.article.authors.add(self.account1, self.account2) + self.article.authors.clear() + self.assertFalse(FrozenAuthor.objects.filter(article=self.article).exists()) From befa6ec4103a3adc59595345e868d851d523820b Mon Sep 17 00:00:00 2001 From: Mauro MSL Date: Wed, 22 Oct 2025 08:41:51 +0100 Subject: [PATCH 3/3] #4491: Fix post_clear signal --- src/submission/models.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/submission/models.py b/src/submission/models.py index 0834b686f..e402b4268 100755 --- a/src/submission/models.py +++ b/src/submission/models.py @@ -3363,18 +3363,23 @@ def backwards_compat_authors( was removed. This signal is a backwards compatibility measure to ensure FrozenAuthor records are being updated correctly. """ - accounts = core_models.Account.objects.filter(pk__in=pk_set) if action == "post_add": subq = models.Subquery( ArticleAuthorOrder.objects.filter( article=instance, author__id=models.OuterRef("id") ).values_list("order") ) + accounts = core_models.Account.objects.filter(pk__in=pk_set) accounts = accounts.annotate(order=subq).order_by("order") for account in accounts: account.snapshot_as_author(instance) - if action in ["post_remove", "post_clear"]: + + if action == "post_remove": + accounts = core_models.Account.objects.filter(pk__in=pk_set) instance.frozen_authors().filter(author__in=pk_set).delete() + if action == "post_clear": + instance.frozen_authors().delete() + m2m_changed.connect(backwards_compat_authors, sender=Article.authors.through)