From f42aab6a59139a4ff07e20807fc8afc910316cdf Mon Sep 17 00:00:00 2001
From: George Katsikas <giorgakis.katsikas@gmail.com>
Date: Tue, 14 Nov 2023 13:48:45 +0100
Subject: [PATCH] add factories for all colleges models

---
 scipost_django/colleges/factories.py          | 130 ++++++++++++++++-
 .../colleges/tests/test_factories.py          | 134 ++++++++++++++++++
 2 files changed, 260 insertions(+), 4 deletions(-)
 create mode 100644 scipost_django/colleges/tests/test_factories.py

diff --git a/scipost_django/colleges/factories.py b/scipost_django/colleges/factories.py
index bcd957b6f..5926211ab 100644
--- a/scipost_django/colleges/factories.py
+++ b/scipost_django/colleges/factories.py
@@ -2,10 +2,21 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
+import datetime
+
 import factory
 from django.utils.text import slugify
-from colleges.models.nomination import FellowshipNomination
-from common.faker import LazyAwareDate
+
+from colleges.models.nomination import (
+    FellowshipInvitation,
+    FellowshipNomination,
+    FellowshipNominationComment,
+    FellowshipNominationDecision,
+    FellowshipNominationEvent,
+    FellowshipNominationVote,
+    FellowshipNominationVotingRound,
+)
+from common.faker import LazyAwareDate, LazyRandEnum, fake
 from ontology.factories import AcademicFieldFactory
 from profiles.factories import ProfileFactory
 from scipost.factories import ContributorFactory
@@ -13,16 +24,30 @@ from scipost.factories import ContributorFactory
 from .models import College, Fellowship
 
 
+############
+# Colleges #
+############
+
+
 class CollegeFactory(factory.django.DjangoModelFactory):
-    name = factory.Faker("word")
+    name = factory.LazyAttribute(
+        lambda _: fake.word(part_of_speech="adjective").title()
+        + " "
+        + fake.word(part_of_speech="noun").title()
+    )
     acad_field = factory.SubFactory(AcademicFieldFactory)
     slug = factory.LazyAttribute(lambda self: slugify(self.name))
-    order = factory.Sequence(lambda n: College.objects.count() + 1)
+    order = factory.Sequence(lambda n: n + 1)
 
     class Meta:
         model = College
 
 
+###############
+# Fellowships #
+###############
+
+
 class BaseFellowshipFactory(factory.django.DjangoModelFactory):
     college = factory.SubFactory(CollegeFactory)
     contributor = factory.SubFactory(ContributorFactory)
@@ -47,6 +72,11 @@ class SeniorFellowshipFactory(BaseFellowshipFactory):
     status = "senior"
 
 
+###############
+# Nominations #
+###############
+
+
 class FellowshipNominationFactory(factory.django.DjangoModelFactory):
     class Meta:
         model = FellowshipNomination
@@ -59,6 +89,15 @@ class FellowshipNominationFactory(factory.django.DjangoModelFactory):
     fellowship = None
 
 
+class EmptyRoundFellowshipNominationFactory(FellowshipNominationFactory):
+    @factory.post_generation
+    def create_voting_round(self, create, extracted, **kwargs):
+        if not create:
+            return
+        self.voting_round = FellowshipNominationVotingRoundFactory(nomination=self)
+        self.voting_round.save()
+
+
 class RegisteredFellowshipNominationFactory(FellowshipNominationFactory):
     @factory.post_generation
     def create_profile_contributor(self, create, extracted, **kwargs):
@@ -77,3 +116,86 @@ class SuccessfulFellowshipNominationFactory(RegisteredFellowshipNominationFactor
             contributor=self.profile.contributor, college=self.college
         )
         self.fellowship.save()
