add tests for parsing and making requests

This commit is contained in:
Matthew Welch 2024-11-27 19:36:39 -08:00
parent 304cceb3da
commit 5be0d6dbcd
7 changed files with 198 additions and 1 deletions

View File

@ -28,7 +28,8 @@ class URL:
) )
s.connect((self.host, self.port)) s.connect((self.host, self.port))
if self.scheme == "https": if self.scheme == "https":
context = ssl.create_default_context() ssl.create_default_context()
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
s = context.wrap_socket(s, server_hostname=self.host) s = context.wrap_socket(s, server_hostname=self.host)
request_str = f"GET {self.path} HTTP/1.0\r\n" request_str = f"GET {self.path} HTTP/1.0\r\n"

0
tests/__init__.py Normal file
View File

21
tests/cert.pem Normal file
View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDbzCCAlegAwIBAgIUROO7imFPFyMzfKCmSSa8TGvAx6AwDQYJKoZIhvcNAQEL
BQAwRzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExDzANBgNVBAcM
BkxvbXBvYzESMBAGA1UEAwwJMTI3LjAuMC4xMB4XDTI0MTEyODAyMjIwN1oXDTI0
MTIyODAyMjIwN1owRzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx
DzANBgNVBAcMBkxvbXBvYzESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Je+aeCg977nlzBJQ+9iqqbos7INnDqMgxUC
oUtpd9+1/++z+WcxUxTCUAhDV/OD6nOLGe4H2O/5jeK/IHcAs/0Gq6ksd0Qvx7J2
VC84WN598e+acgH9b82aYGB63yQqxTUoAJTqjNRJvJnOCjnSlpS8MvBv8DTCKFeF
8rjDu7uxLgdt1787P/uTM62nrZUygLCtJqcDFPxFYjSnnMT2lALwuYab9080bV3w
QoomSs4FTo3ZIFDD6YZ6eyCrUOubIAg8ZAVfcrKUjTY1IkIwnwKiUCMpcg8hD+Gb
BHo9fQiDj1npk++9XjNF0qZy16rgL6aOZqMQiNORxr6coPG+QwIDAQABo1MwUTAd
BgNVHQ4EFgQUHxewwI1PpcU165FViyArQv4bJ3IwHwYDVR0jBBgwFoAUHxewwI1P
pcU165FViyArQv4bJ3IwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
AQEAGHLiixpwlRO5euyrqWEnNPzzLmrOhFQ1SSlo3KnG3kmDcPLC1vifzi9IeqSZ
zG/rl+JQYh30Ij0/CsgZTubXu6F3jQDiG5g3nvN/lDlzWRsePjZAN1OYh7UTKcNY
B5dvjCKXDcMeYM7jYYGKVlS/iowiCogTfd4mgV+jMoQRLXoYi5xTfr3Y5Flb7opu
6G2w4WHT6d/2vPdEuBhMp/2/G6d0WRZ5QILLeF02b6v7MjbZ9sIlNztVq5IWj466
dbqUP6eVHNDjALwwu/6GGChH1rDzbEcRMdzs254oIsQnNbVJannGy7qswKAb5Xrb
Oja90IiarO3y+zfC6xc9gwXpfw==
-----END CERTIFICATE-----

20
tests/conftest.py Normal file
View File

@ -0,0 +1,20 @@
import pytest
from tests.server import create_http_server_process
from tests.server import create_https_server_process
@pytest.fixture
def http_server(request):
server = create_http_server_process(request.param)
server.start()
yield
server.terminate()
@pytest.fixture
def https_server(request):
server = create_https_server_process(request.param)
server.start()
yield
server.terminate()

