initial project commit
This commit is contained in:
7
tests/conftest.py
Normal file
7
tests/conftest.py
Normal file
@@ -0,0 +1,7 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Ensure project root is on sys.path so `web` package can be imported
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
if str(root) not in sys.path:
|
||||
sys.path.insert(0, str(root))
|
||||
152
tests/test_db_integration.py
Normal file
152
tests/test_db_integration.py
Normal file
@@ -0,0 +1,152 @@
|
||||
import os
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import pytest
|
||||
|
||||
import web.db as db
|
||||
from web.utils import now_iso
|
||||
|
||||
|
||||
# Skip this entire test module unless explicitly enabled and DB is reachable
|
||||
if not os.getenv("RUN_DB_TESTS"):
|
||||
pytest.skip("Set RUN_DB_TESTS=1 to run MySQL integration tests",
|
||||
allow_module_level=True)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def db_ready():
|
||||
try:
|
||||
db.db_init()
|
||||
return True
|
||||
except Exception as e:
|
||||
pytest.skip(f"MySQL DB not reachable or init failed: {e}")
|
||||
|
||||
|
||||
def unique_suffix() -> str:
|
||||
# Time-based unique suffix for test records
|
||||
return datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S%f")
|
||||
|
||||
|
||||
def test_user_create_and_auth(db_ready):
|
||||
uname = f"it_user_{unique_suffix()}"
|
||||
pw = "P@ssw0rd!"
|
||||
uid = db.create_or_update_user(
|
||||
uname, password=pw, is_admin=False, is_active=True)
|
||||
assert isinstance(uid, int)
|
||||
assert db.verify_user_credentials(uname, pw) is True
|
||||
assert db.verify_user_credentials(uname, "wrong") is False
|
||||
|
||||
|
||||
def test_regions_keywords_upsert_and_list(db_ready):
|
||||
rname = f"it_region_{unique_suffix()}"
|
||||
kname = f"it_keyword_{unique_suffix()}"
|
||||
rid = db.upsert_region(rname)
|
||||
kid = db.upsert_keyword(kname)
|
||||
assert isinstance(rid, int) and rid > 0
|
||||
assert isinstance(kid, int) and kid > 0
|
||||
regions = db.get_all_regions()
|
||||
keywords = db.get_all_keywords()
|
||||
assert rname in regions
|
||||
assert kname in keywords
|
||||
|
||||
|
||||
def test_user_preferences_roundtrip(db_ready):
|
||||
uname = f"it_pref_user_{unique_suffix()}"
|
||||
db.create_or_update_user(uname, is_active=True)
|
||||
r1, r2 = f"it_r1_{unique_suffix()}", f"it_r2_{unique_suffix()}"
|
||||
k1, k2 = f"it_k1_{unique_suffix()}", f"it_k2_{unique_suffix()}"
|
||||
# Set preferences (upserts regions/keywords internally if missing)
|
||||
db.set_user_regions(uname, [r1, r2])
|
||||
db.set_user_keywords(uname, [k1, k2])
|
||||
assert set(db.get_user_regions(uname)) >= {r1, r2}
|
||||
assert set(db.get_user_keywords(uname)) >= {k1, k2}
|
||||
|
||||
|
||||
def test_upsert_listing_details_and_urls(db_ready):
|
||||
# Create a unique URL
|
||||
jid_suffix = unique_suffix()
|
||||
url = f"https://example.org/it/{jid_suffix}.html"
|
||||
db.upsert_listing(
|
||||
url=url,
|
||||
region="it",
|
||||
keyword="integration",
|
||||
title=f"IT Listing {jid_suffix}",
|
||||
pay="N/A",
|
||||
location="Test City",
|
||||
timestamp=now_iso(),
|
||||
)
|
||||
job_data = {
|
||||
"url": url,
|
||||
"title": f"IT Job {jid_suffix}",
|
||||
"company": "Acme Corp",
|
||||
"location": "Test City",
|
||||
"description": "A test job for integration",
|
||||
"id": jid_suffix, # normalize_job_id should use this or fall back to URL
|
||||
"posted_time": now_iso(),
|
||||
}
|
||||
db.upsert_job_details(job_data)
|
||||
urls = db.db_get_all_job_urls()
|
||||
assert url in urls
|
||||
# Cleanup (best-effort)
|
||||
try:
|
||||
db.db_delete_job(jid_suffix)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def test_cached_page_upsert_and_get(db_ready):
|
||||
jid_suffix = unique_suffix()
|
||||
url = f"https://example.org/it/{jid_suffix}.html"
|
||||
# Ensure a listing exists for FK relation if enforced
|
||||
db.upsert_listing(
|
||||
url=url,
|
||||
region="it",
|
||||
keyword="cache",
|
||||
title=f"IT Cache {jid_suffix}",
|
||||
pay="N/A",
|
||||
location="Test City",
|
||||
timestamp=now_iso(),
|
||||
)
|
||||
fp = f"/tmp/integration_{jid_suffix}.html"
|
||||
db.upsert_cached_page(
|
||||
file_path=fp,
|
||||
url_guess=url,
|
||||
last_modified=now_iso(),
|
||||
size_bytes=123,
|
||||
job_id=int(jid_suffix) if jid_suffix.isdigit() else None,
|
||||
)
|
||||
row = db.db_get_cache_url(url)
|
||||
if row is not None:
|
||||
assert row["url_guess"] == url
|
||||
# Cleanup
|
||||
try:
|
||||
db.remove_cached_page(fp)
|
||||
db.db_remove_cached_url(url)
|
||||
db.db_delete_job(jid_suffix)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def test_user_interactions_mark_and_visit(db_ready):
|
||||
uname = f"it_user_{unique_suffix()}"
|
||||
db.create_or_update_user(uname, is_active=True)
|
||||
jid_suffix = unique_suffix()
|
||||
url = f"https://example.org/it/{jid_suffix}.html"
|
||||
db.upsert_listing(
|
||||
url=url,
|
||||
region="it",
|
||||
keyword="interact",
|
||||
title=f"IT Interact {jid_suffix}",
|
||||
pay="N/A",
|
||||
location="Test City",
|
||||
timestamp=now_iso(),
|
||||
)
|
||||
# Exercise helpers — absence of exceptions is success for integration
|
||||
db.mark_favorite(jid_suffix, uname, True)
|
||||
db.record_visit(jid_suffix, uname, url=url)
|
||||
# Cleanup
|
||||
try:
|
||||
db.db_delete_job(jid_suffix)
|
||||
except Exception:
|
||||
pass
|
||||
19
tests/test_users.py
Normal file
19
tests/test_users.py
Normal file
@@ -0,0 +1,19 @@
|
||||
import pytest
|
||||
from web.db import db_init, create_or_update_user, verify_user_credentials, get_users
|
||||
from web.utils import initialize_users_from_settings
|
||||
|
||||
|
||||
def test_initialize_users_from_settings():
|
||||
db_init()
|
||||
n = initialize_users_from_settings()
|
||||
assert n >= 1 # should at least add 'anonymous'
|
||||
users = get_users()
|
||||
assert any(u['username'] == 'anonymous' for u in users)
|
||||
|
||||
|
||||
def test_create_and_auth_user():
|
||||
db_init()
|
||||
create_or_update_user('testuser', password='secret',
|
||||
is_admin=True, is_active=True)
|
||||
assert verify_user_credentials('testuser', 'secret') is True
|
||||
assert verify_user_credentials('testuser', 'wrong') is False
|
||||
18
tests/test_utils_config.py
Normal file
18
tests/test_utils_config.py
Normal file
@@ -0,0 +1,18 @@
|
||||
import importlib
|
||||
import os
|
||||
|
||||
import web.utils as utils
|
||||
|
||||
|
||||
def test_config_loaded():
|
||||
cfg = utils.get_config()
|
||||
assert isinstance(cfg, dict)
|
||||
|
||||
|
||||
def test_http_settings_helpers():
|
||||
assert isinstance(utils.get_user_agent(), str)
|
||||
assert isinstance(utils.get_request_timeout(), int)
|
||||
assert isinstance(utils.get_max_retries(), int)
|
||||
assert isinstance(utils.get_backoff_factor(), int)
|
||||
assert isinstance(utils.get_min_delay(), int)
|
||||
assert isinstance(utils.get_max_delay(), int)
|
||||
Reference in New Issue
Block a user