Пример #1
0
def test_db_api(app_req_ctx):
    """Test DB API."""
    with app_req_ctx("/data/api/v0.1/organisations/",
                     headers=dict(authorization="Bearer TEST")) as ctx:
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 200
        data = json.loads(rv.data)
        assert "objects" in data
        assert len(data["objects"]) == 4

    with app_req_ctx("/data/api/v0.1/tasks/",
                     headers=dict(authorization="Bearer TEST")) as ctx:
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 200
        data = json.loads(rv.data)
        assert "objects" in data
        assert len(data["objects"]) == 0

    org = Organisation.get(id=1)
    with app_req_ctx(f"/data/api/v0.1/organisations/{org.id}",
                     headers=dict(authorization="Bearer TEST")) as ctx:
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 200
        data = json.loads(rv.data)
        assert data["name"] == org.name
        assert data["tuakiri_name"] == org.tuakiri_name

    org = Organisation.get(id=2)
    with app_req_ctx(f"/data/api/v0.1/organisations/{org.id}",
                     headers=dict(authorization="Bearer TEST")) as ctx:
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 200
        data = json.loads(rv.data)
        assert data["name"] == org.name
        assert data["tuakiri_name"] == org.tuakiri_name
Пример #2
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"
Пример #3
0
def test_user_org_link(test_models):
    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 len(
        User.get(email="*****@*****.**").linked_accounts) == 3

    user = User.get(email="*****@*****.**")
    available_organisations = user.available_organisations
    assert available_organisations.count() == 10
Пример #4
0
def test_orcid_login(client):
    """Test login from orcid."""
    org = Organisation.get(name="THE ORGANISATION")
    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    roles=Role.TECHNICAL,
                    orcid="123",
                    confirmed=True,
                    organisation=org)
    user_org = UserOrg.create(user=u, org=org, is_admin=True)

    resp = client.get("/orcid/login/NOT-EXISTTING", follow_redirects=True)
    assert resp.status_code == 200
    assert b"Failed to login via ORCID using token NOT-EXISTTING" in resp.data

    token = "TOKEN-1234567"
    ui = UserInvitation.create(org=org, invitee=u, email=u.email, token=token)
    resp = client.get(f"/orcid/login/{token}")
    assert resp.status_code == 200
    orcid_authorize = OrcidAuthorizeCall.get(method="GET")
    assert "&email=test123_test_orcid_login%40test.test.net" in orcid_authorize.url
    ui.created_at -= timedelta(days=100)
    ui.save()
    resp = client.get(f"/orcid/login/{token}")
    assert resp.status_code == 302
    url = urlparse(resp.location)
    assert url.path == '/'
    # Testing the expired token flow for researcher
    user_org.is_admin = False
    user_org.save()
    resp = client.get(f"/orcid/login/{token}")
    assert resp.status_code == 302
    url = urlparse(resp.location)
    assert url.path == '/'
Пример #5
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()
Пример #6
0
def test_link_already_affiliated(request_ctx):
    """Test a user affiliation initialization if the uerer is already affilated."""
    with request_ctx("/link") as ctx:
        org = Organisation.get(name="THE ORGANISATION")
        test_user = User(
            email="*****@*****.**",
            name="TEST USER",
            organisation=org,
            orcid="ABC123",
            confirmed=True)
        test_user.save()
        orcidtoken = OrcidToken(
            user=test_user, org=org, scopes="/read-limited", access_token="ABC1234")
        orcidtoken_write = OrcidToken(
            user=test_user,
            org=org,
            scopes="/read-limited,/activities/update",
            access_token="ABC234")
        orcidtoken.save()
        orcidtoken_write.save()
        login_user(test_user, remember=True)
        uo = UserOrg(user=test_user, org=org)
        uo.save()

        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 302, "If the user is already affiliated, the user should be redirected ..."
        assert "profile" in rv.location, "redirection to 'profile' showing the ORCID"
Пример #7
0
def test_link_orcid_auth_callback(name, mocker, client):
    """Test ORCID callback - the user authorized the organisation access to the ORCID profile."""
    mocker.patch("requests_oauthlib.OAuth2Session.fetch_token", lambda self, *args, **kwargs: dict(
        name="NEW TEST",
        access_token="ABC123",
        orcid="ABC-123-456-789",
        scope=["/read-limited"],
        expires_in="1212",
        refresh_token="ABC1235"))

    org = Organisation.get(name="THE ORGANISATION")
    test_user = User.create(
        name=name,
        email="*****@*****.**",
        organisation=org,
        orcid="ABC123",
        confirmed=True)
    UserOrg.create(user=test_user, org=org, affiliations=Affiliation.NONE)
    client.login(test_user)
    User.update(name=name).execute()
    resp = client.get("/link")
    state = session['oauth_state']
    resp = client.get(f"/auth?state={state}")
    assert resp.status_code == 302, "If the user is already affiliated, the user should be redirected ..."
    assert "profile" in resp.location, "redirection to 'profile' showing the ORCID"

    u = User.get(id=test_user.id)
    orcidtoken = OrcidToken.get(user=u)
    assert u.orcid == "ABC-123-456-789"
    assert orcidtoken.access_token == "ABC123"
    if name:
        assert u.name == name, "The user name should be changed"
    else:
        assert u.name == "NEW TEST", "the user name should be set from record coming from ORCID"
