From 8125b9701144dd4b3bb73a2726940ca1639357f6 Mon Sep 17 00:00:00 2001 From: George Katsikas <giorgakis.katsikas@gmail.com> Date: Tue, 21 Nov 2023 14:09:10 +0100 Subject: [PATCH] add factories for all submissions models --- .../submissions/factories/__init__.py | 40 ++---- .../submissions/factories/assignment.py | 38 +++-- .../submissions/factories/communication.py | 20 +++ .../submissions/factories/decision.py | 32 +++++ .../factories/iThenticate_report.py | 29 ++++ .../factories/plagiarism_assessment.py | 43 ++++++ .../submissions/factories/preprint_server.py | 32 +++++ .../submissions/factories/preprintserver.py | 21 --- .../submissions/factories/qualification.py | 19 +++ .../submissions/factories/readiness.py | 23 +++ .../submissions/factories/recommendation.py | 45 ++++-- .../factories/referee_invitation.py | 73 ++++------ .../submissions/factories/report.py | 54 ++++--- .../submissions/factories/submission.py | 135 +++++++++++------- .../submissions/models/factories.py | 21 --- .../submissions/tests/models/__init__.py | 2 - .../submissions/tests/test_factories.py | 116 +++++++++++++++ scipost_django/submissions/urls/__init__.py | 18 ++- 18 files changed, 540 insertions(+), 221 deletions(-) create mode 100644 scipost_django/submissions/factories/communication.py create mode 100644 scipost_django/submissions/factories/decision.py create mode 100644 scipost_django/submissions/factories/iThenticate_report.py create mode 100644 scipost_django/submissions/factories/plagiarism_assessment.py create mode 100644 scipost_django/submissions/factories/preprint_server.py delete mode 100644 scipost_django/submissions/factories/preprintserver.py create mode 100644 scipost_django/submissions/factories/qualification.py create mode 100644 scipost_django/submissions/factories/readiness.py delete mode 100644 scipost_django/submissions/models/factories.py delete mode 100644 scipost_django/submissions/tests/models/__init__.py create mode 100644 scipost_django/submissions/tests/test_factories.py diff --git a/scipost_django/submissions/factories/__init__.py b/scipost_django/submissions/factories/__init__.py index f236ef4ba..1b33e7de9 100644 --- a/scipost_django/submissions/factories/__init__.py +++ b/scipost_django/submissions/factories/__init__.py @@ -2,31 +2,15 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" __license__ = "AGPL v3" -from .submission import ( - SubmissionFactory, - SeekingAssignmentSubmissionFactory, - InRefereeingSubmissionFactory, - ResubmittedSubmissionFactory, - ResubmissionFactory, - PublishedSubmissionFactory, -) - -from .assignment import EditorialAssignmentFactory - -from .referee_invitation import ( - RefereeInvitationFactory, - AcceptedRefereeInvitationFactory, - FulfilledRefereeInvitationFactory, - CancelledRefereeInvitationFactory, -) - -from .report import ( - ReportFactory, - DraftReportFactory, - UnVettedReportFactory, - VettedReportFactory, -) - -from .recommendation import EICRecommendationFactory - -from .preprintserver import PreprintServerFactory +from .assignment import * +from .communication import * +from .decision import * +from .iThenticate_report import * +from .plagiarism_assessment import * +from .preprint_server import * +from .qualification import * +from .readiness import * +from .recommendation import * +from .referee_invitation import * +from .report import * +from .submission import * diff --git a/scipost_django/submissions/factories/assignment.py b/scipost_django/submissions/factories/assignment.py index 96a5ce88a..019cde55a 100644 --- a/scipost_django/submissions/factories/assignment.py +++ b/scipost_django/submissions/factories/assignment.py @@ -4,22 +4,32 @@ __license__ = "AGPL v3" import factory -from scipost.models import Contributor -from submissions.models.submission import Submission -from submissions.models import EditorialAssignment +from common.faker import LazyRandEnum, fake +from ..models import EditorialAssignment -class EditorialAssignmentFactory(factory.django.DjangoModelFactory): - """ - An EditorialAssignmentFactory should always have a `submission` explicitly assigned. This will - mostly be done using the post_generation hook in any SubmissionFactory. - """ - - submission = None - to = factory.Iterator(Contributor.objects.all()) - status = factory.Iterator(Submission.SUBMISSION_STATUSES, getter=lambda c: c[0]) - date_created = factory.lazy_attribute(lambda o: o.submission.latest_activity) - date_answered = factory.lazy_attribute(lambda o: o.submission.latest_activity) +class EditorialAssignmentFactory(factory.django.DjangoModelFactory): class Meta: model = EditorialAssignment + django_get_or_create = ("submission", "to") + + submission = factory.SubFactory("submissions.factories.SubmissionFactory") + to = factory.SubFactory("scipost.factories.ContributorFactory") + status = LazyRandEnum(EditorialAssignment.ASSIGNMENT_STATUSES) + + date_created = factory.LazyAttribute( + lambda self: fake.aware.date_between( + start_date=self.submission.submission_date, end_date="+60d" + ) + ) + date_invited = factory.LazyAttribute( + lambda self: fake.aware.date_between( + start_date=self.date_created, end_date="+10d" + ) + ) + date_answered = factory.LazyAttribute( + lambda self: fake.aware.date_between( + start_date=self.date_invited, end_date="+10d" + ) + ) diff --git a/scipost_django/submissions/factories/communication.py b/scipost_django/submissions/factories/communication.py new file mode 100644 index 000000000..226d983d1 --- /dev/null +++ b/scipost_django/submissions/factories/communication.py @@ -0,0 +1,20 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + +import factory + +from common.faker import LazyAwareDate, LazyRandEnum +from submissions.constants import ED_COMM_CHOICES + +from ..models import EditorialCommunication + + +class EditorialCommunicationFactory(factory.django.DjangoModelFactory): + class Meta: + model = EditorialCommunication + + submission = factory.SubFactory("submissions.factories.SubmissionFactory") + referee = factory.SubFactory("scipost.factories.ContributorFactory") + comtype = LazyRandEnum(ED_COMM_CHOICES) + timestamp = LazyAwareDate("date_time_this_year") + text = factory.Faker("paragraph") diff --git a/scipost_django/submissions/factories/decision.py b/scipost_django/submissions/factories/decision.py new file mode 100644 index 000000000..aa645e4d0 --- /dev/null +++ b/scipost_django/submissions/factories/decision.py @@ -0,0 +1,32 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + +import factory + +from common.faker import LazyRandEnum, fake +from submissions.constants import EDITORIAL_DECISION_CHOICES +from ..models import EditorialDecision + + +class EditorialDecisionFactory(factory.django.DjangoModelFactory): + class Meta: + model = EditorialDecision + django_get_or_create = ("submission", "version") + + submission = factory.SubFactory("submissions.factories.SubmissionFactory") + for_journal = factory.SubFactory("journals.factories.JournalFactory") + taken_on = factory.LazyAttribute( + lambda self: fake.aware.date_time_between( + start_date=self.submission.submission_date, end_date="+2M" + ) + ) + + remarks_for_authors = factory.Faker("paragraph") + remarks_for_editorial_college = factory.Faker("paragraph") + + decision = LazyRandEnum(EDITORIAL_DECISION_CHOICES) + status = EditorialDecision.FIXED_AND_ACCEPTED + + version = factory.LazyAttribute( + lambda self: self.submission.editorialdecision_set.count() + 1 + ) diff --git a/scipost_django/submissions/factories/iThenticate_report.py b/scipost_django/submissions/factories/iThenticate_report.py new file mode 100644 index 000000000..8ebf5b34f --- /dev/null +++ b/scipost_django/submissions/factories/iThenticate_report.py @@ -0,0 +1,29 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + +import factory +import factory.fuzzy + +from submissions.constants import PLAGIARISM_STATUSES + +from ..models import iThenticateReport + +from common.faker import fake, LazyObjectCount, LazyRandEnum + + +class iThenticateReportFactory(factory.django.DjangoModelFactory): + class Meta: + model = iThenticateReport + + uploaded_time = fake.aware.date_time_this_year() + processed_time = factory.LazyAttribute( + lambda self: fake.aware.date_time_between( + start_date=self.uploaded_time, end_date="+10m" + ) + ) + + doc_id = LazyObjectCount(iThenticateReport, offset=1) + part_id = LazyObjectCount(iThenticateReport, offset=1) + + percent_match = factory.fuzzy.FuzzyInteger(0, 100) + status = LazyRandEnum(PLAGIARISM_STATUSES) diff --git a/scipost_django/submissions/factories/plagiarism_assessment.py b/scipost_django/submissions/factories/plagiarism_assessment.py new file mode 100644 index 000000000..c5ee03f30 --- /dev/null +++ b/scipost_django/submissions/factories/plagiarism_assessment.py @@ -0,0 +1,43 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + +import factory + +from common.faker import LazyRandEnum, fake + +from ..models.plagiarism_assessment import ( + PlagiarismAssessment, + InternalPlagiarismAssessment, + iThenticatePlagiarismAssessment, +) + + +class PlagiarismAssessmentFactory(factory.django.DjangoModelFactory): + class Meta: + model = PlagiarismAssessment + abstract = True + django_get_or_create = ("submission",) + + status = LazyRandEnum(PlagiarismAssessment.STATUS_CHOICES) + date_set = factory.LazyAttribute( + lambda self: fake.aware.date_time_between( + start_date=self.submission.submission_date, end_date="+5d" + ) + ) + + comments_for_edadmin = factory.Faker("paragraph") + comments_for_authors = factory.Faker("paragraph") + + +class InternalPlagiarismAssessmentFactory(PlagiarismAssessmentFactory): + class Meta: + model = InternalPlagiarismAssessment + + submission = factory.SubFactory("submissions.factories.SubmissionFactory") + + +class iThenticatePlagiarismAssessmentFactory(PlagiarismAssessmentFactory): + class Meta: + model = iThenticatePlagiarismAssessment + + submission = factory.SubFactory("submissions.factories.SubmissionFactory") diff --git a/scipost_django/submissions/factories/preprint_server.py b/scipost_django/submissions/factories/preprint_server.py new file mode 100644 index 000000000..235ce6eef --- /dev/null +++ b/scipost_django/submissions/factories/preprint_server.py @@ -0,0 +1,32 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + + +import factory + +from ..models.preprint_server import PreprintServer + + +class PreprintServerFactory(factory.django.DjangoModelFactory): + class Meta: + model = PreprintServer + + name = factory.Faker("sentence") + url = factory.Faker("url") + served_by = None + + @factory.post_generation + def acad_fields(self, create, extracted, **kwargs): + if create: + return + if extracted: + for acad_field in extracted: + self.acad_fields.add(acad_field) + else: + self.acad_fields.add( + factory.SubFactory("ontology.factories.AcademicFieldFactory") + ) + + @classmethod + def arxiv(cls): + return cls(name="arXiv", url="https://arxiv.org/") diff --git a/scipost_django/submissions/factories/preprintserver.py b/scipost_django/submissions/factories/preprintserver.py deleted file mode 100644 index 654dcc580..000000000 --- a/scipost_django/submissions/factories/preprintserver.py +++ /dev/null @@ -1,21 +0,0 @@ -__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" -__license__ = "AGPL v3" - - -import factory - -from faker import Faker - -from submissions.models.preprint_server import PreprintServer - - -class PreprintServerFactory(factory.django.DjangoModelFactory): - name = factory.Faker("sentence") - url = factory.Faker("url") - - class Meta: - model = PreprintServer - - @classmethod - def arxiv(cls): - return cls(name="arXiv", url="https://arxiv.org/") diff --git a/scipost_django/submissions/factories/qualification.py b/scipost_django/submissions/factories/qualification.py new file mode 100644 index 000000000..546adcdc0 --- /dev/null +++ b/scipost_django/submissions/factories/qualification.py @@ -0,0 +1,19 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + +import factory + +from common.faker import LazyRandEnum + +from ..models import Qualification + + +class QualificationFactory(factory.django.DjangoModelFactory): + class Meta: + model = Qualification + django_get_or_create = ("submission", "fellow") + + submission = factory.SubFactory("submissions.factories.SubmissionFactory") + fellow = factory.SubFactory("colleges.factories.FellowshipFactory") + expertise_level = LazyRandEnum(Qualification.EXPERTISE_LEVEL_CHOICES) + comments = factory.Faker("paragraph") diff --git a/scipost_django/submissions/factories/readiness.py b/scipost_django/submissions/factories/readiness.py new file mode 100644 index 000000000..8b5131a4d --- /dev/null +++ b/scipost_django/submissions/factories/readiness.py @@ -0,0 +1,23 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + +import factory +from ..models import Readiness + +from common.faker import LazyRandEnum, fake + + +class ReadinessFactory(factory.django.DjangoModelFactory): + class Meta: + model = Readiness + django_get_or_create = ("submission", "fellow") + + submission = factory.SubFactory("submissions.factories.SubmissionFactory") + fellow = factory.SubFactory("colleges.factories.FellowshipFactory") + status = LazyRandEnum(Readiness.STATUS_CHOICES) + comments = factory.Faker("paragraph") + datetime = factory.LazyAttribute( + lambda self: fake.aware.date_time_between( + start_date=self.submission.submission_date, end_date="+2M" + ) + ) diff --git a/scipost_django/submissions/factories/recommendation.py b/scipost_django/submissions/factories/recommendation.py index a789b3169..a37b15340 100644 --- a/scipost_django/submissions/factories/recommendation.py +++ b/scipost_django/submissions/factories/recommendation.py @@ -3,27 +3,46 @@ __license__ = "AGPL v3" import factory -import pytz +import factory.fuzzy -from faker import Faker +from submissions.constants import EIC_REC_CHOICES, EIC_REC_STATUSES +from submissions.models import EICRecommendation -from submissions.constants import REPORT_REC -from submissions.models import Submission, EICRecommendation +from common.faker import fake, LazyRandEnum class EICRecommendationFactory(factory.django.DjangoModelFactory): - submission = factory.Iterator(Submission.objects.all()) - date_submitted = factory.lazy_attribute( - lambda o: Faker().date_time_between( - start_date=o.submission.submission_date, end_date="now", tzinfo=pytz.UTC + class Meta: + model = EICRecommendation + django_get_or_create = ("submission", "version") + + submission = factory.SubFactory("submissions.factories.SubmissionFactory") + formulated_by = factory.SelfAttribute("submission.editor_in_charge") + date_submitted = factory.LazyAttribute( + lambda self: fake.aware.date_time_between( + start_date=self.submission.submission_date, end_date="+1y" ) ) - remarks_for_authors = factory.Faker("paragraph") + requested_changes = factory.Faker("paragraph") + remarks_for_authors = factory.Faker("paragraph") remarks_for_editorial_college = factory.Faker("paragraph") - recommendation = factory.Iterator(REPORT_REC[1:], getter=lambda c: c[0]) - version = 1 + + for_journal = factory.SubFactory("journals.factories.JournalFactory") + + recommendation = LazyRandEnum(EIC_REC_CHOICES) + status = LazyRandEnum(EIC_REC_STATUSES) + + version = factory.LazyAttribute( + lambda self: 1 + + EICRecommendation.objects.filter(submission=self.submission).count() + ) active = True - class Meta: - model = EICRecommendation + voting_deadline = factory.LazyAttribute( + lambda self: fake.aware.date_time_between( + start_date=self.date_submitted, end_date="+30d" + ) + ) + + # TODO: Add fields for the voting process diff --git a/scipost_django/submissions/factories/referee_invitation.py b/scipost_django/submissions/factories/referee_invitation.py index 32ec5442f..3d19a7b88 100644 --- a/scipost_django/submissions/factories/referee_invitation.py +++ b/scipost_django/submissions/factories/referee_invitation.py @@ -3,44 +3,50 @@ __license__ = "AGPL v3" import factory -import pytz -import random -from faker import Faker +from common.faker import fake -from scipost.models import Contributor - -from submissions.models import RefereeInvitation +from ..models import RefereeInvitation class RefereeInvitationFactory(factory.django.DjangoModelFactory): + class Meta: + model = RefereeInvitation + exclude = ("profile_info",) + django_get_or_create = ("submission", "profile") + + class Params: + registered = factory.Trait( + referee=factory.SubFactory("scipost.factories.ContributorFactory"), + profile=None, + profile_info=factory.SelfAttribute("referee.profile"), + ) + + referee = None + profile = factory.SubFactory("profiles.factories.ProfileFactory") + + profile_info = factory.SelfAttribute("profile") + title = factory.SelfAttribute("profile_info.title") + first_name = factory.SelfAttribute("profile_info.first_name") + last_name = factory.SelfAttribute("profile_info.last_name") + email_address = factory.SelfAttribute("profile_info.email") + submission = factory.SubFactory("submissions.factories.SubmissionFactory") - referee = factory.lazy_attribute( - lambda o: Contributor.objects.exclude(id__in=o.submission.authors.all()) - .order_by("?") - .first() - ) - title = factory.lazy_attribute(lambda o: o.referee.profile.title) - first_name = factory.lazy_attribute(lambda o: o.referee.user.first_name) - last_name = factory.lazy_attribute(lambda o: o.referee.user.last_name) - email_address = factory.lazy_attribute(lambda o: o.referee.user.email) - date_invited = factory.lazy_attribute(lambda o: o.submission.latest_activity) - nr_reminders = factory.lazy_attribute(lambda o: random.randint(0, 4)) - date_last_reminded = factory.lazy_attribute(lambda o: o.submission.latest_activity) + date_invited = factory.SelfAttribute("submission.latest_activity") + date_last_reminded = factory.SelfAttribute("submission.latest_activity") + invited_by = factory.SelfAttribute("submission.editor_in_charge") + nr_reminders = factory.Faker("random_int", min=0, max=3) invitation_key = factory.Faker("md5") - invited_by = factory.lazy_attribute(lambda o: o.submission.editor_in_charge) - - class Meta: - model = RefereeInvitation class AcceptedRefereeInvitationFactory(RefereeInvitationFactory): + registered = True accepted = True - date_responded = factory.lazy_attribute( - lambda o: Faker().date_time_between( - start_date=o.date_invited, end_date="now", tzinfo=pytz.UTC + date_responded = factory.LazyAttribute( + lambda self: fake.aware.date_time_between( + start_date=self.date_invited, end_date="+1y" ) ) @@ -54,25 +60,8 @@ class AcceptedRefereeInvitationFactory(RefereeInvitationFactory): class FulfilledRefereeInvitationFactory(AcceptedRefereeInvitationFactory): fulfilled = True - date_responded = factory.lazy_attribute( - lambda o: Faker().date_time_between( - start_date=o.date_invited, end_date="now", tzinfo=pytz.UTC - ) - ) - - @factory.post_generation - def report(self, create, extracted, **kwargs): - if create: - from submissions.factories import VettedReportFactory - - VettedReportFactory(submission=self.submission, author=self.referee) class CancelledRefereeInvitationFactory(AcceptedRefereeInvitationFactory): fulfilled = False cancelled = True - date_responded = factory.lazy_attribute( - lambda o: Faker().date_time_between( - start_date=o.date_invited, end_date="now", tzinfo=pytz.UTC - ) - ) diff --git a/scipost_django/submissions/factories/report.py b/scipost_django/submissions/factories/report.py index 03013e71b..7c04bffbd 100644 --- a/scipost_django/submissions/factories/report.py +++ b/scipost_django/submissions/factories/report.py @@ -3,11 +3,10 @@ __license__ = "AGPL v3" import factory -import pytz -from faker import Faker +from common.faker import LazyRandEnum, fake +from scipost.factories import ContributorFactory -from scipost.models import Contributor from common.helpers import random_scipost_report_doi_label from submissions.constants import ( @@ -24,41 +23,37 @@ from submissions.models import Report class ReportFactory(factory.django.DjangoModelFactory): - status = factory.Iterator(REPORT_STATUSES, getter=lambda c: c[0]) + class Meta: + model = Report + + status = LazyRandEnum(REPORT_STATUSES) submission = factory.SubFactory("submissions.factories.SubmissionFactory") - report_nr = factory.LazyAttribute(lambda o: o.submission.reports.count() + 1) - date_submitted = factory.Faker("date_time_this_decade", tzinfo=pytz.utc) - vetted_by = factory.Iterator(Contributor.objects.all()) - author = factory.Iterator(Contributor.objects.all()) + report_nr = factory.LazyAttribute(lambda self: self.submission.reports.count() + 1) + date_submitted = factory.LazyAttribute( + lambda self: fake.aware.date_between( + start_date=self.submission.submission_date, end_date="+1y" + ) + ) + vetted_by = factory.SubFactory(ContributorFactory) + author = factory.SubFactory(ContributorFactory) strengths = factory.Faker("paragraph") weaknesses = factory.Faker("paragraph") report = factory.Faker("paragraph") requested_changes = factory.Faker("paragraph") - qualification = factory.Iterator(REFEREE_QUALIFICATION[1:], getter=lambda c: c[0]) - validity = factory.Iterator(RANKING_CHOICES[1:], getter=lambda c: c[0]) - significance = factory.Iterator(RANKING_CHOICES[1:], getter=lambda c: c[0]) - originality = factory.Iterator(RANKING_CHOICES[1:], getter=lambda c: c[0]) - clarity = factory.Iterator(RANKING_CHOICES[1:], getter=lambda c: c[0]) - formatting = factory.Iterator(QUALITY_SPEC[1:], getter=lambda c: c[0]) - grammar = factory.Iterator(QUALITY_SPEC[1:], getter=lambda c: c[0]) - recommendation = factory.Iterator(REPORT_REC[1:], getter=lambda c: c[0]) + qualification = LazyRandEnum(REFEREE_QUALIFICATION) + validity = LazyRandEnum(RANKING_CHOICES) + significance = LazyRandEnum(RANKING_CHOICES) + originality = LazyRandEnum(RANKING_CHOICES) + clarity = LazyRandEnum(RANKING_CHOICES) + formatting = LazyRandEnum(QUALITY_SPEC) + grammar = LazyRandEnum(QUALITY_SPEC) + recommendation = LazyRandEnum(REPORT_REC) remarks_for_editors = factory.Faker("paragraph") flagged = factory.Faker("boolean", chance_of_getting_true=10) anonymous = factory.Faker("boolean", chance_of_getting_true=75) - class Meta: - model = Report - - @classmethod - def create(cls, **kwargs): - if Contributor.objects.count() < 5: - from scipost.factories import ContributorFactory - - ContributorFactory.create_batch(5) - return super().create(**kwargs) - class DraftReportFactory(ReportFactory): status = STATUS_DRAFT @@ -73,6 +68,5 @@ class UnVettedReportFactory(ReportFactory): class VettedReportFactory(ReportFactory): status = STATUS_VETTED needs_doi = True - doideposit_needs_updating = factory.Faker("boolean") - doi_label = factory.lazy_attribute(lambda n: random_scipost_report_doi_label()) - pdf_report = factory.Faker("file_name", extension="pdf") + doi_label = factory.LazyAttribute(lambda _: random_scipost_report_doi_label) + pdf_report = factory.django.FileField(filename="report.pdf") diff --git a/scipost_django/submissions/factories/submission.py b/scipost_django/submissions/factories/submission.py index 7cdcfd44f..7807bb865 100644 --- a/scipost_django/submissions/factories/submission.py +++ b/scipost_django/submissions/factories/submission.py @@ -7,9 +7,11 @@ import pytz import random from faker import Faker +from colleges.factories import FellowshipFactory from common.faker import LazyRandEnum, fake from journals.factories import JournalFactory from ontology.factories import AcademicFieldFactory +from organizations.factories import OrganizationFactory from preprints.factories import PreprintFactory from scipost.constants import SCIPOST_APPROACHES @@ -19,7 +21,7 @@ from comments.factories import SubmissionCommentFactory from journals.models import Journal from ontology.models import Specialty, AcademicField -from ..models import Submission, EditorialAssignment +from ..models.submission import * class SubmissionFactory(factory.django.DjangoModelFactory): @@ -27,24 +29,30 @@ class SubmissionFactory(factory.django.DjangoModelFactory): Generate random basic Submission instances. """ - author_list = factory.Faker("name") submitted_by = factory.SubFactory(ContributorFactory) + author_list = factory.LazyAttribute( + lambda self: self.submitted_by.profile.full_name + ) submitted_to = factory.SubFactory(JournalFactory) + title = factory.Faker("sentence") abstract = factory.Faker("paragraph", nb_sentences=10) - list_of_changes = factory.Faker("paragraph", nb_sentences=10) + acad_field = factory.SubFactory(AcademicFieldFactory) - approaches = [LazyRandEnum(SCIPOST_APPROACHES)] - abstract = factory.Faker("paragraph") + approaches = LazyRandEnum(SCIPOST_APPROACHES, repeat=2) + + list_of_changes = factory.Faker("paragraph", nb_sentences=10) author_comments = factory.Faker("paragraph") remarks_for_editors = factory.Faker("paragraph") - thread_hash = factory.Faker("uuid4") + submission_date = factory.Faker("date_time_this_decade", tzinfo=pytz.utc) latest_activity = factory.LazyAttribute( lambda self: fake.date_time_between( start_date=self.submission_date, end_date="now", tzinfo=pytz.UTC ) ) + + thread_hash = factory.Faker("md5") preprint = factory.SubFactory(PreprintFactory) visible_public = True @@ -53,49 +61,26 @@ class SubmissionFactory(factory.django.DjangoModelFactory): class Meta: model = Submission - # @classmethod - # def create(cls, **kwargs): - # if Contributor.objects.count() < 5: - # from scipost.factories import ContributorFactory - - # ContributorFactory.create_batch(5) - # if Journal.objects.count() < 3: - # from journals.factories import JournalFactory - - # JournalFactory.create_batch(3) - # if AcademicField.objects.count() < 10: - # from ontology.factories import AcademicFieldFactory - - # AcademicFieldFactory.create_batch(10) - # if Specialty.objects.count() < 5: - # from ontology.factories import SpecialtyFactory - - # SpecialtyFactory.create_batch(5) - # return super().create(**kwargs) - - # @factory.post_generation - # def add_specialties(self, create, extracted, **kwargs): - # if create: - # self.specialties.set(Specialty.objects.order_by("?")[:3]) - - # @factory.post_generation - # def contributors(self, create, extracted, **kwargs): - # contribs = Contributor.objects.all() - # if self.editor_in_charge: - # contribs = contribs.exclude(id=self.editor_in_charge.id) - # contribs = contribs.order_by("?")[: random.randint(1, 6)] - - # # Auto-add the submitter as an author - # self.submitted_by = contribs[0] - # self.author_list = ", ".join( - # ["%s %s" % (c.user.first_name, c.user.last_name) for c in contribs] - # ) + @factory.post_generation + def add_specialties(self, create, extracted, **kwargs): + if create: + if extracted: + self.specialties.add(*extracted) + else: + self.specialties.set(Specialty.objects.order_by("?")[:3]) - # if not create: - # return + @factory.post_generation + def authors(self, create, extracted, **kwargs): + if create: + if extracted: + # Add submitted_by to the list of authors + if self.submitted_by not in extracted: + extracted.append(self.submitted_by) - # # Add three random authors - # self.authors.add(*contribs) + self.authors.add(*extracted) + self.author_list = ", ".join( + [f"{c.profile.first_name} {c.profile.last_name}" for c in extracted] + ) class SeekingAssignmentSubmissionFactory(SubmissionFactory): @@ -292,15 +277,25 @@ class PublishedSubmissionFactory(InRefereeingSubmissionFactory): @factory.post_generation def generate_publication(self, create, extracted, **kwargs): if create and extracted is not False: - from journals.factories import PublicationFactory + from journals.factories import JournalPublicationFactory - PublicationFactory( + JournalPublicationFactory( journal=self.submitted_to.doi_label, accepted_submission=self, title=self.title, author_list=self.author_list, ) + @factory.post_generation + def editor_in_charge(self, create, extracted, **kwargs): + if create: + return + if extracted: + return extracted + + eic = FellowshipFactory() + return eic.contributor + @factory.post_generation def eic_assignment(self, create, extracted, **kwargs): if create: @@ -323,3 +318,45 @@ class PublishedSubmissionFactory(InRefereeingSubmissionFactory): FulfilledRefereeInvitationFactory(submission=self) for i in range(random.randint(0, 2)): CancelledRefereeInvitationFactory(submission=self) + + +class SubmissionAuthorProfileFactory(factory.django.DjangoModelFactory): + class Meta: + model = SubmissionAuthorProfile + + submission = factory.SubFactory(SubmissionFactory) + profile = factory.SubFactory("profiles.factories.ProfileFactory") + order = factory.LazyAttribute( + lambda self: self.submission.author_profiles.count() + 1 + ) + + @factory.post_generation + def affiliations(self, create, extracted, **kwargs): + if create: + return + if extracted: + for affiliation in extracted: + self.affiliations.add(affiliation) + else: + self.affiliations.add( + *OrganizationFactory.create_batch(random.randint(1, 3)) + ) + + +class SubmissionEventFactory(factory.django.DjangoModelFactory): + class Meta: + model = SubmissionEvent + + submission = factory.SubFactory(SubmissionFactory) + event = LazyRandEnum(EVENT_TYPES) + text = factory.Faker("paragraph") + + +class SubmissionTieringFactory(factory.django.DjangoModelFactory): + class Meta: + model = SubmissionTiering + + submission = factory.SubFactory(SubmissionFactory) + fellow = factory.SubFactory(ContributorFactory) + for_journal = factory.SelfAttribute("submission.submitted_to") + tier = LazyRandEnum(SUBMISSION_TIERS) diff --git a/scipost_django/submissions/models/factories.py b/scipost_django/submissions/models/factories.py deleted file mode 100644 index 070465198..000000000 --- a/scipost_django/submissions/models/factories.py +++ /dev/null @@ -1,21 +0,0 @@ -__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" -__license__ = "AGPL v3" - -import factory -from common.faker import LazyRandEnum -from journals.factories import JournalFactory -from submissions.factories.submission import SubmissionFactory -from submissions.models.decision import EditorialDecision - - -class EditorialDecisionFactory(factory.django.DjangoModelFactory): - class Meta: - model = EditorialDecision - django_get_or_create = ("submission", "for_journal") - - submission = factory.SubFactory(SubmissionFactory) - for_journal = factory.SubFactory(JournalFactory) - decision = LazyRandEnum(EditorialDecision.EDITORIAL_DECISION_STATUSES) - taken_on = factory.Faker("date_this_decade") - remarks_for_authors = factory.Faker("paragraph") - status = LazyRandEnum(EditorialDecision.EDITORIAL_DECISION_STATUSES) diff --git a/scipost_django/submissions/tests/models/__init__.py b/scipost_django/submissions/tests/models/__init__.py deleted file mode 100644 index 5dfd5d6b6..000000000 --- a/scipost_django/submissions/tests/models/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" -__license__ = "AGPL v3" diff --git a/scipost_django/submissions/tests/test_factories.py b/scipost_django/submissions/tests/test_factories.py new file mode 100644 index 000000000..41f3deb4c --- /dev/null +++ b/scipost_django/submissions/tests/test_factories.py @@ -0,0 +1,116 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + +from django.test import TestCase + + +from ..factories import * + + +# Assignment +class TestEditorialAssignmentFactory(TestCase): + def test_can_create_editorial_assignments(self): + editorial_assignment = EditorialAssignmentFactory() + self.assertIsNotNone(editorial_assignment) + + +# Communication +class TestEditorialCommunication(TestCase): + def test_can_create_editorial_communications(self): + editorial_communication = EditorialCommunicationFactory() + self.assertIsNotNone(editorial_communication) + + +# Recommendation +class TestEICRecommendationFactory(TestCase): + def test_can_create_eic_recommendations(self): + eic_recommendation = EICRecommendationFactory() + self.assertIsNotNone(eic_recommendation) + + +# Submissions +class TestSubmissionFactory(TestCase): + def test_can_create_submissions(self): + submission = SubmissionFactory() + self.assertIsNotNone(submission) + + +class TestSubmissionAuthorProfileFactory(TestCase): + def test_can_create_submission_author_profiles(self): + submission_author_profile = SubmissionAuthorProfileFactory() + self.assertIsNotNone(submission_author_profile) + + +class TestSubmissionEventFactory(TestCase): + def test_can_create_submission_events(self): + submission_event = SubmissionEventFactory() + self.assertIsNotNone(submission_event) + + +class TestSubmissionTieringFactory(TestCase): + def test_can_create_submission_tierings(self): + submission_tiering = SubmissionTieringFactory() + self.assertIsNotNone(submission_tiering) + + +# Reports +class TestReportFactory(TestCase): + def test_can_create_reports(self): + report = ReportFactory() + self.assertIsNotNone(report) + + +# Referee Invitation +class TestRefereeInvitationFactory(TestCase): + def test_can_create_unregistered_referee_invitations(self): + referee_invitation = RefereeInvitationFactory() + self.assertIsNotNone(referee_invitation.profile) + self.assertIsNone(referee_invitation.referee) + self.assertIsNotNone(referee_invitation) + + def test_can_create_registered_referee_invitations(self): + referee_invitation = RefereeInvitationFactory(registered=True) + self.assertIsNotNone(referee_invitation.referee) + self.assertIsNone(referee_invitation.profile) + self.assertIsNotNone(referee_invitation) + + +# Readiness +class TestReadinessFactory(TestCase): + def test_can_create_readinesses(self): + readiness = ReadinessFactory() + self.assertIsNotNone(readiness) + + +# Qualification +class TestQualificationFactory(TestCase): + def test_can_create_qualifications(self): + qualification = QualificationFactory() + self.assertIsNotNone(qualification) + + +# Decision +class TestEditorialDecisionFactory(TestCase): + def test_can_create_editorial_decisions(self): + editorial_decision = EditorialDecisionFactory() + self.assertIsNotNone(editorial_decision) + + +# Plagiarism Assessment +class TestInternalPlagiarismAssessmentFactory(TestCase): + def test_can_create_internal_plagiarism_assessments(self): + internal_plagiarism_assessment = InternalPlagiarismAssessmentFactory() + self.assertIsNotNone(internal_plagiarism_assessment) + + +class TestiThenticatePlagiarismAssessmentFactory(TestCase): + def test_can_create_ithenticate_plagiarism_assessments(self): + ithenticate_plagiarism_assessment = iThenticatePlagiarismAssessmentFactory() + self.assertIsNotNone(ithenticate_plagiarism_assessment) + + +# iThenticate Report +class TestiThenticateReportFactory(TestCase): + def test_can_create_ithenticate_reports(self): + ithenticate_report = iThenticateReportFactory() + self.assertIsNotNone(ithenticate_report) diff --git a/scipost_django/submissions/urls/__init__.py b/scipost_django/submissions/urls/__init__.py index e05af836e..6b58ea0ff 100644 --- a/scipost_django/submissions/urls/__init__.py +++ b/scipost_django/submissions/urls/__init__.py @@ -2,14 +2,30 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" __license__ = "AGPL v3" -from django.urls import include, path, re_path +from django.urls import include, path, re_path, register_converter from django.views.generic import TemplateView from django.views.generic.base import RedirectView +from journals.converters import JournalDOILabelConverter + +from ontology.converters import AcademicFieldSlugConverter + +from ..converters import ( + IdentifierConverter, + IdentifierWithoutVersionNumberConverter, + ReportDOILabelConverter, +) from .. import views app_name = "submissions" +# converters +register_converter(JournalDOILabelConverter, "journal_doi_label") +register_converter(AcademicFieldSlugConverter, "acad_field") +register_converter(IdentifierWithoutVersionNumberConverter, "identifier_wo_vn_nr") +register_converter(IdentifierConverter, "identifier") +register_converter(ReportDOILabelConverter, "report_doi_label") + urlpatterns = [ # nested namespaces -- GitLab