Beispiel #1
0
def test_handler_metadata_completed_empty(lambda_module, context,
                                          ddb_record_metadata_completed,
                                          event_metadata_failed, order,
                                          order_products):
    """
    Test handler() with a metadata completed item but no products
    """

    event_metadata_failed = copy.deepcopy(event_metadata_failed)

    table = mock_table(lambda_module.table, "query", ["orderId", "productId"])
    # Stubbing Event Bridge
    eventbridge = stub.Stubber(lambda_module.eventbridge)
    # Ignore time and detail
    event_metadata_failed["Time"] = stub.ANY
    event_metadata_failed["Detail"] = stub.ANY
    expected_params = {"Entries": [event_metadata_failed]}
    eventbridge.add_response("put_events", {}, expected_params)
    eventbridge.activate()

    event = {"Records": [ddb_record_metadata_completed]}

    lambda_module.handler(event, context)

    table.assert_no_pending_responses()
    table.deactivate()

    eventbridge.assert_no_pending_responses()
    eventbridge.deactivate()
Beispiel #2
0
def test_handler(monkeypatch, lambda_module, context):
    """
    Test handler()
    """

    service_name = "ecommerce.test"
    event = {"source": service_name, "message": "test_event"}
    connection_ids = [str(uuid.uuid4()) for _ in range(100)]

    called = {"get_connection_ids": False, "send_event": False}

    def get_connection_ids(service_name_got: str) -> List[str]:
        assert service_name == service_name
        called["get_connection_ids"] = True
        return connection_ids

    def send_event(event_got: dict, connection_ids_got: list):
        assert event == event_got
        assert connection_ids == connection_ids_got
        called["send_event"] = True

    monkeypatch.setattr(lambda_module, "get_connection_ids",
                        get_connection_ids)
    monkeypatch.setattr(lambda_module, "send_event", send_event)

    lambda_module.handler(event, context)

    for k in called.keys():
        assert called[k] == True
Beispiel #3
0
def test_handler_created(lambda_module, context, order, order_products, order_metadata):
    """
    Test handler() with OrderCreated
    """

    table = mock_table(
        lambda_module.table, "get_item", ["orderId", "productId"]
    )
    mock_table(
        table, "batch_write_item",
        ["orderId", "productId"],
        table_name=lambda_module.table.name,
        items=[
            {"PutRequest": {"Item": product}}
            for product in order_products
        ]
    )
    order_metadata = copy.deepcopy(order_metadata)
    order_metadata["newDate"] = order_metadata["modifiedDate"]
    mock_table(
        table, "put_item", ["orderId", "productId"],
        table_name=lambda_module.table.name,
        items=order_metadata
    )

    lambda_module.handler({
        "source": "ecommerce.orders",
        "resources": [order["orderId"]],
        "detail-type": "OrderCreated",
        "detail": order
    }, context)

    table.assert_no_pending_responses()
    table.deactivate()
def test_handler(lambda_module, event, context, order, url, ddb_item):
    """
    Test handler()
    """

    # Mock boto3
    table = mock_table(
        lambda_module.table, "get_item",
        ["orderId"]
    )
    table = mock_table(
        table, "put_item",
        ["orderId"],
        items=ddb_item,
        table_name=lambda_module.table.name
    )

    with requests_mock.Mocker() as m:
        # Mock requests
        m.get(url, text=json.dumps(order))
        lambda_module.handler(event, context)

    # Assertions
    assert m.called
    assert m.call_count == 1
    assert m.request_history[0].method == "GET"
    assert m.request_history[0].url == url

    table.assert_no_pending_responses()
    table.deactivate()
def test_handler(monkeypatch, lambda_module, context, order):
    """
    Test handler()
    """

    test_cases = [{
        "status": "FULFILLED",
        "source": "ecommerce.delivery",
        "detail-type": "DeliveryCompleted",
        "called": True
    }, {
        "status": "DELIVERY_FAILED",
        "source": "ecommerce.delivery",
        "detail-type": "DeliveryFailed",
        "called": True
    }, {
        "status": "PACKAGED",
        "source": "ecommerce.warehouse",
        "detail-type": "PackageCreated",
        "called": True,
        "products": True
    }, {
        "status": "PACKAGING_FAILED",
        "source": "ecommerce.warehouse",
        "detail-type": "PackagingFailed",
        "called": True
    }, {
        "status": "UNKNOWN",
        "source": "ecommerce.warehouse",
        "detail-type": "UnknownDetailType",
        "called": False
    }, {
        "status": "UNKNOWN",
        "source": "ecommerce.delivery",
        "detail-type": "UnknownDetailType",
        "called": False
    }, {
        "status": "UNKNOWN",
        "source": "UNKNOWN",
        "detail-type": "UnknownDetailType",
        "called": False
    }]

    for test_case in test_cases:
        def update_order(order_id: str, status: str, products=None) -> None:
            assert test_case["called"]
            assert order_id == "ORDER_ID"
            assert status == test_case["status"]
            if test_case.get("products", False):
                assert products is not None
        monkeypatch.setattr(lambda_module, "update_order", update_order)

        event = {
            "resources": ["ORDER_ID"],
            "source": test_case["source"],
            "detail-type": test_case["detail-type"],
            "detail": order
        }
        lambda_module.handler(event, context)