Пример #8
0
def test_profile(client):
    """Test an affilated user profile and ORCID data retrieval and a user profile that doesn't hava an ORCID."""
    org = Organisation.get(name="THE ORGANISATION")
    test_user = User.create(email="*****@*****.**",
                            organisation=org,
                            orcid="ABC123",
                            confirmed=True)
    OrcidToken.create(user=test_user,
                      org=org,
                      scope="/read-limited,/activities/update",
                      access_token="ABC1234")
    resp = client.login(test_user, follow_redirects=True)
    resp = client.get("/profile", follow_redirects=True)

    assert resp.status_code == 200
    assert b"ABC123" in resp.data
    client.logout()

    # Test a user profile that doesn't hava an ORCID.
    user = User.select().where(User.organisation == org,
                               User.orcid.is_null()).first()
    resp = client.login(user, follow_redirects=True)
    resp = client.get("/profile")
    assert resp.status_code == 302
    assert "/link" in resp.location
Пример #9
0
def test_load_resources_from_csv(models):
    org = Organisation.get()
    raw_data = readup_test_data("resources.tsv", "r")
    task = ResourceRecord.load_from_csv(raw_data,
                                        filename="resources.tsv",
                                        org=org)
    assert task
    assert task.records.count() == 2
Пример #10
0
def test_link(request_ctx):
    """Test a user affiliation initialization."""
    with request_ctx("/link") as ctx:
        org = Organisation.get(name="THE ORGANISATION")
        test_user = User.create(
            name="TEST USER 123", email="*****@*****.**", organisation=org, confirmed=True)
        login_user(test_user, remember=True)

        rv = ctx.app.full_dispatch_request()
        assert b"<!DOCTYPE html>" in rv.data, "Expected HTML content"
        assert b"TEST USER 123" in rv.data, "Expected to have the user name on the page"
        assert b"*****@*****.**" in rv.data, "Expected to have the user email on the page"
        assert b"URL_123" in rv.data, "Expected to have ORCiD authorization link on the page"
Пример #11
0
def test_link_with_unconfirmed_org(request_ctx):
    """Test a user affiliation initialization if the user Organisation isn't registered yet."""
    with request_ctx("/link") as ctx:
        org = Organisation.get(name="THE ORGANISATION")
        org.confirmed = False
        org.orcid_client_id = "Test Client id"
        org.save()
        test_user = User(
            name="TEST USER", email="*****@*****.**", confirmed=True, organisation=org)
        test_user.save()
        login_user(test_user, remember=True)

        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 302
Пример #12
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)
Пример #13
0
def test_researcher_urls(models):
    org = Organisation.get()
    raw_data0 = readup_test_data("researchurls.json", "r")
    data0 = load_yaml_json("researchurls.json", raw_data0)
    assert isinstance(data0, list) and isinstance(data0[0], NestedDict)
    task0 = PropertyRecord.load_from_json(filename="researchurls000.json",
                                          source=raw_data0,
                                          org=org,
                                          file_property_type="URL")
    data = task0.to_dict(recurse=True)
    raw_data = json.dumps(data, cls=JSONEncoder)
    task = PropertyRecord.load_from_json(filename="researchurls001.json",
                                         source=raw_data,
                                         org=org,
                                         file_property_type="URL")
    assert len(data0) == len(task.to_dict(recurse=True)["records"])
Пример #14
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
Пример #15
0
def test_link_orcid_auth_callback_with_affiliation(name, request_ctx):
    """Test ORCID callback - the user authorized the organisation access to the ORCID profile."""
    with patch("orcid_hub.orcid_client.MemberAPI") as m, patch(
            "orcid_hub.orcid_client.SourceClientId"), request_ctx(
                "/auth?state=xyz") as ctx:
        org = Organisation.get(name="THE ORGANISATION")
        test_user = User.create(name=name,
                                email="*****@*****.**",
                                organisation=org,
                                orcid="ABC123",
                                confirmed=True)

        UserOrg.create(user=test_user,
                       org=org,
                       affiliations=Affiliation.EMP | Affiliation.EDU)

        login_user(test_user, remember=True)
        session['oauth_state'] = "xyz"
        api_mock = m.return_value
        ctx.app.full_dispatch_request()
        assert test_user.orcid == "ABC-123-456-789"

        orcid_token = OrcidToken.get(user=test_user, org=org)
        assert orcid_token.access_token == "ABC123"

        api_mock.create_or_update_affiliation.assert_has_calls([
            call(affiliation=Affiliation.EDU, initial=True),
            call(affiliation=Affiliation.EMP, initial=True),
        ])
        # User with no Affiliation, should get flash warning.
        user_org = UserOrg.get(user=test_user, org=org)
        user_org.affiliations = Affiliation.NONE
        user_org.save()
        orcid_token.delete_instance()
        resp = ctx.app.full_dispatch_request()
        assert resp.status_code == 302
        assert b"<!DOCTYPE HTML" in resp.data, "Expected HTML content"
        assert "profile" in resp.location, "redirection to 'profile' showing the ORCID"
