Example #1
0
def test_jobs_create_with_existing_control_number(base_app, db, create_pidstore):
    data = faker.record("job", with_control_number=True)
    existing_object_uuid = uuid.uuid4()

    create_pidstore(
        object_uuid=existing_object_uuid,
        pid_type="job",
        pid_value=data["control_number"],
    )

    with pytest.raises(PIDAlreadyExists):
        JobsRecord.create(data)
Example #2
0
def test_cn_redirection_works_for_jobs(inspire_app):
    redirected_record = create_record("job")
    record = create_record("job", data={"deleted_records": [redirected_record["self"]]})

    original_record = JobsRecord.get_uuid_from_pid_value(
        redirected_record["control_number"], original_record=True
    )
    new_record = JobsRecord.get_uuid_from_pid_value(redirected_record["control_number"])

    assert original_record != new_record
    assert original_record == redirected_record.id
    assert new_record == record.id
Example #3
0
def test_jobs_create_with_invalid_data(base_app, db, create_pidstore):
    data = faker.record("job", with_control_number=True)
    data["invalid_key"] = "should throw an error"
    record_control_number = str(data["control_number"])

    with pytest.raises(ValidationError):
        JobsRecord.create(data)

    record_pid = PersistentIdentifier.query.filter_by(
        pid_value=record_control_number
    ).one_or_none()
    assert record_pid is None
Example #4
0
    def put(self, pid_value):
        """Updates existing record in db"""
        data = self.load_data_from_request()

        try:
            pid, _ = pid_value.data
            record = JobsRecord.get_record_by_pid_value(pid.pid_value)
            if not self.user_can_edit(record):
                return (
                    jsonify(
                        {"message": "You are not allowed to edit this Job opening"}
                    ),
                    403,
                )
        except PIDDoesNotExistError:
            abort(404)

        self.raise_if_user_can_not_modify_status(data, record)

        builder = self.get_builder_with_updated_record(data, record)
        data = self.get_valid_record_data_from_builder(builder)
        record.update(data)
        db.session.commit()

        if not is_superuser_or_cataloger_logged_in():
            self.create_ticket(record, "rt/update_job.html")

        return jsonify({"pid_value": record["control_number"]})
Example #5
0
def notify_expired_jobs(dry_run):
    jobs_to_notify = []
    dates = [
        datetime.date.today(),
        (datetime.date.today() - datetime.timedelta(days=30)),
        (datetime.date.today() - datetime.timedelta(days=60)),
    ]

    for d in dates:
        expired_jobs = JobsRecord.get_jobs_by_deadline(d)
        LOGGER.info(f"Found {len(expired_jobs)} expired jobs", deadline=d)
        jobs_to_notify.extend(expired_jobs)

    if not jobs_to_notify:
        LOGGER.info("No expired job to notify, exiting.")
        return

    if dry_run:
        LOGGER.warn(f"Skip sending emails for {len(jobs_to_notify)} expired jobs")
        return

    LOGGER.info(f"Sending {len(jobs_to_notify)} emails for expired jobs")

    for job in jobs_to_notify:
        send_job_deadline_reminder(job.to_dict())
Example #6
0
def test_close_expired_jobs_has_exclusive_deadline(inspire_app, cli):
    job = create_record("job", data={"status": "open", "deadline_date": "2019-11-01"})
    result = cli.invoke(["jobs", "close_expired_jobs"])
    job = JobsRecord.get_record_by_pid_value(job["control_number"])

    assert result.exit_code == 0
    assert job["status"] == "open"
