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)
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
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
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"]})
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())
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"
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))
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
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
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
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
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"
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"
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})
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
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
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
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"
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()
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)
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
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
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
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
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"
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
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))
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