Пример #16
0
def test_link_orcid_auth_callback(name, request_ctx):
    """Test ORCID callback - the user authorized the organisation access to the ORCID profile."""
    with request_ctx("/auth?state=xyz") as ctx:
        org = Organisation.get(name="THE ORGANISATION")
        test_user = User.create(name=name,
                                email="*****@*****.**",
                                organisation=org,
                                orcid="ABC123",
                                confirmed=True)
        UserOrg.create(user=test_user, org=org, affiliations=Affiliation.NONE)
        login_user(test_user, remember=True)
        session['oauth_state'] = "xyz"
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 302, "If the user is already affiliated, the user should be redirected ..."
        assert "profile" in rv.location, "redirection to 'profile' showing the ORCID"

        u = User.get(id=test_user.id)
        orcidtoken = OrcidToken.get(user=u)
        assert u.orcid == "ABC-123-456-789"
        assert orcidtoken.access_token == "ABC123"
        if name:
            assert u.name == name, "The user name should be changed"
        else:
            assert u.name == "NEW TEST", "the user name should be set from record coming from ORCID"
Пример #17
0
def test_link_orcid_auth_callback_with_affiliation(name, mocker, client):
    """Test ORCID callback - the user authorized the organisation access to the ORCID profile."""
    mocker.patch("requests_oauthlib.OAuth2Session.fetch_token", lambda self, *args, **kwargs: dict(
        name="NEW TEST",
        access_token="ABC123",
        orcid="ABC-123-456-789",
        scope=['/read-limited,/activities/update'],
        expires_in="1212",
        refresh_token="ABC1235"))
    m = mocker.patch("orcid_hub.orcid_client.MemberAPI")
    mocker.patch("orcid_hub.orcid_client.SourceClientId")

    org = Organisation.get(name="THE ORGANISATION")
    test_user = User.create(
        name=name,
        email="*****@*****.**",
        organisation=org,
        orcid="ABC123",
        confirmed=True)

    UserOrg.create(user=test_user, org=org, affiliations=Affiliation.EMP | Affiliation.EDU)

    client.login(test_user)
    resp = client.get("/link")
    state = session['oauth_state']

    resp = client.get(f"/auth?state={state}")
    api_mock = m.return_value
    test_user = User.get(test_user.id)
    assert test_user.orcid == "ABC-123-456-789"

    orcid_token = OrcidToken.get(user=test_user, org=org)
    assert orcid_token.access_token == "ABC123"

    api_mock.create_or_update_affiliation.assert_has_calls([
        call(affiliation=Affiliation.EDU, initial=True),
        call(affiliation=Affiliation.EMP, initial=True),
    ])

    # User with no Affiliation, should get flash warning.
    user_org = UserOrg.get(user=test_user, org=org)
    user_org.affiliations = Affiliation.NONE
    user_org.save()
    orcid_token.delete_instance()

    assert OrcidToken.select().where(OrcidToken.user == test_user, OrcidToken.org == org).count() == 0
    resp = client.get(f"/auth?state={state}")
    assert resp.status_code == 302
    assert b"<!DOCTYPE HTML" in resp.data, "Expected HTML content"
    assert "profile" in resp.location, "redirection to 'profile' showing the ORCID"
    assert OrcidToken.select().where(OrcidToken.user == test_user, OrcidToken.org == org).count() == 1

    get_person = mocker.patch("requests_oauthlib.OAuth2Session.get", return_value=Mock(status_code=200))
    resp = client.get(f"/profile", follow_redirects=True)
    assert b"can create and update research activities" in resp.data
    get_person.assert_called_once()

    get_person = mocker.patch("requests_oauthlib.OAuth2Session.get", return_value=Mock(status_code=401))
    resp = client.get(f"/profile", follow_redirects=True)
    assert b"you'll be taken to ORCID to create or sign into your ORCID record" in resp.data
    get_person.assert_called_once()