def test_handler_wrong_event_detail(lambda_module, event, context):
    """
    Test handler() with an incorrect event
    """

    event = copy.deepcopy(event)
    event["detail"] = {}

    with pytest.raises(KeyError) as excinfo:
        lambda_module.handler(event, context)
def test_handler_wrong_event_detail_type(lambda_module, event, context):
    """
    Test handler() with an incorrect event
    """

    event = copy.deepcopy(event)
    event["detail-type"] = "WRONG"

    with pytest.raises(AssertionError) as excinfo:
        lambda_module.handler(event, context)
def test_handler_wrong_order(lambda_module, event, context, order, url):
    """
    Test handler() with a non-existing order
    """

    with requests_mock.Mocker() as m:
        m.get(url, status_code=404, text=json.dumps({"message": "Order not found"}))
        
        with pytest.raises(Exception, match="Failed to retrieve order .*") as excinfo:
            lambda_module.handler(event, context)

    assert m.called
    assert m.call_count == 1
    assert m.request_history[0].method == "GET"
    assert m.request_history[0].url == url
def test_handler_missing_total(monkeypatch, lambda_module, context, apigateway_event, payment_token, total):
    """
    Test handler() with a missing total
    """

    def validate_payment_token(payment_token: str, total: int) -> bool:
        # This should never be called
        assert False
        return True

    monkeypatch.setattr(lambda_module, "validate_payment_token", validate_payment_token)

    event = apigateway_event(
        iam="USER_ARN",
        body=json.dumps({
            "paymentToken": payment_token,
        })
    )

    response = lambda_module.handler(event, context)

    assert response["statusCode"] == 400
    assert "body" in response
    body = json.loads(response["body"])
    assert "ok" not in body
    assert "message" in body
    assert isinstance(body["message"], str)
    assert "total" in body["message"]
def test_handler(lambda_module, apigateway_event, order, context):
    """
    Test handler()
    """

    # Stub boto3
    table = stub.Stubber(lambda_module.table.meta.client)
    response = {
        "Item": {k: TypeSerializer().serialize(v)
                 for k, v in order.items()},
        # We do not use ConsumedCapacity
        "ConsumedCapacity": {}
    }
    expected_params = {
        "TableName": lambda_module.TABLE_NAME,
        "Key": {
            "orderId": order["orderId"]
        }
    }
    table.add_response("get_item", response, expected_params)
    table.activate()

    # Send request
    response = lambda_module.handler(apigateway_event, context)

    # Remove stub
    table.assert_no_pending_responses()
    table.deactivate()

    assert response["statusCode"] == 200
    assert "body" in response
    body = json.loads(response["body"])
    compare_dict(order, body)
Beispiel #11
0
def test_handler(monkeypatch, lambda_module, context, apigateway_event, order):
    """
    Test handler()
    """

    event = apigateway_event(iam="USER_ARN",
                             body=json.dumps({
                                 "products": order["products"],
                                 "address": order["address"]
                             }))

    def get_pricing(products: List[dict], address: dict) -> int:
        assert products == order["products"]
        assert address == order["address"]

        return 1000

    monkeypatch.setattr(lambda_module, "get_pricing", get_pricing)

    retval = lambda_module.handler(event, context)

    assert "statusCode" in retval
    assert retval["statusCode"] == 200
    assert "body" in retval

    body = json.loads(retval["body"])
    assert "pricing" in body
    assert body["pricing"] == 1000
Beispiel #12
0
def test_handler_no_id(monkeypatch, lambda_module, context, apigateway_event):
    """
    Test handler()
    """

    connection_id = str(uuid.uuid4())

    event = apigateway_event()

    calls = {"store_id": 0, "enable_rule": 0}

    def store_id(connection_id_req: str):
        calls["store_id"] += 1
        assert connection_id_req == connection_id

    monkeypatch.setattr(lambda_module, "store_id", store_id)

    def enable_rule():
        calls["enable_rule"] += 1

    monkeypatch.setattr(lambda_module, "enable_rule", enable_rule)

    result = lambda_module.handler(event, context)

    assert result["statusCode"] == 400
    assert calls["store_id"] == 0
    assert calls["enable_rule"] == 0
