Exemplo n.º 1
0
def test_me(app_req_ctx):
    """Test the echo endpoint."""
    user = User.get(email="*****@*****.**")
    token = Token.get(user=user)
    with app_req_ctx(
            "/api/me",
            headers=dict(authorization=f"Bearer {token.access_token}")) as ctx:
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 200
        data = json.loads(rv.data)
        assert data["email"] == user.email
        assert data["name"] == user.name

    # Test invalid token:
    with app_req_ctx("/api/me",
                     headers=dict(authorization="Bearer INVALID")) as ctx:
        user = User.get(email="*****@*****.**")
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 401

    # Test expired token:
    from datetime import datetime
    token.expires = datetime(1971, 1, 1)
    token.save()
    with app_req_ctx(
            "/api/me",
            headers=dict(authorization=f"Bearer {token.access_token}")) as ctx:
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 401
Exemplo n.º 2
0
def test_org_switch(client):
    """Test organisation switching."""
    user = User.get(orcid=User.select(fn.COUNT(User.orcid).alias("id_count"), User.orcid).group_by(
        User.orcid).having(fn.COUNT(User.orcid) > 1).naive().first().orcid)
    user_orgs = UserOrg.select().join(User).where(User.orcid == user.orcid)
    new_org = Organisation.select().where(Organisation.id.not_in([uo.org_id for uo in user_orgs])).first()
    UserOrg.create(user=user, org=new_org, affiliations=0)

    resp = client.login(user, follow_redirects=True)
    assert user.email.encode() in resp.data
    assert len(user.org_links) > 1
    assert current_user == user

    # Nothing changes if it is the same organisation
    uo = user.userorg_set.where(UserOrg.org_id == user.organisation_id).first()
    resp = client.get(f"/select/user_org/{uo.id}", follow_redirects=True)
    assert User.get(user.id).organisation_id == user.organisation_id
    assert user.email.encode() in resp.data

    # The current org changes if it's a dirrerent org on the list
    uo = user.userorg_set.where(UserOrg.org_id != user.organisation_id).first()
    resp = client.get(f"/select/user_org/{uo.id}", follow_redirects=True)
    assert User.get(user.id).organisation_id != user.organisation_id
    assert User.get(user.id).organisation_id == uo.org_id

    for ol in user.org_links:
        assert ol.org.name.encode() in resp.data
        if UserOrg.get(ol.id).user.id != user.id:
            next_ol = ol

    # Shoud be a totally different user account:
    resp = client.get(f"/select/user_org/{next_ol.id}", follow_redirects=True)
    next_user = UserOrg.get(next_ol.id).user
    assert next_user.id != user.id
Exemplo n.º 3
0
def test_invite_tech_contact(send_email, client):
    """Test on-boarding of an org."""
    client.login_root()
    email = "*****@*****.**"
    client.post("/invite/organisation",
                data={
                    "org_name": "A NEW ORGANISATION",
                    "org_email": email,
                    "tech_contact": "y",
                })
    u = User.get(email=email)
    oi = OrgInvitation.get(invitee=u)

    assert not u.confirmed
    assert oi.org.name == "A NEW ORGANISATION"
    assert oi.org.tech_contact == u
    send_email.assert_called_once()
    client.logout()

    # Test invited user login:
    client.login(
        u, **{
            "Sn": "Surname",
            "Givenname": "Givenname",
            "Displayname": "Test User"
        })
    u = User.get(email=email)
    assert u.confirmed
    assert u.organisation.tech_contact == u
