/** * Integration tests — verify Appwrite backend is reachable and configured correctly. * These tests make real network calls; they require NUXT_PUBLIC_APPWRITE_* env vars * from .env.local and a live Appwrite instance. */ import { describe, it, expect, beforeAll } from 'vitest'; import { Client, Account, Databases, AppwriteException } from 'appwrite'; const endpoint = process.env.NUXT_PUBLIC_APPWRITE_ENDPOINT; const projectId = process.env.NUXT_PUBLIC_APPWRITE_PROJECT_ID; function makeClient(): Client { return new Client().setEndpoint(endpoint!).setProject(projectId!); } describe('Appwrite configuration', () => { it('has NUXT_PUBLIC_APPWRITE_ENDPOINT set', () => { expect(endpoint, 'NUXT_PUBLIC_APPWRITE_ENDPOINT is missing from .env.local').toBeTruthy(); }); it('has NUXT_PUBLIC_APPWRITE_PROJECT_ID set', () => { expect(projectId, 'NUXT_PUBLIC_APPWRITE_PROJECT_ID is missing from .env.local').toBeTruthy(); }); }); describe('Appwrite health', () => { // Some Appwrite deployments restrict /health to authenticated requests (returns 401). // Either 200 or 401 confirms the server is reachable and responding. it('health endpoint is reachable', async () => { const res = await fetch(`${endpoint}/health`); expect([200, 401], `Unexpected status ${res.status} — is ${endpoint} correct?`).toContain(res.status); }); it('health DB endpoint is reachable', async () => { const res = await fetch(`${endpoint}/health/db`); expect([200, 401], `Unexpected status ${res.status} — is ${endpoint} correct?`).toContain(res.status); }); }); describe('Appwrite account service', () => { let client: Client; beforeAll(() => { client = makeClient(); }); it('rejects unauthenticated session with 401 (not a network error)', async () => { const account = new Account(client); await expect(account.get()).rejects.toSatisfy( (e: unknown) => e instanceof AppwriteException && e.code === 401 ); }); it('can request a magic URL token (email delivery not verified here)', async () => { const account = new Account(client); // Use a clearly synthetic address so no real user is affected. // A 429 (rate limit) also confirms the endpoint is reachable. try { await account.createMagicURLToken('test-probe', 'probe@example.invalid'); // If it succeeds, the endpoint responded (unusual for a fake address but acceptable) } catch (e: unknown) { expect(e).toBeInstanceOf(AppwriteException); // Any AppwriteException means we reached the server expect((e as AppwriteException).code).not.toBe(0); } }); }); describe('Appwrite database service', () => { let client: Client; beforeAll(() => { client = makeClient(); }); it('database "bab_prod" exists (unauthenticated returns 401, not 404)', async () => { const db = new Databases(client); try { await db.listDocuments('bab_prod', 'boat'); // Authenticated session — collection is readable } catch (e: unknown) { expect(e).toBeInstanceOf(AppwriteException); // 401 = reached DB but not authenticated; 403 = authenticated but no permission // Either confirms the database and collection exist expect((e as AppwriteException).code).not.toBe(404); } }); // task, taskTags, skillTags are parked — not yet implemented in bab_prod const collections = ['boat', 'reservation', 'interval', 'intervalTemplate']; it.each(collections)('collection "%s" exists in bab_prod', async (collection) => { const db = new Databases(client); try { await db.listDocuments('bab_prod', collection); } catch (e: unknown) { expect(e).toBeInstanceOf(AppwriteException); expect( (e as AppwriteException).code, `Collection "${collection}" returned 404. ` + `Verify it exists in Appwrite dashboard under database "bab_prod" ` + `and that the collection ID matches exactly (case-sensitive).` ).not.toBe(404); } }); });