Skip to content

Commit 4793efd

Browse files
author
Michal Ploski
committed
Add e2e tests
1 parent 9c5cbd9 commit 4793efd

File tree

4 files changed

+173
-5
lines changed

4 files changed

+173
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
schema {
2+
query: Query
3+
}
4+
5+
type Query {
6+
getPost(id:ID!): Post
7+
allPosts: [Post]
8+
}
9+
10+
type Post {
11+
id: ID!
12+
author: String!
13+
title: String
14+
content: String
15+
url: String
16+
ups: Int
17+
downs: Int
18+
relatedPosts: [Post]
19+
}

tests/e2e/event_handler/infrastructure.py

+46-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1+
from pathlib import Path
12
from typing import Dict, Optional
23

3-
from aws_cdk import CfnOutput
4+
from aws_cdk import CfnOutput, Duration, Expiration
45
from aws_cdk import aws_apigateway as apigwv1
56
from aws_cdk import aws_apigatewayv2_alpha as apigwv2
67
from aws_cdk import aws_apigatewayv2_authorizers_alpha as apigwv2authorizers
78
from aws_cdk import aws_apigatewayv2_integrations_alpha as apigwv2integrations
89
from aws_cdk import aws_ec2 as ec2
910
from aws_cdk import aws_elasticloadbalancingv2 as elbv2
1011
from aws_cdk import aws_elasticloadbalancingv2_targets as targets
12+
from aws_cdk import aws_appsync_alpha as appsync
13+
from aws_cdk import aws_iam
1114
from aws_cdk.aws_lambda import Function, FunctionUrlAuthType
1215

1316
from tests.e2e.utils.infrastructure import BaseInfrastructure
@@ -17,10 +20,11 @@ class EventHandlerStack(BaseInfrastructure):
1720
def create_resources(self):
1821
functions = self.create_lambda_functions()
1922

20-
self._create_alb(function=functions["AlbHandler"])
21-
self._create_api_gateway_rest(function=functions["ApiGatewayRestHandler"])
22-
self._create_api_gateway_http(function=functions["ApiGatewayHttpHandler"])
23-
self._create_lambda_function_url(function=functions["LambdaFunctionUrlHandler"])
23+
# self._create_alb(function=functions["AlbHandler"])
24+
# self._create_api_gateway_rest(function=functions["ApiGatewayRestHandler"])
25+
# self._create_api_gateway_http(function=functions["ApiGatewayHttpHandler"])
26+
# self._create_lambda_function_url(function=functions["LambdaFunctionUrlHandler"])
27+
self._create_appsync_endpoint(function=functions["AppsyncResolverHandler"])
2428