def test_handler(monkeypatch, lambda_module, context, apigateway_event, payment_token, total):
    """
    Test handler()
    """

    def validate_payment_token(pt: str, a: int) -> bool:
        assert pt == payment_token
        assert a == total
        return True

    monkeypatch.setattr(lambda_module, "validate_payment_token", validate_payment_token)

    event = apigateway_event(
        iam="USER_ARN",
        body=json.dumps({
            "paymentToken": payment_token,
            "total": total
        })
    )

    response = lambda_module.handler(event, context)

    assert response["statusCode"] == 200
    assert "body" in response
    body = json.loads(response["body"])
    assert "ok" in body
    assert body["ok"] == True
Beispiel #14
0
def test_handler(monkeypatch, lambda_module, context, apigateway_event):
    """
    Test handler()
    """

    connection_id = str(uuid.uuid4())

    event = apigateway_event()
    event["requestContext"] = {"connectionId": connection_id}

    calls = {
        "delete_id": 0,
        "disable_rule": 0
    }

    def delete_id(connection_id_req: str):
        calls["delete_id"] += 1
        assert connection_id_req == connection_id
    monkeypatch.setattr(lambda_module, "delete_id", delete_id)

    def disable_rule():
        calls["disable_rule"] += 1
    monkeypatch.setattr(lambda_module, "disable_rule", disable_rule)

    result = lambda_module.handler(event, context)

    assert result["statusCode"] == 200
    assert calls["delete_id"] == 1
    assert calls["disable_rule"] == 1
def test_handler_not_found(lambda_module, apigateway_event, order, context):
    """
    Test handler() with an unknown order ID
    """

    # Stub boto3
    table = stub.Stubber(lambda_module.table.meta.client)
    response = {
        # We do not use ConsumedCapacity
        "ConsumedCapacity": {}
    }
    expected_params = {
        "TableName": lambda_module.TABLE_NAME,
        "Key": {
            "orderId": order["orderId"]
        }
    }
    table.add_response("get_item", response, expected_params)
    table.activate()

    # Send request
    response = lambda_module.handler(apigateway_event, context)

    # Remove stub
    table.assert_no_pending_responses()
    table.deactivate()

    assert response["statusCode"] == 404
    assert "body" in response
    body = json.loads(response["body"])
    assert "message" in body
    assert isinstance(body["message"], str)
def test_handler_validation_failure(monkeypatch, lambda_module, context, order):
    """
    Test handler() with failing validation
    """

    def validate_true(order: dict) -> Tuple[bool, str]:
        return (False, "Something went wrong")

    def store_order(order: dict) -> None:
        pass

    monkeypatch.setattr(lambda_module, "validate_delivery", validate_true)
    monkeypatch.setattr(lambda_module, "validate_payment", validate_true)
    monkeypatch.setattr(lambda_module, "validate_products", validate_true)
    monkeypatch.setattr(lambda_module, "store_order", store_order)

    user_id = order["userId"]
    order = copy.deepcopy(order)
    del order["userId"]

    response = lambda_module.handler({
        "order": order,
        "userId": user_id
    }, context)

    print(response)
    assert response["success"] == False
    assert len(response.get("errors", [])) > 0
Beispiel #17
0
def test_handler_wrong_order(monkeypatch, lambda_module, context, order):
    """
    Test handler() with an incorrect order
    """
    async def validate_true(order: dict) -> Tuple[bool, str]:
        return (True, "")

    def store_order(order: dict) -> None:
        pass

    monkeypatch.setattr(lambda_module, "validate_delivery", validate_true)
    monkeypatch.setattr(lambda_module, "validate_payment", validate_true)
    monkeypatch.setattr(lambda_module, "validate_products", validate_true)
    monkeypatch.setattr(lambda_module, "store_order", store_order)

    user_id = order["userId"]
    order = copy.deepcopy(order)
    del order["userId"]
    del order["paymentToken"]

    response = lambda_module.handler({
        "order": order,
        "userId": user_id
    }, context)

    print(response)
    assert response["success"] == False
    assert len(response.get("errors", [])) > 0
