refactor(types): PEP-604 union sweep + UP007/UP045 enforcement
ruff --select UP007,UP045 --fix converted ~1760 sites across the backend: `Optional[T]` → `T | None`, `Union[X, Y]` → `X | Y`. The remaining module-level alias targets that ruff conservatively skips (BindableFloatInput, ColorList, DeviceConfig) were converted by hand earlier in the pass. black -formatted the result so the wider unions fit cleanly under the 100-char line budget. pyproject.toml now sets [tool.ruff.lint] extend-select = ["UP007", "UP045"] so future legacy imports fire CI on every push. The pre-commit ruff hook was bumped from v0.8.0 -> v0.15.12 to recognise UP045 (split off from UP007 in v0.13).
This commit is contained in:
@@ -8,8 +8,6 @@ helpers to make unauthenticated requests by temporarily removing the header.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
def _unauth_get(client, url):
|
||||
"""Make a GET request without the Authorization header."""
|
||||
saved = client.headers.pop("Authorization", None)
|
||||
@@ -54,7 +52,9 @@ class TestAuthEnforcement:
|
||||
def test_request_with_wrong_key_returns_401(self, client):
|
||||
"""Protected endpoint with an incorrect API key returns 401."""
|
||||
resp = _with_header(
|
||||
client, "GET", "/api/v1/devices",
|
||||
client,
|
||||
"GET",
|
||||
"/api/v1/devices",
|
||||
auth_value="Bearer wrong-key-12345",
|
||||
)
|
||||
assert resp.status_code == 401
|
||||
@@ -82,7 +82,9 @@ class TestAuthEnforcement:
|
||||
def test_post_without_auth_returns_401(self, client):
|
||||
"""Creating a device without auth fails."""
|
||||
resp = _unauth_request(
|
||||
client, "POST", "/api/v1/devices",
|
||||
client,
|
||||
"POST",
|
||||
"/api/v1/devices",
|
||||
json={
|
||||
"name": "Unauthorized Device",
|
||||
"url": "mock://test",
|
||||
@@ -115,7 +117,9 @@ class TestAuthEnforcement:
|
||||
def test_malformed_bearer_token_returns_401_or_403(self, client):
|
||||
"""A malformed Authorization header is rejected."""
|
||||
resp = _with_header(
|
||||
client, "GET", "/api/v1/devices",
|
||||
client,
|
||||
"GET",
|
||||
"/api/v1/devices",
|
||||
auth_value="just-a-key",
|
||||
)
|
||||
# FastAPI's HTTPBearer returns 403 for malformed format,
|
||||
|
||||
@@ -5,7 +5,6 @@ create -> get -> update -> brightness -> power -> delete -> verify gone.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class TestDeviceLifecycle:
|
||||
"""A user creates a device, inspects it, modifies it, and deletes it."""
|
||||
|
||||
@@ -76,12 +75,15 @@ class TestDeviceLifecycle:
|
||||
def test_create_multiple_devices_and_list(self, client):
|
||||
"""Creating multiple devices shows all in the list."""
|
||||
for i in range(3):
|
||||
resp = client.post("/api/v1/devices", json={
|
||||
"name": f"Device {i}",
|
||||
"url": "mock://test",
|
||||
"device_type": "mock",
|
||||
"led_count": 30,
|
||||
})
|
||||
resp = client.post(
|
||||
"/api/v1/devices",
|
||||
json={
|
||||
"name": f"Device {i}",
|
||||
"url": "mock://test",
|
||||
"device_type": "mock",
|
||||
"led_count": 30,
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 201
|
||||
|
||||
resp = client.get("/api/v1/devices")
|
||||
@@ -108,13 +110,16 @@ class TestDeviceLifecycle:
|
||||
|
||||
def test_update_tags(self, client):
|
||||
"""Tags can be updated independently."""
|
||||
resp = client.post("/api/v1/devices", json={
|
||||
"name": "Tag Device",
|
||||
"url": "mock://test",
|
||||
"device_type": "mock",
|
||||
"led_count": 10,
|
||||
"tags": ["original"],
|
||||
})
|
||||
resp = client.post(
|
||||
"/api/v1/devices",
|
||||
json={
|
||||
"name": "Tag Device",
|
||||
"url": "mock://test",
|
||||
"device_type": "mock",
|
||||
"led_count": 10,
|
||||
"tags": ["original"],
|
||||
},
|
||||
)
|
||||
device_id = resp.json()["id"]
|
||||
|
||||
resp = client.put(
|
||||
|
||||
Reference in New Issue
Block a user