intercom_test.aws_http module

Module for adapting HTTP requests to AWS API Gateway events

class intercom_test.aws_http.CasePreparer(case: collections.abc.Mapping)[source]

Bases: object

Common base class for building an AWS API Gateway event for a Lambda Function

Parameters:case – test case data

The following keys in case are consulted when generating the Lambda Function input value (lambda_input()):

'method'
(str, required) The HTTP method
'url'
(str, required) The path part of the URL
'stageVariables'
(dict) Mapping of stage variables to their values
'request headers'
(dict or list of 2-item lists) HTTP headers for request
'request body'
A str, bytes, or JSONic data type giving the body of the request to test; JSONic data is rendered to JSON for submission and implies a Content-Type header of 'application/json'

Subclasses may also consult additional keys in case; see the documentation of the subclass.

lambda_input() → dict[source]

Get the Lambda Function input for the test case

method

HTTP method of the test case

url

URL of the test case

class intercom_test.aws_http.FunctionalHandlerMapper(mapper: Callable[[str, str], Callable[[dict, dict], dict]])[source]

Bases: intercom_test.aws_http.HandlerMapper

Adapter class to convert a mapper function to a HandlerMapper

map(method: str, path: str) → Callable[[dict, dict], dict][source]

Given an HTTP method and request path, return a handler function

class intercom_test.aws_http.HandlerMapper[source]

Bases: abc.ABC

Abstract base class for classes that can map HTTP requests to handlers

map(method: str, path: str) → Callable[[dict, dict], dict][source]

Given an HTTP method and request path, return a handler function

class intercom_test.aws_http.HttpCasePreparer(case: collections.abc.Mapping)[source]

Bases: intercom_test.aws_http.CasePreparer

Prepare Lambda Function input event for HTTP API

Parameters:case – test case data

In addition to the keys listed in base class CasePreparer, this class also consults the following optional keys of case when building the Lambda Function input:

'client certificate'
(dict) The field of the client certificate provided for the test, to populate $.requestContext.authentication.clientCert
'request authorization'
(dict) Used to populate $.requestContext.authorizer
exception intercom_test.aws_http.InvalidPathTemplate[source]

Bases: Exception

Raised when an invalid routing path template

ATTRIBUTES = 'path_template error_index'
error_index

Index 1 argument to the constructor

path_template

Index 0 argument to the constructor

class intercom_test.aws_http.LambdaHandlerProxy(handler: Callable[[dict, dict], dict], *, resource: Optional[str] = None)[source]

Bases: object

Wrapper for a Lambda handler allowing decoration with additional attributes

A single handler function may be bound to multiple integrations, and the information relevant to that binding may be useful or needed for constructing the event to send to the handler.

exception intercom_test.aws_http.NoRoute[source]

Bases: Exception

Raised when no route matched the given method and path

ATTRIBUTES = 'method path'
method

Index 0 argument to the constructor

path

Index 1 argument to the constructor

class intercom_test.aws_http.OpenAPIPathMatcher(route_method: str, route_path: str)[source]

Bases: object

A callable class to match and extract parameters from a URL path

Parameters:
  • route_method – HTTP method or '*' for a wildcard
  • route_path – path part of a URL to match, which may include OpenAPI template parameters

Instances accept a call with an HTTP method and a URL path-part and return either None for no match, or a dict mapping path parameter names to their extracted values. A returned mapping may be empty, so be sure to use the is not None test instead of implicit conversion to bool.

NOTE: With the current implementation, template parameters are only allowed to match a full segment of the path (between slashes or from a slash to the end of the path).

class Param[source]

Bases: str

String giving the name of a path parameter

isvartail
class intercom_test.aws_http.RESPONSE_BODY_EXPECTATIONS[source]

Bases: object

Key class for customized response body expectations

For cases where a strict equality test of the response body generated by the handler to the response body specified in the interface data is not desirable, set the entry in the case dict keyed by this class itself (not an instance of it) to a callable that takes the parsed JSONic data as its only argument and returns a bool indicating whether the response expectations are met.

This can, for example, be used to integrate a JSONic data comparison library with more flexible matching.

A common place to set the entry in the case keyed with this class is in the callable passed in the case_env= keyword to ServerlessHandlerMapper.case_tester().

If the default behavior were coded in client code, it would look like:

def around_case(case: dict):
    def response_expectations(response):
        return response == case['response body']
    case[RESPONSE_BODY_EXPECTATIONS] = response_expectations
    
    yield
class intercom_test.aws_http.RestCasePreparer(case: collections.abc.Mapping)[source]

Bases: intercom_test.aws_http.CasePreparer

Prepare Lambda Function input event for REST API

Parameters:case – test case data