Пример #18
0
def test_member_api_v3(app, mocker):
    """Test MemberAPI extension and wrapper of ORCID API."""
    mocker.patch.multiple("orcid_hub.app.logger", error=DEFAULT, exception=DEFAULT, info=DEFAULT)
    org = Organisation.get(name="THE ORGANISATION")
    user = User.create(
        orcid="1001-0001-0001-0001",
        name="TEST USER 123",
        email="*****@*****.**",
        organisation=org,
        confirmed=True)
    UserOrg.create(user=user, org=org, affiliation=Affiliation.EDU)

    api = MemberAPIV3(user=user)
    assert api.api_client.configuration.access_token is None or api.api_client.configuration.access_token == ''

    api = MemberAPIV3(user=user, org=org)
    assert api.api_client.configuration.access_token is None or api.api_client.configuration.access_token == ''

    api = MemberAPIV3(user=user, org=org, access_token="ACCESS000")
    assert api.api_client.configuration.access_token == 'ACCESS000'

    OrcidToken.create(access_token="ACCESS123",
                      user=user,
                      org=org,
                      scopes="/read-limited,/activities/update",
                      expires_in='121')
    api = MemberAPIV3(user=user, org=org)
    assert api.api_client.configuration.access_token == "ACCESS123"

    # Test API call auditing:
    request_mock = mocker.patch.object(
        api.api_client.rest_client.pool_manager, "request",
        MagicMock(return_value=Mock(data=b"""{"mock": "data"}""", status=200)))

    api.get_record()

    request_mock.assert_called_once_with(
        "GET",
        "https://api.sandbox.orcid.org/v3.0/1001-0001-0001-0001",
        fields=None,
        preload_content=False,
        timeout=None,
        headers={
            "Accept": "application/json",
            "Content-Type": "application/json",
            "User-Agent": "Swagger-Codegen/1.0.0/python",
            "Authorization": "Bearer ACCESS123"
        })

    api_call = OrcidApiCall.select().first()
    assert api_call.response == '{"mock": "data"}'
    assert api_call.url == "https://api.sandbox.orcid.org/v3.0/1001-0001-0001-0001"

    create = mocker.patch.object(OrcidApiCall, "create", side_effect=Exception("FAILURE"))
    api.get_record()
    create.assert_called_once()
    app.logger.exception.assert_called_with("Failed to create API call log entry.")

    # Handling of get_record
    call_api = mocker.patch.object(
            api.api_client, "call_api",
            side_effect=v3.rest.ApiException(reason="FAILURE", status=401))
    delete = mocker.patch.object(OrcidToken, "delete")
    api.get_record()
    call_api.assert_called_once()
    delete.assert_called_once()

    call_api = mocker.patch.object(
            api.api_client, "call_api",
            side_effect=v3.rest.ApiException(reason="FAILURE 999", status=999))
    api.get_record()
    app.logger.error.assert_called_with("ApiException Occurred: (999)\nReason: FAILURE 999\n")

    call_api = mocker.patch.object(
            api.api_client, "call_api",
            side_effect=v3.rest.ApiException(reason="FAILURE", status=401))
    api.get_record()
    app.logger.error.assert_called_with("ApiException Occurred: (401)\nReason: FAILURE\n")
    call_api.assert_called_once()

    call_api = mocker.patch.object(
            api.api_client,
            "call_api",
            return_value=(Mock(data=b"""{"mock": "data"}"""), 200, [],))
    api.get_record()
    call_api.assert_called_with(
        f"/v3.0/{user.orcid}",
        "GET",
        _preload_content=False,
        auth_settings=["orcid_auth"],
        header_params={"Accept": "application/json"},
        response_type=None)

    # Failed logging:
    request_mock = mocker.patch(
            "orcid_api_v3.rest.RESTClientObject.request",
            return_value=Mock(data=None, status_code=200))
Пример #19
0
def test_create_or_update_resource(app, mocker):
    """Test research resources."""
    mocker.patch.multiple("orcid_hub.app.logger",
                          error=DEFAULT,
                          exception=DEFAULT,
                          info=DEFAULT)
    org = Organisation.get(name="THE ORGANISATION")
    user = User.create(orcid="1001-0001-0001-0001",
                       name="TEST USER 123",
                       email="*****@*****.**",
                       organisation=org,
                       confirmed=True)
    UserOrg.create(user=user, org=org, affiliation=Affiliation.EDU)

    api = MemberAPIV3(user=user, org=org, access_token="ACCESS000")
    assert api.api_client.configuration.access_token == 'ACCESS000'

    OrcidToken.create(access_token="ACCESS123",
                      user=user,
                      org=org,
                      scopes="/read-limited,/activities/update",
                      expires_in='121')
    api = MemberAPIV3(user=user, org=org)
    assert api.api_client.configuration.access_token == "ACCESS123"

    # Test API call auditing:
    request_mock = mocker.patch.object(
        api.api_client.rest_client.pool_manager, "request",
        MagicMock(return_value=Mock(headers=HTTPHeaderDict({
            'Server':
            'nginx/1.10.0',
            'Date':
            'Wed, 26 Jun 2019 05:26:32 GMT',
            'Content-Type':
            'application/json;charset=UTF-8',
            'Content-Length':
            '0',
            'Connection':
            'keep-alive',
            'Access-Control-Allow-Origin':
            '*',
            'Cache-Control':
            'no-cache, no-store, max-age=0, must-revalidate',
            'Pragma':
            'no-cache',
            'Expires':
            '0',
            'X-XSS-Protection':
            '1; mode=block',
            'X-Frame-Options':
            'DENY',
            'X-Content-Type-Options':
            'nosniff',
            'Location':
            f'http://api.sandbox.orcid.org/v3.0/{user.orcid}/research-resource/2052'
        }),
                                    data=b'',
                                    status=201)))

    hosts = [
        dict(
            name="TEST HOST",
            city="Auckland",
            country="NZ",
            disambiguated_id="3232",
            disambiguation_source="RINGGOLD",
        )
    ]
    external_ids = [dict(value="ABC123", type="agr", relationship="self")]

    put_code, orcid, created, _ = api.create_or_update_resource(
        title="TEST",
        hosts=hosts,
        external_ids=external_ids,
        items=[{
            "name": "TEST",
            "type": "equipment",
            "hosts": hosts,
            "external_ids": external_ids,
        }],
        display_index=999,
        visibility="public",
    )

    request_mock.assert_called_once()
    assert put_code == 2052
    assert orcid == user.orcid