+
+
+class FellowshipNominationEventFactory(factory.django.DjangoModelFactory):
+    class Meta:
+        model = FellowshipNominationEvent
+
+    nomination = factory.SubFactory(FellowshipNominationFactory)
+    description = factory.Faker("text")
+    by = factory.SubFactory(ContributorFactory)
+    on = LazyAwareDate("date_time_this_year")
+
+
+class FellowshipNominationCommentFactory(factory.django.DjangoModelFactory):
+    class Meta:
+        model = FellowshipNominationComment
+
+    nomination = factory.SubFactory(FellowshipNominationFactory)
+    text = factory.Faker("text")
+    by = factory.SubFactory(ContributorFactory)
+    on = LazyAwareDate("date_time_this_year")
+
+
+class FellowshipNominationVotingRoundFactory(factory.django.DjangoModelFactory):
+    class Meta:
+        model = FellowshipNominationVotingRound
+
+    nomination = factory.SubFactory(FellowshipNominationFactory)
+    voting_opens = LazyAwareDate("date_time_this_year")
+    voting_deadline = factory.LazyAttribute(
+        lambda self: self.voting_opens + datetime.timedelta(days=14)
+    )
+
+    @factory.post_generation
+    def eligible_to_vote(self, create, extracted, **kwargs):
+        if not create:
+            # TODO: Eventually should use a method in the object itself,
+            # right now this is part of the view and I don't want to couple them
+            return
+        if extracted:
+            self.eligible_to_vote.set(extracted)
+            self.save()
+
+
+class FellowshipNominationVoteFactory(factory.django.DjangoModelFactory):
+    class Meta:
+        model = FellowshipNominationVote
+        django_get_or_create = ("voting_round", "fellow")
+
+    voting_round = factory.SubFactory(FellowshipNominationVotingRoundFactory)
+    fellow = factory.SubFactory(FellowshipFactory)
+    vote = LazyRandEnum(FellowshipNominationVote.VOTE_CHOICES)
+    on = factory.LazyAttribute(
+        lambda self: fake.aware.date_between(
+            start_date=self.voting_round.voting_opens,
+            end_date=self.voting_round.voting_deadline,
+        )
+    )
+
+
+class FellowshipNominationDecisionFactory(factory.django.DjangoModelFactory):
+    class Meta:
+        model = FellowshipNominationDecision
+        django_get_or_create = ("voting_round",)
+
+    voting_round = factory.SubFactory(FellowshipNominationVotingRoundFactory)
+    outcome = LazyRandEnum(FellowshipNominationDecision.OUTCOME_CHOICES)
+    comments = factory.Faker("text")
+    fixed_on = factory.LazyAttribute(
+        lambda self: fake.aware.date_between(
+            start_date=self.voting_round.voting_deadline,
+            end_date="+1y",
+        )
+    )
+
+
+class FellowshipInvitationFactory(factory.django.DjangoModelFactory):
+    class Meta:
+        model = FellowshipInvitation
+
+    nomination = factory.SubFactory(FellowshipNominationFactory)
+    invited_on = LazyAwareDate("date_time_this_year")
+    response = LazyRandEnum(FellowshipInvitation.RESPONSE_CHOICES)
+    comments = factory.Faker("text")
diff --git a/scipost_django/colleges/tests/test_factories.py b/scipost_django/colleges/tests/test_factories.py
new file mode 100644
index 000000000..9fd11cada
--- /dev/null
+++ b/scipost_django/colleges/tests/test_factories.py
@@ -0,0 +1,134 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+from django.test import TestCase
+
+from ..factories import (
+    CollegeFactory,
+    FellowshipFactory,
+    FellowshipInvitationFactory,
+    FellowshipNominationCommentFactory,
+    FellowshipNominationDecisionFactory,
+    FellowshipNominationEventFactory,
+    FellowshipNominationFactory,
+    FellowshipNominationVoteFactory,
+    FellowshipNominationVotingRoundFactory,
+    GuestFellowshipFactory,
+    RegisteredFellowshipNominationFactory,
+    SeniorFellowshipFactory,
+    SuccessfulFellowshipNominationFactory,
+)
+
+
+class TestCollegeFactory(TestCase):
+    def test_can_create_colleges(self):
+        college = CollegeFactory()
+
+        self.assertIsNotNone(college)
+
+
+class TestFellowshipFactory(TestCase):
+    def test_can_create_fellowships(self):
+        fellowship = FellowshipFactory()
+
+        self.assertIsNotNone(fellowship)
+        self.assertEqual(fellowship.status, "regular")
+
+
+class TestGuestFellowshipFactory(TestCase):
+    def test_can_create_guest_fellowships(self):
+        guest_fellowship = GuestFellowshipFactory()
+
+        self.assertIsNotNone(guest_fellowship)
+        self.assertEqual(guest_fellowship.status, "guest")
+
+
+class TestSeniorFellowshipFactory(TestCase):
+    def test_can_create_senior_fellowships(self):
+        senior_fellowship = SeniorFellowshipFactory()
+
+        self.assertIsNotNone(senior_fellowship)
+        self.assertEqual(senior_fellowship.status, "senior")
+
+
+class TestFellowshipNominationFactory(TestCase):
+    def test_can_create_fellowship_nominations(self):
+        fellowship_nomination = FellowshipNominationFactory()
+
+        self.assertIsNotNone(fellowship_nomination)
+
+
+class TestRegisteredFellowshipNominationFactory(TestCase):
+    def test_can_create_registered_fellowship_nominations(self):
+        registered_fellowship_nomination = RegisteredFellowshipNominationFactory()
+
+        self.assertIsNotNone(registered_fellowship_nomination)
+        self.assertIsNotNone(registered_fellowship_nomination.profile.contributor)
+
+
+class TestSuccessfulFellowshipNominationFactory(TestCase):
+    def test_can_create_successful_fellowship_nominations(self):
+        successful_fellowship_nomination = SuccessfulFellowshipNominationFactory()
+
+        self.assertIsNotNone(successful_fellowship_nomination)
+        self.assertEqual(
+            successful_fellowship_nomination.fellowship.contributor,
+            successful_fellowship_nomination.profile.contributor,
+        )
+        self.assertEqual(
+            successful_fellowship_nomination.fellowship.college,
+            successful_fellowship_nomination.college,
+        )
+
+
+class TestFellowshipNominationEventFactory(TestCase):
+    def test_can_create_fellowship_nomination_events(self):
+        fellowship_nomination_event = FellowshipNominationEventFactory()
+
+        self.assertIsNotNone(fellowship_nomination_event)
+
+
+class TestFellowshipNominationCommentFactory(TestCase):
+    def test_can_create_fellowship_nomination_comments(self):
+        fellowship_nomination_comment = FellowshipNominationCommentFactory()
+
+        self.assertIsNotNone(fellowship_nomination_comment)
+
+
+class TestFellowshipNominationVotingRoundFactory(TestCase):
+    def test_can_create_fellowship_nomination_voting_rounds(self):
+        fellowship_nomination_voting_round = FellowshipNominationVotingRoundFactory()
+
+        self.assertIsNotNone(fellowship_nomination_voting_round)
+
+
+class TestFellowshipNominationVoteFactory(TestCase):
+    def test_can_create_fellowship_nomination_votes(self):
+        fellowship_nomination_vote = FellowshipNominationVoteFactory()
+
+        self.assertIsNotNone(fellowship_nomination_vote)
+
+    def test_nomination_vote_date_is_between_voting_round_open_period(self):
+        fellowship_nomination_vote = FellowshipNominationVoteFactory()
+
+        self.assertGreaterEqual(
+            fellowship_nomination_vote.on,
+            fellowship_nomination_vote.voting_round.voting_opens,
+        )
+        self.assertLessEqual(
+            fellowship_nomination_vote.on,
+            fellowship_nomination_vote.voting_round.voting_deadline,
+        )
+
+
+class TestFellowshipNominationDecisionFactory(TestCase):
+    def test_can_create_fellowship_nomination_decisions(self):
+        fellowship_nomination_decision = FellowshipNominationDecisionFactory()
+
+        self.assertIsNotNone(fellowship_nomination_decision)
+
+
+class TestFellowshipInvitationFactory(TestCase):
+    def test_can_create_fellowship_invitations(self):
+        fellowship_invitation = FellowshipInvitationFactory()
+        self.assertIsNotNone(fellowship_invitation)
-- 
GitLab