async def test_directory_handler_with_menus(directory_handler_with_menus: DirectoryHandler): """Directory handler with generate_menus generates its own menu.""" response = await directory_handler_with_menus.handle(Request("localhost", 7000, "")) assert response == Menu([ MenuItem("0", "example", "example", "localhost", 7000), MenuItem("I", "image.png", "image.png", "localhost", 7000), MenuItem("0", "index", "index", "localhost", 7000), MenuItem("1", "test", "test", "localhost", 7000), ])
async def dispatch(self, hostname: str, port: int, selector: bytes) -> bytes: """ Dispatches a request. This is called by a listener, and in turn calls the `Application`'s handler. The hostname and port are passed through in a :class:`Request <gopher_server.handlers.Request>` object so that handlers which generate a menu can include the right values for local selectors. """ try: decoded_selector = selector.decode("utf-8") except UnicodeDecodeError: return b"3Bad selector.\t\terror.host\t0\r\n.\r\n" decoded_selector = decoded_selector.strip() if "\t" in decoded_selector or "\r" in decoded_selector or "\n" in decoded_selector: return b"3Bad selector.\t\terror.host\t0\r\n.\r\n" request = Request(hostname, port, decoded_selector) try: response = await self.handler.handle(request) except NotFound: return b"3Not found.\t\terror.host\t0\r\n.\r\n" except Exception as e: log.error("Caught exception:", exc_info=e) return b"3Internal server error.\t\terror.host\t0\r\n.\r\n" if isinstance(response, Menu): response = response.serialize() if isinstance(response, str): encoded_response = response.encode("utf-8") encoded_response = encoded_response.replace(b"\n", b"\r\n") if not encoded_response.endswith(b"\r\n"): encoded_response += b"\r\n" return encoded_response + b".\r\n" return response
async def test_pattern_handler_static(pattern_handler: PatternHandler): response = await pattern_handler.handle(Request("localhost", 7000, "static_pattern")) assert response == "static pattern response"
async def test_directory_handler_with_menus_subdirectory(directory_handler_with_menus: DirectoryHandler): """Directory handler with generate_menus generates its own menu.""" response = await directory_handler_with_menus.handle(Request("localhost", 7000, "test")) assert response == Menu([ MenuItem("0", "lol", "test/lol", "localhost", 7000), ])
async def test_directory_handler_directory(directory_handler: DirectoryHandler): """Directory name returns index file from the directory.""" response = await directory_handler.handle(Request("localhost", 7000, "")) with open(os.path.join(BASE_PATH + "index")) as f: assert response == f.read()
async def test_directory_handler_not_found(directory_handler: DirectoryHandler): """Non-existient file raises NotFound.""" with pytest.raises(NotFound): await directory_handler.handle(Request("localhost", 7000, "qwertyuiop"))
async def test_directory_handler_binary(directory_handler: DirectoryHandler): """Binary files are returned as bytes.""" response = await directory_handler.handle(Request("localhost", 7000, "image.png")) with open(os.path.join(BASE_PATH + "image.png"), "rb") as f: assert response == f.read()
async def test_directory_handler_file(directory_handler: DirectoryHandler): """File path returns file from the directory.""" response = await directory_handler.handle(Request("localhost", 7000, "example")) with open(os.path.join(BASE_PATH + "example")) as f: assert response == f.read()
async def test_pattern_handler_not_found(pattern_handler: PatternHandler): """Unrecognised pattern raises NotFound.""" with pytest.raises(NotFound): await pattern_handler.handle(Request("localhost", 7000, "qwertyuiop"))
async def test_pattern_handler_async(pattern_handler: PatternHandler): response = await pattern_handler.handle(Request("localhost", 7000, "async_view")) assert response == "async view response"
async def test_pattern_handler_dynamic(pattern_handler: PatternHandler): response = await pattern_handler.handle(Request("localhost", 7000, "dynamic_pattern/foo")) assert response == "dynamic response for foo"