def test_upload_affiliation_with_wrong_country(request_ctx, mocker): """Test task loading and processing with failures.""" org = Organisation.get(name="TEST0") super_user = User.get(email="*****@*****.**") with request_ctx("/") as ctx: exception = mocker.patch.object(ctx.app.logger, "exception") login_user(super_user) # flake8: noqa with pytest.raises(ModelException): task = Task.load_from_csv( """First name\tLast name\temail address\tOrganisation\tCampus/Department\tCity\tCourse or Job title\tStart date\tEnd date\tStudent/Staff\tCountry FNA\tLBA\[email protected]\tTEST1\tResearch Funding\tWellington\tProgramme Manager - ORCID\t2016-09 19:00:00 PM\t\tStaff\tNO COUNTRY """, filename="TEST.tsv", org=org) # this should work: task = Task.load_from_csv( """First name\tLast name\temail address\tOrganisation\tCampus/Department\tCity\tCourse or Job title\tStart date\tEnd date\tStudent/Staff\tCountry FNA\tLBA\[email protected]\tTEST1\tResearch Funding\tWellington\tProgramme Manager - ORCID\t2016-09 19:00:00 PM\t\tStaff\t """, filename="TEST-2.tsv", org=org) rec = task.records.first() assert rec.country is None exception.assert_called_once()
def test_send_work_funding_peer_review_invitation(test_db, request_ctx): """Test to send user invitation.""" org = Organisation(id=1, name="THE ORGANISATION", tuakiri_name="THE ORGANISATION", confirmed=True, orcid_client_id="CLIENT ID", orcid_secret="Client Secret", city="CITY", country="COUNTRY", disambiguation_org_id="ID", disambiguation_org_source="SOURCE") inviter = User(email="*****@*****.**", name="TEST USER", username="******", roles=Role.RESEARCHER, orcid=None, confirmed=True, organisation=org) u = User(email="*****@*****.**", name="TEST USER", username="******", roles=Role.RESEARCHER, orcid=None, confirmed=True, organisation=org) u.save() user_org = UserOrg(user=u, org=org) user_org.save() task = Task(org=org, task_type=1) task.save() email = "*****@*****.**" fr = FundingRecord(task=task.id, title="xyz", type="Award") fr.save() fc = FundingInvitees(funding_record=fr.id, email=email, first_name="Alice", last_name="Bob") fc.save() with request_ctx("/") as ctxx: utils.send_work_funding_peer_review_invitation(inviter=inviter, org=org, email=email, name=u.name, task_id=task.id) rv = ctxx.app.full_dispatch_request() assert rv.status_code == 200
def test_test_database(models): """Test of the consitency of the test database.""" assert Organisation.select().count() == 10 assert User.select().count() == 63 assert OrcidToken.select().count() == 60 assert AffiliationRecord.select().count() == 10 assert FundingRecord.select().count() == 10 assert FundingContributor.select().count() == 10 assert FundingInvitee.select().count() == 10 assert ExternalId.select().count() == 10 assert WorkRecord.select().count() == 10 assert WorkContributor.select().count() == 10 assert WorkExternalId.select().count() == 10 assert WorkInvitee.select().count() == 10 assert PeerReviewRecord.select().count() == 10 assert PeerReviewExternalId.select().count() == 10 assert PeerReviewInvitee.select().count() == 10 assert ResearcherUrlRecord.select().count() == 10 assert OtherNameRecord.select().count() == 10 assert KeywordRecord.select().count() == 10 assert Task.select().count() == 30 assert UserOrgAffiliation.select().count() == 30 assert User.get(id=43).admin_for.count() == 10 assert User.get(id=1).admin_for.count() == 0 assert User.get(id=42).admin_for.count() > 0 assert User.get(id=2).organisations.count() > 0 assert Organisation.get(id=1).admins.count() == 1 assert Organisation.get(id=5).users.count() > 0 assert Organisation.get(id=5).admins.count() > 0 assert User.select().where(User.orcid == User.get( email="*****@*****.**").orcid).count() == 3 assert len(User.get(email="*****@*****.**").org_links) == 3 user = User.get(email="*****@*****.**") available_organisations = user.available_organisations assert available_organisations.count() == 10 admin = User.create(email="*****@*****.**", organisation=user.organisation, confirmed=True, first_name="TEST", last_name="ADMIN", roles=Role.ADMIN) ui = UserInvitation.create(email=user.email, invitee=user, inviter=admin, token="TOKEN-123") admin.delete_instance() ui = UserInvitation.get(ui.id) assert ui.inviter_id is None user.delete_instance() assert not UserInvitation.select().where(UserInvitation.id == ui.id).exists() org = Organisation.select().limit(1).first() user = User.select().limit(1).first() ot = OrcidToken.create(user=user, org=org, scope="S1,S2,S3") assert len(ot.scopes) == 3 ot.scopes = ["A", "B", "C", "D"] assert ot.scope == "A,B,C,D"
def test_process_tasks(app, mocker): """Test task hanging.""" send_email = mocker.patch("orcid_hub.utils.send_email") org = Organisation.select().first() Task.insert_many( dict(org=org, updated_at=utils.datetime.utcnow(), filename=tt.name, task_type=tt.value) for tt in TaskType).execute() utils.process_tasks() send_email.assert_not_called() Task.insert_many( dict(org=org, created_by=org.tech_contact, created_at=utils.datetime(2017, 1, 1), updated_at=utils.datetime(2017, 1, 1), filename=tt.name, task_type=tt.value) for tt in TaskType).execute() utils.process_tasks() send_email.assert_called() task_count = Task.select().count() utils.process_tasks() assert Task.select().count() == task_count // 2
def test_process_other_id_records(app, mocker): """Test create or update researcher other id.""" mocker.patch("orcid_hub.utils.send_email", send_mail_mock) mocker.patch( "orcid_api_v3.api.DevelopmentMemberAPIV30Api.create_external_identifierv3", create_or_update_fund_mock) mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record", return_value=get_profile()) org = app.data["org"] u = User.create(email="*****@*****.**", name="TEST USER", roles=Role.RESEARCHER, orcid="12344", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) t = Task.create(org=org, filename="xyz.json", created_by=u, updated_by=u, task_type=TaskType.OTHER_ID) OtherIdRecord.create(task=t, type="grant_number", value="xyz", url="https://xyz.com", relationship="SELF", is_active=True, status="email sent", first_name="Test", last_name="Test", email="*****@*****.**", visibility="PUBLIC", display_index=1) UserInvitation.create(invitee=u, inviter=u, org=org, task=t, email="*****@*****.**", token="xyztoken") OrcidToken.create(user=u, org=org, scopes="/read-limited,/person/update", access_token="Test_token") utils.process_other_id_records() record = OtherIdRecord.get(email="*****@*****.**") assert 12399 == record.put_code assert "12344" == record.orcid
def test_upload_affiliation_with_wrong_country(request_ctx): """Test task loading and processing with failures.""" org = Organisation.get(name="TEST0") super_user = User.get(email="*****@*****.**") with patch("emails.html") as mock_msg, request_ctx("/") as ctx: login_user(super_user) # flake8: noqa with pytest.raises(ModelException): task = Task.load_from_csv( """First name\tLast name\temail address\tOrganisation\tCampus/Department\tCity\tCourse or Job title\tStart date\tEnd date\tStudent/Staff\tCountry FNA\tLBA\[email protected]\tTEST1\tResearch Funding\tWellington\tProgramme Manager - ORCID\t2016-09 19:00:00 PM\t\tStaff\tNO COUNTRY """, filename="TEST.tsv", org=org)
def test_scheduled_tasks(app, mocker): """Test scheduled tasks.""" org = app.data["org"] task = Task.create(org=org, task_type=TaskType.AFFILIATION) rq = app.extensions["rq2"] s = rq.get_scheduler() s.run(burst=True) task = Task.get(task.id) utils.process_tasks.queue() task = Task.get(task.id) assert task.expires_at is not None task.expires_at = utils.datetime(1988, 1, 1) task.save() utils.process_tasks.queue() assert Task.select().where(Task.id == task.id).count() == 0 Organisation.update(webhook_enabled=True, email_notifications_enabled=True).execute() User.update(orcid_updated_at=utils.date.today().replace(day=1) - utils.timedelta(days=1)).execute() send_email = mocker.patch("orcid_hub.utils.send_email") utils.send_orcid_update_summary.queue(org_id=org.id) send_email.assert_called()
def test_sync_profile(app, mocker): """Test sync_profile.""" mocker.patch("orcid_api.MemberAPIV20Api.update_employment", return_value=Mock(status=201, headers={'Location': '12344/XYZ/54321'})) mocker.patch("orcid_api.MemberAPIV20Api.update_education", return_value=Mock(status=201, headers={'Location': '12344/XYZ/12345'})) org = Organisation.create( name="THE ORGANISATION:test_sync_profile", tuakiri_name="THE ORGANISATION:test_sync_profile", confirmed=True, orcid_client_id="APP-5ZVH4JRQ0C27RVH5", orcid_secret="Client Secret", city="CITY", country="COUNTRY", disambiguated_id="ID", disambiguation_source="SOURCE") u = User.create(email="*****@*****.**", name="TEST USER", roles=Role.RESEARCHER, orcid="12344", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) access_token = "ACCESS-TOKEN" t = Task.create(org=org, task_type=TaskType.SYNC) api = MemberAPI(org=org) mocker.patch("orcid_hub.orcid_client.MemberAPI.get_record", lambda *args: None) api.sync_profile(task=t, user=u, access_token=access_token) OrcidToken.create(user=u, org=org, scope="/read-limited,/activities/update") mocker.patch("orcid_hub.orcid_client.MemberAPI.get_record", lambda *args: None) api.sync_profile(task=t, user=u, access_token=access_token) assert Log.select().count() > 0 mocker.patch("orcid_hub.orcid_client.MemberAPI.get_record", return_value=get_profile()) api.sync_profile(task=t, user=u, access_token=access_token) last_log = Log.select().order_by(Log.id.desc()).first() assert "Successfully update" in last_log.message
def test_load_task_from_csv(models): org = Organisation.create(name="TEST0") # flake8: noqa test = Task.load_from_csv( """First name Last name email address Organisation Campus/Department City Course or Job title Start date End date Student/Staff FNA LBA [email protected] TEST1 Research Funding Wellington Programme Manager - ORCID 2016-09 Staff FNA LBA [email protected] TEST1 Research Funding Wellington Programme Manager - Insights and Evaluation 2014 Staff FNA LBA [email protected] TEST0 External Affairs Wellington Senior Evaluation Officer 2011 2014 Staff FNA LBA [email protected] TEST0 Policy and Evaluation Wellington Evaluation Officer 2005 2011 Staff FNA LBA [email protected] TEST0 Marsden Fund Wellington Research Assessor 2001 2004 Staff FNB LNB [email protected] TEST1 Communications and Outreach Wellington Projects and Events Coordinator 2013 Staff FNB LNB [email protected] TEST0 Science and Education Group Wellington School Programmes Manager 2008 2013 Staff FNB LNB TEST_FN TEST_LN <*****@*****.**> TEST0 Science and Education Group Wellington Project Manager 2000 2004 Staff FNB LNB [email protected] TEST0 Science and Education Group Wellington Manager Special Programmes 2004 2008 Staff """, filename="TEST.tsv", org=org) assert test.record_count == 9 assert AffiliationRecord.select().count( ) == test.record_count + 10 # The 10 value is from already inserted entries.
def test_process_task_from_csv_with_failures(request_ctx): """Test task loading and processing with failures.""" org = Organisation.get(name="TEST0") super_user = User.get(email="*****@*****.**") with patch("emails.html") as mock_msg, request_ctx("/") as ctx: login_user(super_user) # flake8: noqa task = Task.load_from_csv( """First name Last name email address Organisation Campus/Department City Course or Job title Start date End date Student/Staff FNA LBA [email protected] TEST1 Research Funding Wellington Programme Manager - ORCID 2016-09 Staff """, filename="TEST.tsv", org=org) AffiliationRecord.update(is_active=True).where( AffiliationRecord.task_id == task.id).execute() mock_msg().send = Mock(side_effect=Exception("FAILED TO SEND EMAIL")) utils.process_affiliation_records(10000) rec = AffiliationRecord.select().where(AffiliationRecord.task_id == task.id).first() assert "FAILED TO SEND EMAIL" in rec.status assert rec.processed_at is not None
def test_send_work_funding_peer_review_invitation(app, mocker): """Test to send user invitation.""" send_email = mocker.patch("orcid_hub.utils.send_email") org = app.data["org"] inviter = User.create(email="*****@*****.**", name="TEST USER", roles=Role.RESEARCHER, orcid=None, confirmed=True, organisation=org) email = "*****@*****.**" u = User.create(email=email, name="TEST USER", roles=Role.RESEARCHER, orcid=None, confirmed=True, organisation=org) UserOrg.create(user=u, org=org) task = Task.create(org=org, task_type=1) fr = FundingRecord.create(task=task, title="xyz", type="Award") FundingInvitee.create(record=fr, email=email, first_name="Alice", last_name="Bob") server_name = app.config.get("SERVER_NAME") app.config["SERVER_NAME"] = "abc.orcidhub.org.nz" utils.send_user_invitation(inviter=inviter, org=org, email=email, name=u.name, user=u, task_id=task.id) app.config["SERVER_NAME"] = server_name send_email.assert_called_once()
def test_create_or_update_peer_review(email_patch, patch, test_db, request_ctx): """Test create or update peer review.""" org = Organisation.create(name="THE ORGANISATION", tuakiri_name="THE ORGANISATION", confirmed=True, orcid_client_id="APP-5ZVH4JRQ0C27RVH5", orcid_secret="Client Secret", city="CITY", country="COUNTRY", disambiguation_org_id="ID", disambiguation_org_source="SOURCE") u = User.create(email="*****@*****.**", name="TEST USER", username="******", roles=Role.RESEARCHER, orcid="12344", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) t = Task.create(id=12, org=org, filename="xyz.json", created_by=u, updated_by=u, task_type=3) pr = PeerReviewRecord.create(task=t, review_group_id="issn:12131", reviewer_role="reviewer", review_url="xyz", review_type="REVIEW", subject_external_id_type="doi", subject_external_id_value="1212", subject_external_id_url="url/SELF", subject_external_id_relationship="SELF", subject_container_name="Journal title", subject_type="JOURNAL_ARTICLE", subject_name_title="name", subject_name_subtitle="subtitle", subject_name_translated_title_lang_code="en", subject_name_translated_title="sdsd", subject_url="url", convening_org_name="THE ORGANISATION", convening_org_city="auckland", convening_org_region="auckland", convening_org_country="nz", convening_org_disambiguated_identifier="123", convening_org_disambiguation_source="1212", is_active=True) PeerReviewInvitee.create(peer_review_record=pr, first_name="Test", email="*****@*****.**", orcid="12344", visibility="PUBLIC") PeerReviewExternalId.create(peer_review_record=pr, type="Test_type", value="122334_different", url="Test", relationship="SELF") UserInvitation.create(invitee=u, inviter=u, org=org, task=t, email="*****@*****.**", token="xyztoken") OrcidToken.create(user=u, org=org, scope="/read-limited,/activities/update", access_token="Test_token") utils.process_peer_review_records() peer_review_invitees = PeerReviewInvitee.get(orcid=12344) assert 12399 == peer_review_invitees.put_code assert "12344" == peer_review_invitees.orcid
def test_create_or_update_work(email_patch, patch, test_db, request_ctx): """Test create or update work.""" org = Organisation.create(name="THE ORGANISATION", tuakiri_name="THE ORGANISATION", confirmed=True, orcid_client_id="APP-5ZVH4JRQ0C27RVH5", orcid_secret="Client Secret", city="CITY", country="COUNTRY", disambiguation_org_id="ID", disambiguation_org_source="SOURCE") u = User.create(email="*****@*****.**", name="TEST USER", username="******", roles=Role.RESEARCHER, orcid="12344", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) t = Task.create(org=org, filename="xyz.json", created_by=u, updated_by=u, task_type=2) wr = WorkRecord.create(task=t, title="Test titile", sub_title="Test titile", translated_title="Test title", translated_title_language_code="Test", journal_title="Test titile", short_description="Test desc", citation_type="Test", citation_value="Test", type="BOOK_CHAPTER", url="Test org", language_code="en", country="Test", org_name="Test_orgname", city="Test city", region="Test", is_active=True) WorkInvitees.create(work_record=wr, first_name="Test", email="*****@*****.**", orcid="12344", visibility="PUBLIC") WorkExternalId.create(work_record=wr, type="Test_type", value="Test_value", url="Test", relationship="SELF") WorkContributor.create(work_record=wr, contributor_sequence="1", orcid="1213", role="LEAD", name="xyz", email="*****@*****.**") UserInvitation.create(invitee=u, inviter=u, org=org, task=t, email="*****@*****.**", token="xyztoken") OrcidToken.create(user=u, org=org, scope="/read-limited,/activities/update", access_token="Test_token") utils.process_work_records() work_invitees = WorkInvitees.get(orcid=12344) assert 12399 == work_invitees.put_code assert "12344" == work_invitees.orcid
def test_create_or_update_funding(email_patch, patch, test_db, request_ctx): """Test create or update funding.""" org = Organisation.create(name="THE ORGANISATION", tuakiri_name="THE ORGANISATION", confirmed=True, orcid_client_id="APP-5ZVH4JRQ0C27RVH5", orcid_secret="Client Secret", city="CITY", country="COUNTRY", disambiguation_org_id="ID", disambiguation_org_source="SOURCE") u = User.create(email="*****@*****.**", name="TEST USER", username="******", roles=Role.RESEARCHER, orcid="123", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) t = Task.create(org=org, filename="xyz.json", created_by=u, updated_by=u, task_type=1) fr = FundingRecord.create(task=t, title="Test titile", translated_title="Test title", translated_title_language_code="Test", type="GRANT", organization_defined_type="Test org", short_description="Test desc", amount="1000", currency="USD", org_name="Test_orgname", city="Test city", region="Test", country="Test", disambiguated_org_identifier="Test_dis", disambiguation_source="Test_source", is_active=True) FundingInvitees.create(funding_record=fr, first_name="Test", email="*****@*****.**", visibility="PUBLIC", orcid="123") ExternalId.create(funding_record=fr, type="Test_type", value="Test_value", url="Test", relationship="SELF") FundingContributor.create(funding_record=fr, orcid="1213", role="LEAD", name="Contributor", email="*****@*****.**") UserInvitation.create(invitee=u, inviter=u, org=org, task=t, email="*****@*****.**", token="xyztoken") OrcidToken.create(user=u, org=org, scope="/read-limited,/activities/update", access_token="Test_token") utils.process_funding_records() funding_invitees = FundingInvitees.get(orcid=12344) assert 12399 == funding_invitees.put_code assert "12344" == funding_invitees.orcid
def test_sync_profile(app, mocker): """Test sync_profile.""" mocker.patch( "orcid_api_v3.api.DevelopmentMemberAPIV30Api.update_employmentv3", return_value=Mock(status=201, headers={'Location': '12344/XYZ/54321'})) mocker.patch( "orcid_api_v3.api.DevelopmentMemberAPIV30Api.update_educationv3", return_value=Mock(status=201, headers={'Location': '12344/XYZ/12345'})) def sync_profile_mock(*args, **kwargs): utils.sync_profile(*args, **kwargs) return Mock(id="test-test-test-test") mocker.patch("orcid_hub.utils.sync_profile.queue", sync_profile_mock) org = Organisation.create( name="THE ORGANISATION:test_sync_profile", tuakiri_name="THE ORGANISATION:test_sync_profile", confirmed=True, orcid_client_id="APP-5ZVH4JRQ0C27RVH5", orcid_secret="Client Secret", city="CITY", country="NZ", disambiguated_id="ID", disambiguation_source="SOURCE") u = User.create(email="*****@*****.**", name="TEST USER", roles=Role.RESEARCHER, orcid="12344", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) utils.sync_profile(task_id=999999) t = Task.create(org=org, task_type=TaskType.SYNC) mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record", lambda *args: None) utils.sync_profile(task_id=t.id, delay=0) resp = get_profile() mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record", lambda *args: resp) utils.sync_profile(task_id=t.id, delay=0) resp["activities-summary"]["educations"]["affiliation-group"] = [] mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record", lambda *args: resp) utils.sync_profile(task_id=t.id, delay=0) mocker.patch("orcid_hub.orcid_client.MemberAPIV3.update_employmentv3", side_effect=Exception("FAILED")) utils.sync_profile(task_id=t.id, delay=0) resp["activities-summary"]["employments"]["affiliation-group"][0][ "summaries"][0]["employment-summary"]["source"] = None resp["activities-summary"]["employments"]["affiliation-group"][0][ "summaries"][0]["employment-summary"]["source"] = None mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record", lambda *args: resp) utils.sync_profile(task_id=t.id, delay=0) org.disambiguated_id = None org.save() utils.sync_profile(task_id=t.id, delay=0) assert Log.select().count() > 0
def test_create_or_update_peer_review(app, mocker): """Test create or update peer review.""" mocker.patch("orcid_hub.utils.send_email", send_mail_mock) mocker.patch( "orcid_api_v3.api.DevelopmentMemberAPIV30Api.create_peer_reviewv3", create_or_update_fund_mock) org = app.data["org"] mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record", return_value=get_profile(org=org)) u = User.create(email="*****@*****.**", name="TEST USER", roles=Role.RESEARCHER, orcid="12344", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) t = Task.create(id=12, org=org, filename="xyz.json", created_by=u, updated_by=u, task_type=TaskType.PEER_REVIEW) pr = PeerReviewRecord.create( task=t, review_group_id="issn:12131", reviewer_role="reviewer", review_url="xyz", review_type="REVIEW", subject_external_id_type="doi", subject_external_id_value="1212", subject_external_id_url="url/SELF", subject_external_id_relationship="SELF", subject_container_name="Journal title", subject_type="JOURNAL_ARTICLE", subject_name_title="name", subject_name_subtitle="subtitle", review_completion_date=PartialDate.create("2003-07-14"), subject_name_translated_title_lang_code="en", subject_name_translated_title="sdsd", subject_url="url", convening_org_name="THE ORGANISATION", convening_org_city="auckland", convening_org_region="auckland", convening_org_country="NZ", convening_org_disambiguated_identifier="123", convening_org_disambiguation_source="1212", is_active=True) PeerReviewInvitee.create(record=pr, first_name="Test", email="*****@*****.**", orcid="12344", visibility="PUBLIC") PeerReviewExternalId.create(record=pr, type="Test_type", value="122334_different", url="Test", relationship="SELF") UserInvitation.create(invitee=u, inviter=u, org=org, task=t, email="*****@*****.**", token="xyztoken") OrcidToken.create(user=u, org=org, scopes="/read-limited,/activities/update", access_token="Test_token") utils.process_peer_review_records() peer_review_invitees = PeerReviewInvitee.get(orcid=12344) assert 12399 == peer_review_invitees.put_code assert "12344" == peer_review_invitees.orcid
def models(testdb): Organisation.insert_many((dict(name="Organisation #%d" % i, tuakiri_name="Organisation #%d" % i, orcid_client_id="client-%d" % i, orcid_secret="secret-%d" % i, confirmed=(i % 2 == 0)) for i in range(10))).execute() User.insert_many( (dict(name="Test User #%d" % i, first_name="Test_%d" % i, last_name="User_%d" % i, email="user%d@org%d.org.nz" % (i, i * 4 % 10), confirmed=(i % 3 != 0), roles=Role.SUPERUSER if i % 42 == 0 else Role.ADMIN if i % 13 == 0 else Role.RESEARCHER) for i in range(60))).execute() User.insert_many((dict(name="Test User with ORCID ID 'ABC-123' #%d" % i, orcid="ABC-123", first_name="Test_%d" % i, last_name="User_%d" % i, email="user_the_same_id_%d@org%d.org.nz" % (i, i), confirmed=True, organisation=(i + 1), roles=Role.RESEARCHER) for i in range(3))).execute() UserOrg.insert_many( dict(user=u.id, org=u.organisation_id) for u in User.select().where(User.orcid == "ABC-123")).execute() UserOrg.insert_many( (dict(is_admin=((u + o) % 23 == 0), user=u, org=o) for (u, o) in product(range(2, 60, 4), range(2, 10)))).execute() UserOrg.insert_many( (dict(is_admin=True, user=43, org=o) for o in range(1, 11))).execute() OrcidToken.insert_many((dict(user=User.get(id=1), org=Organisation.get(id=1), scopes="/read-limited", access_token="Test_%d" % i) for i in range(60))).execute() UserOrgAffiliation.insert_many((dict(user=User.get(id=1), organisation=Organisation.get(id=1), department_name="Test_%d" % i, department_city="Test_%d" % i, role_title="Test_%d" % i, path="Test_%d" % i, put_code="%d" % i) for i in range(30))).execute() Task.insert_many((dict(org=Organisation.get(id=1), created_by=User.get(id=1), updated_by=User.get(id=1), filename="Test_%d" % i, task_type=0) for i in range(30))).execute() AffiliationRecord.insert_many((dict(is_active=False, task=Task.get(id=1), put_code=90, external_id="Test_%d" % i, status="Test_%d" % i, first_name="Test_%d" % i, last_name="Test_%d" % i, email="Test_%d" % i, orcid="123112311231%d" % i, organisation="Test_%d" % i, affiliation_type="Test_%d" % i, role="Test_%d" % i, department="Test_%d" % i, city="Test_%d" % i, state="Test_%d" % i, country="Test_%d" % i, disambiguated_id="Test_%d" % i, disambiguation_source="Test_%d" % i) for i in range(10))).execute() PropertyRecord.insert_many((dict(type="URL", is_active=False, task=Task.get(id=1), put_code=90, status="Test_%d" % i, first_name="Test_%d" % i, last_name="Test_%d" % i, email="Test_%d" % i, orcid="123112311231%d" % i, name="Test_%d" % i, value="Test_%d" % i, visibility="Test_%d" % i, display_index=i) for i in range(10))).execute() PropertyRecord.insert_many((dict(type="NAME", is_active=False, task=Task.get(id=1), put_code=90, status="Test_%d" % i, first_name="Test_%d" % i, last_name="Test_%d" % i, email="Test_%d" % i, orcid="123112311231%d" % i, value="Test_%d" % i, visibility="Test_%d" % i, display_index=i) for i in range(10))).execute() PropertyRecord.insert_many((dict(type="KEYWORD", is_active=False, task=Task.get(id=1), put_code=90, status="Test_%d" % i, first_name="Test_%d" % i, last_name="Test_%d" % i, email="Test_%d" % i, orcid="123112311231%d" % i, value="Test_%d" % i, visibility="Test_%d" % i, display_index=i) for i in range(10))).execute() FundingRecord.insert_many( (dict(task=Task.get(id=1), title="Test_%d" % i, translated_title="Test_%d" % i, translated_title_language_code="Test_%d" % i, type="Test_%d" % i, organization_defined_type="Test_%d" % i, short_description="Test_%d" % i, amount="Test_%d" % i, currency="Test_%d" % i, org_name="Test_%d" % i, city="Test_%d" % i, region="Test_%d" % i, country="Test_%d" % i, disambiguated_id="Test_%d" % i, disambiguation_source="Test_%d" % i, is_active=False, status="Test_%d" % i) for i in range(10))).execute() record = FundingRecord.get() FundingContributor.insert_many((dict(record=record, orcid="123112311231%d" % i, name="Test_%d" % i, role="Test_%d" % i) for i in range(10))).execute() FundingInvitee.insert_many((dict(record=record, orcid="123112311231%d" % i, first_name="Test_%d" % i, last_name="Test_%d" % i, put_code=i, status="Test_%d" % i, identifier="%d" % i, visibility="Test_%d" % i, email="Test_%d" % i) for i in range(10))).execute() ExternalId.insert_many((dict(record=record, type="Test_%d" % i, value="Test_%d" % i, url="Test_%d" % i, relationship="Test_%d" % i) for i in range(10))).execute() task = Task.get() PeerReviewRecord.insert_many( (dict(task=task, review_group_id="issn:1212_%d" % i, reviewer_role="reviewer_%d" % i, review_url="xyz_%d" % i, review_type="REVIEW_%d" % i, subject_external_id_type="doi_%d" % i, subject_external_id_value="1212_%d" % i, subject_external_id_url="url/SELF_%d" % i, subject_external_id_relationship="SELF_%d" % i, subject_container_name="Journal title_%d" % i, subject_type="JOURNAL_ARTICLE_%d" % i, subject_name_title="name_%d" % i, subject_name_subtitle="subtitle_%d" % i, subject_name_translated_title_lang_code="en", subject_name_translated_title="sdsd_%d" % i, subject_url="url_%d" % i, convening_org_name="THE ORGANISATION_%d" % i, convening_org_city="auckland_%d" % i, convening_org_region="auckland_%d" % i, convening_org_country="nz_%d" % i, convening_org_disambiguated_identifier="123_%d" % i, convening_org_disambiguation_source="1212_%d" % i, is_active=False) for i in range(10))).execute() record = PeerReviewRecord.get() PeerReviewExternalId.insert_many((dict(record=record, type="Test1_%d" % i, value="Test1_%d" % i, url="Test1_%d" % i, relationship="Test1_%d" % i) for i in range(10))).execute() PeerReviewInvitee.insert_many((dict(record=record, orcid="1231123112311%d" % i, first_name="Test1_%d" % i, last_name="Test1_%d" % i, put_code=i, status="Test1_%d" % i, identifier="1%d" % i, visibility="PUBLIC", email="Test1_%d" % i) for i in range(10))).execute() WorkRecord.insert_many((dict(task=task, title="Test_%d" % i, subtitle="Test_%d" % i, translated_title="Test_%d" % i, translated_title_language_code="Test_%d" % i, journal_title="Test_%d" % i, short_description="Test_%d" % i, citation_type="Test_%d" % i, citation_value="Test_%d" % i, type="Test_%d" % i, url="Test_%d" % i, language_code="Test_%d" % i, country="Test_%d" % i, is_active=False, status="Test_%d" % i) for i in range(10))).execute() record = WorkRecord.get() WorkContributor.insert_many((dict(record=record, orcid="123112311231%d" % i, name="Test_%d" % i, contributor_sequence="%d" % i, role="Test_%d" % i) for i in range(10))).execute() WorkExternalId.insert_many((dict(record=record, type="Test_%d" % i, value="Test_%d" % i, url="Test_%d" % i, relationship="Test_%d" % i) for i in range(10))).execute() WorkInvitee.insert_many((dict(record=record, orcid="123112311231%d" % i, first_name="Test_%d" % i, last_name="Test_%d" % i, put_code=i, status="Test_%d" % i, identifier="%d" % i, visibility="Test_%d" % i, email="Test_%d" % i) for i in range(10))).execute() yield testdb
def test_funding_api(client): """Test funding API in various formats.""" admin = client.data.get("admin") resp = client.login(admin, follow_redirects=True) resp = client.post( "/load/researcher/funding", data={ "file_": ( BytesIO( """Put Code,Title,Translated Title,Translated Title Language Code,Type,Organization Defined Type,Short Description,Amount,Currency,Start Date,End Date,Org Name,City,Region,Country,Disambiguated Org Identifier,Disambiguation Source,Visibility,ORCID iD,Email,First Name,Last Name,Name,Role,External Id Type,External Id Value,External Id Url,External Id Relationship,Identifier ,This is the project title,,,CONTRACT,Fast-Start,This is the project abstract,300000,NZD,2018,2021,Marsden Fund,Wellington,,NZ,http://dx.doi.org/10.13039/501100009193,FUNDREF,,0000-0002-9207-4933,,,,Associate Professor A Contributor 1,lead,grant_number,XXX1701,,SELF, ,This is the project title,,,CONTRACT,Fast-Start,This is the project abstract,300000,NZD,2018,2021,Marsden Fund,Wellington,,NZ,http://dx.doi.org/10.13039/501100009193,FUNDREF,,,,,,Dr B Contributor 2,co_lead,grant_number,XXX1701,,SELF, ,This is the project title,,,CONTRACT,Fast-Start,This is the project abstract,300000,NZD,2018,2021,Marsden Fund,Wellington,,NZ,http://dx.doi.org/10.13039/501100009193,FUNDREF,,,,,,Dr E Contributor 3,,grant_number,XXX1701,,SELF, ,This is the project title,,,CONTRACT,Fast-Start,This is the project abstract,300000,NZD,2018,2021,Marsden Fund,Wellington,,NZ,http://dx.doi.org/10.13039/501100009193,FUNDREF,,,[email protected],FN,LN,Dr E Contributor 4,,grant_number,XXX1701,,SELF, ,This is another project title,,,CONTRACT,Standard,This is another project abstract,800000,NZD,2018,2021,Marsden Fund,Wellington,,NZ,http://dx.doi.org/10.13039/501100009193,FUNDREF,,,[email protected],,,Associate Professor F Contributor 4,lead,grant_number,XXX1702,,SELF,9999 ,This is another project title,,,CONTRACT,Standard,This is another project abstract,800000,NZD,2018,2021,Marsden Fund,Wellington,,NZ,http://dx.doi.org/10.13039/501100009193,FUNDREF,,,[email protected],John,Doe,,co_lead,grant_number,XXX1702,,SELF,8888 """ .encode() # noqa: E501 ), # noqa: E501 "fundings042.csv", ), }, follow_redirects=True) assert resp.status_code == 200 assert Task.select().count() == 1 # TODO: factor it out resp = client.post( "/oauth/token", content_type="application/x-www-form-urlencoded", data= b"grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET" ) data = json.loads(resp.data) access_token = data["access_token"] resp = client.get("/api/v1.0/tasks?type=FUNDING", headers=dict(authorization=f"Bearer {access_token}")) data = json.loads(resp.data) task_id = int(data[0]["id"]) resp = client.get(f"/api/v1.0/funds/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) data = json.loads(resp.data) assert len(data["records"]) == 2 assert data["filename"] == "fundings042.csv" resp = client.post("/api/v1.0/funds/?filename=fundings333.json", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(data)) assert resp.status_code == 200 assert Task.select().count() == 2 records = data["records"] resp = client.post("/api/v1.0/funds/?filename=fundings444.json", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(records)) assert resp.status_code == 200 assert Task.select().count() == 3 resp = client.post(f"/api/v1.0/funds/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(records)) assert resp.status_code == 200 assert Task.select().count() == 3 resp = client.head(f"/api/v1.0/funds/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert "Last-Modified" in resp.headers assert resp.status_code == 200 resp = client.delete(f"/api/v1.0/funds/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 200 assert Task.select().count() == 2 resp = client.head(f"/api/v1.0/funds/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 404
def test_affiliation_api(client): """Test affiliation API in various formats.""" resp = client.post( "/oauth/token", content_type="application/x-www-form-urlencoded", data= b"grant_type=client_credentials&client_id=TEST0-ID&client_secret=TEST0-SECRET" ) data = json.loads(resp.data) access_token = data["access_token"] resp = client.post( "/api/v1.0/affiliations/?filename=TEST42.csv", headers=dict(authorization=f"Bearer {access_token}"), content_type="text/csv", data= b"First Name,Last Name,email,Organisation,Affiliation Type,Role,Department,Start Date," b"End Date,City,State,Country,Disambiguated Id,Disambiguated Source\n" b"Researcher,Par,[email protected],Royal Org1,Staff,Programme Guide - " b"ORCID,Research Funding,2016-09,,Wellington,SATE,NZ,,\n" b"Roshan,Pawar,[email protected],Royal Org1,Staff,AAA,Research " b"Funding,2016-09,,Wellington,SATE,NZ,,\n" b"Roshan,Pawar,[email protected],Royal Org1,Student,BBB,Research " b"Funding,2016-09,,Wellington,SATE,New Zealand,,") data = json.loads(resp.data) assert data["filename"] == "TEST42.csv" assert data["task-type"] == "AFFILIATION" assert len(data["records"]) == 3 task_id = data["id"] resp = client.get("/api/v1.0/tasks", headers=dict(authorization=f"Bearer {access_token}")) tasks = json.loads(resp.data) assert tasks[0]["id"] == task_id task_copy = copy.deepcopy(data) del (task_copy["id"]) task_copy["filename"] = "TASK-COPY.csv" resp = client.post("/api/v1.0/affiliations/", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(task_copy)) assert Task.select().count() == 2 for r in data["records"]: del (r["id"]) r["city"] = "TEST000" resp = client.post(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(data)) data = json.loads(resp.data) assert len(data["records"]) == 3 # should get a new set of records del (data["records"][2]) resp = client.post(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(data)) new_data = json.loads(resp.data) assert len(new_data["records"]) == 2 incorrect_data = copy.deepcopy(data) incorrect_data["records"].insert(0, { "first-name": "TEST000 FN", "last-name": "TEST000 LN", }) resp = client.post(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(incorrect_data)) data = json.loads(resp.data) assert resp.status_code == 422 assert data["error"] == "Validation error." resp = client.get(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) data = json.loads(resp.data) incorrect_data = copy.deepcopy(data) incorrect_data["records"].insert( 0, { "email": "*****@*****.**", "first-name": "TEST000 FN", "last-name": "TEST000 LN", }) resp = client.post(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(incorrect_data)) data = json.loads(resp.data) assert resp.status_code == 422 assert data["error"] == "Validation error." resp = client.get(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) data = json.loads(resp.data) new_data = copy.deepcopy(data) new_data["records"].insert( 0, { "email": "*****@*****.**", "first-name": "TEST000 FN", "last-name": "TEST000 LN", "affiliation-type": "staff", "city": "TEST000" }) resp = client.post(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(new_data)) data = json.loads(resp.data) assert resp.status_code == 200 assert len(data["records"]) == 3 resp = client.put(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(data)) data = json.loads(resp.data) assert resp.status_code == 200 assert len(data["records"]) == 3 resp = client.get(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) data = json.loads(resp.data) new_data = copy.deepcopy(data) for i, r in enumerate(new_data["records"]): new_data["records"][i] = {"id": r["id"], "is-active": True} resp = client.patch(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(new_data)) data = json.loads(resp.data) assert resp.status_code == 200 assert len(data["records"]) == 3 assert all(r["is-active"] for r in data["records"]) assert all(r["city"] == "TEST000" for r in data["records"]) resp = client.head(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert "Last-Modified" in resp.headers resp = client.head("/api/v1.0/affiliations/999999999", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 404 resp = client.get("/api/v1.0/affiliations/999999999", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 404 resp = client.patch("/api/v1.0/affiliations/999999999", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(new_data)) assert resp.status_code == 404 resp = client.delete(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert Task.select().count() == 1 resp = client.delete(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 404 other_user = User.get(email="*****@*****.**") other_task = Task.create(created_by=other_user, org=other_user.organisation, filename="OTHER.csv", task_type=TaskType.AFFILIATION) resp = client.head(f"/api/v1.0/affiliations/{other_task.id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 403 resp = client.get(f"/api/v1.0/affiliations/{other_task.id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 403 resp = client.patch(f"/api/v1.0/affiliations/{other_task.id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(new_data)) assert resp.status_code == 403 resp = client.delete(f"/api/v1.0/affiliations/{other_task.id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 403 resp = client.patch(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=b'') assert resp.status_code == 400 resp = client.post("/api/v1.0/affiliations/?filename=TEST42.csv", headers=dict(authorization=f"Bearer {access_token}", accept="text/yaml"), content_type="text/yaml", data="""task-type: AFFILIATION filename: TEST42.yml records: - affiliation-type: student city: Wellington country: NZ department: Research Funding email: [email protected] first-name: Roshan last-name: Pawar organisation: Royal Org1 role: BBB start-date: 2016-09 - affiliation-type: staff city: Wellington country: NZ department: Research Funding email: [email protected] first-name: Roshan last-name: Pawar organisation: Royal Org1 role: AAA start-date: 2016-09 - affiliation-type: staff city: Wellington country: NZ department: Research Funding email: [email protected] first-name: Researcher is-active: false last-name: Par organisation: Royal Org1 role: Programme Guide - ORCID start-date: 2016-09 """) data = json.loads(resp.data) assert data["filename"] == "TEST42.yml" assert data["task-type"] == "AFFILIATION" assert len(data["records"]) == 3 task_id = data["id"] task = Task.get(id=task_id) assert task.affiliation_records.count() == 3
def test_send_user_invitation(app, mocker): """Test to send user invitation.""" send_email = mocker.patch("orcid_hub.utils.send_email") org = app.data["org"] inviter = User.create(email="*****@*****.**", name="TEST USER", roles=Role.RESEARCHER, orcid=None, confirmed=True, organisation=org) email = "*****@*****.**" first_name = "TEST" last_name = "Test" affiliation_types = {"staff"} u = User.create(email=email, name="TEST USER", roles=Role.RESEARCHER, orcid=None, confirmed=True, organisation=org) UserOrg.create(user=u, org=org) task = Task.create(org=org) mock_smtp = mocker.patch("smtplib.SMTP").return_value instance = mock_smtp.return_value error = { email: (450, "Requested mail action not taken: mailbox unavailable") } instance.utils.send_user_invitation.return_value = error result = instance.utils.send_user_invitation( inviter=inviter, org=org, email=email, first_name=first_name, last_name=last_name, affiliation_types=affiliation_types, task_id=task.id) assert instance.utils.send_user_invitation.called # noqa: E712 assert (450, 'Requested mail action not taken: mailbox unavailable' ) == result[email] send_email = mocker.patch("orcid_hub.utils.send_email") result = utils.send_user_invitation(inviter=inviter.id, org=org.id, email=email, first_name=first_name, last_name=last_name, affiliation_types=affiliation_types, start_date=[1971, 1, 1], end_date=[2018, 5, 29], task_id=task.id) send_email.assert_called_once() assert result == UserInvitation.select().order_by( UserInvitation.id.desc()).first() with pytest.raises(Exception) as excinfo: send_email.reset_mock() dkim_key_path = utils.app.conig["DKIM_KEY_PATH"] app.conig["DKIM_KEY_PATH"] = "/file/not/found.key" result = utils.send_user_invitation( inviter=inviter.id, org=org.id, email=email, first_name=first_name, last_name=last_name, affiliation_types=affiliation_types, start_date=[1971, 1, 1], end_date=[2018, 5, 29], task_id=task.id) send_email.assert_not_called() utils.app.conig["DKIM_KEY_PATH"] = dkim_key_path assert "/file/not/found.key" in str(excinfo.value)
def test_create_or_update_affiliation(app, mocker): """Test create or update affiliation.""" mocker.patch( "orcid_api_v3.api.DevelopmentMemberAPIV30Api.update_employmentv3", return_value=Mock(status=201, headers={'Location': '12344/XYZ/12399'})) mocker.patch( "orcid_api_v3.api.DevelopmentMemberAPIV30Api.create_employmentv3", return_value=Mock(status=201, headers={'Location': '12344/XYZ/12399'})) send_email = mocker.patch("orcid_hub.utils.send_email") capture_event = mocker.patch( "sentry_sdk.transport.HttpTransport.capture_event") org = app.data["org"] u = User.create(email="*****@*****.**", name="TEST USER", roles=Role.RESEARCHER, orcid="123", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) t = Task.create(org=org, filename="xyz.json", created_by=u, updated_by=u, task_type=TaskType.AFFILIATION) OrcidToken.create(user=u, org=org, scopes="/read-limited,/activities/update", access_token="Test_token") UserInvitation.create(invitee=u, inviter=u, org=org, task=t, email="*****@*****.**", token="xyztoken") u = User.create(email="*****@*****.**", name="TEST USER 2", roles=Role.RESEARCHER, confirmed=True, organisation=org) UserOrg.create(user=u, org=org) AffiliationRecord.create(is_active=True, task=t, local_id="Test", first_name="Test", last_name="Test", email="*****@*****.**", orcid="123112311231", organisation="asdasd", affiliation_type="staff", role="Test", department="Test", city="Test", state="Test", country="NZ", disambiguated_id="Test", disambiguation_source="Test") AffiliationRecord.create(is_active=True, task=t, local_id="Test", first_name="Test", last_name="Test", email="*****@*****.**", orcid="123112311231", organisation=org.name, affiliation_type="staff", role="Test", department="Test", city="Test", state="Test", country="NZ") AffiliationRecord.create(is_active=True, task=t, local_id="Test", first_name="Test", last_name="Test", email="*****@*****.**", orcid="123112311231", organisation="ANOTHER ORG", affiliation_type="staff", role="Test", department="Test", city="Test", state="Test", country="NZ", visibility="PUBLIC") AffiliationRecord.create(is_active=True, task=t, local_id="Test#2", first_name="Test2", last_name="Test2", email="*****@*****.**", organisation=org.name, affiliation_type="staff") tasks = (Task.select( Task, AffiliationRecord, User, UserInvitation.id.alias("invitation_id"), OrcidToken).join( AffiliationRecord, on=(Task.id == AffiliationRecord.task_id).alias("record")).join( User, JOIN.LEFT_OUTER, on=((User.email == AffiliationRecord.email) | (User.orcid == AffiliationRecord.orcid))).join( Organisation, JOIN.LEFT_OUTER, on=(Organisation.id == Task.org_id)).join( UserInvitation, JOIN.LEFT_OUTER, on=((UserInvitation.email == AffiliationRecord.email) & (UserInvitation.task_id == Task.id))). join(OrcidToken, JOIN.LEFT_OUTER, on=((OrcidToken.user_id == User.id) & (OrcidToken.org_id == Organisation.id) & (OrcidToken.scopes.contains("/activities/update"))))) app.config["SERVER_NAME"] = "orcidhub" for (task_id, org_id, user), tasks_by_user in groupby( tasks, lambda t: ( t.id, t.org_id, t.record.user, )): with patch("orcid_hub.orcid_client.MemberAPIV3.get_record", return_value=get_profile() if user.orcid else None) as get_record: utils.create_or_update_affiliations(user=user, org_id=org_id, records=tasks_by_user) get_record.assert_any_call() affiliation_record = AffiliationRecord.select().order_by( AffiliationRecord.id).limit(1).first() assert 12399 == affiliation_record.put_code assert "12344" == affiliation_record.orcid assert ("Employment record was updated" in affiliation_record.status or "Employment record was created" in affiliation_record.status) capture_event.assert_called() send_email.assert_called_once()
def test_create_or_update_funding(app, mocker): """Test create or update funding.""" mocker.patch("orcid_hub.utils.send_email", send_mail_mock) mocker.patch( "orcid_api_v3.api.DevelopmentMemberAPIV30Api.create_fundingv3", create_or_update_fund_mock) org = app.data["org"] mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record", return_value=get_profile(org=org)) u = User.create(email="*****@*****.**", name="TEST USER", roles=Role.RESEARCHER, orcid="123", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) t = Task.create(org=org, filename="xyz.json", created_by=u, updated_by=u, task_type=TaskType.FUNDING) fr = FundingRecord.create(task=t, title="Test titile", translated_title="Test title", translated_title_language_code="hi", type="GRANT", organization_defined_type="Test org", short_description="Test desc", amount="1000", currency="USD", org_name="Test_orgname", city="Test city", region="Test", url="url", start_date=PartialDate.create("2003-07-14"), end_date=PartialDate.create("2004-07-14"), country="NZ", disambiguated_id="Test_dis", disambiguation_source="Test_source", is_active=True) FundingInvitee.create(record=fr, first_name="Test", email="*****@*****.**", visibility="PUBLIC", orcid="123") ExternalId.create(record=fr, type="Test_type", value="Test_value", url="Test", relationship="SELF") FundingContributor.create(record=fr, orcid="1213", role="LEAD", name="Contributor", email="*****@*****.**") UserInvitation.create(invitee=u, inviter=u, org=org, task=t, email="*****@*****.**", token="xyztoken") OrcidToken.create(user=u, org=org, scopes="/read-limited,/activities/update", access_token="Test_token") utils.process_funding_records() funding_invitees = FundingInvitee.get(orcid="12344") assert 12399 == funding_invitees.put_code assert "12344" == funding_invitees.orcid
def test_create_or_update_property_record(app, mocker): """Test create or update researcher keyword, researcher url, other name and country""" mocker.patch("orcid_hub.utils.send_email", send_mail_mock) mocker.patch( "orcid_api_v3.api.DevelopmentMemberAPIV30Api.create_keywordv3", create_or_update_fund_mock) mocker.patch( "orcid_api_v3.api.DevelopmentMemberAPIV30Api.create_researcher_urlv3", create_or_update_fund_mock) mocker.patch( "orcid_api_v3.api.DevelopmentMemberAPIV30Api.create_other_namev3", create_or_update_fund_mock) mocker.patch( "orcid_api_v3.api.DevelopmentMemberAPIV30Api.create_addressv3", create_or_update_fund_mock) mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record", return_value=get_profile()) org = app.data["org"] u = User.create(email="*****@*****.**", name="TEST USER", roles=Role.RESEARCHER, orcid="12344", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) OrcidToken.create(user=u, org=org, scopes="/read-limited,/person/update", access_token="Test_token") t = Task.create(id=12, org=org, filename="xyz.json", created_by=u, updated_by=u, task_type=TaskType.PROPERTY) PropertyRecord.create(task=t, type="KEYWORD", is_active=True, status="email sent", first_name="Test", last_name="Test", email="*****@*****.**", visibility="PUBLIC", value="dummy name", display_index=1) PropertyRecord.create(task=t, type="COUNTRY", is_active=True, status="email sent", first_name="Test", last_name="Test", email="*****@*****.**", visibility="PUBLIC", value="IN", display_index=1) PropertyRecord.create(task=t, type="URL", is_active=True, status="email sent", first_name="Test", last_name="Test", email="*****@*****.**", visibility="PUBLIC", name="url name", value="https://www.xyz.com", display_index=1) PropertyRecord.create(task=t, type="NAME", is_active=True, status="email sent", first_name="Test", last_name="Test", email="*****@*****.**", visibility="PUBLIC", value="dummy name", display_index=1) UserInvitation.create(invitee=u, inviter=u, org=org, task=t, email="*****@*****.**", token="xyztoken") utils.process_property_records() keyword_record = PropertyRecord.get(email="*****@*****.**", type="KEYWORD") assert 12399 == keyword_record.put_code assert "12344" == keyword_record.orcid address_record = PropertyRecord.get(email="*****@*****.**", type="COUNTRY") assert 12399 == address_record.put_code assert "12344" == address_record.orcid url_record = PropertyRecord.get(email="*****@*****.**", type="URL") assert 12399 == url_record.put_code assert "12344" == url_record.orcid other_name_record = PropertyRecord.get(email="*****@*****.**", type="NAME") assert 12399 == other_name_record.put_code assert "12344" == other_name_record.orcid
def test_create_or_update_affiliation(patch, test_db, request_ctx): """Test create or update affiliation.""" org = Organisation.create(name="THE ORGANISATION", tuakiri_name="THE ORGANISATION", confirmed=True, orcid_client_id="APP-5ZVH4JRQ0C27RVH5", orcid_secret="Client Secret", city="CITY", country="COUNTRY", disambiguation_org_id="ID", disambiguation_org_source="SOURCE") u = User.create(email="*****@*****.**", name="TEST USER", username="******", roles=Role.RESEARCHER, orcid="123", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) t = Task.create(org=org, filename="xyz.json", created_by=u, updated_by=u, task_type=0) AffiliationRecord.create(is_active=True, task=t, external_id="Test", first_name="Test", last_name="Test", email="*****@*****.**", orcid="123112311231", organisation="asdasd", affiliation_type="staff", role="Test", department="Test", city="Test", state="Test", country="Test", disambiguated_id="Test", disambiguation_source="Test") UserInvitation.create(invitee=u, inviter=u, org=org, task=t, email="*****@*****.**", token="xyztoken") OrcidToken.create(user=u, org=org, scope="/read-limited,/activities/update", access_token="Test_token") tasks = (Task.select( Task, AffiliationRecord, User, UserInvitation.id.alias("invitation_id"), OrcidToken ).where( AffiliationRecord.processed_at.is_null(), AffiliationRecord.is_active, ((User.id.is_null(False) & User.orcid.is_null(False) & OrcidToken.id.is_null(False)) | ((User.id.is_null() | User.orcid.is_null() | OrcidToken.id.is_null()) & UserInvitation.id.is_null() & (AffiliationRecord.status.is_null() | AffiliationRecord.status.contains("sent").__invert__())))).join( AffiliationRecord, on=(Task.id == AffiliationRecord.task_id)).join( User, JOIN.LEFT_OUTER, on=((User.email == AffiliationRecord.email) | (User.orcid == AffiliationRecord.orcid))).join( Organisation, JOIN.LEFT_OUTER, on=(Organisation.id == Task.org_id)). join(UserInvitation, JOIN.LEFT_OUTER, on=((UserInvitation.email == AffiliationRecord.email) & (UserInvitation.task_id == Task.id))).join( OrcidToken, JOIN.LEFT_OUTER, on=((OrcidToken.user_id == User.id) & (OrcidToken.org_id == Organisation.id) & (OrcidToken.scope.contains("/activities/update")) )).limit(20)) for (task_id, org_id, user), tasks_by_user in groupby( tasks, lambda t: ( t.id, t.org_id, t.affiliation_record.user, )): utils.create_or_update_affiliations(user=user, org_id=org_id, records=tasks_by_user) affiliation_record = AffiliationRecord.get(task=t) assert 12399 == affiliation_record.put_code assert "12344" == affiliation_record.orcid assert "Employment record was updated" in affiliation_record.status
def test_affiliation_api(client, mocker): """Test affiliation API in various formats.""" exception = mocker.patch.object(client.application.logger, "exception") capture_event = mocker.patch( "sentry_sdk.transport.HttpTransport.capture_event") resp = client.post( "/oauth/token", content_type="application/x-www-form-urlencoded", data= b"grant_type=client_credentials&client_id=TEST0-ID&client_secret=TEST0-SECRET" ) data = json.loads(resp.data) access_token = data["access_token"] resp = client.post( "/api/v1.0/affiliations/?filename=TEST42.csv", headers=dict(authorization=f"Bearer {access_token}"), content_type="text/csv", data= b"First Name,Last Name,email,Organisation,Affiliation Type,Role,Department,Start Date," b"End Date,City,State,Country,Disambiguated Id,Disambiguated Source\n" b"Researcher,Par,[email protected],Royal Org1,Staff,Programme Guide - " b"ORCID,Research Funding,2016-09,,Wellington,SATE,NZ,,\n" b"Roshan,Pawar,[email protected],Royal Org1,Staff,AAA,Research " b"Funding,2016-09,,Wellington,SATE,NZ,,\n" b"Roshan,Pawar,[email protected],Royal Org1,Student,BBB,Research " b"Funding,2016-09,,Wellington,SATE,New Zealand,,") data = json.loads(resp.data) assert data["filename"] == "TEST42.csv" assert data["task-type"] == "AFFILIATION" assert len(data["records"]) == 3 task_id = data["id"] resp = client.get("/api/v1.0/tasks", headers=dict(authorization=f"Bearer {access_token}")) tasks = json.loads(resp.data) assert tasks[0]["id"] == task_id resp = client.get("/api/v1.0/tasks?type=AFFILIATION", headers=dict(authorization=f"Bearer {access_token}")) tasks = json.loads(resp.data) assert tasks[0]["id"] == task_id resp = client.get("/api/v1.0/tasks?type=AFFILIATION&page=1&page_size=20", headers=dict(authorization=f"Bearer {access_token}")) tasks = json.loads(resp.data) assert tasks[0]["id"] == task_id task_copy = copy.deepcopy(data) del (task_copy["id"]) task_copy["filename"] = "TASK-COPY.csv" resp = client.post("/api/v1.0/affiliations/", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(task_copy)) assert Task.select().count() == 2 for r in data["records"]: del (r["id"]) r["city"] = "TEST000" resp = client.post(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(data)) data = json.loads(resp.data) assert len(resp.json["records"]) == 3 # should get a new set of records del (data["records"][2]) resp = client.post(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(data)) assert len(resp.json["records"]) == 2 incorrect_data = copy.deepcopy(data) incorrect_data["records"].insert(0, { "first-name": "TEST000 FN", "last-name": "TEST000 LN", }) resp = client.post(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(incorrect_data)) assert resp.status_code == 422 assert resp.json["error"] == "Validation error." resp = client.get(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) incorrect_data = copy.deepcopy(resp.json) incorrect_data["records"].insert( 0, { "email": "*****@*****.**", "first-name": "TEST000 FN", "last-name": "TEST000 LN", }) resp = client.post(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(incorrect_data)) assert resp.status_code == 422 assert resp.json["error"] == "Validation error." resp = client.get(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) new_data = copy.deepcopy(resp.json) new_data["records"].insert( 0, { "email": "*****@*****.**", "first-name": "TEST000 FN", "last-name": "TEST000 LN", "affiliation-type": "staff", "city": "TEST000" }) resp = client.post(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(new_data)) data = json.loads(resp.data) assert resp.status_code == 200 assert len(data["records"]) == 3 resp = client.put(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(data)) data = json.loads(resp.data) assert resp.status_code == 200 assert len(resp.json["records"]) == 3 resp = client.get(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) new_data = copy.deepcopy(resp.json) for i, r in enumerate(new_data["records"]): new_data["records"][i] = {"id": r["id"], "is-active": True} resp = client.patch(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(new_data)) assert resp.status_code == 200 assert len(resp.json["records"]) == 3 assert all(r["is-active"] for r in resp.json["records"]) assert all(r["city"] == "TEST000" for r in resp.json["records"]) resp = client.head(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert "Last-Modified" in resp.headers resp = client.head("/api/v1.0/affiliations/999999999", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 404 resp = client.get("/api/v1.0/affiliations/999999999", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 404 resp = client.patch("/api/v1.0/affiliations/999999999", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(new_data)) assert resp.status_code == 404 with patch.object(Task, "get", side_effect=Exception("ERROR")): resp = client.delete( f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 400 assert resp.json == { "error": "Unhandled exception occurred.", "exception": "ERROR" } resp = client.delete(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert Task.select().count() == 1 resp = client.delete(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 404 other_user = User.get(email="*****@*****.**") other_task = Task.create(created_by=other_user, org=other_user.organisation, filename="OTHER.csv", task_type=TaskType.AFFILIATION) resp = client.head(f"/api/v1.0/affiliations/{other_task.id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 403 resp = client.get(f"/api/v1.0/affiliations/{other_task.id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 403 resp = client.patch(f"/api/v1.0/affiliations/{other_task.id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(new_data)) assert resp.status_code == 403 resp = client.delete(f"/api/v1.0/affiliations/{other_task.id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 403 resp = client.patch(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=b'') assert resp.status_code == 400 resp = client.post("/api/v1.0/affiliations/?filename=TEST42.csv", headers=dict(authorization=f"Bearer {access_token}", accept="text/yaml"), content_type="text/yaml", data="""task-type: AFFILIATION filename: TEST42.yml records: - affiliation-type: student city: Wellington country: NZ department: Research Funding email: [email protected] first-name: Roshan last-name: Pawar organisation: Royal Org1 role: BBB start-date: 2016-09 - affiliation-type: staff city: Wellington country: NZ department: Research Funding email: [email protected] first-name: Roshan last-name: Pawar organisation: Royal Org1 role: AAA start-date: 2016-09 - affiliation-type: staff city: Wellington country: NZ department: Research Funding email: [email protected] first-name: Researcher is-active: false last-name: Par organisation: Royal Org1 role: Programme Guide - ORCID start-date: 2016-09 """) assert resp.json["filename"] == "TEST42.yml" assert resp.json["task-type"] == "AFFILIATION" assert len(resp.json["records"]) == 3 task_id = resp.json["id"] task = Task.get(id=task_id) assert task.affiliation_records.count() == 3 resp = client.put(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}", accept="text/yaml"), content_type="text/yaml", data="""task-type: AFFILIATION filename: TEST42.yml records: - affiliation-type: student id: 9999999999 city: Wellington country: NZ department: Research Funding email: [email protected] first-name: Roshan last-name: Pawar organisation: Royal Org1 role: BBB start-date: 2016-09 """) assert resp.status_code == 400 assert resp.json["error"] == "Unhandled exception occurred." assert "Instance matching query does not exist" in resp.json["exception"] with patch.object(AffiliationRecord, "get", side_effect=Exception("ERROR")): resp = client.put(f"/api/v1.0/affiliations/{task_id}", headers=dict(authorization=f"Bearer {access_token}", accept="text/yaml"), content_type="text/yaml", data="""task-type: AFFILIATION filename: TEST42.yml records: - affiliation-type: student id: 9999999999 city: Wellington country: NZ department: Research Funding email: [email protected] first-name: Roshan last-name: Pawar organisation: Royal Org1 role: BBB start-date: 2016-09 """) assert resp.status_code == 400 assert resp.json == { "error": "Unhandled exception occurred.", "exception": "ERROR" } resp = client.post(f"/api/v1.0/affiliations/?filename=TEST42.csv", headers=dict(authorization=f"Bearer {access_token}", accept="text/yaml"), content_type="text/yaml", data="""task-type: INCORRECT filename: TEST42.yml records: - affiliation-type: student id: 9999999999 """) assert resp.status_code == 422 assert resp.json["error"] == "Validation error." assert "INCORRECT" in resp.json["message"] resp = client.post("/api/v1.0/affiliations/?filename=TEST_ERROR.csv", headers=dict(authorization=f"Bearer {access_token}", accept="text/yaml"), content_type="text/yaml", data="""task-type: AFFILIATION filename: TEST_ERROR.yml records: - affiliation-type: student something fishy is going here... """) assert resp.status_code == 415 assert resp.json[ "error"] == "Invalid request format. Only JSON, CSV, or TSV are acceptable." assert "something fishy is going here..." in resp.json["message"] exception.assert_called() capture_event.assert_called()
def test_process_tasks(request_ctx): """Test expiration data setting and deletion of the exprired tasks.""" org = Organisation.get(name="TEST0") super_user = User.get(email="*****@*****.**") with patch("orcid_hub.utils.send_email") as send_email, request_ctx("/") as ctx: login_user(super_user) # flake8: noqa task = Task.load_from_csv( """First name Last name email address Organisation Campus/Department City Course or Job title\tStart date End date Student/Staff\tCountry FNA LBA [email protected] TEST1 Research Funding Wellington Programme Manager - ORCID 2016-09 Staff\tNew Zealand """, filename="TEST_TASK.tsv", org=org) Task.update(created_at=datetime(1999, 1, 1), updated_at=datetime(1999, 1, 1)).execute() utils.process_tasks() assert Task.select().count() == 1 assert not Task.select().where(Task.expires_at.is_null()).exists() send_email.assert_called_once() task = Task.select().first() args, kwargs = send_email.call_args assert "email/task_expiration.html" in args assert kwargs["error_count"] == 0 hostname = ctx.request.host assert kwargs["export_url"] == ( f"https://{hostname}/admin/affiliationrecord/export/csv/?task_id={task.id}") assert kwargs["recipient"] == ( super_user.name, super_user.email, ) assert kwargs["subject"] == "Batch process task is about to expire" assert kwargs["task"] == task # After the second go everything should be deleted utils.process_tasks() assert Task.select().count() == 0 # Funding processing task: task = Task.create( created_at=datetime(1999, 1, 1), org=org, filename="FUNDING.json", created_by=super_user, updated_by=super_user, task_type=TaskType.FUNDING.value) Task.update(updated_at=datetime(1999, 1, 1)).execute() assert Task.select().where(Task.expires_at.is_null()).count() == 1 utils.process_tasks() assert Task.select().count() == 1 assert Task.select().where(Task.expires_at.is_null()).count() == 0 utils.process_tasks() assert Task.select().count() == 0 args, kwargs = send_email.call_args assert "email/task_expiration.html" in args assert kwargs["error_count"] == 0 hostname = ctx.request.host assert kwargs["export_url"] == ( f"https://{hostname}/admin/fundingrecord/export/csv/?task_id={task.id}") assert kwargs["recipient"] == ( super_user.name, super_user.email, ) assert kwargs["subject"] == "Batch process task is about to expire" assert kwargs["task"] == task # Incorrect task type: task = Task.create( created_at=datetime(1999, 1, 1), org=org, filename="ERROR.err", created_by=super_user, updated_by=super_user, task_type=-12345) Task.update(updated_at=datetime(1999, 1, 1)).execute() with pytest.raises(Exception, message="Unexpeced task type: -12345 (ERROR.err)."): utils.process_tasks() task.delete().execute() # Cover case with an exterenal SP: with patch("orcid_hub.utils.EXTERNAL_SP", "SOME.EXTERNAL.SP"): Task.create( created_at=datetime(1999, 1, 1), org=org, filename="FILE.file", created_by=super_user, updated_by=super_user) Task.update(updated_at=datetime(1999, 1, 1)).execute() assert Task.select().count() == 1 utils.process_tasks() utils.process_tasks() assert Task.select().count() == 0
def test_peer_review_api(client): """Test peer review API in various formats.""" admin = client.data.get("admin") resp = client.login(admin, follow_redirects=True) resp = client.post("/load/researcher/peer_review", data={ "file_": (open( os.path.join(os.path.dirname(__file__), "data", "example_peer_reviews.json"), "rb"), "peer-reviews042.json"), }, follow_redirects=True) assert resp.status_code == 200 assert Task.select().count() == 1 access_token = client.get_access_token() resp = client.get("/api/v1.0/tasks?type=PEER_REVIEW", headers=dict(authorization=f"Bearer {access_token}")) data = json.loads(resp.data) task_id = int(data[0]["id"]) resp = client.get(f"/api/v1.0/peer-reviews/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) data = json.loads(resp.data) assert len(data["records"]) == 1 assert data["filename"] == "peer-reviews042.json" del (data["id"]) resp = client.post("/api/v1.0/peer-reviews/?filename=peer_reviews333.json", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(data)) assert resp.status_code == 200 assert Task.select().count() == 2 records = data["records"] resp = client.post("/api/v1.0/peer-reviews/?filename=peer_reviews444.json", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(records)) assert resp.status_code == 200 assert Task.select().count() == 3 resp = client.post("/api/v1.0/peer-reviews", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(records)) assert resp.status_code == 200 assert Task.select().count() == 4 resp = client.post(f"/api/v1.0/peer-reviews/{task_id}", headers=dict(authorization=f"Bearer {access_token}"), content_type="application/json", data=json.dumps(records)) assert resp.status_code == 200 assert Task.select().count() == 4 resp = client.head(f"/api/v1.0/peer-reviews/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert "Last-Modified" in resp.headers assert resp.status_code == 200 resp = client.delete(f"/api/v1.0/peer-reviews/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 200 assert Task.select().count() == 3 resp = client.head(f"/api/v1.0/peer-reviews/{task_id}", headers=dict(authorization=f"Bearer {access_token}")) assert resp.status_code == 404
def test_send_user_invitation(test_db, request_ctx): """Test to send user invitation.""" org = Organisation.create(name="THE ORGANISATION", tuakiri_name="THE ORGANISATION", confirmed=True, orcid_client_id="CLIENT ID", orcid_secret="Client Secret", city="CITY", country="COUNTRY", disambiguation_org_id="ID", disambiguation_org_source="SOURCE") inviter = User.create(email="*****@*****.**", name="TEST USER", username="******", roles=Role.RESEARCHER, orcid=None, confirmed=True, organisation=org) u = User(email="*****@*****.**", name="TEST USER", username="******", roles=Role.RESEARCHER, orcid=None, confirmed=True, organisation=org) u.save() user_org = UserOrg(user=u, org=org) user_org.save() task = Task(id=123, org=org) task.save() email = "*****@*****.**" first_name = "TEST" last_name = "Test" affiliation_types = {"staff"} with patch("smtplib.SMTP") as mock_smtp, request_ctx("/") as ctxx: instance = mock_smtp.return_value error = { email: (450, "Requested mail action not taken: mailbox unavailable") } instance.utils.send_user_invitation.return_value = error result = instance.utils.send_user_invitation( inviter=inviter, org=org, email=email, first_name=first_name, last_name=last_name, affiliation_types=affiliation_types, task_id=task.id) rv = ctxx.app.full_dispatch_request() assert rv.status_code == 200 assert instance.utils.send_user_invitation.called # noqa: E712 assert (450, 'Requested mail action not taken: mailbox unavailable' ) == result[email] with patch("orcid_hub.utils.send_email") as send_email: result = utils.send_user_invitation( inviter=inviter.id, org=org.id, email=email, first_name=first_name, last_name=last_name, affiliation_types=affiliation_types, start_date=[1971, 1, 1], end_date=[2018, 5, 29], task_id=task.id) send_email.assert_called_once() assert result == UserInvitation.select().order_by( UserInvitation.id.desc()).first().id
def test_Task_count(test_models): assert Task.select().count() == 30
def test_create_or_update_work(app, mocker): """Test create or update work.""" mocker.patch("orcid_hub.utils.send_email", send_mail_mock) mocker.patch("orcid_api_v3.api.DevelopmentMemberAPIV30Api.create_workv3", create_or_update_fund_mock) org = app.data["org"] mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record", return_value=get_profile(org=org)) u = User.create(email="*****@*****.**", name="TEST USER", roles=Role.RESEARCHER, orcid="12344", confirmed=True, organisation=org) UserOrg.create(user=u, org=org) t = Task.create(org=org, filename="xyz.json", created_by=u, updated_by=u, task_type=TaskType.WORK) wr = WorkRecord.create(task=t, title="Test titile", subtitle="Test titile", translated_title="Test title", translated_title_language_code="hi", journal_title="Test titile", short_description="Test desc", citation_type="bibtex", citation_value="Test", type="BOOK_CHAPTER", publication_date=PartialDate.create("2003-07-14"), url="Test org", language_code="en", country="NZ", org_name="Test_orgname", city="Test city", region="Test", is_active=True) WorkInvitee.create(record=wr, first_name="Test", email="*****@*****.**", orcid="12344", visibility="PUBLIC") WorkExternalId.create(record=wr, type="Test_type", value="Test_value", url="Test", relationship="SELF") WorkContributor.create(record=wr, contributor_sequence="first", orcid="1213", role="author", name="xyz", email="*****@*****.**") UserInvitation.create(invitee=u, inviter=u, org=org, task=t, email="*****@*****.**", token="xyztoken") OrcidToken.create(user=u, org=org, scopes="/read-limited,/activities/update", access_token="Test_token") utils.process_work_records() invitee = WorkInvitee.get(orcid="12344") assert 12399 == invitee.put_code assert "12344" == invitee.orcid