2529
def _create_alb(self, function: Function):
2630
vpc = ec2.Vpc.from_lookup(
@@ -84,3 +88,40 @@ def _create_lambda_function_url(self, function: Function):
8488
# Maintenance: move auth to IAM when we create sigv4 builders
8589
function_url = function.add_function_url(auth_type=FunctionUrlAuthType.AWS_IAM)
8690
CfnOutput(self.stack, "LambdaFunctionUrl", value=function_url.url)
91+
92+
def _create_appsync_endpoint(self, function: Function):
93+
api = appsync.GraphqlApi(
94+
self.stack,
95+
"Api",
96+
name="e2e-tests",
97+
schema=appsync.SchemaFile.from_asset(str(Path(self.feature_path, "files/schema.graphql"))),
98+
authorization_config=appsync.AuthorizationConfig(
99+
default_authorization=appsync.AuthorizationMode(
100+
authorization_type=appsync.AuthorizationType.API_KEY,
101+
api_key_config=appsync.ApiKeyConfig(
102+
description="public key for getting data",
103+
expires=Expiration.after(Duration.hours(25)),
104+
name="API Token",
105+
),
106+
)
107+
),
108+
xray_enabled=False,
109+
)
110+
lambda_datasource = api.add_lambda_data_source("DataSource", lambda_function=function)
111+
112+
lambda_datasource.create_resolver(
113+
"QueryGetAllPostsResolver",
114+
type_name="Query",
115+
field_name="allPosts",
116+
)
117+
lambda_datasource.create_resolver(
118+
"QueryGetPostResolver",
119+
type_name="Query",
120+
field_name="getPost",
121+
)
122+
lambda_datasource.create_resolver(
123+
"QueryGetPostRelatedResolver", type_name="Post", field_name="relatedPosts", max_batch_size=10
124+
)
125+
126+
CfnOutput(self.stack, "GraphQLHTTPUrl", value=api.graphql_url)
127+
CfnOutput(self.stack, "GraphQLAPIKey", value=api.api_key)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import json
2+
import pytest
3+
from requests import HTTPError, Request
4+
5+
from tests.e2e.utils import data_fetcher
6+
from tests.e2e.utils.auth import build_iam_auth
7+
8+
9+
@pytest.fixture
10+
def appsync_endpoint(infrastructure: dict) -> str:
11+
return infrastructure["GraphQLHTTPUrl"]
12+
13+
14+
@pytest.fixture
15+
def appsync_access_key(infrastructure: dict) -> str:
16+
return infrastructure["GraphQLAPIKey"]
17+
18+
19+
@pytest.mark.xdist_group(name="event_handler")
20+
def test_appsync_get_all_posts(appsync_endpoint, appsync_access_key):
21+
# GIVEN
22+
body = {
23+
"query": "query MyQuery { allPosts { id }}",
24+
"variables": None,
25+
"operationName": "MyQuery",
26+
}
27+
28+
# WHEN
29+
response = data_fetcher.get_http_response(
30+
Request(
31+
method="POST",
32+
url=appsync_endpoint,
33+
json=body,
34+
headers={"x-api-key": appsync_access_key, "Content-Type": "application/json"},
35+
)
36+
)
37+
38+
# THEN expect a HTTP 200 response and content return list of Posts
39+
assert response.status_code == 200
40+
assert response.content is not None
41+
42+
data = json.loads(response.content.decode("ascii"))["data"]
43+
44+
assert data["allPosts"] is not None
45+
assert len(data["allPosts"]) > 0
46+
47+
48+
@pytest.mark.xdist_group(name="event_handler")
49+
def test_appsync_get_post(appsync_endpoint, appsync_access_key):
50+
# GIVEN
51+
post_id = "1"
52+
body = {
53+
"query": f'query MyQuery {{ getPost(id: "{post_id}") {{ id }} }}',
54+
"variables": None,
55+
"operationName": "MyQuery",
56+
}
57+
58+
# WHEN
59+
response = data_fetcher.get_http_response(
60+
Request(
61+
method="POST",
62+
url=appsync_endpoint,
63+
json=body,
64+
headers={"x-api-key": appsync_access_key, "Content-Type": "application/json"},
65+
)
66+
)
67+
68+
# THEN expect a HTTP 200 response and content return Post id
69+
assert response.status_code == 200
70+
assert response.content is not None
71+
72+
data = json.loads(response.content.decode("ascii"))["data"]
73+
74+
assert data["getPost"]["id"] == post_id
75+
76+
77+
@pytest.mark.xdist_group(name="event_handler")
78+
def test_appsync_get_related_posts_batch(appsync_endpoint, appsync_access_key):
79+
# GIVEN
80+
post_id = "2"
81+
related_posts_ids = ["3", "5"]
82+
83+
body = {
84+
"query": f'query MyQuery {{ getPost(id: "{post_id}") {{ id relatedPosts {{ id }} }} }}',
85+
"variables": None,
86+
"operationName": "MyQuery",
87+
}
88+
89+
# WHEN
90+
response = data_fetcher.get_http_response(
91+
Request(
92+
method="POST",
93+
url=appsync_endpoint,
94+
json=body,
95+
headers={"x-api-key": appsync_access_key, "Content-Type": "application/json"},
96+
)
97+
)
98+
99+
# THEN expect a HTTP 200 response and content return Post id with dependent Posts id's
100+
assert response.status_code == 200
101+
assert response.content is not None
102+
103+
data = json.loads(response.content.decode("ascii"))["data"]
104+
105+
assert data["getPost"]["id"] == post_id
106+
assert len(data["getPost"]["relatedPosts"]) == len(related_posts_ids)
107+
for post in data["getPost"]["relatedPosts"]:
108+
assert post["id"] in related_posts_ids

0 commit comments

Comments
 (0)