diff --git a/http_request_recorder/http_request_recorder.py b/http_request_recorder/http_request_recorder.py index 27c963d..cf7ebe8 100644 --- a/http_request_recorder/http_request_recorder.py +++ b/http_request_recorder/http_request_recorder.py @@ -106,6 +106,7 @@ def __init__(self, name: str, port: int): self._port = port self._expectations: list[ExpectedInteraction] = [] + self._unexpected_requests: list[RecordedRequest] = [] app = web.Application() @@ -138,6 +139,9 @@ def unsatisfied_expectations(self) -> list[ExpectedInteraction]: """Usage in unittest: `self.assertListEqual([], a_recorder.unsatisfied_expectations())`""" return [exp for exp in self._expectations if exp.is_still_expecting_requests()] + def unexpected_requests(self) -> list[RecordedRequest]: + return self._unexpected_requests + async def handle_request(self, request: BaseRequest): request_body = await request.read() self._logger.info(f"{self} got {await self._request_string_for_log(request)}") @@ -147,6 +151,7 @@ async def handle_request(self, request: BaseRequest): matches = [exp for exp in self._expectations if exp.can_respond(recorded_request)] if len(matches) == 0: self._logger.warning(f"{self} got unexpected {await self._request_string_for_log(request)}") + self._unexpected_requests.append(recorded_request) return web.Response(status=404) if len(matches) > 1: diff --git a/setup.py b/setup.py index 4e126fe..f97743a 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ setup( name='http_request_recorder', - version='0.3.0', + version='0.4.0', description='A package to record an respond to http requests, primarily for use in black box testing.', long_description=readme, author='', diff --git a/tests/test_http_request_recorder.py b/tests/test_http_request_recorder.py index 58b6e37..a6ea8c9 100644 --- a/tests/test_http_request_recorder.py +++ b/tests/test_http_request_recorder.py @@ -1,5 +1,6 @@ import asyncio import logging +import re import unittest from aiohttp import web, ClientSession @@ -117,7 +118,7 @@ async def test_successful_response_logs_debug_message(self): async def test_log_warning_for_unrequested_expected_request(self): with self.assertLogs("recorder", level=logging.INFO) as log_recorder: - logging.getLogger("recorder").addHandler(logging.StreamHandler()) + logging.getLogger("recorder").addHandler(logging.StreamHandler()) # also output logging request_paths = ["/never_gets_called", "/neither"] async with HttpRequestRecorder(name="disappointed recorder", port=self.port) as recorder: @@ -135,7 +136,7 @@ async def test_log_warning_for_unrequested_expected_request(self): for path in request_paths: self.assertIn(path, record.msg) - async def test_provide_unrequested_expected_requests(self): + async def test_provide_unsatisfied_expectations(self): expected_paths = ["/called", "/never_gets_called", "/neither"] async with (HttpRequestRecorder(name="disappointed recorder", port=self.port) as recorder, ClientSession() as http_session): @@ -147,6 +148,27 @@ async def test_provide_unrequested_expected_requests(self): unsatisfied = {e.name for e in recorder.unsatisfied_expectations()} self.assertSetEqual({"/never_gets_called", "/neither"}, unsatisfied) + async def test_handle_unexpected_requests(self): + with self.assertLogs("recorder", level=logging.INFO) as log_recorder: + logging.getLogger("recorder").addHandler(logging.StreamHandler()) # also output logging + + async with (HttpRequestRecorder(name="surprised recorder", port=self.port) as recorder, + ClientSession() as http_session): + # expect nothing + await http_session.get(f"http://localhost:{self.port}/called") + + with self.subTest("logs warning"): + logs = log_recorder.records + log_about_unexpected = [l for l in logs if 'got unexpected GET' in l.msg] + self.assertEqual(1, len(log_about_unexpected)) + self.assertEqual(logging.WARNING, log_about_unexpected[0].levelno) + + with self.subTest("provides unexpected request"): + unexpected_requests = recorder.unexpected_requests() + self.assertEqual(1, len(unexpected_requests)) + self.assertEqual("/called", unexpected_requests[0].path) + self.assertEqual("GET", unexpected_requests[0].method) + async def test_should_handle_late_request(self): async with HttpRequestRecorder(name="patient recorder", port=self.port) as recorder, ClientSession() as http_session: expectation = recorder.expect_path(path='/called-late', responses="response")