""" Tests for admin settings and admin customers endpoints. """ from unittest.mock import AsyncMock from tests.conftest import USER_ID SAMPLE_SETTING = { "key": "default_booking_price", "value": 0, "updated_at": "2026-01-01T00:00:00", } SAMPLE_CUSTOMER = { "id": USER_ID, "email": "client@test.com", "full_name": "Marie Dupont", "phone": "+49123456789", "is_blocked": False, "created_at": "2026-01-01T00:00:00", "orders_count": 2, "bookings_count": 1, "total_spent": 378.0, } # ── Admin settings ──────────────────────────────────────────────────────────── async def test_get_settings_returns_list(admin_client, mock_db): mock_db.fetch = AsyncMock(return_value=[SAMPLE_SETTING]) r = await admin_client.get("/api/v1/admin/settings") assert r.status_code == 200 body = r.json() assert body["success"] is True assert isinstance(body["data"], list) assert body["data"][0]["key"] == "default_booking_price" async def test_get_settings_empty_table(admin_client, mock_db): """Frontend must handle an empty settings list gracefully.""" mock_db.fetch = AsyncMock(return_value=[]) r = await admin_client.get("/api/v1/admin/settings") assert r.status_code == 200 assert r.json()["data"] == [] async def test_update_setting_upsert(admin_client, mock_db): saved = {**SAMPLE_SETTING, "value": 50, "updated_at": "2026-05-21T10:00:00"} mock_db.fetchrow = AsyncMock(return_value=saved) r = await admin_client.put("/api/v1/admin/settings/default_booking_price", json={"value": 50}) assert r.status_code == 200 body = r.json() assert body["success"] is True assert body["data"]["key"] == "default_booking_price" async def test_update_setting_zero_value(admin_client, mock_db): """0 is a valid value (= free appointments).""" saved = {**SAMPLE_SETTING, "value": 0} mock_db.fetchrow = AsyncMock(return_value=saved) r = await admin_client.put("/api/v1/admin/settings/default_booking_price", json={"value": 0}) assert r.status_code == 200 async def test_settings_requires_admin(auth_client): r = await auth_client.get("/api/v1/admin/settings") assert r.status_code == 403 async def test_settings_requires_auth(anon_client): r = await anon_client.get("/api/v1/admin/settings") assert r.status_code == 401 # ── Admin customers ─────────────────────────────────────────────────────────── async def test_list_customers(admin_client, mock_db): mock_db.fetchval = AsyncMock(return_value=1) mock_db.fetch = AsyncMock(return_value=[SAMPLE_CUSTOMER]) r = await admin_client.get("/api/v1/admin/customers") assert r.status_code == 200 body = r.json() assert body["success"] is True data = body["data"] assert len(data) == 1 assert data[0]["full_name"] == "Marie Dupont" assert data[0]["orders_count"] == 2 async def test_list_customers_empty(admin_client, mock_db): mock_db.fetchval = AsyncMock(return_value=0) mock_db.fetch = AsyncMock(return_value=[]) r = await admin_client.get("/api/v1/admin/customers") assert r.status_code == 200 assert r.json()["data"] == [] async def test_list_customers_search(admin_client, mock_db): mock_db.fetchval = AsyncMock(return_value=1) mock_db.fetch = AsyncMock(return_value=[SAMPLE_CUSTOMER]) r = await admin_client.get("/api/v1/admin/customers?search=marie") assert r.status_code == 200 async def test_block_customer(admin_client, mock_db): blocked = {**SAMPLE_CUSTOMER, "is_blocked": True} mock_db.fetchrow = AsyncMock(return_value=blocked) r = await admin_client.patch(f"/api/v1/admin/customers/{USER_ID}", json={"is_blocked": True}) assert r.status_code == 200 assert r.json()["data"]["is_blocked"] is True async def test_unblock_customer(admin_client, mock_db): unblocked = {**SAMPLE_CUSTOMER, "is_blocked": False} mock_db.fetchrow = AsyncMock(return_value=unblocked) r = await admin_client.patch(f"/api/v1/admin/customers/{USER_ID}", json={"is_blocked": False}) assert r.status_code == 200 assert r.json()["data"]["is_blocked"] is False async def test_customers_requires_admin(auth_client): r = await auth_client.get("/api/v1/admin/customers") assert r.status_code == 403 async def test_customers_requires_auth(anon_client): r = await anon_client.get("/api/v1/admin/customers") assert r.status_code == 401