Пример #1
0
    def test_store_events_with_classification(self):
        """Store events including classification."""
        user = User(12345, '*****@*****.**')
        ev = CreateSubmission(creator=user)
        ev2 = SetPrimaryClassification(creator=user,
                                            category='physics.soc-ph')
        ev3 = AddSecondaryClassification(creator=user,
                                              category='physics.acc-ph')
        submission = ev.apply()
        submission = ev2.apply(submission)
        submission = ev3.apply(submission)

        with in_memory_db() as session:
            submission = classic.store_events(ev, ev2, ev3,
                                              submission=submission)

            db_submission = session.query(classic.models.Submission)\
                .get(submission.submission_id)
            db_events = session.query(classic.DBEvent).all()

        self.assertEqual(db_submission.submission_id, submission.submission_id,
                         "The submission should be updated with the PK id.")
        self.assertEqual(len(db_events), 3, "Three events should be stored")
        for db_event in db_events:
            self.assertEqual(db_event.submission_id, submission.submission_id,
                             "The submission id should be set")
        self.assertEqual(len(db_submission.categories), 2,
                         "Two category relations should be set")
        self.assertEqual(db_submission.primary_classification.category,
                         submission.primary_classification.category,
                         "Primary classification should be set.")
Пример #2
0
    def test_get_submission_with_hold_and_reclass(self):
        """Test changes made externally are reflected in submission data."""
        user = User(12345, '*****@*****.**')
        events = [
            CreateSubmission(creator=user),
            UpdateMetadata(creator=user, metadata=[
                ('title', 'Foo title'),
                ('abstract', 'Indeed'),
                ('authors', [
                    Author(order=0, forename='Joe', surname='Bloggs',
                           email='*****@*****.**'),
                    Author(order=1, forename='Jane', surname='Doe',
                           email='*****@*****.**'),
                ])
            ]),
            SelectLicense(creator=user, license_uri='http://foo.org/1.0/',
                               license_name='Foo zero 1.0'),
            SetPrimaryClassification(creator=user, category='cs.DL'),
            AcceptPolicy(creator=user),
            VerifyContactInformation(creator=user),
            FinalizeSubmission(creator=user)
        ]
        submission = None
        for ev in events:
            submission = ev.apply(submission) if submission else ev.apply()

        with in_memory_db() as session:
            # User creates and finalizes submission.
            submission = classic.store_events(*events, submission=submission)
            ident = submission.submission_id

            # Moderation happens, things change outside the event model.
            db_submission = session.query(classic.models.Submission).get(ident)

            # Reclassification!
            session.delete(db_submission.primary_classification)
            session.add(classic.models.SubmissionCategory(
                submission_id=ident, category='cs.IR', is_primary=1
            ))

            # On hold!
            db_submission.status = db_submission.ON_HOLD
            session.add(db_submission)
            session.commit()

            # Now get the submission.
            submission_loaded, _ = classic.get_submission(ident)

        self.assertEqual(submission.metadata.title,
                         submission_loaded.metadata.title,
                         "Event-derived metadata should be preserved.")
        self.assertEqual(submission_loaded.primary_classification.category,
                         "cs.IR",
                         "Primary classification should reflect the"
                         " reclassification that occurred outside the purview"
                         " of the event model.")
        self.assertEqual(submission_loaded.status, Submission.ON_HOLD,
                         "Submission status should reflect hold action"
                         " performed outside the purview of the event model.")
Пример #3
0
    def test_get_submission_with_publish(self):
        """Test that publication state is reflected in submission data."""
        user = User(12345, '*****@*****.**')
        events = [
            CreateSubmission(creator=user),
            UpdateMetadata(creator=user, metadata=[
                ('title', 'Foo title'),
                ('abstract', 'Indeed'),
                ('authors', [
                    Author(order=0, forename='Joe', surname='Bloggs',
                           email='*****@*****.**'),
                    Author(order=1, forename='Jane', surname='Doe',
                           email='*****@*****.**'),
                ])
            ]),
            SelectLicense(creator=user, license_uri='http://foo.org/1.0/',
                               license_name='Foo zero 1.0'),
            SetPrimaryClassification(creator=user, category='cs.DL'),
            AcceptPolicy(creator=user),
            VerifyContactInformation(creator=user),
            FinalizeSubmission(creator=user)
        ]
        submission = None
        for ev in events:
            submission = ev.apply(submission) if submission else ev.apply()

        with in_memory_db() as session:
            # User creates and finalizes submission.
            submission = classic.store_events(*events, submission=submission)
            ident = submission.submission_id

            # Moderation happens, things change outside the event model.
            db_submission = session.query(classic.models.Submission).get(ident)

            # Published!
            db_submission.status = db_submission.PUBLISHED
            db_document = classic.models.Document(paper_id='1234.5678')
            db_submission.document = db_document
            session.add(db_submission)
            session.add(db_document)
            session.commit()

            # Now get the submission.
            submission_loaded, _ = classic.get_submission(ident)

        self.assertEqual(submission.metadata.title,
                         submission_loaded.metadata.title,
                         "Event-derived metadata should be preserved.")
        self.assertEqual(submission_loaded.arxiv_id, "1234.5678",
                         "arXiv paper ID should be set")
        self.assertEqual(submission_loaded.status, Submission.PUBLISHED,
                         "Submission status should reflect publish action")