Пример #20
0
def test_org_webhook(app_req_ctx, monkeypatch):
    """Test Organisation webhooks."""
    monkeypatch.setattr(
        utils.requests, "post", lambda *args, **kwargs: SimpleObject(
            status_code=201,
            json=lambda: dict(access_token="ABC123",
                              refresh_token="REFRESS_ME",
                              expires_in=123456789)))
    monkeypatch.setattr(utils.requests, "put",
                        lambda *args, **kwargs: SimpleObject(status_code=201))
    monkeypatch.setattr(utils.requests, "delete",
                        lambda *args, **kwargs: SimpleObject(status_code=204))

    org = app_req_ctx.data["org"]
    admin = org.tech_contact
    user = app_req_ctx.data["user"]

    monkeypatch.setattr(utils.register_orcid_webhook, "queue",
                        utils.register_orcid_webhook)

    utils.enable_org_webhook(org)
    assert org.webhook_enabled
    assert org.users.where(User.orcid.is_null(False),
                           User.webhook_enabled).count() > 0

    utils.disable_org_webhook(org)
    assert not org.webhook_enabled
    assert org.users.where(User.orcid.is_null(False),
                           User.webhook_enabled).count() == 0

    with app_req_ctx(f"/services/{user.id}/updated",
                     method="POST") as ctx, patch.object(
                         utils, "send_email") as send_email:
        send_email.assert_not_called()

    with app_req_ctx("/settings/webhook",
                     method="POST",
                     data=dict(webhook_url="https://ORG.org/HANDLE",
                               webhook_enabled='y')) as ctx:

        login_user(admin)
        assert not Organisation.get(id=org.id).webhook_enabled
        resp = ctx.app.full_dispatch_request()
        assert Organisation.get(id=org.id).webhook_enabled
        assert resp.status_code == 200

        with app_req_ctx(f"/services/{user.id}/updated",
                         method="POST") as ctx, patch.object(
                             utils, "send_email") as send_email:
            resp = ctx.app.full_dispatch_request()
            send_email.assert_not_called()
            assert resp.status_code == 204

    with app_req_ctx("/settings/webhook",
                     method="POST",
                     data=dict(webhook_url="https://ORG.org/HANDLE",
                               webhook_enabled='y',
                               email_notifications_enabled='y')) as ctx:

        login_user(admin)
        assert not Organisation.get(id=org.id).email_notifications_enabled
        resp = ctx.app.full_dispatch_request()
        assert Organisation.get(id=org.id).email_notifications_enabled
        assert resp.status_code == 200

        with app_req_ctx(f"/services/{user.id}/updated",
                         method="POST") as ctx, patch.object(
                             utils, "send_email") as send_email:
            resp = ctx.app.full_dispatch_request()
            send_email.assert_called()
            assert resp.status_code == 204
