# Testing Guide

This directory contains the test setup for the Amical Desktop application's main process.

## Overview

We use **Vitest** to test the Electron main process, specifically:

- **tRPC router procedures** - Direct testing by calling router methods
- **Service business logic** - Testing services with different database states
- **App initialization** - Testing how the app initializes with various database conditions

## Architecture

### Test Database

- Uses real SQLite databases (not mocked)
- Each test gets an isolated database in a temporary directory
- Migrations are applied automatically
- Fixtures for seeding test data

### Mocking Strategy

- **Electron APIs** - Fully mocked (app, ipcMain, BrowserWindow, Menu, etc.)
- **Native Modules** - Mocked (onnxruntime, whisper, keytar, etc.)
- **Database** - Real SQLite with test fixtures
- **tRPC** - Called directly, bypassing IPC layer

## Running Tests

```bash
# Run all tests
pnpm test

# Watch mode
pnpm test:watch

# UI mode
pnpm test:ui

# With coverage
pnpm test:coverage
```

## Writing Tests

### Testing tRPC Procedures

```typescript
import { createTestDatabase } from "../helpers/test-db";
import { initializeTestServices } from "../helpers/test-app";
import { seedDatabase } from "../helpers/fixtures";

describe("My Service", () => {
  let testDb;
  let trpcCaller;
  let cleanup;

  beforeEach(async () => {
    testDb = await createTestDatabase({ name: "my-test" });
    await seedDatabase(testDb, "withTranscriptions"); // or 'empty', 'full', etc.

    const result = await initializeTestServices(testDb);
    trpcCaller = result.trpcCaller;
    cleanup = result.cleanup;
  });

  afterEach(async () => {
    if (cleanup) await cleanup();
    if (testDb) await testDb.close();
  });

  it("should do something", async () => {
    const result = await trpcCaller.myRouter.myProcedure({ input });
    expect(result).toBeDefined();
  });
});
```

### Available Fixtures

- `empty` - Empty database with default settings
- `withTranscriptions` - Database with sample transcriptions
- `withVocabulary` - Database with vocabulary items
- `withModels` - Database with downloaded models
- `withNotes` - Database with notes
- `withAuth` - Database with authenticated user
- `full` - Database with all types of data

### Custom Fixtures

```typescript
await fixtures.withCustomSettings(testDb, {
  ui: { theme: "dark" },
  transcription: { language: "es" },
});
```

## Known Limitations

1. **Full AppManager initialization** - Currently has issues with ServiceManager initialization. Use `initializeTestServices` instead for testing service business logic.

2. **Some modules require additional mocking** - If you encounter errors about missing modules, add mocks to `tests/setup.ts`.

3. **Database mocking** - The dynamic database mocking via `vi.doMock` doesn't work well with the existing module resolution. Tests work best when testing services directly rather than full app initialization.

## Troubleshooting

### "ServiceManager not initialized"

This means you're trying to use AppManager which requires more complex initialization. Use `initializeTestServices` to test services directly.

### "No procedure found on path"

Check that the tRPC procedure name matches the actual router definition. Refer to `src/trpc/routers/` for available procedures.

### "ENOENT: no such file or directory"

The test database or migrations folder might not be found. Ensure migrations exist at `src/db/migrations/`.

## Future Improvements

- Fix AppManager initialization for full integration tests
- Add more comprehensive fixtures
- Add test coverage reporting
- Add database state assertions helpers
- Create mock factories for complex objects
