Spaces:
Running
Running
| """Suite A — Token usage consistency (P0).""" | |
| import pytest | |
| from sqlalchemy import select | |
| from app.models.client_access import ClientAccess | |
| from app.services.analytics_core.tracker import track_turn | |
| from app.services.token_budget import tokens_remaining, total_budget, usage_summary | |
| from tests.conftest import FakePipelineResult | |
| def test_admin_token_usage_includes_bonus_tokens(client_access): | |
| """A-10: Admin token-usage includes bonus_tokens in budget.""" | |
| response = usage_summary(client_access) | |
| expected_total = total_budget(client_access) | |
| assert response["budget"] == expected_total | |
| assert response["remaining"] == expected_total - client_access.tokens_used | |
| def test_admin_and_embed_remaining_match(client_access): | |
| """A-43: Token Usage page and Embed Token card must show same remaining.""" | |
| admin = usage_summary(client_access) | |
| embed_remaining = tokens_remaining(client_access) | |
| assert admin["remaining"] == embed_remaining | |
| async def test_track_turn_increments_client_access_tokens_used( | |
| db_session, mock_redis, author_user, client_access, | |
| ): | |
| """A-01: Chat increments client_access.tokens_used.""" | |
| from app.models.base import generate_uuid | |
| from app.models.chat_session import ChatSession | |
| from datetime import datetime, timezone | |
| from tests.conftest import FakePipelineResult | |
| from app.services.analytics_core.tracker import track_turn | |
| db_session.add( | |
| ChatSession( | |
| id="session-1", | |
| author_id=author_user.id, | |
| visitor_fingerprint="fp-test", | |
| created_at=datetime.now(timezone.utc), | |
| ) | |
| ) | |
| await db_session.flush() | |
| tokens_before = client_access.tokens_used | |
| result = FakePipelineResult(prompt_tokens=100, completion_tokens=50) | |
| await track_turn( | |
| db=db_session, | |
| redis=mock_redis, | |
| session_id="session-1", | |
| author_id=author_user.id, | |
| book_id=None, | |
| user_message="Hello", | |
| result=result, | |
| ) | |
| await db_session.commit() | |
| row = await db_session.scalar( | |
| select(ClientAccess).where(ClientAccess.id == client_access.id) | |
| ) | |
| assert row.tokens_used == tokens_before + 150 | |
| async def test_track_turn_increments_redis_counter( | |
| db_session, mock_redis, author_user, client_access | |
| ): | |
| """A-02: Redis tokens:{author_id}:current is incremented on chat.""" | |
| from app.models.chat_session import ChatSession | |
| from datetime import datetime, timezone | |
| db_session.add(ChatSession( | |
| id="session-redis", | |
| author_id=author_user.id, | |
| visitor_fingerprint="fp-redis", | |
| created_at=datetime.now(timezone.utc), | |
| )) | |
| await db_session.flush() | |
| result = FakePipelineResult(prompt_tokens=100, completion_tokens=50) | |
| await track_turn( | |
| db=db_session, | |
| redis=mock_redis, | |
| session_id="session-redis", | |
| author_id=author_user.id, | |
| book_id=None, | |
| user_message="Hello", | |
| result=result, | |
| ) | |
| key = f"tokens:{author_user.id}:current" | |
| # Redis counter must have been incremented by the 150 tokens in this turn | |
| assert (mock_redis._counters.get(key) or 0) >= 150 | |
| def test_superadmin_and_admin_budget_formula_match(client_access): | |
| """Consistency matrix: SuperAdmin total_budget vs Admin budget must match.""" | |
| super_total = total_budget(client_access) | |
| admin_budget = usage_summary(client_access)["budget"] | |
| assert admin_budget == super_total | |
| def test_no_active_subscription_returns_zeros(): | |
| """Authors without an active grant must see zero budget, not stale grants.""" | |
| from app.services.token_budget import usage_summary_or_empty | |
| result = usage_summary_or_empty(None) | |
| assert result["budget"] == 0 | |
| assert result["used"] == 0 | |
| assert result["remaining"] == 0 | |
| assert result["has_active_subscription"] is False | |
| assert result["subscription_status"] == "none" | |