Exemplo n.º 4
0
def test_tuakiri_login_with_orcid(client):
    """
    Test logging attempt via Shibboleth.

    After getting logged in a new user entry shoulg be created.
    """
    data = {
        "Auedupersonsharedtoken": "ABC123",
        "Sn": "LAST NAME/SURNAME/FAMILY NAME",
        'Givenname': "FIRST NAME/GIVEN NAME",
        "Mail": "*****@*****.**",
        "O": "ORGANISATION 123",
        "Displayname": "TEST USER FROM 123",
        "Unscoped-Affiliation": "staff",
        "Eppn": "*****@*****.**",
        "Orcid-Id": "http://orcid.org/ERROR-ERROR-ERROR",
    }

    # Incorrect ORCID iD
    resp = client.get("/sso/login", headers=data)
    assert resp.status_code == 302
    u = User.get(email="*****@*****.**")
    assert u.name == "TEST USER FROM 123", "Expected to have the user in the DB"
    assert u.first_name == "FIRST NAME/GIVEN NAME"
    assert u.last_name == "LAST NAME/SURNAME/FAMILY NAME"
    assert u.orcid is None

    # Correct ORCID iD, existing user:
    client.logout()
    data["Orcid-Id"] = "http://orcid.org/1893-2893-3893-00X3"
    resp = client.get("/sso/login", headers=data)
    assert resp.status_code == 302
    u = User.get(email="*****@*****.**")
    assert u.name == "TEST USER FROM 123", "Expected to have the user in the DB"
    assert u.first_name == "FIRST NAME/GIVEN NAME"
    assert u.last_name == "LAST NAME/SURNAME/FAMILY NAME"
    assert u.orcid == "1893-2893-3893-00X3"

    # A new user with ORCID iD:
    client.logout()
    data = {
        "Auedupersonsharedtoken": "ABC123ABC123",
        "Sn": "LAST NAME/SURNAME/FAMILY NAME",
        'Givenname': "FIRST NAME/GIVEN NAME",
        "Mail": "*****@*****.**",
        "O": "ORGANISATION 123",
        "Displayname": "TEST USER FROM 123",
        "Unscoped-Affiliation": "staff",
        "Eppn": "*****@*****.**",
        "Orcid-Id": "1965-2965-3965-00X3",
    }
    resp = client.get("/sso/login", headers=data)
    assert resp.status_code == 302
    u = User.get(email="*****@*****.**")
    assert u.name == "TEST USER FROM 123", "Expected to have the user in the DB"
    assert u.first_name == "FIRST NAME/GIVEN NAME"
    assert u.last_name == "LAST NAME/SURNAME/FAMILY NAME"
    assert u.orcid == "1965-2965-3965-00X3"
Exemplo n.º 5
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(name="THE ORGANISATION", confirmed=True)
        org.save()

        test_user = User.create(
            name=name,
            email="*****@*****.**",
            organisation=org,
            orcid="ABC123",
            confirmed=True)
        orcidtoken = OrcidToken.create(
            user=test_user,
            org=org,
            scope="/read-limited,/activities/update",
            access_token="ABC1234")
        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 == "ABC1234"
        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"
Exemplo n.º 6
0
def test_user_summary(request_ctx):
    """Test user summary."""
    user = User.get(email="*****@*****.**")
    with request_ctx(
            "/user_summary?from_date=2017-01-01&to_date=2018-02-28") as ctx:
        login_user(user, remember=True)
        resp = ctx.app.full_dispatch_request()
        assert resp.status_code == 200
        assert b"<!DOCTYPE html>" in resp.data, "Expected HTML content"
        assert b"TEST0" in resp.data
        assert b"*****@*****.**" in resp.data
        assert b"4 / 9 (44%)" in resp.data
    with request_ctx(
            "/user_summary?from_date=2017-01-01&to_date=2017-12-31") as ctx:
        login_user(user, remember=True)
        resp = ctx.app.full_dispatch_request()
        assert resp.status_code == 200
        assert b"<!DOCTYPE html>" in resp.data, "Expected HTML content"
        assert b"TEST0" in resp.data
        assert b"*****@*****.**" in resp.data
        assert b"0 / 9 (0%)" in resp.data
    for (sort, desc) in [(0, 0), (0, 1), (1, 0), (1, 1)]:
        with request_ctx(
                f"/user_summary?from_date=2017-01-01&to_date=2018-12-31&sort={sort}&desc={desc}"
        ) as ctx:
            login_user(user, remember=True)
            resp = ctx.app.full_dispatch_request()
            assert resp.status_code == 200
            data = resp.data.decode()
            assert f"&sort={0 if sort else 1}&desc=0" in data
            assert f"&sort={sort}&desc={0 if desc else 1}" in data
    with request_ctx("/user_summary") as ctx:
        login_user(user, remember=True)
        resp = ctx.app.full_dispatch_request()
        assert resp.status_code == 302
