+from typing import Any, Self
+import threading
+from http.server import BaseHTTPRequestHandler, HTTPServer
+
+
+class FakeGlowficHTTPRequestHandler(BaseHTTPRequestHandler):
+
+ def _notify_server(self) -> None:
+ raise NotImplementedError()
+
+ def _response_code(self) -> int:
+ if self.path == "/not_found":
+ return 404
+ if self.path == "/server_error":
+ return 500
+ return 200
+
+ def do_GET(self) -> None:
+ body = b'''<html>
+ <body>
+ <div class="post-container post-post">
+ <div class="post-edit-box">We don't want edit boxes</div>
+ This is glowfic
+ <div class="post-footer">We don't want footers</div>
+ </div>
+ <div class="flat-post-replies">
+ <div class="post-container post-reply">
+ <div class="post-edit-box">We don't want edit boxes</div>
+ You <em>sure</em>?
+ <div class="post-footer">We don't want footers</div>
+ </div>
+ <div class="post-container post-reply">
+ Pretty sure.
+ </div>
+ </div>
+ </body>
+</html>'''
+ self.send_response(self._response_code())
+ self.send_header("Content-type", "text/html")
+ self.send_header("Content-Length", str(len(body)))
+ self.end_headers()
+ self.wfile.write(body)
+ self._notify_server()
+
+
+class FakeGlowficServer():
+ def __init__(self) -> None:
+ self._request_counter = 0
+ handler = type("Handler", (FakeGlowficHTTPRequestHandler,), {
+ '_notify_server': lambda _: self._count_request()})
+ self._web_server = HTTPServer(('', 0), handler)
+ self._thread = threading.Thread(target=self._web_server.serve_forever)
+
+ def __enter__(self) -> Self:
+ self._thread.start()
+ return self
+
+ def __exit__(self, *_: Any) -> None:
+ self._web_server.shutdown()
+ self._thread.join()
+ self._web_server.server_close()
+
+ def _count_request(self) -> None:
+ self._request_counter += 1
+
+ def port(self) -> int:
+ p = self._web_server.socket.getsockname()[1]
+ assert isinstance(p, int)
+ return p
+
+ def request_count(self) -> int:
+ return self._request_counter