Пример #21
0
def test_onboard_org(client):
    """Test to organisation onboarding."""
    org = Organisation.create(name="THE ORGANISATION:test_onboard_org",
                              tuakiri_name="THE ORGANISATION:test_onboard_org",
                              confirmed=False,
                              orcid_client_id="CLIENT ID",
                              orcid_secret="Client Secret",
                              city="CITY",
                              country="COUNTRY",
                              disambiguated_id="ID",
                              disambiguation_source="RINGGOLD",
                              is_email_sent=True)
    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    roles=Role.TECHNICAL,
                    orcid="123",
                    confirmed=True,
                    organisation=org)
    second_user = User.create(email="*****@*****.**",
                              name="TEST USER",
                              roles=Role.ADMIN,
                              orcid="1243",
                              confirmed=True,
                              organisation=org)
    UserOrg.create(user=second_user, org=org, is_admin=True)
    org_info = OrgInfo.create(name="A NEW ORGANISATION",
                              tuakiri_name="A NEW ORGANISATION")
    org.tech_contact = u
    org_info.save()
    org.save()

    client.login_root()
    with patch("orcid_hub.utils.send_email"):
        resp = client.post("/invite/organisation",
                           data=dict(org_name="A NEW ORGANISATION",
                                     org_email="*****@*****.**"),
                           follow_redirects=True)
        assert User.select().where(
            User.email == "*****@*****.**").exists()
        resp = client.post("/invite/organisation",
                           data=dict(org_name="A NEW ORGANISATION",
                                     org_email="*****@*****.**",
                                     tech_contact='y'),
                           follow_redirects=True)
        assert User.select().where(
            User.email == "*****@*****.**").exists()
    org = Organisation.get(name="A NEW ORGANISATION")
    user = User.get(email="*****@*****.**")
    assert user.name is None
    assert org.tech_contact == user
    client.logout()

    resp = client.login(user,
                        **{
                            "Sn": "TECHNICAL",
                            "Givenname": "CONTACT",
                            "Displayname": "Test User",
                            "shib_O": "NEW ORGANISATION"
                        },
                        follow_redirects=True)
    user = User.get(email="*****@*****.**")
    org = user.organisation
    assert user.is_tech_contact_of(org)
    resp = client.get("/confirm/organisation")
    assert resp.status_code == 200
    org = Organisation.get(org.id)
    assert b"<!DOCTYPE html>" in resp.data, "Expected HTML content"
    assert b"Take me to ORCID to obtain my Client ID and Client Secret" in resp.data

    with patch("orcid_hub.authcontroller.requests") as requests:
        requests.post.return_value = Mock(data=b'XXXX', status_code=200)
        resp = client.post("/confirm/organisation",
                           data={
                               "orcid_client_id": "APP-1234567890ABCDEF",
                               "orcid_secret":
                               "12345678-1234-1234-1234-1234567890ab",
                               "country": "NZ",
                               "city": "Auckland",
                               "disambiguated_id": "XYZ123",
                               "disambiguation_source": "RINGGOLD",
                               "name": org.name,
                               "email": user.email,
                           })
    assert resp.status_code == 302
    url = urlparse(resp.location).path
    assert url == "/link"
    resp = client.get(url)
    client.logout()
    org = Organisation.get(org.id)
    assert org.disambiguated_id == "XYZ123"
    assert org.disambiguation_source == "RINGGOLD"
    assert org.orcid_client_id == "APP-1234567890ABCDEF"
    assert org.orcid_secret == "12345678-1234-1234-1234-1234567890ab"

    user = User.get(email="*****@*****.**")
    resp = client.login(user,
                        **{
                            "Sn": "NEW ORGANISATION",
                            "Givenname": "ADMINISTRATOR",
                            "Displayname": "Admin User",
                            "shib_O": "NEW ORGANISATION"
                        },
                        follow_redirects=True)
    assert b"Take me to ORCID to allow A NEW ORGANISATION permission to access my ORCID record" in resp.data
    resp = client.get("/confirm/organisation")
    assert resp.status_code == 302
    assert urlparse(resp.location).path == "/admin/viewmembers/"

    resp = client.get("/admin/viewmembers/")
    assert b"*****@*****.**" in resp.data

    resp = client.get("/admin/viewmembers/export/csv/")
    assert resp.headers["Content-Type"] == "text/csv; charset=utf-8"
    assert b"*****@*****.**" in resp.data
    assert b"*****@*****.**" in resp.data
Пример #22
0
def test_user_org_link_user_constraint(models):
    org = Organisation.get(id=1)
    uo = UserOrg(user_id=999999, org=org)
    with pytest.raises(User.DoesNotExist):
        uo.save()
Пример #23
0
def test_is_emp_or_edu_record_present(app, mocker):
    """Test 'is_emp_or_edu_record_present' method."""
    mocker.patch.multiple("orcid_hub.app.logger", error=DEFAULT, exception=DEFAULT, info=DEFAULT)
    org = Organisation.get(name="THE ORGANISATION")
    user = User.create(
        orcid="1001-0001-0001-0001",
        name="TEST USER 123",
        email="*****@*****.**",
        organisation=org,
        confirmed=True)
    UserOrg.create(user=user, org=org, affiliation=Affiliation.EDU)

    api = MemberAPI(user=user, org=org)

    test_responses = [
        None,
        """{"mock": "data"}""",
        """{
            "employment-summary": [{"source": {"source-client-id": {"path": "CLIENT000"}}, "put-code": 123}],
            "education-summary": [{"source": {"source-client-id": {"path": "CLIENT000"}}, "put-code": 456}]
        }""",
        """{"employment-summary": [], "education-summary": []}"""
    ]

    for data in test_responses:
        with patch.object(
                api_client.ApiClient,
                "call_api",
                return_value=Mock(data=data)) as call_api:
            api.is_emp_or_edu_record_present(Affiliation.EDU)
            call_api.assert_called_with(
                "/v2.0/{orcid}/educations",
                "GET", {"orcid": "1001-0001-0001-0001"}, {}, {"Accept": "application/json"},
                _preload_content=False,
                _request_timeout=None,
                _return_http_data_only=True,
                auth_settings=["orcid_auth"],
                body=None,
                callback=None,
                collection_formats={},
                files={},
                post_params=[],
                response_type="Educations")
            api.is_emp_or_edu_record_present(Affiliation.EMP)
            call_api.assert_called_with(
                "/v2.0/{orcid}/employments",
                "GET", {"orcid": "1001-0001-0001-0001"}, {}, {"Accept": "application/json"},
                _preload_content=False,
                _request_timeout=None,
                _return_http_data_only=True,
                auth_settings=["orcid_auth"],
                body=None,
                callback=None,
                collection_formats={},
                files={},
                post_params=[],
                response_type="Employments")

    with patch.object(
            api_client.ApiClient, "call_api", side_effect=ApiException(
                reason="FAILURE", status=401)) as call_api:
        api.is_emp_or_edu_record_present(Affiliation.EDU)
        app.logger.error.assert_called_with(
            "For TEST USER 123 ([email protected]) while checking for employment "
            "and education records, Encountered Exception: (401)\nReason: FAILURE\n")

    with patch.object(
            api_client.ApiClient, "call_api", side_effect=Exception("EXCEPTION")) as call_api:
        api.is_emp_or_edu_record_present(Affiliation.EDU)
        app.logger.exception.assert_called_with(
            "Failed to verify presence of employment or education record.")