Example #7
0
def close_expired_jobs(notify):
    now = datetime.datetime.utcnow()
    today = now.strftime("%Y-%m-%d")

    record_json = type_coerce(RecordMetadata.json, JSONB)
    before_deadline_date = record_json["deadline_date"].astext.cast(
        DateTime) < today
    only_jobs_collection = record_json["_collections"].contains(["Jobs"])
    only_not_closed = not_(record_json["status"].astext == "closed")
    only_not_deleted = or_(
        not_(record_json.has_key("deleted")),  # noqa: W601
        not_(record_json["deleted"] == cast(True, JSONB)),
    )
    expired_jobs = RecordMetadata.query.filter(only_jobs_collection,
                                               only_not_deleted,
                                               only_not_closed,
                                               before_deadline_date).all()
    expired_job_records = [
        JobsRecord(job.json, model=job) for job in expired_jobs
    ]
    for job_record in expired_job_records:
        job_record["status"] = "closed"
        job_record.update(dict(job_record))

    db.session.commit()

    if notify:
        for job_record in expired_job_records:
            send_job_deadline_reminder(dict(job_record))

    LOGGER.info("Closed expired jobs",
                notify=notify,
                num_records=len(expired_jobs))
Example #8
0
def test_dump_ref_letter_contact():
    data_to_load = {
        **DEFAULT_DATA_TO_DUMP,
        "reference_letters": {
            "emails": ["one@email", "second@email"],
            "urls": [
                {
                    "description": "Description of url",
                    "value": "http://url1"
                },
                {
                    "value": "http://url2"
                },
            ],
        },
    }

    record = JobsRecord(data_to_load)
    result = Job().dump(record).data

    expected_data = {
        **DEFAULT_EXPECTED_DATA_AFTER_DUMP,
        "reference_letters": [
            "one@email",
            "second@email",
            "http://url1",
            "http://url2",
        ],
    }
    assert result == expected_data
Example #9
0
 def post(self):
     """Adds new job record"""
     data = job_loader_v1()
     data = self.prepare_data(data)
     record = JobsRecord.create(data)
     db.session.commit()
     self.create_ticket(record, "rt/new_job.html")
     return jsonify({"pid_value": record["control_number"]}), 201
Example #10
0
def test_dump_required_data():
    data_to_load = {**DEFAULT_DATA_TO_DUMP}
    record = JobsRecord(data_to_load)
    result = Job().dump(record).data

    expected_data = {**DEFAULT_EXPECTED_DATA_AFTER_DUMP}

    assert result == expected_data
Example #11
0
def test_get_jobs_by_deadline_doesnt_get_pending_expired_job(inspire_app):
    deadline = datetime.date(2019, 9, 27)
    data = faker.record("job")
    data["deadline_date"] = deadline.isoformat()
    data["status"] = "pending"
    create_record("job", data=data)

    results = JobsRecord.get_jobs_by_deadline(deadline)
    assert not results
Example #12
0
def test_create_record_from_db_depending_on_its_pid_type(inspire_app):
    data = faker.record("job")
    record = InspireRecord.create(data)
    assert isinstance(record, JobsRecord)
    assert record.pid_type == "job"

    record = JobsRecord.create(data)
    assert isinstance(record, JobsRecord)
    assert record.pid_type == "job"
Example #13
0
def test_create_record_from_db_depending_on_its_pid_type(base_app, db, es):
    data = faker.record("job")
    record = InspireRecord.create(data)
    assert type(record) == JobsRecord
    assert record.pid_type == "job"

    record = JobsRecord.create(data)
    assert type(record) == JobsRecord
    assert record.pid_type == "job"
Example #14
0
    def get(self, pid_value):
        try:
            pid, _ = pid_value.data
            record = JobsRecord.get_record_by_pid_value(pid.pid_value)
        except PIDDoesNotExistError:
            abort(404)

        serialized_record = job_v1.dump(record)
        return jsonify({"data": serialized_record})
Example #15
0
def test_get_jobs_by_deadline_doesnt_get_pending_expired_job(base_app, db, es_clear, create_record):
    deadline = datetime.date(2019, 9, 27)
    data = faker.record("job")
    data['deadline_date'] = deadline.isoformat()
    data['status'] = 'pending'
    create_record("job", data=data)

    results = JobsRecord.get_jobs_by_deadline(deadline)
    assert not results
Example #16
0
 def post(self):
     """Adds new job record"""
     data = self.load_data_from_request()
     builder = self.get_builder_with_new_record(data)
     data = self.get_valid_record_data_from_builder(builder)
     record = JobsRecord.create(data)
     db.session.commit()
     self.create_ticket(record, "rt/new_job.html")
     return jsonify({"pid_value": record["control_number"]}), 201
