Esempio n. 1
0
def should_return_error_when_trying_to_delete_dataset_with_versions() -> None:
    storage_bucket_name = get_param(ParameterName.STORAGE_BUCKET_NAME)
    with Dataset() as dataset, S3Object(
            file_object=BytesIO(),
            bucket_name=storage_bucket_name,
            key=
            f"{dataset.dataset_id}/{any_dataset_version_id()}/{any_safe_filename()}",
    ):
        response = entrypoint.lambda_handler(
            {
                "httpMethod": "DELETE",
                "body": {
                    "id": dataset.dataset_id
                }
            }, any_lambda_context())

    expected_message = (
        f"Conflict: Can’t delete dataset “{dataset.dataset_id}”: dataset versions still exist"
    )
    assert response == {
        "statusCode": HTTPStatus.CONFLICT,
        "body": {
            "message": expected_message
        },
    }
Esempio n. 2
0
def should_return_error_when_trying_to_delete_dataset_with_versions() -> None:
    with Dataset() as dataset, S3Object(
            file_object=BytesIO(),
            bucket_name=ResourceName.STORAGE_BUCKET_NAME.value,
            key=
            f"{dataset.dataset_id}/{any_dataset_version_id()}/{any_safe_filename()}",
    ):
        response = lambda_handler(
            {
                HTTP_METHOD_KEY: "DELETE",
                BODY_KEY: {
                    DATASET_ID_SHORT_KEY: dataset.dataset_id
                }
            },
            any_lambda_context(),
        )

    expected_message = (
        f"Conflict: Can’t delete dataset “{dataset.dataset_id}”: dataset versions still exist"
    )
    assert response == {
        STATUS_CODE_KEY: HTTPStatus.CONFLICT,
        BODY_KEY: {
            MESSAGE_KEY: expected_message
        },
    }
Esempio n. 3
0
def should_delete_dataset_with_no_versions() -> None:
    with Dataset() as dataset:
        response = lambda_handler(
            {
                HTTP_METHOD_KEY: "DELETE",
                BODY_KEY: {
                    DATASET_ID_SHORT_KEY: dataset.dataset_id
                }
            },
            any_lambda_context(),
        )

    assert response == {STATUS_CODE_KEY: HTTPStatus.NO_CONTENT, BODY_KEY: {}}
Esempio n. 4
0
def should_return_error_when_trying_to_delete_dataset_with_missing_id(
) -> None:
    response = lambda_handler({
        HTTP_METHOD_KEY: "DELETE",
        BODY_KEY: {}
    }, any_lambda_context())

    assert response == {
        STATUS_CODE_KEY: HTTPStatus.BAD_REQUEST,
        BODY_KEY: {
            MESSAGE_KEY:
            f"Bad Request: '{DATASET_ID_SHORT_KEY}' is a required property"
        },
    }
Esempio n. 5
0
def should_fail_if_updating_not_existing_dataset() -> None:
    dataset_id = any_dataset_id()

    body = {"id": dataset_id, "title": any_dataset_title()}
    response = entrypoint.lambda_handler({
        "httpMethod": "PATCH",
        "body": body
    }, any_lambda_context())

    assert response == {
        "statusCode": HTTPStatus.NOT_FOUND,
        "body": {
            "message": f"Not Found: dataset '{dataset_id}' does not exist"
        },
    }
Esempio n. 6
0
def should_fail_if_updating_not_existing_dataset() -> None:
    dataset_id = any_dataset_id()

    body = {DATASET_ID_SHORT_KEY: dataset_id, TITLE_KEY: any_dataset_title()}
    response = lambda_handler({
        HTTP_METHOD_KEY: "PATCH",
        BODY_KEY: body
    }, any_lambda_context())

    assert response == {
        STATUS_CODE_KEY: HTTPStatus.NOT_FOUND,
        BODY_KEY: {
            MESSAGE_KEY: f"Not Found: dataset '{dataset_id}' does not exist"
        },
    }