In addition to the keys listed in base class CasePreparer, this class also consults the following optional keys of case when building the Lambda Function input:

'identity'
(dict) Client identity information used to populate $.requestContext.identity
class intercom_test.aws_http.ServerlessHandlerMapper(project_dir: Union[str, pathlib.Path])[source]

Bases: intercom_test.aws_http.HandlerMapper

A HandlerMapper drawing information from a Serverless project config

Parameters:project_dir – root directory of the Serverless project

The typical usage of this class is with InterfaceCaseProvider, as:

import intercom_test.aws_http

def around_interface_case(case: dict):
    # Some kind of setup, possibly using *case*
    try:
        yield
    finally:
        # The corresponding teardown

def test_interface_entrypoints():
    case_provider = intercom_test.InterfaceCaseProvider(<args>)
    service = intercom_test.aws_http.ServerlessHandlerMapper(<path-to-serverless-project>)
    for test_runner in case_provider.case_runners(
        service.case_tester(case_env=around_interface_case)
    ):
        yield (test_runner,)

Note that the case_env= handler can set the RESPONSE_BODY_EXPECTATIONS key in the case to customize validation of the generated response body if there is reason to do so.

SERVERLESS_PROGRAM = 'serverless'
case_tester(api_style: Optional[Callable] = None, **kwargs) → Callable[[dict], None][source]

Convenience method for applying the HTTP API event adapter/testing logic

The result of this method is intended to be passed to intercom_test.framework.InterfaceCaseProvider.case_runners().

See HttpCasePreparer and CasePreparer for information on keys of the test case that are consulted in constructing the Lambda Function input event. See confirm_expected_response() for information on keys of the test case consulted when evaluating the Lambda Function response.

config_file = 'serverless.yml'
map(method: str, path: str) → Callable[[dict, dict], dict][source]

Use routing defined in the Serverless config to map a handler

project_dir

Directory of the project

exception intercom_test.aws_http.UnexpectedResponseBody[source]

Bases: AssertionError

Raised when the expected HTTP response was not generated

ATTRIBUTES = 'actual expected'
actual

Index 0 argument to the constructor

expected

Index 1 argument to the constructor

intercom_test.aws_http.ala_http_api(handler_mapper: intercom_test.aws_http.HandlerMapper, context: Optional[dict] = None, case_env=None) → Callable[[dict], None][source]

Build a case tester from a HandlerMapper for an HTTP API

Parameters:
  • handler_mapper – maps from method and path to an AWS Lambda handler function
  • context – optional context information to pass to the identified handler
  • case_env – context function for setup/teardown with access to the test case

The case_env (if given) must be either a generator function that yields a single time or a callable returning a context manager. If a generator function is given, it is converted to a context manager constructor with contextlib.contextmanager(). In either case, the context manager constructor is invoked with the test case data dict around invocation of the handler callable.

See HttpCasePreparer and CasePreparer for information on keys of the test case that are consulted in constructing the Lambda Function input event. See confirm_expected_response() for information on keys of the test case consulted when evaluating the Lambda Function response.

intercom_test.aws_http.ala_rest_api(handler_mapper: intercom_test.aws_http.HandlerMapper, context: Optional[dict] = None, case_env=None) → Callable[[dict], None][source]

Build a case tester from a HandlerMapper for a REST API

Parameters:
  • handler_mapper – maps from method and path to an AWS Lambda handler function
  • context – optional context information to pass to the identified handler
  • case_env – context function for setup/teardown with access to the test case

The case_env (if given) must be either a generator function that yields a single time or a callable returning a context manager. If a generator function is given, it is converted to a context manager constructor with contextlib.contextmanager(). In either case, the context manager constructor is invoked with the test case data dict around invocation of the handler callable.

See RestCasePreparer and CasePreparer for information on keys of the test case that are consulted in constructing the Lambda Function input event.

intercom_test.aws_http.confirm_expected_response(handler_result: dict, case: dict) → None[source]

Confirm that the (normalized) output of the handler meets case expectations

Parameters:
  • handler_result – result from the Lambda Function handler
  • case – the test case data

Normalization of the handler function output does not occur in this function; normalize handler_result before passing it in.

The following keys in case are consulted when evaluating the Lambda Function response:

'response status'
(int) The HTTP response status code number expected, defaulting to 200
'response headers'
(dict or list of 2-item lists) HTTP headers required in the response; if a header is listed here and is returned as a multi-value header (in 'multiValueHeaders'), the set of values in the response is expected to match the set of values listed here in the test case
'response body'
(required) A str, bytes, or JSONic data type giving the expected body of the response; JSONic data is compared against the response by parsing the body of the response as JSON, then comparing to the data given here in the test case