From 64402edae270fc4271a7efffe2c496bc3239bab5 Mon Sep 17 00:00:00 2001
From: George Katsikas <giorgakis.katsikas@gmail.com>
Date: Mon, 20 Nov 2023 17:57:50 +0100
Subject: [PATCH] add factories for all scipost models

---
 scipost_django/scipost/factories.py           |  62 ++++++++++-
 .../scipost/tests/test_factories.py           | 100 ++++++++++++++++++
 2 files changed, 158 insertions(+), 4 deletions(-)
 create mode 100644 scipost_django/scipost/tests/test_factories.py

diff --git a/scipost_django/scipost/factories.py b/scipost_django/scipost/factories.py
index 5a7c0cb78..43d6f95c0 100644
--- a/scipost_django/scipost/factories.py
+++ b/scipost_django/scipost/factories.py
@@ -7,11 +7,13 @@ import pytz
 
 from django.contrib.auth import get_user_model
 from django.contrib.auth.models import Group
+from journals.models.publication import Publication
 from profiles.factories import ProfileFactory
+from submissions.models.submission import Submission
 
 from .constants import NORMAL_CONTRIBUTOR
-from .models import Contributor, Remark, TOTPDevice
-from common.faker import fake
+from .models import *
+from common.faker import LazyRandEnum, fake
 
 
 class ContributorFactory(factory.django.DjangoModelFactory):
@@ -20,10 +22,11 @@ class ContributorFactory(factory.django.DjangoModelFactory):
         django_get_or_create = ("user",)
 
     user = factory.SubFactory("scipost.factories.UserFactory", contributor=None)