def test_handler(monkeypatch, lambda_module, context, order):
    """
    Test handler()
    """

    def validate_true(order: dict) -> Tuple[bool, str]:
        return (True, "")

    def store_order(order: dict) -> None:
        pass

    monkeypatch.setattr(lambda_module, "validate_delivery", validate_true)
    monkeypatch.setattr(lambda_module, "validate_payment", validate_true)
    monkeypatch.setattr(lambda_module, "validate_products", validate_true)
    monkeypatch.setattr(lambda_module, "store_order", store_order)

    user_id = order["userId"]
    order = copy.deepcopy(order)
    del order["userId"]

    response = lambda_module.handler({
        "order": order,
        "userId": user_id
    }, context)

    print(response)
    assert response["success"] == True
    assert len(response.get("errors", [])) == 0
    assert "order" in response
    compare_dict(order, response["order"])
def test_handler_invalid_body(monkeypatch, lambda_module, context, apigateway_event):
    """
    Test handler() without a correct JSON body
    """

    connection_id = str(uuid.uuid4())
    service_name = "ecommerce.test"

    event = apigateway_event()
    event["requestContext"] = {"connectionId": connection_id}
    event["body"] = "{"

    calls = {
        "register_service": 0
    }

    def register_service(connection_id_req: str, service_name_req: str):
        calls["register_service"] += 1
        assert connection_id_req == connection_id
        assert service_name_req == service_name
    monkeypatch.setattr(lambda_module, "register_service", register_service)

    result = lambda_module.handler(event, context)

    assert result["statusCode"] == 400
    assert calls["register_service"] == 0
def test_handler_no_id(monkeypatch, lambda_module, context, apigateway_event):
    """
    Test handler() without connectionId
    """

    connection_id = str(uuid.uuid4())
    service_name = "ecommerce.test"

    event = apigateway_event()
    event["body"] = json.dumps({"serviceName": service_name})

    calls = {
        "register_service": 0
    }

    def register_service(connection_id_req: str, service_name_req: str):
        calls["register_service"] += 1
        assert connection_id_req == connection_id
        assert service_name_req == service_name
    monkeypatch.setattr(lambda_module, "register_service", register_service)

    result = lambda_module.handler(event, context)

    assert result["statusCode"] == 400
    assert calls["register_service"] == 0
def test_handler_correct(monkeypatch, lambda_module, apigateway_event, context, product):
    """
    Test the function handler against an incorrect product
    """

    def validate_products(products):
        return [], ""

    monkeypatch.setattr(lambda_module, "validate_products", validate_products)

    # Create request
    event = apigateway_event(
        iam="USER_ARN",
        body=json.dumps({"products": [product]})
    )

    # Parse request
    response = lambda_module.handler(event, context)

    # Check response
    assert response["statusCode"] == 200

    # There should be 1 item in the response body
    response_body = json.loads(response["body"])
    assert "message" in response_body
    assert isinstance(response_body["message"], str)
    assert "products" not in response_body
def test_handler_missing_products(monkeypatch, lambda_module, apigateway_event, context, product):
    """
    Test the function handler with missing 'products' in request body
    """

    def validate_products(products):
        assert False # This should never be called

    monkeypatch.setattr(lambda_module, "validate_products", validate_products)

    # Create request
    event = apigateway_event(
        iam="USER_ARN",
        body=json.dumps({})
    )

    # Parse request
    response = lambda_module.handler(event, context)

    # Check response
    assert response["statusCode"] == 400

    # There should be a reason in the response body
    response_body = json.loads(response["body"])
    assert "message" in response_body
    assert isinstance(response_body["message"], str)
Beispiel #23
0
def test_handler_wrong_event(lambda_module, context, postconfirm_data):
    """
    Test handler()
    """

    postconfirm_data["input"]["triggerSource"] += "_WRONG_EVENT"

    # Prepare stub
    eventbridge = stub.Stubber(lambda_module.eventbridge)
    eventbridge.activate()

    # Execute function
    lambda_module.handler(postconfirm_data["input"], context)

    # End
    eventbridge.assert_no_pending_responses()
    eventbridge.deactivate()
Beispiel #24
0
def test_handler_nothing(lambda_module, context, order, ddb_record_new):
    """
    Test handler() with records that should not create events
    """

    # Prepare event
    event = {"Records": [ddb_record_new]}

    # Stub
    eventbridge = stub.Stubber(lambda_module.eventbridge)
    eventbridge.activate()

    # Send request
    lambda_module.handler(event, context)

    # Check that events were sent
    eventbridge.assert_no_pending_responses()
    eventbridge.deactivate()