Esempio n. 7
0
def should_fail_if_updating_with_already_existing_dataset_title() -> None:
    dataset_title = any_dataset_title()
    body = {DATASET_ID_SHORT_KEY: any_dataset_id(), TITLE_KEY: dataset_title}

    with Dataset(title=dataset_title):
        response = lambda_handler({
            HTTP_METHOD_KEY: "PATCH",
            BODY_KEY: body
        }, any_lambda_context())

    assert response == {
        STATUS_CODE_KEY: HTTPStatus.CONFLICT,
        BODY_KEY: {
            MESSAGE_KEY: f"Conflict: dataset '{dataset_title}' already exists"
        },
    }
Esempio n. 8
0
def should_fail_if_post_request_containing_duplicate_dataset_title() -> None:
    dataset_title = any_dataset_title()
    body = {"title": dataset_title}

    with Dataset(title=dataset_title):
        response = entrypoint.lambda_handler(
            {
                "httpMethod": "POST",
                "body": body
            }, any_lambda_context())

    assert response == {
        "statusCode": HTTPStatus.CONFLICT,
        "body": {
            "message": f"Conflict: dataset '{dataset_title}' already exists"
        },
    }
Esempio n. 9
0
def should_fail_if_updating_with_already_existing_dataset_title() -> None:
    dataset_title = any_dataset_title()
    body = {"id": any_dataset_id(), "title": dataset_title}

    with Dataset(title=dataset_title):
        response = entrypoint.lambda_handler(
            {
                "httpMethod": "PATCH",
                "body": body
            }, any_lambda_context())

    assert response == {
        "statusCode": HTTPStatus.CONFLICT,
        "body": {
            "message": f"Conflict: dataset '{dataset_title}' already exists"
        },
    }
Esempio n. 10
0
def should_return_single_dataset(subtests: SubTests) -> None:
    # Given a dataset instance
    with Dataset() as dataset:
        body = {DATASET_ID_SHORT_KEY: dataset.dataset_id}

        # When requesting the dataset by ID and type
        response = lambda_handler({
            HTTP_METHOD_KEY: "GET",
            BODY_KEY: body
        }, any_lambda_context())
    logger.info("Response: %s", response)

    # Then we should get the dataset in return
    with subtests.test(msg="status code"):
        assert response[STATUS_CODE_KEY] == HTTPStatus.OK

    with subtests.test(msg="ID"):
        assert response[BODY_KEY][DATASET_ID_SHORT_KEY] == dataset.dataset_id
Esempio n. 11
0
def should_fail_if_post_request_containing_duplicate_dataset_title() -> None:
    dataset_title = any_dataset_title()
    body = {
        TITLE_KEY: dataset_title,
        DESCRIPTION_KEY: any_dataset_description()
    }

    with Dataset(title=dataset_title):
        response = lambda_handler({
            HTTP_METHOD_KEY: "POST",
            BODY_KEY: body
        }, any_lambda_context())

    assert response == {
        STATUS_CODE_KEY: HTTPStatus.CONFLICT,
        BODY_KEY: {
            MESSAGE_KEY: f"Conflict: dataset '{dataset_title}' already exists"
        },
    }
Esempio n. 12
0
def should_return_client_error_when_title_contains_unsupported_characters(
    subtests: SubTests, ) -> None:
    for character in "!@#$%^&*(){}?+| /=":
        with subtests.test(msg=character):
            response = entrypoint.lambda_handler(
                {
                    "httpMethod": "POST",
                    "body": {
                        "title": character
                    }
                }, any_lambda_context())

            assert response == {
                "statusCode": HTTPStatus.BAD_REQUEST,
                "body": {
                    "message":
                    f"Bad Request: '{character}' does not match '{TITLE_PATTERN}'"
                },
            }
Esempio n. 13
0
def should_create_dataset(subtests: SubTests) -> None:
    dataset_title = any_dataset_title()

    body = {"title": dataset_title}

    response = entrypoint.lambda_handler({
        "httpMethod": "POST",
        "body": body
    }, any_lambda_context())
    logger.info("Response: %s", response)

    with subtests.test(msg="status code"):
        assert response["statusCode"] == HTTPStatus.CREATED

    with subtests.test(msg="ID length"):
        assert len(response["body"]["id"]) == 41

    with subtests.test(msg="title"):
        assert response["body"]["title"] == dataset_title
