amical/apps/desktop/tests/README.md
2025-11-12 17:10:28 +05:30

127 lines
3.6 KiB
Markdown

# 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