Пример #4
0
    def test_store_event(self):
        """Store a single event."""
        with in_memory_db() as session:
            user = User(12345, '*****@*****.**')
            ev = CreateSubmission(creator=user)
            submission = ev.apply()
            submission = classic.store_events(ev, submission=submission)

            db_submission = session.query(classic.models.Submission)\
                .get(submission.submission_id)

        self.assertEqual(db_submission.submission_id, submission.submission_id,
                         "The submission should be updated with the PK id.")
        self.assertEqual(db_submission.submitter_id,
                         submission.creator.native_id,
                         "The native ID of the creator should be used")
        self.assertEqual(db_submission.status, db_submission.NOT_SUBMITTED,
                         "Submission in database should be in status 0 (not"
                         " submitted) by default.")
Пример #5
0
    def test_store_events_with_finalized_submission(self):
        """Store events and a finalized submission."""
        with in_memory_db() as session:
            user = User(12345, '*****@*****.**')
            ev = CreateSubmission(creator=user)
            ev2 = FinalizeSubmission(creator=user)
            submission = ev.apply()
            submission = ev2.apply(submission)
            submission = classic.store_events(ev, ev2, submission=submission)

            db_submission = session.query(classic.models.Submission)\
                .get(submission.submission_id)
            db_events = session.query(classic.DBEvent).all()

        self.assertEqual(db_submission.submission_id, submission.submission_id,
                         "The submission should be updated with the PK id.")
        self.assertEqual(len(db_events), 2, "Two events should be stored")
        for db_event in db_events:
            self.assertEqual(db_event.submission_id, submission.submission_id,
                             "The submission id should be set")
Пример #6
0
    def test_store_events_with_metadata(self):
        """Store events and attendant submission with metadata."""
        metadata = {
            'title': 'foo title',
            'abstract': 'very abstract',
            'comments': 'indeed',
            'msc_class': 'foo msc',
            'acm_class': 'computer-y',
            'doi': '10.01234/5678',
            'journal_ref': 'Nature 1: 1',
            'authors': [Author(order=0, forename='Joe', surname='Bloggs')]
        }
        with in_memory_db() as session:
            user = User(12345, '*****@*****.**')
            ev = CreateSubmission(creator=user)
            ev2 = UpdateMetadata(creator=user,
                                      metadata=list(metadata.items()))

            submission = ev.apply()
            submission = ev2.apply(submission)
            submission = classic.store_events(ev, ev2, submission=submission)

            db_submission = session.query(classic.models.Submission)\
                .get(submission.submission_id)

            db_events = session.query(classic.DBEvent).all()

        for key, value in metadata.items():
            if key == 'authors':
                continue
            self.assertEqual(getattr(db_submission, key), value,
                             f"The value of {key} should be {value}")
        self.assertEqual(db_submission.authors,
                         submission.metadata.authors_display,
                         "The canonical author string should be used to"
                         " update the submission in the database.")

        self.assertEqual(len(db_events), 2, "Two events should be stored")
        for db_event in db_events:
            self.assertEqual(db_event.submission_id, submission.submission_id,
                             "The submission id should be set")
Пример #7
0
def save(*events: Event, submission_id: Optional[str] = None) \
        -> Tuple[Submission, List[Event]]:
    """
    Commit a set of new :class:`.Event`s for a submission.

    This will persist the events to the database, along with the final
    state of the submission, and generate external notification(s) on the
    appropriate channels.

    Parameters
    ----------
    events : :class:`.Event`
        Events to apply and persist.
    submission_id : int
        The unique ID for the submission, if available. If not provided, it is
        expected that ``events`` includes a :class:`.CreateSubmission`.

    Returns
    -------
    :class:`events.domain.submission.Submission`
        The state of the submission after all events (including rule-derived
        events) have been applied. Updated with the submission ID, if a
        :class:`.CreateSubmission` was included.
    list
        A list of :class:`.Event` instances applied to the submission. Note
        that this list may contain more events than were passed, if event
        rules were triggered.

    Raises
    ------
    :class:`.NoSuchSubmission`
        Raised if ``submission_id`` is not provided and the first event is not
        a :class:`.CreateSubmission`, or ``submission_id`` is provided but
        no such submission exists.
    :class:`.InvalidEvent`
        If an invalid event is encountered, the entire operation is aborted
        and this exception is raised.
    :class:`.SaveError`
        There was a problem persisting the events and/or submission state
        to the database.

    """
    if len(events) == 0:
        raise ValueError('Must pass at least one event')

    # Do some sanity checks before proceeding.
    for event in events:
        if submission_id is not None:
            if event.submission_id is None:
                event.submission_id = submission_id
            if event.submission_id != submission_id:
                raise InvalidEvent(
                    event, "Can't mix events for multiple submissions")

    # We want to play events from the beginning.
    if submission_id is not None:
        existing_events = classic.get_events(submission_id)
    else:
        existing_events = []
    combined = existing_events + list(events)

    # Load any relevant event rules for this submission.
    rules = []  # database.get_rules(submission_id)

    # Calculate the state of the submission from old and new events.
    submission, combined = _apply_events(combined, rules)

    # Update the submission ID to ensure the existing submission is updated.
    if submission.submission_id is None:
        submission.submission_id = submission_id  # May still be None.

    # Persist in database; submission ID is updated after transaction.
    try:
        submission = classic.store_events(*combined, submission=submission)
    except classic.CommitFailed as e:
        logger.debug('Encountered CommitFailed exception: %s', str(e))
        raise SaveError('Failed to store events') from e

    for event in combined:
        event.submission_id = submission.submission_id
    return submission, combined