Exemplo n.º 7
0
def test_sso_loging_with_external_sp(client, mocker):
    """Test with EXTERNAL_SP."""
    data = {
        "Auedupersonsharedtoken": "ABC123",
        "Sn": "LAST NAME/SURNAME/FAMILY NAME",
        'Givenname': "FIRST NAME/GIVEN NAME",
        "Mail": "[email protected];[email protected]",
        "O": client.data["org"].name,
        "Displayname": "TEST USER #42",
        "Unscoped-Affiliation": "staff",
        "Eppn": "*****@*****.**"
    }

    client.application.config["EXTERNAL_SP"] = "https://exernal.ac.nz/SP"
    resp = client.get("/index")
    assert b"https://exernal.ac.nz/SP" in resp.data
    get = mocker.patch(
        "requests.get",
        return_value=Mock(text=base64.b64encode(zlib.compress(pickle.dumps(data)))))

    resp = client.get("/sso/login", follow_redirects=True)
    get.assert_called_once()
    assert b"TEST USER #42" in resp.data
    assert b"*****@*****.**" in resp.data
    u = User.get(email="*****@*****.**")
    assert u.name == "TEST USER #42"
Exemplo n.º 8
0
def test_tuakiri_login_with_org(client):
    """
    Test logging attempt via Shibboleth.

    If a user logs in from an organisation that isn't
    onboared, the user should be informed about that and
    redirected to the login page.
    """
    org = Organisation(tuakiri_name="THE ORGANISATION", confirmed=True)
    org.save()

    rv = client.get("/Tuakiri/login",
                    headers={
                        "Auedupersonsharedtoken": "ABC111",
                        "Sn": "LAST NAME/SURNAME/FAMILY NAME",
                        'Givenname': "FIRST NAME/GIVEN NAME",
                        "Mail": "*****@*****.**",
                        "O": "THE ORGANISATION",
                        "Displayname": "TEST USER FROM THE ORGANISATION",
                        "Unscoped-Affiliation": "staff",
                        "Eppn": "*****@*****.**"
                    },
                    follow_redirects=True)

    u = User.get(email="*****@*****.**")
    assert u.organisation == org
    assert org in u.organisations
    assert b"Your organisation (THE ORGANISATION) is not onboarded" not in rv.data
    uo = UserOrg.get(user=u, org=org)
    assert not uo.is_admin
Exemplo n.º 9
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()
Exemplo n.º 10
0
def test_tuakiri_login_wo_org(client):
    """
    Test logging attempt via Shibboleth.

    If a user logs in from an organisation that isn't
    onboared, the user should be informed about that and
    redirected to the login page.
    """
    rv = client.get("/Tuakiri/login",
                    headers={
                        "Auedupersonsharedtoken": "ABC999",
                        "Sn": "LAST NAME/SURNAME/FAMILY NAME",
                        'Givenname': "FIRST NAME/GIVEN NAME",
                        "Mail": "*****@*****.**",
                        "O": "INCOGNITO",
                        "Displayname": "TEST USER FROM UNKNOWN",
                        "Unscoped-Affiliation": "staff",
                        "Eppn": "*****@*****.**"
                    },
                    follow_redirects=True)

    u = User.get(email="*****@*****.**")
    assert u is not None
    assert u.eppn == "*****@*****.**"
    assert b"Your organisation (INCOGNITO) is not yet using the Hub, " \
           b"see your Technical Contact for a timeline" in rv.data
Exemplo n.º 11
0
def test_tuakiri_login_usgin_eppn(client):
    """Test logging attempt via Shibboleth using differt values to identify the user."""
    org = Organisation(tuakiri_name="ORGANISATION 123ABC")
    org.save()
    user = User.create(email="*****@*****.**",
                       eppn="*****@*****.**",
                       roles=Role.RESEARCHER)
    user.save()

    rv = client.get("/Tuakiri/login",
                    headers={
                        "Auedupersonsharedtoken": "ABC123",
                        "Sn": "LAST NAME/SURNAME/FAMILY NAME",
                        'Givenname': "FIRST NAME/GIVEN NAME",
                        "Mail": "*****@*****.**",
                        "O": "ORGANISATION 123ABC",
                        "Displayname": "TEST USER FROM 123",
                        "Unscoped-Affiliation": "staff",
                        "Eppn": "*****@*****.**"
                    })

    assert rv.status_code == 302
    u = User.get(eppn="*****@*****.**")
    assert u.email == "*****@*****.**"
    assert u.name == "TEST USER FROM 123", "Expected to have the user in the DB"
    assert u.first_name == "FIRST NAME/GIVEN NAME"
    assert u.last_name == "LAST NAME/SURNAME/FAMILY NAME"