Example #17
0
def test_dump_external_job_identifier():
    data_to_load = {**DEFAULT_DATA_TO_DUMP, "description": "Test 1234"}

    record = JobsRecord(data_to_load)
    result = Job().dump(record).data

    expected_data = {
        **DEFAULT_EXPECTED_DATA_AFTER_DUMP, "description": "Test 1234"
    }

    assert result == expected_data
Example #18
0
def test_close_expired_jobs_ignores_deleted_records(inspire_app, cli):
    deleted_record = create_record(
        "job", data={"status": "open", "deadline_date": "2019-11-01"}
    )
    deleted_record["deleted"] = True
    deleted_record.update(dict(deleted_record))
    result = cli.invoke(["jobs", "close_expired_jobs"])
    deleted_record = JobsRecord.get_record_by_pid_value(
        deleted_record["control_number"], with_deleted=True
    )

    assert result.exit_code == 0
    assert deleted_record["status"] == "open"
Example #19
0
def test_close_expired_jobs_without_notify(
    mock_send_job_deadline_reminder, inspire_app, cli
):
    expired_record = create_record(
        "job", data={"status": "open", "deadline_date": "2019-11-01"}
    )
    not_expired_record = create_record(
        "job", data={"status": "open", "deadline_date": "2020-11-01"}
    )
    result = cli.invoke(["jobs", "close_expired_jobs"])
    expired_record = JobsRecord.get_record_by_pid_value(
        expired_record["control_number"]
    )
    not_expired_record = JobsRecord.get_record_by_pid_value(
        not_expired_record["control_number"]
    )

    assert result.exit_code == 0
    assert expired_record["status"] == "closed"
    assert not_expired_record["status"] == "open"

    mock_send_job_deadline_reminder.assert_not_called()
Example #20
0
def test_indexer_deletes_record_from_es(inspire_app):
    def assert_record_is_deleted_from_es():
        current_search.flush_and_refresh("records-jobs")
        expected_records_count = 0
        record_lit_es = JobsSearch().get_record(str(record.id)).execute().hits
        assert expected_records_count == len(record_lit_es)

    record = JobsRecord.create(faker.record("job"))
    db.session.commit()

    record.delete()
    db.session.commit()

    retry_until_pass(assert_record_is_deleted_from_es)
Example #21
0
def test_get_jobs_by_deadline_gets_open_expired_job(inspire_app):
    deadline = datetime.date(2019, 9, 27)
    data = faker.record("job")
    data["deadline_date"] = deadline.isoformat()
    data["status"] = "open"
    expected_result = create_record("job", data=data)

    results = JobsRecord.get_jobs_by_deadline(deadline)
    assert len(results) == 1

    result = results[0]
    del result["_created"]
    del result["_updated"]

    assert result == expected_result
Example #22
0
def test_jobs_create_or_update_with_new_record(base_app, db, es):
    data = faker.record("job")
    record = JobsRecord.create_or_update(data)

    control_number = str(record["control_number"])
    record_db = RecordMetadata.query.filter_by(id=record.id).one()

    assert record == record_db.json

    record_pid = PersistentIdentifier.query.filter_by(
        pid_type="job", pid_value=str(control_number)
    ).one()

    assert record.model.id == record_pid.object_uuid
    assert control_number == record_pid.pid_value
Example #23
0
def test_get_jobs_by_deadline_gets_open_expired_job(base_app, db, es_clear, create_record):
    deadline = datetime.date(2019, 9, 27)
    data = faker.record("job")
    data['deadline_date'] = deadline.isoformat()
    data['status'] = 'open'
    expected_result = create_record("job", data=data)

    results = JobsRecord.get_jobs_by_deadline(deadline)
    assert len(results) == 1

    result = results[0]
    del result['_created']
    del result['_updated']

    assert result == expected_result
