def test_sticky_status_is_set(self):
        """A sticky status is set during moderation."""
        # Client creates the submission.
        example = os.path.join(BASEPATH, 'examples/complete_submission.json')
        with open(example) as f:
            data = json.load(f)
        response = self.client.post('/',
                                    data=json.dumps(data),
                                    content_type='application/json',
                                    headers=self.headers)
        submission_id = json.loads(response.data)['submission_id']

        # Moderator, admin, or other agent places the submission on hold,
        #  and a sticky status is set.
        with self.app.app_context():
            from arxiv.submission.services import classic
            session = classic.current_session()
            submission = session.query(classic.models.Submission)\
                .get(submission_id)
            submission.status = submission.ON_HOLD
            submission.sticky_status = submission.ON_HOLD
            session.add(submission)
            session.commit()

        # Client gets submission state.
        response = self.client.get(f'/{submission_id}/', headers=self.headers)
        submission_data = json.loads(response.data)
        self.assertEqual(submission_data['status'], 'hold',
                         "Status should be `hold`")

        # Client withdraws the submission from the queue.
        response = self.client.post(f'/{submission_id}/',
                                    data=json.dumps({"finalized": False}),
                                    content_type='application/json',
                                    headers=self.headers)
        submission_data = json.loads(response.data)
        self.assertFalse(submission_data['finalized'],
                         "Should no longer be finalized")

        # Client gets submission state.
        response = self.client.get(f'/{submission_id}/', headers=self.headers)
        submission_data = json.loads(response.data)
        self.assertFalse(submission_data['finalized'],
                         "Should no longer be finalized")
        self.assertEqual(submission_data['status'], 'working',
                         "Status should be `working`")

        # Client finalizes the submission for moderation.
        response = self.client.post(f'/{submission_id}/',
                                    data=json.dumps({"finalized": True}),
                                    content_type='application/json',
                                    headers=self.headers)
        submission_data = json.loads(response.data)

        # Client gets submission state.
        response = self.client.get(f'/{submission_id}/', headers=self.headers)
        submission_data = json.loads(response.data)
        self.assertTrue(submission_data['finalized'], "Should be finalized")
        self.assertEqual(submission_data['status'], 'hold',
                         "Status should be `hold`, as sticky_status was set")
    def test_submission_placed_on_hold(self):
        """Before publication, a submission may be placed on hold."""
        # Client creates the submission.
        example = os.path.join(BASEPATH, 'examples/complete_submission.json')
        with open(example) as f:
            data = json.load(f)
        response = self.client.post('/',
                                    data=json.dumps(data),
                                    content_type='application/json',
                                    headers=self.headers)
        submission_id = json.loads(response.data)['submission_id']

        # Moderator, admin, or other agent places the submission on hold.
        with self.app.app_context():
            from arxiv.submission.services import classic
            session = classic.current_session()
            submission = session.query(classic.models.Submission) \
                .get(submission_id)
            submission.status = submission.ON_HOLD
            session.add(submission)
            session.commit()

        # Client gets submission state.
        response = self.client.get(f'/{submission_id}/', headers=self.headers)
        submission_data = json.loads(response.data)
        self.assertEqual(submission_data['status'], 'hold',
                         "Status should be `hold`")
    def test_request_withdrawal(self):
        """User requests withdrawal of a announced submission."""
        # Get the JREF page.
        endpoint = f'/{self.submission_id}/withdraw'
        response = self.client.get(endpoint, headers=self.headers)
        self.assertEqual(response.status_code, status.OK)
        self.assertEqual(response.content_type, 'text/html; charset=utf-8')
        self.assertIn(b'Request withdrawal', response.data)
        token = self._parse_csrf_token(response)

        # Set the withdrawal reason, but make it huge.
        request_data = {
            'withdrawal_reason': 'This is the reason' * 400,
            'csrf_token': token
        }
        response = self.client.post(endpoint,
                                    data=request_data,
                                    headers=self.headers)
        self.assertEqual(response.status_code, status.BAD_REQUEST)
        token = self._parse_csrf_token(response)

        # Set the withdrawal reason to something reasonable (ha).
        request_data = {
            'withdrawal_reason': 'This is the reason',
            'csrf_token': token
        }
        response = self.client.post(endpoint,
                                    data=request_data,
                                    headers=self.headers)
        self.assertEqual(response.status_code, status.OK)
        self.assertEqual(response.content_type, 'text/html; charset=utf-8')
        self.assertIn(b'Confirm and Submit', response.data)
        token = self._parse_csrf_token(response)

        # Confirm the withdrawal request.
        request_data['confirmed'] = True
        request_data['csrf_token'] = token
        response = self.client.post(endpoint,
                                    data=request_data,
                                    headers=self.headers)
        self.assertEqual(response.status_code, status.SEE_OTHER)

        with self.app.app_context():
            session = classic.current_session()
            # What happened.
            db_submissions = session.query(classic.models.Submission) \
                .filter(classic.models.Submission.doc_paper_id == '1234.5678')
            self.assertEqual(db_submissions.count(), 2,
                             "Creates a second row for the withdrawal")
            db_submission = db_submissions \
                .order_by(classic.models.Submission.submission_id.desc()) \
                .first()
            self.assertEqual(db_submission.type,
                             classic.models.Submission.WITHDRAWAL)
