Exemple #1
0
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()
Exemple #2
0
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
Exemple #3
0
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
Exemple #6
0
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.
Exemple #10
0
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()
Exemple #12
0
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
Exemple #13
0
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
Exemple #14
0
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
Exemple #19
0
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
Exemple #24
0
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()
Exemple #26
0
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
Exemple #28
0
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
Exemple #29
0
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