Exemplo n.º 12
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"
Exemplo n.º 13
0
def test_get_client_credentials_token(request_ctx):
    """Test retrieval of the webhook tokens."""
    with request_ctx("/"), patch("orcid_hub.utils.requests.post") as mockpost:
        admin = User.get(email="*****@*****.**")
        org = admin.organisation
        login_user(admin)
        mockresp = MagicMock(status_code=201)
        mockresp.json.return_value = {
            "access_token": "ACCESS-TOKEN-123",
            "token_type": "bearer",
            "refresh_token": "REFRESH-TOKEN-123",
            "expires_in": 99999,
            "scope": "/webhook",
            "orcid": None,
        }
        mockpost.return_value = mockresp

        OrcidToken.create(
            org=org, access_token="access_token", refresh_token="refresh_token", scopes="/webhook"
        )
        token = utils.get_client_credentials_token(org, "/webhook")
        assert (
            OrcidToken.select()
            .where(OrcidToken.org == org, OrcidToken.scopes == "/webhook")
            .count()
            == 1
        )
        assert token.access_token == "ACCESS-TOKEN-123"
        assert token.refresh_token == "REFRESH-TOKEN-123"
        assert token.expires_in == 99999
        assert token.scopes == "/webhook"
Exemplo n.º 14
0
def test_admin_view_access(request_ctx):
    """Test if SUPERUSER can run reports."""
    user = User.get(email="*****@*****.**")
    with request_ctx("/org_invitatin_summary") as ctx:
        login_user(user, remember=True)
        resp = ctx.app.full_dispatch_request()
        assert resp.status_code == 200
        assert b"<!DOCTYPE html>" in resp.data, "Expected HTML content"
        assert b"Organisation Invitation Summary" in resp.data
        assert b"*****@*****.**" in resp.data
Exemplo n.º 15
0
def test_user_invitation_summary(request_ctx):
    """Test user invitation summary."""
    user = User.get(email="*****@*****.**")
    with request_ctx("/user_invitatin_summary") as ctx:
        login_user(user, remember=True)
        resp = ctx.app.full_dispatch_request()
        assert resp.status_code == 200
        assert b"<!DOCTYPE html>" in resp.data, "Expected HTML content"
        assert b"User Invitation Summary" in resp.data
        assert b"*****@*****.**" in resp.data
