snipe/tests/db/test_store.py
pyr0ball fb81422c54 feat: snipe beta backlog batch (tickets #22/#28/#30/#34/#35/#36/#37/#38)
Cloud/session:
- fix(_extract_session_token): return "" for non-JWT cookie strings (snipe_guest=uuid was
  triggering 401 → forced login redirect for all unauthenticated cloud visitors)
- fix(affiliate): exclude guest: and anonymous users from pref-store writes (#38)
- fix(market-comp): use enriched comp_query for market comp hash so write/read keys match (#30)

Frontend:
- feat(SearchView): unauthenticated landing strip with free-account CTA (#36)
- feat(SearchView): aria-pressed on filter toggles, aria-label on icon buttons, focus-visible
  rings on all interactive controls, live region for result count (#35)
- feat(SearchView): no-results empty-state hint text (#36)
- feat(SEO): og:image 1200x630, summary_large_image twitter card, canonical link (#37)
- feat(OG): generated og-image.png (dark tactical theme, feature pills) (#37)
- feat(settings): TrustSignalPref view wired to /settings route (#28)
- fix(router): /settings route added; unauthenticated access redirects to home (#34)

CI/CD:
- feat(ci): Forgejo Actions workflow (ruff + pytest + vue-tsc + vitest) (#22)
- feat(ci): mirror workflow (GitHub + Codeberg on push to main/tags) (#22)
- feat(ci): release workflow (Docker build+push + git-cliff changelog) (#22)
- chore: git-cliff config (.cliff.toml) for conventional commit changelog (#22)
- chore(pyproject): dev extras (pytest/ruff/httpx), ruff config with ignore list (#22)

Lint:
- fix: remove 11 unused imports across api/, app/, tests/ (ruff F401 clean)
2026-04-13 19:32:50 -07:00

80 lines
2.1 KiB
Python

from datetime import datetime, timedelta, timezone
import pytest
from app.db.models import Listing, MarketComp, Seller
from app.db.store import Store
@pytest.fixture
def store(tmp_path):
return Store(tmp_path / "test.db")
def test_store_creates_tables(store):
# If no exception on init, tables exist
pass
def test_save_and_get_seller(store):
seller = Seller(
platform="ebay",
platform_seller_id="user123",
username="techseller",
account_age_days=730,
feedback_count=450,
feedback_ratio=0.991,
category_history_json="{}",
)
store.save_seller(seller)
result = store.get_seller("ebay", "user123")
assert result is not None
assert result.username == "techseller"
assert result.feedback_count == 450
def test_save_and_get_listing(store):
listing = Listing(
platform="ebay",
platform_listing_id="ebay-123",
title="RTX 4090 FE",
price=950.00,
currency="USD",
condition="used",
seller_platform_id="user123",
url="https://ebay.com/itm/123",
photo_urls=["https://i.ebayimg.com/1.jpg"],
listing_age_days=3,
)
store.save_listing(listing)
result = store.get_listing("ebay", "ebay-123")
assert result is not None
assert result.title == "RTX 4090 FE"
assert result.price == 950.00
def test_save_and_get_market_comp(store):
comp = MarketComp(
platform="ebay",
query_hash="abc123",
median_price=1050.0,
sample_count=12,
expires_at=(datetime.now(timezone.utc) + timedelta(hours=6)).isoformat(),
)
store.save_market_comp(comp)
result = store.get_market_comp("ebay", "abc123")
assert result is not None
assert result.median_price == 1050.0
def test_get_market_comp_returns_none_for_expired(store):
comp = MarketComp(
platform="ebay",
query_hash="expired",
median_price=900.0,
sample_count=5,
expires_at="2020-01-01T00:00:00", # past
)
store.save_market_comp(comp)
result = store.get_market_comp("ebay", "expired")
assert result is None