Skip to content

Commit ab9613a

Browse files
authored
Apigw ng implement mock integration (#11148)
1 parent bf7967c commit ab9613a

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

localstack-core/localstack/services/apigateway/next_gen/execute_api/integrations/mock.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
1+
import json
2+
import logging
3+
from json import JSONDecodeError
4+
5+
from localstack.http import Response
6+
from localstack.utils.strings import to_str
7+
8+
from ..context import IntegrationRequest, RestApiInvocationContext
9+
from ..gateway_response import InternalServerError
110
from .core import RestApiIntegration
211

12+
LOG = logging.getLogger(__name__)
13+
314

415
class RestApiMockIntegration(RestApiIntegration):
516
"""
@@ -12,3 +23,35 @@ class RestApiMockIntegration(RestApiIntegration):
1223
"""
1324

1425
name = "MOCK"
26+
27+
def invoke(self, context: RestApiInvocationContext) -> Response:
28+
integration_req: IntegrationRequest = context.integration_request
29+
30+
status_code = self.get_status_code(integration_req)
31+
32+
if status_code is None:
33+
LOG.debug(
34+
"Execution failed due to configuration error: Unable to parse statusCode. "
35+
"It should be an integer that is defined in the request template."
36+
)
37+
raise InternalServerError("Internal server error")
38+
39+
return Response(status=status_code)
40+
41+
@staticmethod
42+
def get_status_code(integration_req: IntegrationRequest) -> int | None:
43+
try:
44+
body = json.loads(to_str(integration_req["body"]))
45+
except JSONDecodeError as e:
46+
LOG.debug(
47+
"Exception while parsing integration request body: %s",
48+
e,
49+
exc_info=LOG.isEnabledFor(logging.DEBUG),
50+
)
51+
return
52+
53+
status_code = body.get("statusCode")
54+
if not isinstance(status_code, int):
55+
return
56+
57+
return status_code
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import pytest
2+
3+
from localstack.http import Request
4+
from localstack.services.apigateway.next_gen.execute_api.context import (
5+
IntegrationRequest,
6+
RestApiInvocationContext,
7+
)
8+
from localstack.services.apigateway.next_gen.execute_api.gateway_response import InternalServerError
9+
from localstack.services.apigateway.next_gen.execute_api.integrations import RestApiMockIntegration
10+
from localstack.utils.strings import to_bytes
11+
12+
13+
@pytest.fixture
14+
def create_default_context():
15+
def _create_context(body: str) -> RestApiInvocationContext:
16+
context = RestApiInvocationContext(request=Request())
17+
context.integration_request = IntegrationRequest(body=to_bytes(body))
18+
return context
19+
20+
return _create_context
21+
22+
23+
class TestMockIntegration:
24+
def test_mock_integration(self, create_default_context):
25+
mock_integration = RestApiMockIntegration()
26+
27+
ctx = create_default_context(body='{"statusCode": 200}')
28+
response = mock_integration.invoke(ctx)
29+
assert response.status_code == 200
30+
31+
# It needs to be an integer
32+
ctx = create_default_context(body='{"statusCode": "200"}')
33+
with pytest.raises(InternalServerError) as exc_info:
34+
mock_integration.invoke(ctx)
35+
assert exc_info.match("Internal server error")
36+
37+
# Any integer will do
38+
ctx = create_default_context(body='{"statusCode": 0}')
39+
response = mock_integration.invoke(ctx)
40+
assert response.status_code == 0
41+
42+
# Literally any
43+
ctx = create_default_context(body='{"statusCode": -1000}')
44+
response = mock_integration.invoke(ctx)
45+
assert response.status_code == -1000
46+
47+
# Malformed Json
48+
ctx = create_default_context(body='{"statusCode": 200')
49+
with pytest.raises(InternalServerError) as exc_info:
50+
mock_integration.invoke(ctx)
51+
assert exc_info.match("Internal server error")

0 commit comments

Comments
 (0)