示例#4
0
def in_memory_db():
    """Provide an in-memory sqlite database for testing purposes."""
    app = Flask('foo')
    app.config['CLASSIC_DATABASE_URI'] = 'sqlite://'
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

    with app.app_context():
        classic.init_app(app)
        classic.create_all()
        try:
            yield classic.current_session()
        except Exception:
            raise
        finally:
            classic.drop_all()
    def test_publication_failed(self):
        """The submission was not announced successfully."""
        with self.app.app_context():
            from arxiv.submission.services import classic
            session = classic.current_session()

            # Publication agent publishes the paper.
            db_submission = session.query(classic.models.Submission)\
                .get(self.submission_id)
            db_submission.status = db_submission.ERROR_STATE
            session.add(db_submission)
            session.commit()

            # Submission state should reflect scheduled status.
            response = self.client.get(f'/{self.submission_id}/',
                                       headers=self.headers)
            submission = json.loads(response.data)
            self.assertEqual(submission['status'], Submission.ERROR,
                             "Submission should have error status.")
    def test_scheduled_tomorrow_status_is_reflected(self):
        """The submission has been scheduled for publication tomorrow."""
        with self.app.app_context():
            from arxiv.submission.services import classic
            session = classic.current_session()

            # Publication agent publishes the paper.
            db_submission = session.query(classic.models.Submission)\
                .get(self.submission_id)
            db_submission.status = db_submission.NEXT_PUBLISH_DAY
            session.add(db_submission)
            session.commit()

            # Submission state should reflect scheduled status.
            response = self.client.get(f'/{self.submission_id}/',
                                       headers=self.headers)
            submission = json.loads(response.data)
            self.assertEqual(submission['status'], Submission.SCHEDULED,
                             "Submission should be scheduled for tomorrow.")
    def test_scheduled_status_is_reflected_prior_to_announcement(self):
        """The submission is being announced; not yet announced."""
        with self.app.app_context():
            from arxiv.submission.services import classic
            session = classic.current_session()

            # Publication agent publishes the paper.
            db_submission = session.query(classic.models.Submission)\
                .get(self.submission_id)
            db_submission.status = db_submission.NEEDS_EMAIL
            session.add(db_submission)
            session.commit()

            # Submission state should reflect scheduled status.
            response = self.client.get(f'/{self.submission_id}/',
                                       headers=self.headers)
            submission = json.loads(response.data)
            self.assertEqual(submission['status'], Submission.SCHEDULED,
                             "Submission should have scheduled status.")
    def test_deleted(self):
        """The submission was deleted."""
        with self.app.app_context():
            from arxiv.submission.services import classic
            session = classic.current_session()

            for classic_status in classic.models.Submission.DELETED:
                # Publication agent publishes the paper.
                db_submission = session.query(classic.models.Submission)\
                    .get(self.submission_id)
                db_submission.status = classic_status
                session.add(db_submission)
                session.commit()

                # Submission state should reflect scheduled status.
                response = self.client.get(f'/{self.submission_id}/',
                                           headers=self.headers)
                submission = json.loads(response.data)
                self.assertEqual(submission['status'], Submission.DELETED,
                                 "Submission should have deleted status.")
    def test_create_submission(self):
        """User creates a new submission, and proceeds up to upload stage."""
        # Get the JREF page.
        endpoint = f'/{self.submission_id}/jref'
        response = self.client.get(endpoint, headers=self.headers)
        self.assertEqual(response.status_code, status.OK)
        self.assertEqual(response.content_type, 'text/html; charset=utf-8')
        self.assertIn(b'Journal reference', response.data)
        token = self._parse_csrf_token(response)

        # Set the DOI, journal reference, report number.
        request_data = {
            'doi': '10.1000/182',
            'journal_ref': 'foo journal 1992',
            'report_num': 'abc report 42',
            'csrf_token': token
        }
        response = self.client.post(endpoint,
                                    data=request_data,
                                    headers=self.headers)
        self.assertEqual(response.status_code, status.OK)
        self.assertEqual(response.content_type, 'text/html; charset=utf-8')
        self.assertIn(b'Confirm and Submit', response.data)
        token = self._parse_csrf_token(response)

        request_data['confirmed'] = True
        request_data['csrf_token'] = token
        response = self.client.post(endpoint,
                                    data=request_data,
                                    headers=self.headers)
        self.assertEqual(response.status_code, status.SEE_OTHER)

        with self.app.app_context():
            session = classic.current_session()
            # What happened.
            db_submission = session.query(classic.models.Submission) \
                .filter(classic.models.Submission.doc_paper_id == '1234.5678')
            self.assertEqual(db_submission.count(), 2,
                             "Creates a second row for the JREF")