Example #24
0
def test_jobs_create_or_update_with_existing_record(base_app, db, es):
    data = faker.record("job", with_control_number=True)
    record = JobsRecord.create(data)

    assert data["control_number"] == record["control_number"]

    data_update = {"description": "UPDATED"}
    data.update(data_update)

    record_updated = JobsRecord.create_or_update(data)
    control_number = str(record_updated["control_number"])

    assert record["control_number"] == record_updated["control_number"]

    record_updated_db = RecordMetadata.query.filter_by(id=record_updated.id).one()

    assert data == record_updated_db.json

    record_updated_pid = PersistentIdentifier.query.filter_by(
        pid_type="job", pid_value=str(control_number)
    ).one()

    assert record_updated.model.id == record_updated_pid.object_uuid
    assert control_number == record_updated_pid.pid_value
Example #25
0
def test_dump_field_of_interest():
    data_to_load = {
        **DEFAULT_DATA_TO_DUMP,
        "arxiv_categories": ["cond-mat.dis-nn", "nlin.SI"],
    }

    record = JobsRecord(data_to_load)
    result = Job().dump(record).data

    expected_data = {
        **DEFAULT_EXPECTED_DATA_AFTER_DUMP,
        "field_of_interest": ["cond-mat.dis-nn", "nlin.SI"],
    }

    assert result == expected_data
def test_new_job_submit_by_user(create_ticket_mock, app, api_client, create_user):
    user = create_user()
    login_user_via_session(api_client, email=user.email)
    response = api_client.post(
        "/submissions/jobs",
        content_type="application/json",
        data=json.dumps({"data": DEFAULT_EXAMPLE_JOB_DATA}),
    )
    assert response.status_code == 201

    job_id = json.loads(response.data)["pid_value"]
    job_data = JobsRecord.get_record_by_pid_value(job_id)

    assert job_data["status"] == "pending"
    create_ticket_mock.delay.assert_called_once()
def test_new_job_submit_by_cataloger(ticket_mock, app, api_client, create_user):
    user = create_user(role=Roles.cataloger.value)
    login_user_via_session(api_client, email=user.email)

    post_data = {**DEFAULT_EXAMPLE_JOB_DATA, "status": "open"}
    response = api_client.post(
        "/submissions/jobs",
        content_type="application/json",
        data=json.dumps({"data": post_data}),
    )
    assert response.status_code == 201

    job_id = json.loads(response.data)["pid_value"]
    job_data = JobsRecord.get_record_by_pid_value(job_id)

    assert job_data["status"] == "open"
Example #28
0
def test_jobs_serializer_should_serialize_whole_basic_record():
    schema = JobsRawSchema()
    data = {
        "$schema": "http://localhost:5000/schemas/records/jobs.json",
        "_collections": ["Jobs"],
        "deadline_date": "1996-11-15",
        "description": "Join us!",
        "position": "staff",
        "regions": ["Europe"],
        "status": "closed",
    }

    job = JobsRecord(data)
    result = schema.dump(job).data

    assert result == data
Example #29
0
def test_close_expired_jobs_with_notify(
    mock_send_job_deadline_reminder, inspire_app, cli
):
    expired_record = create_record(
        "job", data={"status": "open", "deadline_date": "2019-11-01"}
    )
    not_expired_record = create_record(
        "job", data={"status": "open", "deadline_date": "2020-11-01"}
    )
    cli.invoke(["jobs", "close_expired_jobs", "--notify"])

    expired_record = JobsRecord.get_record_by_pid_value(
        expired_record["control_number"]
    )

    mock_send_job_deadline_reminder.assert_called_once()
    mock_send_job_deadline_reminder.assert_called_with(dict(expired_record))
Example #30
0
def test_get_jobs_by_deadline_gets_open_expired_job(inspire_app):
    deadline = datetime.date(2019, 9, 27)
    record_data = {
        "deadline_date": deadline.isoformat(),
        "status": "open",
        "acquisition_source": {"orcid": "0000-0000-0000-0000"},
    }
    data = faker.record("job", data=record_data)
    expected_result = create_record("job", data=data)

    results = JobsRecord.get_jobs_by_deadline(deadline)
    assert len(results) == 1

    result = results[0]
    del result["_created"]
    del result["_updated"]

    assert result == expected_result