Пример #24
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
Пример #25
0
def test_member_api(app, mocker):
    """Test MemberAPI extension and wrapper of ORCID API."""
    mocker.patch.multiple("orcid_hub.app.logger",
                          error=DEFAULT,
                          exception=DEFAULT,
                          info=DEFAULT)
    org = Organisation.get(name="THE ORGANISATION")
    user = User.create(orcid="1001-0001-0001-0001",
                       name="TEST USER 123",
                       email="*****@*****.**",
                       organisation=org,
                       confirmed=True)
    UserOrg.create(user=user, org=org, affiliation=Affiliation.EDU)

    MemberAPI(user=user)
    assert configuration.access_token is None or configuration.access_token == ''

    MemberAPI(user=user, org=org)
    assert configuration.access_token is None or configuration.access_token == ''

    MemberAPI(user=user, org=org, access_token="ACCESS000")
    assert configuration.access_token == 'ACCESS000'

    OrcidToken.create(access_token="ACCESS123",
                      user=user,
                      org=org,
                      scope="/read-limited,/activities/update",
                      expires_in='121')
    api = MemberAPI(user=user, org=org)
    assert configuration.access_token == "ACCESS123"

    with patch.object(api_client.ApiClient,
                      "call_api",
                      side_effect=ApiException(reason="FAILURE",
                                               status=401)) as call_api:
        with patch.object(OrcidToken, "delete") as delete:
            api.get_record()
            app.logger.error.assert_called_with(
                "ApiException Occured: (401)\nReason: FAILURE\n")
            call_api.assert_called_once()
            delete.assert_called_once()

    with patch.object(api_client.ApiClient,
                      "call_api",
                      side_effect=ApiException(reason="FAILURE 999",
                                               status=999)) as call_api:
        api.get_record()
        app.logger.error.assert_called_with(
            "ApiException Occured: (999)\nReason: FAILURE 999\n")

    with patch.object(api_client.ApiClient,
                      "call_api",
                      side_effect=ApiException(reason="FAILURE",
                                               status=401)) as call_api:
        with patch.object(OrcidToken, "get",
                          side_effect=Exception("FAILURE")) as get:
            api.get_record()
            app.logger.exception.assert_called_with(
                "Exception occured while retriving ORCID Token")
            call_api.assert_called_once()
            get.assert_called_once()

    with patch.object(api_client.ApiClient,
                      "call_api",
                      return_value=(
                          Mock(data=b"""{"mock": "data"}"""),
                          200,
                          [],
                      )) as call_api:
        api.get_record()
        call_api.assert_called_with(
            f"/v2.0/{user.orcid}",
            "GET",
            _preload_content=False,
            auth_settings=["orcid_auth"],
            header_params={"Accept": "application/json"},
            response_type=None)

    # Test API call auditing:
    with patch.object(api_client.RESTClientObject.__base__,
                      "request",
                      return_value=Mock(data=b"""{"mock": "data"}""",
                                        status_code=200)) as request_mock:

        api.get_record()

        request_mock.assert_called_once_with(
            _preload_content=False,
            _request_timeout=None,
            body=None,
            headers={
                "Accept": "application/json",
                "User-Agent": "Swagger-Codegen/1.0.0/python",
                "Authorization": "Bearer ACCESS123"
            },
            method="GET",
            post_params=None,
            query_params=None,
            url="https://api.sandbox.orcid.org/v2.0/1001-0001-0001-0001")
        api_call = OrcidApiCall.select().first()
        assert api_call.response == '{"mock": "data"}'
        assert api_call.url == "https://api.sandbox.orcid.org/v2.0/1001-0001-0001-0001"

        with patch.object(OrcidApiCall,
                          "create",
                          side_effect=Exception("FAILURE")) as create:
            api.get_record()
            create.assert_called_once()

    with patch.object(api_client.RESTClientObject.__base__,
                      "request",
                      return_value=Mock(data=None,
                                        status_code=200)) as request_mock:
        # api.get_record()
        OrcidApiCall.delete().execute()
        api.view_person("1234-XXXX-XXXX-XXXX")
        api_call = OrcidApiCall.select().first()
        assert api_call.response is None
        assert api_call.url == "https://api.sandbox.orcid.org/v2.0/1234-XXXX-XXXX-XXXX/person"