示例#10
0
    def test_publication_status_is_reflected_after_files_expire(self):
        """The submission has been announced/announced, and files expired."""
        with self.app.app_context():
            from arxiv.submission.services import classic
            session = classic.current_session()

            # Publication agent publishes the paper.
            db_submission = session.query(classic.models.Submission)\
                .get(self.submission_id)
            db_submission.status = db_submission.DELETED_ANNOUNCED
            dated = (datetime.now() - datetime.utcfromtimestamp(0))
            primary = self.submission['primary_classification']['category']
            db_submission.document = classic.models.Document(
                document_id=1,
                paper_id='1901.00123',
                title=self.submission['metadata']['title'],
                authors=self.submission['metadata']['authors_display'],
                dated=dated.total_seconds(),
                primary_subject_class=primary,
                created=datetime.now(UTC),
                submitter_email=self.submission['creator']['email'],
                submitter_id=self.submission['creator']['user_id'])
            session.add(db_submission)
            session.commit()

            # Submission state should reflect publication status.
            response = self.client.get(f'/{self.submission_id}/',
                                       headers=self.headers)
            submission = json.loads(response.data)
            self.assertEqual(submission['status'], Submission.ANNOUNCED,
                             "Submission should have announced status.")
            self.assertEqual(submission['arxiv_id'], "1901.00123",
                             "arXiv paper ID should be set")
            self.assertFalse(
                submission['active'],
                "Announced submission should no longer be active")
示例#11
0
from arxiv.submission.services import classic
from arxiv.submission.services.classic import bootstrap
from arxiv.users.helpers import generate_token
from arxiv.users.auth import scopes
from submit.factory import create_ui_web_app

logging.getLogger('arxiv.submission.services.classic.interpolate') \
    .setLevel(logging.ERROR)
logging.getLogger('arxiv.base.alerts').setLevel(logging.ERROR)

logger = logging.getLogger(__name__)

app = create_ui_web_app()

with app.app_context():
    session = classic.current_session()
    engine = classic.util.current_engine()
    logger.info('Waiting for database server to be available')
    logger.info(app.config['SQLALCHEMY_DATABASE_URI'])
    wait = 2
    while True:
        try:
            session.execute('SELECT 1')
            break
        except Exception as e:
            logger.info(e)
            logger.info(f'...waiting {wait} seconds...')
            time.sleep(wait)
            wait *= 2

    logger.info('Checking for database')
示例#12
0
    def setUp(self):
        """Create an application instance."""
        self.app = create_ui_web_app()
        os.environ['JWT_SECRET'] = self.app.config.get('JWT_SECRET')
        _, self.db = tempfile.mkstemp(suffix='.db')
        self.app.config['CLASSIC_DATABASE_URI'] = f'sqlite:///{self.db}'
        self.user = User('1234',
                         '*****@*****.**',
                         endorsements=['astro-ph.GA', 'astro-ph.CO'])
        self.token = generate_token(
            '1234',
            '*****@*****.**',
            'foouser',
            scope=[
                scopes.CREATE_SUBMISSION, scopes.EDIT_SUBMISSION,
                scopes.VIEW_SUBMISSION, scopes.READ_UPLOAD,
                scopes.WRITE_UPLOAD, scopes.DELETE_UPLOAD_FILE
            ],
            endorsements=[
                Category('astro-ph.GA'),
                Category('astro-ph.CO'),
            ])
        self.headers = {'Authorization': self.token}
        self.client = self.app.test_client()

        # Create and announce a submission.
        with self.app.app_context():
            classic.create_all()
            session = classic.current_session()

            cc0 = 'http://creativecommons.org/publicdomain/zero/1.0/'
            self.submission, _ = save(
                CreateSubmission(creator=self.user),
                ConfirmContactInformation(creator=self.user),
                ConfirmAuthorship(creator=self.user, submitter_is_author=True),
                SetLicense(creator=self.user,
                           license_uri=cc0,
                           license_name='CC0 1.0'),
                ConfirmPolicy(creator=self.user),
                SetPrimaryClassification(creator=self.user,
                                         category='astro-ph.GA'),
                SetUploadPackage(
                    creator=self.user,
                    checksum="a9s9k342900skks03330029k",
                    source_format=SubmissionContent.Format.TEX,
                    identifier=123,
                    uncompressed_size=593992,
                    compressed_size=59392,
                ), SetTitle(creator=self.user, title='foo title'),
                SetAbstract(creator=self.user, abstract='ab stract' * 20),
                SetComments(creator=self.user, comments='indeed'),
                SetReportNumber(creator=self.user, report_num='the number 12'),
                SetAuthors(creator=self.user,
                           authors=[
                               Author(order=0,
                                      forename='Bob',
                                      surname='Paulson',
                                      email='*****@*****.**',
                                      affiliation='Fight Club')
                           ]), FinalizeSubmission(creator=self.user))

            # announced!
            db_submission = session.query(classic.models.Submission) \
                .get(self.submission.submission_id)
            db_submission.status = classic.models.Submission.ANNOUNCED
            db_document = classic.models.Document(paper_id='1234.5678')
            db_submission.doc_paper_id = '1234.5678'
            db_submission.document = db_document
            session.add(db_submission)
            session.add(db_document)
            session.commit()

        self.submission_id = self.submission.submission_id