Beispiel #25
0
def test_handler(monkeypatch, lambda_module, context, order_id, payment_token):
    """
    Test handler()
    """

    event = {
        "source": "ecommerce.delivery",
        "detail-type": "DeliveryFailed",
        "resources": [order_id],
        "detail": {
            "old": {
                "orderId": order_id,
                "total": 300
            },
            "new": {
                "orderId": order_id,
                "total": 200
            }
        }
    }

    called = []

    def update_payment_amount(p: str, a: int) -> None:
        called.append("update_payment_amount")
        assert a == 200
        assert p == payment_token

    def get_payment_token(o: str) -> str:
        called.append("get_payment_token")
        assert o == order_id
        return payment_token

    monkeypatch.setattr(lambda_module, "get_payment_token", get_payment_token)
    monkeypatch.setattr(lambda_module, "update_payment_amount",
                        update_payment_amount)

    lambda_module.handler(event, context)

    assert "update_payment_amount" in called
    assert "get_payment_token" in called
Beispiel #26
0
def test_handler(lambda_module, context, postconfirm_data):
    """
    Test handler()
    """

    output = copy.deepcopy(postconfirm_data["output"])
    output["Time"] = stub.ANY

    # Prepare stub
    eventbridge = stub.Stubber(lambda_module.eventbridge)
    response = {}
    expected_params = {"Entries": [output]}
    eventbridge.add_response("put_events", response, expected_params)
    eventbridge.activate()

    # Execute function
    lambda_module.handler(postconfirm_data["input"], context)

    # End
    eventbridge.assert_no_pending_responses()
    eventbridge.deactivate()
def test_handler(monkeypatch, lambda_module, context, order_id, payment_token):
    """
    Test handler()
    """

    event = {
        "source": "ecommerce.delivery",
        "detail-type": "DeliveryFailed",
        "resources": [order_id],
        "detail": {
            "orderId": order_id,
            "total": 1234
        }
    }

    called = []

    def cancel_payment(p: str) -> None:
        called.append("cancel_payment")
        assert p == payment_token

    def get_payment_token(o: str) -> str:
        called.append("get_payment_token")
        assert o == order_id
        return payment_token

    def delete_payment_token(o: str) -> str:
        called.append("delete_payment_token")
        assert o == order_id

    monkeypatch.setattr(lambda_module, "get_payment_token", get_payment_token)
    monkeypatch.setattr(lambda_module, "delete_payment_token",
                        delete_payment_token)
    monkeypatch.setattr(lambda_module, "cancel_payment", cancel_payment)

    lambda_module.handler(event, context)

    assert "cancel_payment" in called
    assert "get_payment_token" in called
    assert "delete_payment_token" in called
Beispiel #28
0
def test_handler(lambda_module, context, insert_data):
    """
    Test the Lambda function handler
    """

    # Prepare Lambda event and context
    event = {"Records": [insert_data["record"]]}

    # Stubbing boto3
    eventbridge = stub.Stubber(lambda_module.eventbridge)
    # Ignore time
    insert_data["event"]["Time"] = stub.ANY
    expected_params = {"Entries": [insert_data["event"]]}
    eventbridge.add_response("put_events", {}, expected_params)
    eventbridge.activate()

    # Send request
    lambda_module.handler(event, context)

    # Check that events were sent
    eventbridge.assert_no_pending_responses()
    eventbridge.deactivate()
def test_handler(monkeypatch, lambda_module, context, order_id, payment_token):
    """
    Test handler()
    """

    event = {
        "source": "ecommerce.orders",
        "detail-type": "OrderCreated",
        "resources": [order_id],
        "detail": {
            "orderId": order_id,
            "paymentToken": payment_token
        }
    }

    def save_payment_token(o: str, p: str):
        assert o == order_id
        assert p == payment_token

    monkeypatch.setattr(lambda_module, "save_payment_token",
                        save_payment_token)

    lambda_module.handler(event, context)
Beispiel #30
0
def test_handler_deleted(lambda_module, context, order, order_products, order_metadata):
    """
    Test handler() with OrderDeleted
    """

    table = mock_table(
        lambda_module.table, "get_item", ["orderId", "productId"],
        items=order_metadata
    )
    mock_table(
        table, "batch_write_item",
        ["orderId", "productId"],
        table_name=lambda_module.table.name,
        items=[
            {"DeleteRequest": {"Key": {
                "orderId": product["orderId"],
                "productId": product["productId"]
            }}}
            for product in order_products
        ]
    )
    mock_table(
        table, "delete_item",
        ["orderId", "productId"],
        table_name=lambda_module.table.name,
        items=order_metadata
    )

    lambda_module.handler({
        "source": "ecommerce.orders",
        "resources": [order["orderId"]],
        "detail-type": "OrderDeleted",
        "detail": order
    }, context)

    table.assert_no_pending_responses()
    table.deactivate()