Esempio n. 14
0
def should_update_dataset(subtests: SubTests) -> None:
    new_dataset_title = any_dataset_title()

    with Dataset() as dataset:
        body = {"id": dataset.dataset_id, "title": new_dataset_title}
        response = entrypoint.lambda_handler(
            {
                "httpMethod": "PATCH",
                "body": body,
            },
            any_lambda_context(),
        )
    logger.info("Response: %s", response)

    with subtests.test(msg="status code"):
        assert response["statusCode"] == HTTPStatus.OK

    with subtests.test(msg="title"):
        assert response["body"]["title"] == new_dataset_title
Esempio n. 15
0
def should_update_dataset(subtests: SubTests) -> None:
    new_dataset_title = any_dataset_title()

    with Dataset() as dataset:
        body = {
            DATASET_ID_SHORT_KEY: dataset.dataset_id,
            TITLE_KEY: new_dataset_title
        }
        response = lambda_handler({
            HTTP_METHOD_KEY: "PATCH",
            BODY_KEY: body
        }, any_lambda_context())
    logger.info("Response: %s", response)

    with subtests.test(msg="status code"):
        assert response[STATUS_CODE_KEY] == HTTPStatus.OK

    with subtests.test(msg="title"):
        assert response[BODY_KEY][TITLE_KEY] == new_dataset_title
Esempio n. 16
0
def should_return_single_dataset(subtests: SubTests) -> None:
    # Given a dataset instance
    with Dataset() as dataset:
        body = {"id": dataset.dataset_id}

        # When requesting the dataset by ID and type
        response = entrypoint.lambda_handler(
            {
                "httpMethod": "GET",
                "body": body
            }, any_lambda_context())
    logger.info("Response: %s", response)

    # Then we should get the dataset in return
    with subtests.test(msg="status code"):
        assert response["statusCode"] == HTTPStatus.OK

    with subtests.test(msg="ID"):
        assert response["body"]["id"] == dataset.dataset_id
Esempio n. 17
0
def should_return_all_datasets(subtests: SubTests) -> None:
    # Given two datasets
    with Dataset() as first_dataset, Dataset() as second_dataset:
        # When requesting all datasets
        response = entrypoint.lambda_handler({
            "httpMethod": "GET",
            "body": {}
        }, any_lambda_context())
        logger.info("Response: %s", response)

        # Then we should get both datasets in return
        with subtests.test(msg="status code"):
            assert response["statusCode"] == HTTPStatus.OK

        actual_dataset_ids = [entry["id"] for entry in response["body"]]
        for dataset_id in (first_dataset.dataset_id,
                           second_dataset.dataset_id):
            with subtests.test(msg=f"ID {dataset_id}"):
                assert dataset_id in actual_dataset_ids
Esempio n. 18
0
def should_return_all_datasets(subtests: SubTests) -> None:
    # Given two datasets
    with Dataset() as first_dataset, Dataset() as second_dataset:
        # When requesting all datasets
        response = lambda_handler({
            HTTP_METHOD_KEY: "GET",
            BODY_KEY: {}
        }, any_lambda_context())
        logger.info("Response: %s", response)

        # Then we should get both datasets in return
        with subtests.test(msg="status code"):
            assert response[STATUS_CODE_KEY] == HTTPStatus.OK

        actual_dataset_ids = [
            entry[DATASET_ID_SHORT_KEY] for entry in response[BODY_KEY]
        ]
        for dataset_id in (first_dataset.dataset_id,
                           second_dataset.dataset_id):
            with subtests.test(msg=f"ID {dataset_id}"):
                assert dataset_id in actual_dataset_ids
Esempio n. 19
0
def should_return_client_error_when_title_contains_unsupported_characters(
    subtests: SubTests, ) -> None:
    for character in "!@#$%^&*(){}?+| /=":
        with subtests.test(msg=character):
            response = lambda_handler(
                {
                    HTTP_METHOD_KEY: "POST",
                    BODY_KEY: {
                        TITLE_KEY: character,
                        DESCRIPTION_KEY: any_dataset_description()
                    },
                },
                any_lambda_context(),
            )

            assert response == {
                STATUS_CODE_KEY: HTTPStatus.BAD_REQUEST,
                BODY_KEY: {
                    MESSAGE_KEY:
                    f"Bad Request: '{character}' does not match '{TITLE_PATTERN}'"
                },
            }
