def test_get_dataset(mdb): """ Confirm that datasets are returned correctly. Tests: * Confirm that the correct dataset is returned * Confirm that the dataset is not listed in ``related`` """ session = requests.Session() order_id = helpers.add_order() ds_id = helpers.add_dataset(order_id) ds_id2 = helpers.add_dataset(order_id) coll_id = helpers.add_collection([ds_id]) coll_id2 = helpers.add_collection([ds_id]) helpers.as_user(session, helpers.USERS["edit"]) order_data = mdb["orders"].find_one({"_id": order_id}) response = helpers.make_request(session, f"/api/v1/dataset/{ds_id}") assert response.code == 200 result = response.data["dataset"] assert result["order"]["id"] == str(order_id) assert set(entry["id"] for entry in result["related"]) == {str(ds_id2)} assert set(entry["id"] for entry in result["collections"]) == { str(coll_id), str(coll_id2) } assert set(entry["id"] for entry in result["authors"]) == set( str(entry) for entry in order_data["authors"]) assert set(entry["id"] for entry in result["generators"]) == set( str(entry) for entry in order_data["generators"]) assert result["organisation"]["id"] == str(order_data["organisation"]) assert set(entry["id"] for entry in result["editors"]) == set( str(entry) for entry in order_data["editors"]) helpers.as_user(session, helpers.USERS["base"]) order_data = mdb["orders"].find_one({"_id": order_id}) response = helpers.make_request(session, f"/api/v1/dataset/{ds_id}") assert response.code == 200 result = response.data["dataset"] assert "order" not in result assert set(entry["id"] for entry in result["related"]) == {str(ds_id2)} assert set(entry["id"] for entry in result["collections"]) == { str(coll_id), str(coll_id2) } assert set(entry["id"] for entry in result["authors"]) == set( str(entry) for entry in order_data["authors"]) assert set(entry["id"] for entry in result["generators"]) == set( str(entry) for entry in order_data["generators"]) assert result["organisation"]["id"] == str(order_data["organisation"]) assert "editors" not in result mdb["orders"].delete_one({"_id": order_id}) mdb["datasets"].delete_one({"_id": ds_id}) mdb["datasets"].delete_one({"_id": ds_id2}) mdb["collections"].delete_one({"_id": coll_id}) mdb["collections"].delete_one({"_id": coll_id2})
def test_get_collection_logs_permissions(mdb): """ Confirm that collection logs can only be accessed by the intended users. Checks: * DATA_MANAGEMENT can access any log. * DATA_EDIT can access entries where they are editors. * User in editors, but not DATA_EDIT cannot access logs. * Other users cannot access logs. """ collections = list(mdb["collections"].aggregate([{ "$sample": { "size": 5 } }])) session = requests.Session() helpers.as_user(session, helpers.USERS["data"]) for collection in collections: response = make_request(session, f'/api/v1/collection/{collection["_id"]}/log', ret_json=True) assert response.code == 200 assert "logs" in response.data coll_id = helpers.add_collection() responses = make_request_all_roles(f"/api/v1/collection/{coll_id}/log", ret_json=True) for response in responses: if response.role in ("edit", "data", "root"): assert response.code == 200 assert "logs" in response.data elif response.role == "no-login": assert response.code == 401 assert not response.data else: assert response.code == 403 assert not response.data base_user = mdb["users"].find_one({"auth_ids": helpers.USERS["base"]}) mdb["collections"].update_one({"_id": coll_id}, {"$set": { "editors": [base_user["_id"]] }}) for collection in collections: responses = make_request_all_roles( f'/api/v1/collection/{collection["_id"]}/log', ret_json=True) for response in responses: if response.role in ("data", "root"): assert response.code == 200 assert "logs" in response.data elif response.role == "no-login": assert response.code == 401 assert not response.data else: assert response.code == 403 assert not response.data
def test_delete_order_data(mdb): """ Confirm that order deletion works as intended. Checks: * Entry is deleted - A delete log is created for the order * Related datasets are deleted - A delete log is created for each dataset * References to datasets from collections are deleted - An edit log is created for each collection with removed datasets """ session = requests.Session() helpers.as_user(session, helpers.USERS["data"]) order_id = helpers.add_order() ds_ids = [helpers.add_dataset(order_id) for _ in range(5)] extra_ds_ids = [ ds["_id"] for ds in mdb["datasets"].aggregate([{ "$sample": { "size": 2 } }]) ] collection_id = helpers.add_collection(ds_ids + extra_ds_ids) response = helpers.make_request(session, f"/api/v1/order/{order_id}", method="DELETE", ret_json=True) assert response.code == 200 assert not response.data assert (mdb["logs"].count_documents({ "data_type": "order", "action": "delete", "data._id": order_id }) == 1) assert not mdb["datasets"].find_one({"_id": ds_ids}) assert mdb["logs"].count_documents({ "data_type": "dataset", "action": "delete", "data._id": { "$in": ds_ids } }) == len(ds_ids) coll_data = mdb["collections"].find_one({"_id": collection_id}) for ds_id in ds_ids: assert ds_id not in coll_data["datasets"] assert mdb["logs"].find_one({ "data_type": "collection", "action": "edit", "data._id": collection_id }) # clean up added orders for entry in mdb["orders"].find(TEST_LABEL): response = helpers.make_request(session, f'/api/v1/order/{entry["_id"]}', method="DELETE") assert response.code == 200 assert not mdb["orders"].find_one({"_id": entry["_id"]}) assert not mdb["datasets"].find_one( {"_id": { "$in": entry["datasets"] }}) assert not mdb["collections"].find_one( {"datasets": { "$in": entry["datasets"] }})
def test_delete_collection(mdb): """ Confirm that collection deletions work as intended. Checks: * DATA_MANAGEMENT can delete any entry. * Users in editors with DATA_EDIT can delete the entry. * No other users can delete entries. """ session = requests.Session() collections = [ entry["_id"] for entry in mdb["collections"].find({"tags": "testing"}) ] collections.append(helpers.add_collection()) helpers.as_user(session, USERS["data"]) for coll_id in collections: response = make_request(session, f"/api/v1/collection/{coll_id}", method="DELETE") assert response.code == 200 assert not response.data assert not mdb["collections"].find_one({"_id": coll_id}) coll_id = helpers.add_collection() for role in USERS: helpers.as_user(session, USERS[role]) if role in ("data", "root", "edit"): continue response = helpers.make_request(session, f"/api/v1/collection/{coll_id}", method="DELETE") if role == "no-login": assert response.code == 401 else: assert response.code == 403 assert not response.data assert mdb["collections"].find_one({"_id": coll_id}) helpers.as_user(session, USERS["edit"]) response = make_request(session, f"/api/v1/collection/{coll_id}", method="DELETE") assert response.code == 200 assert not response.data assert not mdb["collections"].find_one({"_id": coll_id}) coll_id = helpers.add_collection() mdb["collections"].update_one({"_id": coll_id}, {"$set": {"editors": []}}) for role in USERS: helpers.as_user(session, USERS[role]) if role in ("data", "root"): continue response = helpers.make_request(session, f"/api/v1/collection/{coll_id}", method="DELETE") if role == "no-login": assert response.code == 401 else: assert response.code == 403 assert not response.data assert mdb["collections"].find_one({"_id": coll_id}) helpers.as_user(session, USERS["data"]) response = make_request(session, f"/api/v1/collection/{coll_id}", method="DELETE") assert response.code == 200 assert not response.data assert not mdb["collections"].find_one({"_id": coll_id})
def test_update_collection_bad(): """ Confirm that bad inputs are handled gracefully. Checks: * Bad field * Bad uuid in list * No data * Bad collection identifiers (uuid, random text) """ coll_id = helpers.add_collection() indata = {"bad_tag": "value"} responses = make_request_all_roles( f"/api/v1/collection/{coll_id}", method="PATCH", data=indata, ret_json=True, ) for response in responses: if response.role in ("edit", "data", "root"): assert response.code == 400 assert not response.data elif response.role == "no-login": assert response.code == 401 assert not response.data else: assert response.code == 403 assert not response.data indata = { "description": "Test description", "editors": [str(uuid.uuid4())], "title": "Test bad update title", } responses = make_request_all_roles( f"/api/v1/collection/{coll_id}", method="PATCH", data=indata, ret_json=True, ) for response in responses: if response.role in ("edit", "data", "root"): assert response.code == 400 assert not response.data elif response.role == "no-login": assert response.code == 401 assert not response.data else: assert response.code == 403 assert not response.data responses = make_request_all_roles( f"/api/v1/collection/{coll_id}", method="PATCH", ret_json=True, ) for response in responses: if response.role in ("edit", "data", "root"): assert response.code == 400 assert not response.data elif response.role == "no-login": assert response.code == 401 assert not response.data else: assert response.code == 403 assert not response.data indata = {"title": "Test bad update title"} responses = make_request_all_roles( f"/api/v1/collection/{uuid.uuid4()}", method="PATCH", data=indata, ret_json=True, ) for response in responses: if response.role == "no-login": assert response.code == 401 assert not response.data elif response.role in ("edit", "root", "data"): assert response.code == 404 assert not response.data else: assert response.code == 403 assert not response.data indata = {"title": "Test bad update title"} responses = make_request_all_roles( f"/api/v1/collection/{random_string()}", method="PATCH", data=indata, ret_json=True, ) for response in responses: if response.role == "no-login": assert response.code == 401 assert not response.data elif response.role in ("edit", "root", "data"): assert response.code == 404 assert not response.data else: assert response.code == 403 assert not response.data
def test_delete_dataset(mdb): """ Confirm that datasets are deleted correctly. Tests: * Check that datasets are deleted correctly * Check that references to the dataset are deleted in orders and collections * Check that logs are created correctly """ session = requests.Session() order_id = helpers.add_order() ds_id = helpers.add_dataset(order_id) coll_id = helpers.add_collection([ds_id]) coll_id2 = helpers.add_collection([ds_id]) helpers.as_user(session, helpers.USERS["edit"]) response = helpers.make_request(session, f"/api/v1/dataset/{ds_id}", method="DELETE") assert response.code == 200 assert not mdb["datasets"].find_one({"_id": ds_id}) assert (mdb["logs"].count_documents({ "data_type": "dataset", "action": "delete", "data._id": ds_id }) == 1) assert not mdb["orders"].find_one({"datasets": ds_id}) assert (mdb["logs"].count_documents({ "data_type": "order", "comment": "Dataset deleted", "action": "edit", "data._id": order_id, }) == 1) assert not mdb["collections"].find_one({"datasets": ds_id}) assert (mdb["logs"].count_documents({ "data_type": "collection", "comment": "Dataset deleted", "action": "edit", "data._id": { "$in": (coll_id, coll_id2) }, }) == 2) # clean up added datasets for ds in mdb["datasets"].find(TEST_LABEL): response = helpers.make_request(session, f'/api/v1/dataset/{ds["_id"]}', method="DELETE") if response.code == 200: assert not mdb["datasets"].find_one({"_id": ds["_id"]}) assert not mdb["orders"].find_one({"datasets": ds["_id"]}) assert not mdb["collections"].find_one({"datasets": ds["_id"]}) helpers.as_user(session, helpers.USERS["data"]) # clean up added datasets for ds in mdb["datasets"].find(TEST_LABEL): response = helpers.make_request(session, f'/api/v1/dataset/{ds["_id"]}', method="DELETE") assert response.code == 200 assert not mdb["datasets"].find_one({"_id": ds["_id"]}) assert not mdb["orders"].find_one({"datasets": ds["_id"]}) assert not mdb["collections"].find_one({"datasets": ds["_id"]})