Пример #26
0
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
Пример #27
0
def test_org_webhook(client, mocker):
    """Test Organisation webhooks."""
    mocker.patch.object(
        utils.requests,
        "post",
        lambda *args, **kwargs: SimpleObject(
            status_code=201,
            json=lambda: dict(
                access_token="ABC123", refresh_token="REFRESS_ME", expires_in=123456789
            ),
        ),
    )
    mocker.patch.object(
        utils.requests, "put", lambda *args, **kwargs: SimpleObject(status_code=201, text="")
    )
    mocker.patch.object(
        utils.requests, "delete", lambda *args, **kwargs: SimpleObject(status_code=204, text="")
    )

    org = client.data["org"]
    admin = org.tech_contact
    user = client.data["user"]

    mocker.patch.object(utils.register_orcid_webhook, "queue", utils.register_orcid_webhook)
    mocker.patch.object(utils.invoke_webhook_handler, "queue", utils.invoke_webhook_handler)

    utils.enable_org_webhook(org)
    assert org.webhook_enabled
    assert org.users.where(User.orcid.is_null(False), User.webhook_enabled).count() > 0

    utils.disable_org_webhook(org)
    assert not org.webhook_enabled
    assert org.users.where(User.orcid.is_null(False), User.webhook_enabled).count() == 0

    resp = client.login(admin)
    resp = client.post(f"/services/{user.id}/updated")
    send_email = mocker.patch.object(utils, "send_email")
    send_email.assert_not_called()

    assert not Organisation.get(org.id).webhook_enabled
    resp = client.post(
        "/settings/webhook", data=dict(webhook_url="https://ORG.org/HANDLE", webhook_enabled="y")
    )
    assert Organisation.get(org.id).webhook_enabled
    assert resp.status_code == 200

    resp = client.post(f"/services/{user.id}/updated")
    send_email.assert_not_called()
    assert resp.status_code == 204

    assert not Organisation.get(org.id).email_notifications_enabled
    resp = client.post(
        "/settings/webhook",
        data=dict(
            webhook_url="https://ORG.org/HANDLE",
            webhook_enabled="y",
            email_notifications_enabled="y",
        ),
    )
    assert Organisation.get(org.id).email_notifications_enabled
    assert resp.status_code == 200

    resp = client.post(f"/services/{user.id}/updated")
    send_email.assert_called()
    assert resp.status_code == 204

    post = mocker.patch.object(utils.requests, "post", return_value=Mock(status_code=204))
    for u in User.select().where(
        User.organisation == user.organisation, User.orcid.is_null(False)
    ):
        post.reset_mock()
        send_email.reset_mock()
        resp = client.post(f"/services/{u.id}/updated")
        send_email.assert_called()
        post.assert_called()
        assert resp.status_code == 204

    # Enable only email notification:
    resp = client.post(
        "/settings/webhook", data=dict(webhook_enabled="", email_notifications_enabled="")
    )
    assert resp.status_code == 200
    assert not Organisation.get(org.id).email_notifications_enabled
    resp = client.post(
        "/settings/webhook",
        data=dict(webhook_url="", webhook_enabled="", email_notifications_enabled="y"),
    )
    assert Organisation.get(org.id).email_notifications_enabled
    assert resp.status_code == 200

    post.reset_mock()
    send_email.reset_mock()
    resp = client.post(f"/services/{user.id}/updated")
    send_email.assert_called()
    post.assert_not_called()
    assert resp.status_code == 204

    # Test update summary:
    mocker.patch.object(utils.send_orcid_update_summary, "queue", utils.send_orcid_update_summary)

    send_email.reset_mock()
    utils.send_orcid_update_summary()
    send_email.assert_not_called()

    utils.send_orcid_update_summary(org.id)
    send_email.assert_not_called()

    utils.send_orcid_update_summary(9999999)
    send_email.assert_not_called()

    user.orcid_updated_at = utils.date.today().replace(day=1) - utils.timedelta(days=1)
    user.save()
    utils.send_orcid_update_summary()
    send_email.assert_called()

    send_email.reset_mock()
    org.notification_email = "*****@*****.**"
    org.save()
    utils.send_orcid_update_summary()
    send_email.assert_called_once()

    resp = client.post("/settings/webhook", data=dict(save_webhook="Save"))
    assert resp.status_code == 200
    assert not Organisation.get(org.id).webhook_enabled
    assert not Organisation.get(org.id).email_notifications_enabled