Skip to content

Commit

Permalink
Write tests confirming Binary Support response behavior
Browse files Browse the repository at this point in the history
No functional change to the Zappa codebase is introduced by this commit.

This area of the application was untested. Tests introduced to ensure new
behavior discussed in zappa#908 does not cause
a regression.
  • Loading branch information
Quidge authored and Jonathan Demirgian committed Nov 29, 2021
1 parent b5b80cf commit 0125954
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 0 deletions.
12 changes: 12 additions & 0 deletions tests/test_binary_support_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
API_STAGE = "dev"
APP_FUNCTION = "app"
APP_MODULE = "tests.test_wsgi_binary_support_app"
BINARY_SUPPORT = True
CONTEXT_HEADER_MAPPINGS = {}
DEBUG = "True"
DJANGO_SETTINGS = None
DOMAIN = "api.example.com"
ENVIRONMENT_VARIABLES = {}
LOG_LEVEL = "DEBUG"
PROJECT_NAME = "binary_support_settings"
COGNITO_TRIGGER_MAPPING = {}
61 changes: 61 additions & 0 deletions tests/test_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from mock import Mock

from tests.utils import is_base64
from zappa.handler import LambdaHandler
from zappa.utilities import merge_headers

Expand Down Expand Up @@ -225,6 +226,66 @@ def test_exception_handler_on_web_request(self):
self.assertEqual(response["statusCode"], 500)
mocked_exception_handler.assert_called()

def test_wsgi_script_binary_support_base64_behavior(self):
"""
With Binary Support enabled, response mimetypes that are not text/* or application/json will be base64 encoded
"""
lh = LambdaHandler("tests.test_binary_support_settings")

text_plain_event = {
"body": "",
"resource": "/{proxy+}",
"requestContext": {},
"queryStringParameters": {},
"headers": {
"Host": "1234567890.execute-api.us-east-1.amazonaws.com",
},
"pathParameters": {"proxy": "return/request/url"},
"httpMethod": "GET",
"stageVariables": {},
"path": "/textplain_mimetype_response1",
}

response = lh.handler(text_plain_event, None)

self.assertEqual(response["statusCode"], 200)
self.assertNotIn("isBase64Encoded", response)
self.assertFalse(is_base64(response["body"]))

text_arbitrary_event = {
**text_plain_event,
**{"path": "/textarbitrary_mimetype_response1"},
}

response = lh.handler(text_arbitrary_event, None)

self.assertEqual(response["statusCode"], 200)
self.assertNotIn("isBase64Encoded", response)
self.assertFalse(is_base64(response["body"]))

application_json_event = {
**text_plain_event,
**{"path": "/json_mimetype_response1"},
}

response = lh.handler(application_json_event, None)

self.assertEqual(response["statusCode"], 200)
self.assertNotIn("isBase64Encoded", response)
self.assertFalse(is_base64(response["body"]))

arbitrary_binary_event = {
**text_plain_event,
**{"path": "/arbitrarybinary_mimetype_response1"},
}

response = lh.handler(arbitrary_binary_event, None)

self.assertEqual(response["statusCode"], 200)
self.assertIn("isBase64Encoded", response)
self.assertTrue(response["isBase64Encoded"])
self.assertTrue(is_base64(response["body"]))

def test_wsgi_script_on_cognito_event_request(self):
"""
Ensure that requests sent by cognito behave sensibly
Expand Down
31 changes: 31 additions & 0 deletions tests/test_wsgi_binary_support_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
###
# This test application exists to confirm how Zappa handles WSGI application
# _responses_ when Binary Support is enabled.
###

import io
import json

from flask import Flask, Response, send_file

app = Flask(__name__)


@app.route("/textplain_mimetype_response1", methods=["GET"])
def text_mimetype_response_1():
return Response(response="OK", mimetype="text/plain")


@app.route("/textarbitrary_mimetype_response1", methods=["GET"])
def text_mimetype_response_2():
return Response(response="OK", mimetype="text/arbitary")


@app.route("/json_mimetype_response1", methods=["GET"])
def json_mimetype_response_1():
return Response(response=json.dumps({"some": "data"}), mimetype="application/json")


@app.route("/arbitrarybinary_mimetype_response1", methods=["GET"])
def arbitrary_mimetype_response_1():
return Response(response=b"some binary data", mimetype="arbitrary/binary_mimetype")
9 changes: 9 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import base64
import functools
import os
from contextlib import contextmanager
Expand Down Expand Up @@ -74,3 +75,11 @@ def stub_open(*args, **kwargs):

with patch("__builtin__.open", stub_open):
yield mock_open, mock_file


def is_base64(test_string: str) -> bool:
# Taken from https://stackoverflow.com/a/45928164/3200002
try:
return base64.b64encode(base64.b64decode(test_string)).decode() == test_string
except Exception:
return False

0 comments on commit 0125954

Please sign in to comment.