28
tests/key.pem Normal file
View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDYl75p4KD3vueX
MElD72Kqpuizsg2cOoyDFQKhS2l337X/77P5ZzFTFMJQCENX84Pqc4sZ7gfY7/mN
4r8gdwCz/QarqSx3RC/HsnZULzhY3n3x75pyAf1vzZpgYHrfJCrFNSgAlOqM1Em8
mc4KOdKWlLwy8G/wNMIoV4XyuMO7u7EuB23Xvzs/+5MzraetlTKAsK0mpwMU/EVi
NKecxPaUAvC5hpv3TzRtXfBCiiZKzgVOjdkgUMPphnp7IKtQ65sgCDxkBV9yspSN
NjUiQjCfAqJQIylyDyEP4ZsEej19CIOPWemT771eM0XSpnLXquAvpo5moxCI05HG
vpyg8b5DAgMBAAECggEACdMsUdzc1brPrOXa/51oHN9Ftq0GKAbnNnpUAba22eII
fUvFdAlFzVknjVN/9ok3JoHyQTgGcW/v9+CIFJ7BUJN9jiOLlFIVVsTWJZsfaQyY
AEsC9wFMb+9kKCiy5NSyVKVveJieC8sEw0I40fGYh2Mc0bS4EdiFfCioN1VBRQ6O
SBy5px0qFuYaGlZQrqUOZqJSMtPoQZf/ivEm2tvhVS8WACBZKvniex9LycqrhJAY
4qh+LwvC2qjszQonL52zcKQMy+/rgk4soaGPdmG09FeTFYhGIR0HWEFMFqgoejiH
oDC08yFLauKkvgc2EOuD5IkZHU+2/zpVLN9xldq3wQKBgQD+cXWuchD+N7qBpZd5
CDbHzm6b+vLpCcHst+DyajrV9laabnlFGDFuR0EktWieldDvwyb3LgL42YJg5zIZ
ghyWzyhpFn/OkAjbwoWIkcOgn/50O02JHkmjc103UJXuAmkgiVSJ2k2ewtjHN8GL
AYSMx/mOB8Yrls9rm8Bdws38QQKBgQDZ6v+BNWpkd3PrEVSDGQM4EvkDtbvYPS4p
9+1HhF6uYZ3EoP3e/Qzp9P1iyX/4NUXeWkyWsdMBJf5vJg42B/gEKEXYnT5tQhqF
ac+JnzDYWw3udpl2W1X2oiGH3B04PSbMb41+DQ5NYSZtnJPOwH/mS5bfLoZpATrW
2rm3rFNpgwKBgH4o5a/UUQarvScxYvSZFQhnG8LtX+oac3QbDEdGUtvqI7C43Bpd
T40deXhpFnGjWRC406Y1wzV+K74+hEHPmLtSBfhtNnvGQQ4t2iYIGFaZXgJlsSEu
ylZoCi02IND9kwCV9zvO6TOx6uiEhcuVuhJPyTYaNrFAOqJhfLVAtP/BAoGAWrxW
lt4+5oY2ZfJZVhzcEkUUGk9ZX7hZuG/bBKRBKCrNHkpKasbC0ceImdF8z0SfSu4e
ZcC1Mw022+DkmerHgjOioYcXrzaPBG4CVDNMi0mei2QmkfmF2aO4gnFMWVZdCVKJ
f6rAAcgp0AoaIURV/PYMY/FjVeWFMmDwY2IFeTECgYBhI8vjdFDpfwZvD2d7GwqT
/wK7GOJWbqJGx5KgzVxxNzZtOF8pM1+3AKcoVhnO42oalB+Zywq4Ju3d5673owm3
HZ83nrgiHvYrIb/xEjIfctqKZLWyQndFY++TTenFPhNHw6BV12tZlPKbS3bl6lHX
EY3aH2GtHyGlOssSyMSWZQ==
-----END PRIVATE KEY-----

44
tests/server.py Normal file
View File

@ -0,0 +1,44 @@
import ssl
from multiprocessing import Process
from http import HTTPStatus
from http.server import HTTPServer
from http.server import BaseHTTPRequestHandler
class Handler(BaseHTTPRequestHandler):
def log_message(self, format, *args):
pass
def send_text(self, content: str):
self.wfile.write(content.encode("utf8"))
def do_GET(self):
if self.path == "/":
self.send_response(HTTPStatus.OK)
self.end_headers()
self.send_text("test")
def get_ssl_context(cert_file, key_file):
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.load_cert_chain(cert_file, key_file)
context.set_ciphers("@SECLEVEL=1:ALL")
return context
def _start_http_server(port: int, use_tls: bool = False):
with HTTPServer(("127.0.0.1", port), Handler) as httpd:
if use_tls:
context = get_ssl_context("tests/cert.pem", "tests/key.pem")
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
httpd.serve_forever()
def create_http_server_process(port: int = 80):
server_process = Process(target=_start_http_server, kwargs={"port": port, "use_tls": False})
return server_process
def create_https_server_process(port: int = 443):
server_process = Process(target=_start_http_server, kwargs={"port": port, "use_tls": True})
return server_process

83
tests/url_test.py Normal file
View File

@ -0,0 +1,83 @@
import pytest
from browser import URL
@pytest.mark.parametrize(
"url_string,scheme,host,port,path",
[
(
"http://example.com",
"http",
"example.com",
80,
"/",
),
(
"http://example.com/",
"http",
"example.com",
80,
"/",
),
(
"https://example.com/",
"https",
"example.com",
443,
"/",
),
(
"http://example.com:5000/",
"http",
"example.com",
5000,
"/",
),
(
"http://example.com:5000/test/example",
"http",
"example.com",
5000,
"/test/example",
),
(
"https://example.com:5000/test/example",
"https",
"example.com",
5000,
"/test/example",
),
],
)
def test_url_parsing(url_string, scheme, host, port, path):
url = URL(url_string)
assert url.scheme == scheme
assert url.host == host
assert url.port == port
assert url.path == path
@pytest.mark.parametrize(
"http_server,url_string",
[
(80, "http://127.0.0.1/"),
(5000, "http://127.0.0.1:5000/"),
],
indirect=["http_server"],
)
def test_http_request(http_server, url_string):
url = URL(url_string)
assert url.request() == "test"
@pytest.mark.parametrize(
"https_server,url_string",
[
(443, "https://127.0.0.1/"),
(5000, "https://127.0.0.1:5000/"),
],
indirect=["https_server"],
)
def test_https_request(https_server, url_string):
url = URL(url_string)
assert url.request() == "test"