def test_db_api(client): """Test DB API.""" resp = client.get("/data/api/v0.1/organisations/", headers=dict(authorization="Bearer TEST")) assert resp.status_code == 200 assert "objects" in resp.json assert len(resp.json["objects"]) == 4 resp = client.get("/data/api/v0.1/tasks/", headers=dict(authorization="Bearer TEST")) assert resp.status_code == 200 assert "objects" in resp.json assert len(resp.json["objects"]) == 0 org = Organisation.select().where( Organisation.tuakiri_name.is_null(False)).first() resp = client.get(f"/data/api/v0.1/organisations/{org.id}", headers=dict(authorization="Bearer TEST")) assert resp.status_code == 200 assert resp.json["name"] == org.name assert resp.json["tuakiri_name"] == org.tuakiri_name org = Organisation.select().where(Organisation.tuakiri_name.is_null(False), Organisation.id != org.id).first() resp = client.get(f"/data/api/v0.1/organisations/{org.id}", headers=dict(authorization="Bearer TEST")) assert resp.status_code == 200 assert resp.json["name"] == org.name assert resp.json["tuakiri_name"] == org.tuakiri_name
def test_test_database(models): """Test of the consitency of the test database.""" assert Organisation.select().count() == 10 assert User.select().count() == 63 assert OrcidToken.select().count() == 60 assert AffiliationRecord.select().count() == 10 assert FundingRecord.select().count() == 10 assert FundingContributor.select().count() == 10 assert FundingInvitee.select().count() == 10 assert ExternalId.select().count() == 10 assert WorkRecord.select().count() == 10 assert WorkContributor.select().count() == 10 assert WorkExternalId.select().count() == 10 assert WorkInvitee.select().count() == 10 assert PeerReviewRecord.select().count() == 10 assert PeerReviewExternalId.select().count() == 10 assert PeerReviewInvitee.select().count() == 10 assert ResearcherUrlRecord.select().count() == 10 assert OtherNameRecord.select().count() == 10 assert KeywordRecord.select().count() == 10 assert Task.select().count() == 30 assert UserOrgAffiliation.select().count() == 30 assert User.get(id=43).admin_for.count() == 10 assert User.get(id=1).admin_for.count() == 0 assert User.get(id=42).admin_for.count() > 0 assert User.get(id=2).organisations.count() > 0 assert Organisation.get(id=1).admins.count() == 1 assert Organisation.get(id=5).users.count() > 0 assert Organisation.get(id=5).admins.count() > 0 assert User.select().where(User.orcid == User.get( email="*****@*****.**").orcid).count() == 3 assert len(User.get(email="*****@*****.**").org_links) == 3 user = User.get(email="*****@*****.**") available_organisations = user.available_organisations assert available_organisations.count() == 10 admin = User.create(email="*****@*****.**", organisation=user.organisation, confirmed=True, first_name="TEST", last_name="ADMIN", roles=Role.ADMIN) ui = UserInvitation.create(email=user.email, invitee=user, inviter=admin, token="TOKEN-123") admin.delete_instance() ui = UserInvitation.get(ui.id) assert ui.inviter_id is None user.delete_instance() assert not UserInvitation.select().where(UserInvitation.id == ui.id).exists() org = Organisation.select().limit(1).first() user = User.select().limit(1).first() ot = OrcidToken.create(user=user, org=org, scope="S1,S2,S3") assert len(ot.scopes) == 3 ot.scopes = ["A", "B", "C", "D"] assert ot.scope == "A,B,C,D"
def test_process_tasks(app, mocker): """Test task hanging.""" send_email = mocker.patch("orcid_hub.utils.send_email") org = Organisation.select().first() Task.insert_many( dict(org=org, updated_at=utils.datetime.utcnow(), filename=tt.name, task_type=tt.value) for tt in TaskType).execute() utils.process_tasks() send_email.assert_not_called() Task.insert_many( dict(org=org, created_by=org.tech_contact, created_at=utils.datetime(2017, 1, 1), updated_at=utils.datetime(2017, 1, 1), filename=tt.name, task_type=tt.value) for tt in TaskType).execute() utils.process_tasks() send_email.assert_called() task_count = Task.select().count() utils.process_tasks() assert Task.select().count() == task_count // 2
def test_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
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"
def test_researcher_urls(models): org = Organisation.select().first() raw_data0 = open(os.path.join(os.path.dirname(__file__), "data", "researchurls.json"), "r").read() data0 = load_yaml_json("researchurls.json", raw_data0) assert isinstance(data0, list) and isinstance(data0[0], NestedDict) task0 = ResearcherUrlRecord.load_from_json(filename="researchurls000.json", source=raw_data0, org=org) data = task0.to_dict() raw_data = json.dumps(data, cls=JSONEncoder) task = ResearcherUrlRecord.load_from_json(filename="researchurls001.json", source=raw_data, org=org) assert len(data0) == len(task.to_dict()["records"])
def test_other_names(models): org = Organisation.select().first() raw_data0 = open(os.path.join(os.path.dirname(__file__), "data", "othernames.json"), "r").read() data0 = load_yaml_json("othernames000.json", raw_data0) assert isinstance(data0, list) and isinstance(data0[0], NestedDict) data0 = load_yaml_json(None, source=raw_data0, content_type="json") assert isinstance(data0, list) and isinstance(data0[0], NestedDict) data0 = load_yaml_json(None, source=raw_data0) assert isinstance(data0, list) and isinstance(data0[0], NestedDict) task0 = OtherNameRecord.load_from_json(filename="othernames000.json", source=raw_data0, org=org) data = task0.to_dict() raw_data = json.dumps(data, cls=JSONEncoder) task = OtherNameRecord.load_from_json(filename="othernames001.json", source=raw_data, org=org) assert len(data0) == len(task.to_dict()["records"])
def test_work_task(models): org = Organisation.select().first() raw_data0 = open(os.path.join(os.path.dirname(__file__), "data", "example_works.json"), "r").read() data0 = load_yaml_json("test0001.json", raw_data0) assert isinstance(data0, list) and isinstance(data0[0], NestedDict) data0 = load_yaml_json(None, source=raw_data0, content_type="json") assert isinstance(data0, list) and isinstance(data0[0], NestedDict) data0 = load_yaml_json(None, source=raw_data0) assert isinstance(data0, list) and isinstance(data0[0], NestedDict) task0 = WorkRecord.load_from_json(filename="work0042.json", source=raw_data0, org=org) data = task0.to_export_dict() raw_data = json.dumps(data, cls=JSONEncoder) task = WorkRecord.load_from_json(filename="work0001.json", source=raw_data, org=org) export = task.to_export_dict() for a in ["id", "filename", "created-at", "updated-at"]: del(export[a]) del(data[a]) assert data == export
def test_org_count(test_models): assert Organisation.select().count() == 10
def test_org_webhook_api(client, mocker): """Test Organisation webhooks.""" mocker.patch.object( utils.requests, "post", lambda *args, **kwargs: Mock( status_code=201, json=lambda: dict( access_token="ABC123", refresh_token="REFRESH_ME", expires_in=123456789 ), ), ) mockput = mocker.patch.object(utils.requests, "put") mockdelete = mocker.patch.object(utils.requests, "delete") org = client.data["org"] admin = org.tech_contact send_email = mocker.patch("orcid_hub.utils.send_email") api_client = Client.get(org=org) resp = client.post( "/oauth/token", data=dict( grant_type="client_credentials", client_id=api_client.client_id, client_secret=api_client.client_secret, scope="/webhook", ), ) assert resp.status_code == 200 data = json.loads(resp.data) api_client = Client.get(client_id="CLIENT_ID") token = Token.select().where(Token.user == admin, Token._scopes == "/webhook").first() assert data["access_token"] == token.access_token assert data["expires_in"] == client.application.config["OAUTH2_PROVIDER_TOKEN_EXPIRES_IN"] assert data["token_type"] == token.token_type client.access_token = token.access_token resp = client.put("/api/v1/webhook/INCORRECT-WEBHOOK-URL") assert resp.status_code == 415 assert json.loads(resp.data) == { "error": "Invalid call-back URL", "message": "Invalid call-back URL: INCORRECT-WEBHOOK-URL", } # Webhook registration response: mockresp = MagicMock(status_code=201, data=b"") mockresp.headers = { "Server": "TEST123", "Connection": "keep-alive", "Pragma": "no-cache", "Expires": "0", } mockput.return_value = mockresp # Webhook deletion response: mockresp = MagicMock(status_code=204, data=b"") mockresp.headers = { "Seresper": "TEST123", "Connection": "keep-alive", "Location": "TEST-LOCATION", "Pragma": "no-cache", "Expires": "0", } mockdelete.return_value = mockresp resp = client.put("/api/v1/webhook/http%3A%2F%2FCALL-BACK") assert resp.status_code == 200 resp = client.put( "/api/v1/webhook/http%3A%2F%2FCALL-BACK", data=dict(enabled=True, url="https://CALL-BACK.edu/callback"), ) assert resp.status_code == 201 server_name = client.application.config["SERVER_NAME"] mockput.assert_has_calls( [ call( "https://api.sandbox.orcid.org/1001-0001-0001-0001/webhook/" f"https%3A%2F%2F{server_name}%2Fservices%2F21%2Fupdated", headers={ "Accept": "application/json", "Authorization": "Bearer ABC123", "Content-Length": "0", }, ), call( "https://api.sandbox.orcid.org/0000-0000-0000-00X3/webhook/" f"https%3A%2F%2F{server_name}%2Fservices%2F22%2Fupdated", headers={ "Accept": "application/json", "Authorization": "Bearer ABC123", "Content-Length": "0", }, ), call( "https://api.sandbox.orcid.org/0000-0000-0000-11X2/webhook/" f"https%3A%2F%2F{server_name}%2Fservices%2F30%2Fupdated", headers={ "Accept": "application/json", "Authorization": "Bearer ABC123", "Content-Length": "0", }, ), ] ) q = OrcidToken.select().where(OrcidToken.org == org, OrcidToken.scopes == "/webhook") assert q.exists() assert q.count() == 1 orcid_token = q.first() assert orcid_token.access_token == "ABC123" assert orcid_token.refresh_token == "REFRESH_ME" assert orcid_token.expires_in == 123456789 assert orcid_token.scopes == "/webhook" # deactivate: resp = client.delete("/api/v1/webhook/http%3A%2F%2FCALL-BACK") assert resp.status_code == 200 assert "job-id" in resp.json # activate with all options: mockput.reset_mock() resp = client.put( "/api/v1/webhook", data={ "enabled": True, "append-orcid": True, "apikey": "APIKEY123", "email-notifications-enabled": True, "notification-email": "*****@*****.**", }, ) server_name = client.application.config["SERVER_NAME"] mockput.assert_has_calls( [ call( "https://api.sandbox.orcid.org/1001-0001-0001-0001/webhook/" f"https%3A%2F%2F{server_name}%2Fservices%2F21%2Fupdated", headers={ "Accept": "application/json", "Authorization": "Bearer ABC123", "Content-Length": "0", }, ), call( "https://api.sandbox.orcid.org/0000-0000-0000-00X3/webhook/" f"https%3A%2F%2F{server_name}%2Fservices%2F22%2Fupdated", headers={ "Accept": "application/json", "Authorization": "Bearer ABC123", "Content-Length": "0", }, ), call( "https://api.sandbox.orcid.org/0000-0000-0000-11X2/webhook/" f"https%3A%2F%2F{server_name}%2Fservices%2F30%2Fupdated", headers={ "Accept": "application/json", "Authorization": "Bearer ABC123", "Content-Length": "0", }, ), ] ) # Link other org to the users org2 = Organisation.select().where(Organisation.id != org.id).first() UserOrg.insert_many([dict(user_id=u.id, org_id=org2.id) for u in org.users]).execute() org2.webhook_enabled = True org2.save() resp = client.delete("/api/v1/webhook") mockput.reset_mock() resp = client.put( "/api/v1/webhook", data={ "enabled": False, "url": "https://CALL-BACK.edu/callback", "append-orcid": False, "email-notifications-enabled": True, "notification-email": "*****@*****.**", }, ) mockput.assert_not_called() # Test update summary: User.update( orcid_updated_at=datetime.date.today().replace(day=1) - datetime.timedelta(days=15) ).execute() send_email.reset_mock() utils.send_orcid_update_summary() send_email.assert_called_once() client.logout()