Beispiel #1
0
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})
Beispiel #2
0
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
Beispiel #3
0
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"]
            }})
Beispiel #4
0
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})
Beispiel #5
0
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
Beispiel #6
0
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"]})