Esempio n. 20
0
def should_return_single_dataset_filtered_by_title(subtests: SubTests) -> None:
    # Given matching and non-matching dataset instances
    dataset_title = any_dataset_title()
    body = {"title": dataset_title}

    with Dataset(title=dataset_title) as matching_dataset, Dataset():
        # When requesting a specific type and title
        response = entrypoint.lambda_handler(
            {
                "httpMethod": "GET",
                "body": body
            }, any_lambda_context())
        logger.info("Response: %s", response)

    with subtests.test(msg="ID"):
        # Then only the matching dataset should be returned
        assert response["body"][0]["id"] == matching_dataset.dataset_id

    with subtests.test(msg="status code"):
        assert response["statusCode"] == HTTPStatus.OK

    with subtests.test(msg="body length"):
        assert len(response["body"]) == 1
Esempio n. 21
0
def should_return_single_dataset_filtered_by_title(subtests: SubTests) -> None:
    # Given matching and non-matching dataset instances
    dataset_title = any_dataset_title()
    body = {TITLE_KEY: dataset_title}

    with Dataset(title=dataset_title) as matching_dataset, Dataset():
        # When requesting a specific type and title
        response = lambda_handler({
            HTTP_METHOD_KEY: "GET",
            BODY_KEY: body
        }, any_lambda_context())
        logger.info("Response: %s", response)

    with subtests.test(msg="ID"):
        # Then only the matching dataset should be returned
        assert response[BODY_KEY][0][
            DATASET_ID_SHORT_KEY] == matching_dataset.dataset_id

    with subtests.test(msg="status code"):
        assert response[STATUS_CODE_KEY] == HTTPStatus.OK

    with subtests.test(msg="body length"):
        assert len(response[BODY_KEY]) == 1
Esempio n. 22
0
def should_create_dataset(subtests: SubTests, s3_client: S3Client) -> None:
    dataset_title = any_dataset_title()
    dataset_description = any_dataset_description()
    body = {TITLE_KEY: dataset_title, DESCRIPTION_KEY: dataset_description}

    try:

        with patch("backend.datasets.create.SQS_RESOURCE") as sqs_mock:
            response = lambda_handler({
                HTTP_METHOD_KEY: "POST",
                BODY_KEY: body
            }, any_lambda_context())

        logger.info("Response: %s", response)

        with subtests.test(msg="status code"):
            assert response[STATUS_CODE_KEY] == HTTPStatus.CREATED

        with subtests.test(msg="ID length"):
            assert len(response[BODY_KEY][DATASET_ID_SHORT_KEY]) == 26

        with subtests.test(msg="title"):
            assert response[BODY_KEY][TITLE_KEY] == dataset_title

        catalog = get_s3_prefix_versions(
            ResourceName.STORAGE_BUCKET_NAME.value, dataset_title,
            s3_client)[0]

        dataset_prefix = (
            f"{dataset_title}{DATASET_KEY_SEPARATOR}{response[BODY_KEY][DATASET_ID_SHORT_KEY]}"
        )
        expected_sqs_call = {
            "MessageBody": dataset_prefix,
            "MessageAttributes": {
                MESSAGE_ATTRIBUTE_TYPE_KEY: {
                    STRING_VALUE_KEY: MESSAGE_ATTRIBUTE_TYPE_ROOT,
                    DATA_TYPE_KEY: DATA_TYPE_STRING,
                }
            },
        }
        with smart_open(
                f"{S3_URL_PREFIX}{ResourceName.STORAGE_BUCKET_NAME.value}/{catalog['Key']}"
        ) as new_catalog_metadata_file:

            catalog_json = load(new_catalog_metadata_file)

            with subtests.test(msg="catalog title"):
                assert catalog_json[STAC_TITLE_KEY] == dataset_title

            with subtests.test(msg="catalog description"):
                assert catalog_json[
                    STAC_DESCRIPTION_KEY] == dataset_description

            with subtests.test(msg="root catalog"):
                assert sqs_mock.get_queue_by_name.return_value.send_message.called

            with subtests.test(msg="correct url passed to sqs"):
                assert (sqs_mock.get_queue_by_name.return_value.send_message.
                        call_args[1] == expected_sqs_call)

    finally:
        delete_s3_prefix(ResourceName.STORAGE_BUCKET_NAME.value, dataset_title,
                         s3_client)