add http-api
This commit is contained in:
0
http-api/tests/__init__.py
Normal file
0
http-api/tests/__init__.py
Normal file
95
http-api/tests/conftest.py
Normal file
95
http-api/tests/conftest.py
Normal file
@@ -0,0 +1,95 @@
|
||||
import base64
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
from http import HTTPMethod
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@dataclass
|
||||
class LambdaContext:
|
||||
function_name: str = 'test'
|
||||
memory_limit_in_mb: int = 128
|
||||
invoked_function_arn: str = 'arn:aws:lambda:eu-west-1:809313241:function:test'
|
||||
aws_request_id: str = '52fdfc07-2182-154f-163f-5f0f9a621d72'
|
||||
|
||||
|
||||
class HttpApiProxy:
|
||||
def __call__(
|
||||
self,
|
||||
raw_path: str,
|
||||
method: str = HTTPMethod.GET,
|
||||
body: dict = {},
|
||||
*,
|
||||
headers: dict = {},
|
||||
**kwargs,
|
||||
) -> dict:
|
||||
return {
|
||||
'version': '2.0',
|
||||
'routeKey': '$default',
|
||||
'rawPath': raw_path,
|
||||
'rawQueryString': 'parameter1=value1¶meter1=value2¶meter2=value',
|
||||
'cookies': ['cookie1', 'cookie2'],
|
||||
'headers': headers,
|
||||
'queryStringParameters': {
|
||||
'parameter1': 'value1,value2',
|
||||
'parameter2': 'value',
|
||||
},
|
||||
'requestContext': {
|
||||
'accountId': '123456789012',
|
||||
'apiId': 'api-id',
|
||||
'authorizer': {
|
||||
'lambda': {
|
||||
'user': {},
|
||||
'tenant': '*',
|
||||
},
|
||||
'jwt': {
|
||||
'claims': {'claim1': 'value1', 'claim2': 'value2'},
|
||||
'scopes': ['scope1', 'scope2'],
|
||||
},
|
||||
},
|
||||
'domainName': 'id.execute-api.us-east-1.amazonaws.com',
|
||||
'domainPrefix': 'id',
|
||||
'http': {
|
||||
'method': str(method),
|
||||
'path': raw_path,
|
||||
'protocol': 'HTTP/1.1',
|
||||
'sourceIp': '192.168.0.1/32',
|
||||
'userAgent': 'agent',
|
||||
},
|
||||
'requestId': 'id',
|
||||
'routeKey': '$default',
|
||||
'stage': '$default',
|
||||
'time': '12/Mar/2020:19:03:58 +0000',
|
||||
'timeEpoch': 1583348638390,
|
||||
},
|
||||
'body': _base64_dict(body),
|
||||
'pathParameters': {'parameter1': 'value1'},
|
||||
'isBase64Encoded': True,
|
||||
'stageVariables': {'stageVariable1': 'value1', 'stageVariable2': 'value2'},
|
||||
}
|
||||
|
||||
|
||||
def _base64_dict(obj: dict = {}) -> str | None:
|
||||
if not obj:
|
||||
return None
|
||||
return base64.b64encode(json.dumps(obj).encode()).decode()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def lambda_context() -> LambdaContext:
|
||||
return LambdaContext()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def http_api_proxy():
|
||||
return HttpApiProxy()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_app(monkeypatch):
|
||||
monkeypatch.setattr('settings.ELASTIC_CONN', {'hosts': 'http://127.0.0.1:9200'})
|
||||
|
||||
import app
|
||||
|
||||
return app
|
||||
0
http-api/tests/routes/__init__.py
Normal file
0
http-api/tests/routes/__init__.py
Normal file
19
http-api/tests/routes/test_courses.py
Normal file
19
http-api/tests/routes/test_courses.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from http import HTTPMethod, HTTPStatus
|
||||
|
||||
from ..conftest import HttpApiProxy, LambdaContext
|
||||
|
||||
|
||||
def test_courses(mock_app, http_api_proxy: HttpApiProxy, lambda_context: LambdaContext):
|
||||
r = mock_app.lambda_handler(
|
||||
http_api_proxy(
|
||||
raw_path='/courses',
|
||||
method=HTTPMethod.POST,
|
||||
body={
|
||||
'name': 'pytest',
|
||||
'access_period': 365,
|
||||
},
|
||||
),
|
||||
lambda_context,
|
||||
)
|
||||
|
||||
assert r['statusCode'] == HTTPStatus.CREATED
|
||||
24
http-api/tests/test_auth.py
Normal file
24
http-api/tests/test_auth.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import auth as app
|
||||
|
||||
|
||||
def test_bearer_jwt(lambda_context):
|
||||
app.get_user = lambda *args, **kwargs: {
|
||||
'sub': '58efed8d-d276-41a8-8502-4ab8b5a6415e',
|
||||
'name': 'pytest',
|
||||
}
|
||||
bearer_token = 'eyJraWQiOiJiSkZaSlNkMjhIeUtJNEQ0bG84SlkxSzk5NEdSUGhYU3YwV1BNczZ3aGVzPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI1OGVmZWQ4ZC1kMjc2LTQxYTgtODUwMi00YWI4YjVhNjQxNWUiLCJldmVudF9pZCI6IjJhNjlmOWE5LWQ2N2MtNDU0Ny04YzJlLWU5N2U2YzI5MzY4YSIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE3NDIzOTMxNjMsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5zYS1lYXN0LTEuYW1hem9uYXdzLmNvbVwvc2EtZWFzdC0xX3M2WW1WU2ZYaiIsImV4cCI6MTc0MjQzNzA4NywiaWF0IjoxNzQyNDMzNDg3LCJqdGkiOiJmNjQ2MTdhMy04MzY2LTQxZWUtOGU2MC04YTA3YzA2N2UzOTMiLCJjbGllbnRfaWQiOiJsZGZ2ZHZrdDZjbDIybjdwMzN2cXRzZjRqIiwidXNlcm5hbWUiOiI1OGVmZWQ4ZC1kMjc2LTQxYTgtODUwMi00YWI4YjVhNjQxNWUifQ.dRhCaEItKEBbzrl7b5Ndh2xI8YGCK8trfKRs6YsW0cdZ_lU59oLhfd1bXEUe-dPyUb3zzGM41bSVUKHZTTlaMx8QNq2U4HbtrgQuQ77yXkN_i8Ft0DpLJiOFtBJzdx-LDUU8CwfjgLNN9fSUyUfkPkCnssBug0fIVcUJpixadk19-7_LJ3_gCPxlpcWT3vCb3yQtY8DzpW4iFcbqBUt1i6XWMTQHfTNamqzaWQ7m6QarefWK1gfDxGmfRg5qQJCRYzsQXcCe3JXRy0BgErpKrVHeIx0Dz8DyOWy1s0hSmv6n9ZPrHOFj13LprS7XihEK9DFwq4usolBungPLRIs_Og'
|
||||
event = {
|
||||
'headers': {
|
||||
'authorization': f'Bearer {bearer_token}',
|
||||
},
|
||||
}
|
||||
|
||||
assert app.lambda_handler(event, lambda_context) == { # type: ignore
|
||||
'isAuthorized': True,
|
||||
'context': {
|
||||
'user': {
|
||||
'sub': '58efed8d-d276-41a8-8502-4ab8b5a6415e',
|
||||
'name': 'pytest',
|
||||
}
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user