Exemplo n.º 16
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"
Exemplo n.º 17
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)
Exemplo n.º 18
0
def test_create_hub_administrator(app):
    """Test creation of the Hub administrators."""
    org = app.data["org"]
    runner = CliRunner()
    runner.invoke(create_hub_administrator, ["*****@*****.**"])
    assert User.select().where(User.email == "*****@*****.**").exists()
    assert Organisation.select().where(
        Organisation.name == "ORCID Hub").exists()
    runner.invoke(create_hub_administrator,
                  ["*****@*****.**", "-O", "NEW ORGANISATION #0"])
    assert Organisation.select().where(
        Organisation.name == "NEW ORGANISATION #0").exists()
    assert User.get(
        email="*****@*****.**").organisation.name == "NEW ORGANISATION #0"

    runner.invoke(create_hub_administrator,
                  ["*****@*****.**", "-O", "NEW ORG"])
    assert Organisation.select().where(Organisation.name == "NEW ORG").exists()
    assert User.get(email="*****@*****.**").organisation.name == "NEW ORG"

    org_count = Organisation.select().count()
    runner.invoke(create_hub_administrator,
                  ["*****@*****.**", "-O", org.name])
    assert Organisation.select().count() == org_count
    assert User.get(email="*****@*****.**").organisation.name == org.name

    runner.invoke(create_hub_administrator,
                  ["*****@*****.**", "-I", "INTERNAL NAME 111"])
    assert User.select().where(User.email == "*****@*****.**").exists()
    assert Organisation.select().where(
        Organisation.name == "ORCID Hub",
        Organisation.tuakiri_name == "INTERNAL NAME 111").exists()
    assert User.get(email="*****@*****.**"
                    ).organisation.tuakiri_name == "INTERNAL NAME 111"

    runner.invoke(
        create_hub_administrator,
        ["*****@*****.**", "-O", "NEW ORG", "-I", "INTERNAL NAME 222"])
    assert Organisation.select().where(
        Organisation.name == "NEW ORG",
        Organisation.tuakiri_name == "INTERNAL NAME 222").exists()
    assert User.get(email="*****@*****.**"
                    ).organisation.tuakiri_name == "INTERNAL NAME 222"

    org_count = Organisation.select().count()
    runner.invoke(
        create_hub_administrator,
        ["*****@*****.**", "-O", org.name, "-I", "INTERNAL NAME 333"])
    assert Organisation.select().count() == org_count
    assert User.get(email="*****@*****.**"
                    ).organisation.tuakiri_name == "INTERNAL NAME 333"
Exemplo n.º 19
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
Exemplo n.º 20
0
def test_me(client):
    """Test the echo endpoint."""
    user = User.get(email="*****@*****.**")
    token = Token.get(user=user)
    resp = client.get(
        "/api/me", headers=dict(authorization=f"Bearer {token.access_token}"))
    assert resp.status_code == 200
    assert resp.json["email"] == user.email
    assert resp.json["name"] == user.name

    # Test invalid token:
    resp = client.get("/api/me", headers=dict(authorization="Bearer INVALID"))
    assert resp.status_code == 401

    # Test expired token:
    token.expires = datetime(1971, 1, 1)
    token.save()
    resp = client.get(
        "/api/me", headers=dict(authorization=f"Bearer {token.access_token}"))
    assert resp.status_code == 401
Exemplo n.º 21
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
Exemplo n.º 22
0
def test_tuakiri_login(client):
    """
    Test logging attempt via Shibboleth.

    After getting logged in a new user entry shoulg be created.
    """
    rv = client.get("/Tuakiri/login",
                    headers={
                        "Auedupersonsharedtoken": "ABC123",
                        "Sn": "LAST NAME/SURNAME/FAMILY NAME",
                        'Givenname': "FIRST NAME/GIVEN NAME",
                        "Mail": "*****@*****.**",
                        "O": "ORGANISATION 123",
                        "Displayname": "TEST USER FROM 123",
                        "Unscoped-Affiliation": "staff",
                        "Eppn": "*****@*****.**"
                    })

    assert rv.status_code == 302
    u = User.get(email="*****@*****.**")
    assert u.name == "TEST USER FROM 123", "Expected to have the user in the DB"
    assert u.first_name == "FIRST NAME/GIVEN NAME"
    assert u.last_name == "LAST NAME/SURNAME/FAMILY NAME"
Exemplo n.º 23
0
def test_user_org_link_org_constraint(test_models):
    user = User.get(id=1)
    uo = UserOrg(user=user, org_id=999999)
    with pytest.raises(Organisation.DoesNotExist):
        uo.save()
