pryscraper/tests/test_infrastructure.py
cryptorugmunch 0ecc250349 refactor(pry): rename 19 root modules to pry_<name> to remove naming collision with routers/
The duplicate file names (advanced, agency, auth, compliance, costing, etc.) in
both root and routers/ made imports ambiguous. Renamed root modules to
pry_<name>.py so:

  from quality import X     ->  from pry_quality import X
  from routers.quality import router  (unchanged)

Also:
- Renamed x402.py to pry_x402/ package directory
- Fixed 21+ bare imports across api.py, deps.py, routers/, tests/, llm_providers/

Tests: 593 passed, 1 skipped (test_ready_returns_200 fails pre-existing
because Ollama is unreachable from test env, unrelated to this refactor).

Audit item 8.
2026-07-06 10:25:44 +02:00

99 lines
2.7 KiB
Python

# SPDX-License-Identifier: MIT
# Copyright (c) 2026 Rug Munch Media LLC
#
# Part of Pry — https://git.rugmunch.io/RugMunchMedia/pryscraper
# Licensed under MIT. See LICENSE.
"""Tests for production infrastructure (auth, db, observability, jobs)."""
import asyncio
from pry_auth import AuthManager, base64_decode, base64_encode
from db import _has_sqlalchemy, get_db
from observability import track_llm_call, track_request, track_scrape
from tasks import JobQueue, JobStatus
def test_auth_hash_password() -> None:
a = AuthManager()
h, salt = a.hash_password("hunter2")
assert a.verify_password("hunter2", h, salt) is True
assert a.verify_password("wrong", h, salt) is False
def test_auth_api_key() -> None:
a = AuthManager()
user = a.create_user("test@example.com", "password")
key = a.create_api_key(user["id"])
assert key.startswith("pry_")
verified = a.verify_api_key(key)
assert verified is not None
assert verified["user_id"] == user["id"]
# Invalid key
assert a.verify_api_key("invalid") is None
def test_auth_rate_limit() -> None:
a = AuthManager()
a._rate_limits["test"] = {"window_start": 0, "count": 0}
allowed, remaining = a.check_rate_limit("test")
assert allowed is True
assert remaining >= 0
def test_auth_jwt_fallback() -> None:
a = AuthManager()
user = a.create_user("jwt@test.com", "pass")
token = a.create_jwt(user["id"])
payload = a.verify_jwt(token)
assert payload is not None
assert payload["sub"] == user["id"]
def test_base64_roundtrip() -> None:
assert base64_decode(base64_encode("hello world")) == "hello world"
def test_observability_track_request() -> None:
with track_request("/test"):
pass # Should not raise
def test_observability_track_scrape() -> None:
with track_scrape("direct"):
pass
def test_observability_track_llm() -> None:
track_llm_call("openai", "gpt-4o-mini", 0.001)
def test_db_is_available() -> None:
# Just check it doesn't crash; may be unavailable if no sqlalchemy
db = get_db()
if _has_sqlalchemy:
assert db is not None
def test_job_queue_submit() -> None:
async def _test():
q = JobQueue()
async def my_task(x):
return x * 2
job_id = await q.submit("double", my_task, args=(5,))
assert job_id in q.jobs
# Run inline
job = q.jobs[job_id]
await q._execute(job)
assert job.status == JobStatus.COMPLETED
assert job.result == 10
asyncio.run(_test())
def test_job_listing() -> None:
q = JobQueue()
q.jobs["test"] = type("J", (), {"to_dict": lambda self: {"id": "test", "name": "x"}})()
# Simple smoke test
assert hasattr(q, "list_jobs")