-    profile = factory.SubFactory(
+    profile = factory.RelatedFactory(
         ProfileFactory,
         first_name=factory.SelfAttribute("..user.first_name"),
         last_name=factory.SelfAttribute("..user.last_name"),
+        factory_related_name="contributor",
     )
     invitation_key = factory.Faker("md5")
     activation_key = factory.Faker("md5")
@@ -33,10 +36,13 @@ class ContributorFactory(factory.django.DjangoModelFactory):
 
     @classmethod
     def from_profile(cls, profile):
-        return cls(
+        contributor = cls(
             user__first_name=profile.first_name,
             user__last_name=profile.last_name,
         )
+        contributor.profile = profile
+        contributor.save()
+        return contributor
 
 
 class VettingEditorFactory(ContributorFactory):
@@ -64,6 +70,7 @@ class UserFactory(factory.django.DjangoModelFactory):
 
     class Meta:
         model = get_user_model()
+        django_get_or_create = ("username",)
 
     @factory.post_generation
     def groups(self, create, extracted, **kwargs):
@@ -80,6 +87,13 @@ class UserFactory(factory.django.DjangoModelFactory):
             )
 
 
+class GroupFactory(factory.django.DjangoModelFactory):
+    name = factory.Faker("word")
+
+    class Meta:
+        model = Group
+
+
 class TOTPDeviceFactory(factory.django.DjangoModelFactory):
     user = factory.SubFactory("scipost.factories.UserFactory")
     name = factory.Faker("pystr")
@@ -87,6 +101,7 @@ class TOTPDeviceFactory(factory.django.DjangoModelFactory):
 
     class Meta:
         model = TOTPDevice
+        django_get_or_create = ("user", "name")
 
 
 class SubmissionRemarkFactory(factory.django.DjangoModelFactory):
@@ -97,3 +112,42 @@ class SubmissionRemarkFactory(factory.django.DjangoModelFactory):
 
     class Meta:
         model = Remark
+
+
+class UnavailabilityPeriodFactory(factory.django.DjangoModelFactory):
+    class Meta:
+        model = UnavailabilityPeriod
+
+    contributor = factory.SubFactory(ContributorFactory)
+    start = factory.Faker("date_time_this_decade")
+    end = factory.LazyAttribute(
+        lambda self: fake.aware.date_between(start_date=self.start, end_date="+1y")
+    )
+
+
+class AuthorshipClaimFactory(factory.django.DjangoModelFactory):
+    class Meta:
+        model = AuthorshipClaim
+
+    claimant = factory.SubFactory(ContributorFactory)
+    status = LazyRandEnum(AUTHORSHIP_CLAIM_STATUS)
+    vetted_by = factory.LazyAttribute(
+        lambda self: VettingEditorFactory() if self.status != 0 else None
+    )
+
+
+class CitationNotificationFactory(factory.django.DjangoModelFactory):
+    class Meta:
+        model = CitationNotification
+
+    class Params:
+        item = None
+
+    contributor = factory.SubFactory(ContributorFactory)
+    processed = factory.Faker("boolean")
+    cited_in_submission = factory.LazyAttribute(
+        lambda self: self.item if isinstance(self.item, Submission) else None
+    )
+    cited_in_publication = factory.LazyAttribute(
+        lambda self: self.item if isinstance(self.item, Publication) else None
+    )
diff --git a/scipost_django/scipost/tests/test_factories.py b/scipost_django/scipost/tests/test_factories.py
new file mode 100644
index 000000000..dff78d923
--- /dev/null
+++ b/scipost_django/scipost/tests/test_factories.py
@@ -0,0 +1,100 @@
+from django.test import TestCase
+
+from profiles.factories import ProfileFactory
+from scipost.constants import AUTHORSHIP_CLAIM_ACCEPTED
+
+from ..factories import *
+
+from submissions.factories import SubmissionFactory
+from journals.factories import JournalPublicationFactory
+
+
+class TestContributorFactory(TestCase):
+    def test_can_create_contributors(self):
+        contributor = ContributorFactory()
+
+        self.assertIsNotNone(contributor)
+
+    def test_contributor_user_and_profile_have_same_name(self):
+        contributor = ContributorFactory()
+
+        self.assertEqual(contributor.profile.first_name, contributor.user.first_name)
+        self.assertEqual(contributor.profile.last_name, contributor.user.last_name)
+
+    def test_contributor_user_name_propagates_to_profile(self):
+        contributor = ContributorFactory(user__first_name="John", user__last_name="Doe")
+
+        self.assertEqual(contributor.profile.first_name, "John")
+        self.assertEqual(contributor.profile.last_name, "Doe")
+
+    def test_contributor_from_user_refers_to_user_used(self):
+        user = UserFactory(first_name="John", last_name="Doe")
+        contributor = ContributorFactory(user=user)
+
+        self.assertEqual(contributor.user, user)
+
+    def test_contributor_from_profile_refers_to_profile_used(self):
+        profile = ProfileFactory(title="Mr", first_name="John", last_name="Doe")
+        contributor = ContributorFactory.from_profile(profile)
+
+        self.assertEqual(contributor.profile, profile)
+
+
+class TestUserFactory(TestCase):
+    def test_can_create_users(self):
+        user = UserFactory()
+        self.assertIsNotNone(user)
+
+    def test_user_username_contains_first_and_last_name(self):
+        user = UserFactory(first_name="John", last_name="Doe")
+        self.assertEqual(user.username, "jdoe")
+
+
+class TestTOTPDeviceFactory(TestCase):
+    def test_can_create_totp_devices(self):
+        totp_device = TOTPDeviceFactory()
+        self.assertIsNotNone(totp_device)
+
+
+class TestSubmissionRemarkFactory(TestCase):
+    def test_can_create_submission_remarks(self):
+        submission_remark = SubmissionRemarkFactory()
+        self.assertIsNotNone(submission_remark)
+
+
+class TestUnavailabilityPeriodFactory(TestCase):
+    def test_can_create_unavailability_periods(self):
+        unavailability_period = UnavailabilityPeriodFactory()
+        self.assertIsNotNone(unavailability_period)
+
+
+class TestAuthorshipClaimFactory(TestCase):
+    def test_can_create_authorship_claims(self):
+        authorship_claim = AuthorshipClaimFactory()
+        self.assertIsNotNone(authorship_claim)
+
+    def test_non_pending_authorship_claim_has_editor(self):
+        authorship_claim = AuthorshipClaimFactory(status=AUTHORSHIP_CLAIM_ACCEPTED)
+        self.assertIsNotNone(authorship_claim.vetted_by)
+        self.assertIsNotNone(authorship_claim)
+
+    def test_pending_authorship_claim_has_no_editor(self):
+        authorship_claim = AuthorshipClaimFactory(status=AUTHORSHIP_CLAIM_PENDING)
+        self.assertIsNone(authorship_claim.vetted_by)
+        self.assertIsNotNone(authorship_claim)
+
+
+class TestCitationNotificationFactory(TestCase):
+    def test_can_create_citation_notifications_with_publication(self):
+        citation_notification = CitationNotificationFactory(
+            item=JournalPublicationFactory()
+        )
+        self.assertIsNotNone(citation_notification.cited_in_publication)
+        self.assertIsNone(citation_notification.cited_in_submission)
+        self.assertIsNotNone(citation_notification)
+
+    def test_can_create_citation_notifications_with_submission(self):
+        citation_notification = CitationNotificationFactory(item=SubmissionFactory())
+        self.assertIsNotNone(citation_notification.cited_in_submission)
+        self.assertIsNone(citation_notification.cited_in_publication)
+        self.assertIsNotNone(citation_notification)
-- 
GitLab