Exemplo n.º 24
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()
Exemplo n.º 25
0
def test_proxy_get_profile(client):
    """Test the echo endpoint."""
    user = User.get(email="*****@*****.**")
    token = Token.get(user=user)
    orcid_id = "0000-0000-0000-00X3"

    with patch("orcid_hub.apis.requests.Session.send") as mocksend:
        mockresp = MagicMock(status_code=200)
        mockresp.raw.stream = lambda *args, **kwargs: iter(
            [b"""{"data": "TEST"}"""])
        mockresp.raw.headers = {
            "Server": "TEST123",
            "Content-Type": "application/json;charset=UTF-8",
            "Transfer-Encoding": "chunked",
            "Connection": "keep-alive",
            "Access-Control-Allow-Origin": "*",
            "Cache-Control": "no -cache, no-store, max-age=0, must-revalidate",
            "Pragma": "no-cache",
            "Expires": "0",
        }
        mocksend.return_value = mockresp
        resp = client.get(
            f"/orcid/api/v2.23/{orcid_id}",
            headers=dict(authorization=f"Bearer {token.access_token}"))
        assert resp.status_code == 200
        args, kwargs = mocksend.call_args
        assert kwargs["stream"]
        assert args[0].url == f"https://api.sandbox.orcid.org/v2.23/{orcid_id}"
        assert args[0].headers[
            "Authorization"] == "Bearer ORCID-TEST-ACCESS-TOKEN"
        assert resp.json == {"data": "TEST"}

    with patch("orcid_hub.apis.requests.Session.send") as mocksend:
        mockresp = MagicMock(status_code=201)
        mockresp.raw.stream = lambda *args, **kwargs: iter(
            [b"""{"data": "TEST"}"""])
        mockresp.raw.headers = {
            "Server": "TEST123",
            "Content-Type": "application/json;charset=UTF-8",
            "Transfer-Encoding": "chunked",
            "Connection": "keep-alive",
            "Access-Control-Allow-Origin": "*",
            "Cache-Control": "no -cache, no-store, max-age=0, must-revalidate",
            "Pragma": "no-cache",
            "Loction": "TEST-LOCATION",
            "Expires": "0",
        }
        mocksend.return_value = mockresp
        resp = client.post(
            f"/orcid/api/v2.23/{orcid_id}/SOMETHING-MORE",
            headers=dict(authorization=f"Bearer {token.access_token}"),
            data=b"""{"data": "REQUEST"}""")
        assert resp.status_code == 201
        args, kwargs = mocksend.call_args
        assert kwargs["stream"]
        assert args[
            0].url == f"https://api.sandbox.orcid.org/v2.23/{orcid_id}/SOMETHING-MORE"
        assert args[0].headers[
            "Authorization"] == "Bearer ORCID-TEST-ACCESS-TOKEN"
        assert resp.json == {"data": "TEST"}

    # malformatted ORCID ID:
    resp = client.get(
        "/orcid/api/v2.23/NOT-ORCID-ID/PATH",
        headers=dict(authorization=f"Bearer {token.access_token}"))
    assert resp.status_code == 415

    # wrong version number:
    resp = client.get(
        f"/orcid/api/v1.23_ERROR/{orcid_id}/PATH",
        headers=dict(authorization=f"Bearer {token.access_token}"))
    assert resp.status_code == 404
    assert resp.json == {
        "error": "Resource not found",
        "message": "Incorrect version: v1.23_ERROR"
    }

    # no ORCID access token
    resp = client.get(
        "/orcid/api/v2.23/0000-0000-0000-11X2/PATH",
        headers=dict(authorization=f"Bearer {token.access_token}"))
    assert resp.status_code == 403
