]> git.scottworley.com Git - paperdoorknob/blob - testing/fakeserver.py
Bundle the things needed for a run together into a Spec
[paperdoorknob] / testing / fakeserver.py
1 from typing import Any, Self
2 import threading
3 from http.server import BaseHTTPRequestHandler, HTTPServer
4
5
6 class FakeGlowficHTTPRequestHandler(BaseHTTPRequestHandler):
7
8 def _notify_server(self) -> None:
9 raise NotImplementedError()
10
11 def _response_code(self) -> int:
12 if self.path == "/not_found":
13 return 404
14 if self.path == "/server_error":
15 return 500
16 return 200
17
18 def do_GET(self) -> None:
19 body = b'''<html>
20 <body>
21 <div class="post-container post-post">
22 <div class="post-edit-box">We don't want edit boxes</div>
23 This is glowfic
24 <div class="post-footer">We don't want footers</div>
25 </div>
26 <div class="flat-post-replies">
27 <div class="post-container post-reply">
28 <div class="post-edit-box">We don't want edit boxes</div>
29 You <em>sure</em>?
30 <div class="post-footer">We don't want footers</div>
31 </div>
32 <div class="post-container post-reply">
33 Pretty sure.
34 </div>
35 </div>
36 </body>
37 </html>'''
38 self.send_response(self._response_code())
39 self.send_header("Content-type", "text/html")
40 self.send_header("Content-Length", str(len(body)))
41 self.end_headers()
42 self.wfile.write(body)
43 self._notify_server()
44
45
46 class FakeGlowficServer():
47 def __init__(self) -> None:
48 self._request_counter = 0
49 handler = type("Handler", (FakeGlowficHTTPRequestHandler,), {
50 '_notify_server': lambda _: self._count_request()})
51 self._web_server = HTTPServer(('', 0), handler)
52 self._thread = threading.Thread(target=self._web_server.serve_forever)
53
54 def __enter__(self) -> Self:
55 self._thread.start()
56 return self
57
58 def __exit__(self, *_: Any) -> None:
59 self._web_server.shutdown()
60 self._thread.join()
61 self._web_server.server_close()
62
63 def _count_request(self) -> None:
64 self._request_counter += 1
65
66 def port(self) -> int:
67 p = self._web_server.socket.getsockname()[1]
68 assert isinstance(p, int)
69 return p
70
71 def request_count(self) -> int:
72 return self._request_counter