Exemplo n.º 26
0
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()
Exemplo n.º 27
0
def test_user_and_token_api(client, resource, version):
    """Test the echo endpoint."""
    user = User.get(email="*****@*****.**")
    org2_user = User.get(email="*****@*****.**")
    resp = client.get(f"/api/{version}/{resource}/ABC123",
                      headers=dict(authorization="Bearer TEST"))
    assert resp.status_code == 400
    assert "error" in resp.json
    assert "incorrect identifier" in resp.json["error"].lower()

    resp = client.get(f"/api/{version}/{resource}/0000-0000-0000-0000",
                      headers=dict(authorization="Bearer TEST"))
    assert resp.status_code == 400
    assert "error" in resp.json
    assert "incorrect identifier" in resp.json["error"].lower()

    resp = client.get(f"/api/{version}/{resource}/[email protected]",
                      headers=dict(authorization="Bearer TEST"))
    assert resp.status_code == 404
    assert "error" in resp.json
    assert "not found" in resp.json["error"].lower()

    resp = client.get(f"/api/{version}/{resource}/0000-0000-0000-0001",
                      headers=dict(authorization="Bearer TEST"))
    assert resp.status_code == 404
    assert "error" in resp.json
    assert "not found" in resp.json["error"].lower()

    for identifier in [
            user.email,
            user.orcid,
    ]:
        resp = client.get(f"/api/{version}/{resource}/{identifier}",
                          headers=dict(authorization="Bearer TEST"))
        assert resp.status_code == 200
        if resource == "users":
            assert resp.json["email"] == user.email
            assert resp.json["eppn"] == user.eppn
            assert resp.json["orcid"] == user.orcid
        else:
            token = OrcidToken.get(user_id=user.id)
            assert resp.json["access_token"] == token.access_token

    if resource == "users":  # test user listing
        resp = client.get(f"/api/{version}/{resource}",
                          headers=dict(authorization="Bearer TEST"))
        assert resp.status_code == 200
        assert len(resp.json) == 11

        resp = client.get(
            f"/api/{version}/{resource}?page=INVALID&page_size=INVALID",
            headers=dict(authorization="Bearer TEST"))
        assert resp.status_code == 200
        assert len(resp.json) == 11

        resp = client.get(f"/api/{version}/{resource}?page=2&page_size=3",
                          headers=dict(authorization="Bearer TEST"))
        assert resp.status_code == 200
        assert len(resp.json) == 3

        resp = client.get(f"/api/{version}/{resource}?page_size=3",
                          headers=dict(authorization="Bearer TEST"))
        assert resp.status_code == 200
        assert len(resp.json) == 3

        resp = client.get(f"/api/{version}/{resource}?page=42",
                          headers=dict(authorization="Bearer TEST"))
        assert resp.status_code == 200
        assert len(resp.json) == 0

        resp = client.get(f"/api/{version}/{resource}?from_date=ABCD",
                          headers=dict(authorization="Bearer TEST"))
        assert resp.status_code == 422

        resp = client.get(f"/api/{version}/{resource}?from_date=2018-01-01",
                          headers=dict(authorization="Bearer TEST"))
        assert resp.status_code == 200
        assert len(resp.json) == 4

        resp = client.get(f"/api/{version}/{resource}?to_date=2018-01-01",
                          headers=dict(authorization="Bearer TEST"))
        assert resp.status_code == 200
        assert len(resp.json) == 7

        resp = client.get(
            f"/api/{version}/{resource}?from_date=2017-12-20&to_date=2017-12-21",
            headers=dict(authorization="Bearer TEST"))
        assert resp.status_code == 200
        assert len(resp.json) == 2

    if resource == "tokens":
        user2 = User.get(email="*****@*****.**")
        for identifier in [
                user2.email,
                user2.orcid,
        ]:
            resp = client.get(f"/api/{version}/tokens/{identifier}",
                              headers=dict(authorization="Bearer TEST"))
            assert resp.status_code == 404
            assert "error" in resp.json

    resp = client.get(f"/api/{version}/{resource}/{org2_user.email}",
                      headers=dict(authorization="Bearer TEST"))
    assert resp.status_code == 404
    assert "error" in resp.json
Exemplo n.º 28
0
def test_user_cv(client, mocker):
    """Test user CV."""
    user0 = User.get(email="*****@*****.**")
    client.login(user0)
    resp = client.get("/user_cv")
    assert resp.status_code == 302
    client.logout()

    user = User.get(email="*****@*****.**")
    client.login(user, follow_redirects=True)

    resp = client.get("/user_cv")
    assert resp.status_code == 302
    url = urlparse(resp.location)
    assert url.path == '/link'

    OrcidToken.create(access_token="ABC12345678901",
                      user=user,
                      org=user.organisation,
                      scope="/scope/read-limited")

    mocker.patch("orcid_hub.reports.MemberAPI.get_record",
                 side_effect=Exception("ERROR!!!"))
    resp = client.get("/user_cv", follow_redirects=True)
    assert resp.status_code == 200
    assert b"iframe" not in resp.data
    assert b"ERROR!!!" in resp.data

    get_record = mocker.patch(
        "orcid_hub.reports.MemberAPI.get_record",
        return_value=json.loads(json.dumps({
            "orcid-identifier": {
                "uri": "http://sandbox.orcid.org/0000-0001-7027-8698",
                "path": "0000-0001-7027-8698",
                "host": "sandbox.orcid.org"
            },
            "preferences": {
                "locale": "EN"
            },
            "history": {
                "creation-method": "MEMBER_REFERRED",
                "completion-date": None,
                "submission-date": {
                    "value": 1505964892638
                },
                "last-modified-date": {
                    "value": 1505965202659
                },
                "claimed": True,
                "source": None,
                "deactivation-date": None,
                "verified-email": False,
                "verified-primary-email": False
            },
            "person": {
                "last-modified-date": {
                    "value": 1505964892861
                },
                "name": {
                    "created-date": {
                        "value": 1505964892638
                    },
                    "last-modified-date": {
                        "value": 1505964892861
                    },
                    "given-names": {
                        "value": "Sally"
                    },
                    "family-name": {
                        "value": "Simpsond"
                    },
                    "credit-name": None,
                    "source": None,
                    "visibility": "PUBLIC",
                    "path": "0000-0001-7027-8698"
                },
                "other-names": {
                    "last-modified-date": None,
                    "other-name": [],
                    "path": "/0000-0001-7027-8698/other-names"
                },
                "biography": None,
                "researcher-urls": {
                    "last-modified-date": None,
                    "researcher-url": [],
                    "path": "/0000-0001-7027-8698/researcher-urls"
                },
                "emails": {
                    "last-modified-date": {
                        "value": 1505964892861
                    },
                    "email": [{
                        "created-date": {
                            "value": 1505964892861
                        },
                        "last-modified-date": {
                            "value": 1505964892861
                        },
                        "source": {
                            "source-orcid": {
                                "uri":
                                "http://sandbox.orcid.org/0000-0001-7027-8698",
                                "path": "0000-0001-7027-8698",
                                "host": "sandbox.orcid.org"
                            },
                            "source-client-id": None,
                            "source-name": {
                                "value": "Sally Simpson"
                            }
                        },
                        "email": "*****@*****.**",
                        "path": None,
                        "visibility": "LIMITED",
                        "verified": False,
                        "primary": True,
                        "put-code": None
                    }],
                    "path":
                    "/0000-0001-7027-8698/email"
                },
                "addresses": {
                    "last-modified-date": None,
                    "address": [],
                    "path": "/0000-0001-7027-8698/address"
                },
                "keywords": {
                    "last-modified-date": None,
                    "keyword": [],
                    "path": "/0000-0001-7027-8698/keywords"
                },
                "external-identifiers": {
                    "last-modified-date": None,
                    "external-identifier": [],
                    "path": "/0000-0001-7027-8698/external-identifiers"
                },
                "path": "/0000-0001-7027-8698/person"
            },
            "activities-summary": {
                "last-modified-date": None,
                "educations": {
                    "last-modified-date": None,
                    "education-summary": [],
                    "path": "/0000-0001-7027-8698/educations"
                },
                "employments": {
                    "last-modified-date": None,
                    "employment-summary": [],
                    "path": "/0000-0001-7027-8698/employments"
                },
                "fundings": {
                    "last-modified-date": None,
                    "group": [],
                    "path": "/0000-0001-7027-8698/fundings"
                },
                "peer-reviews": {
                    "last-modified-date": None,
                    "group": [],
                    "path": "/0000-0001-7027-8698/peer-reviews"
                },
                "works": {
                    "last-modified-date": None,
                    "group": [],
                    "path": "/0000-0001-7027-8698/works"
                },
                "path": "/0000-0001-7027-8698/activities"
            },
            "path": "/0000-0001-7027-8698"
        }),
                                object_pairs_hook=NestedDict))

    resp = client.get("/user_cv")
    assert resp.status_code == 200
    assert b"iframe" in resp.data
    assert user.first_name.encode() not in resp.data

    resp = client.get("/user_cv/show")
    assert resp.status_code == 200
    assert user.name.encode() in resp.data
    get_record.assert_called_once_with()

    get_record.reset_mock()
    resp = client.get("/user_cv/download")
    assert resp.status_code == 200
    assert user.name.replace(' ', '_') in resp.headers["Content-Disposition"]
    assert b"content.xml" in resp.data
    get_record.asser_not_called()
Exemplo n.º 29
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
Exemplo n.º 30
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