bugsink mcp and claude subagents - documentation and test fixes
This commit is contained in:
252
docs/development/TESTING.md
Normal file
252
docs/development/TESTING.md
Normal file
@@ -0,0 +1,252 @@
|
||||
# Testing Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This project has comprehensive test coverage including unit tests, integration tests, and E2E tests. All tests must be run in the **Linux dev container environment** for reliable results.
|
||||
|
||||
## Test Execution Environment
|
||||
|
||||
**CRITICAL**: All tests and type-checking MUST be executed inside the dev container (Linux environment).
|
||||
|
||||
### Why Linux Only?
|
||||
|
||||
- Path separators: Code uses POSIX-style paths (`/`) which may break on Windows
|
||||
- TypeScript compilation works differently on Windows vs Linux
|
||||
- Shell scripts and external dependencies assume Linux
|
||||
- Test results from Windows are **unreliable and should be ignored**
|
||||
|
||||
### Running Tests Correctly
|
||||
|
||||
#### Option 1: Inside Dev Container (Recommended)
|
||||
|
||||
Open VS Code and use "Reopen in Container", then:
|
||||
|
||||
```bash
|
||||
npm test # Run all tests
|
||||
npm run test:unit # Run unit tests only
|
||||
npm run test:integration # Run integration tests
|
||||
npm run type-check # Run TypeScript type checking
|
||||
```
|
||||
|
||||
#### Option 2: Via Podman from Windows Host
|
||||
|
||||
From the Windows host, execute commands in the container:
|
||||
|
||||
```bash
|
||||
# Run unit tests (2900+ tests - pipe to file for AI processing)
|
||||
podman exec -it flyer-crawler-dev npm run test:unit 2>&1 | tee test-results.txt
|
||||
|
||||
# Run integration tests
|
||||
podman exec -it flyer-crawler-dev npm run test:integration
|
||||
|
||||
# Run type checking
|
||||
podman exec -it flyer-crawler-dev npm run type-check
|
||||
|
||||
# Run specific test file
|
||||
podman exec -it flyer-crawler-dev npm test -- --run src/hooks/useAuth.test.tsx
|
||||
```
|
||||
|
||||
## Type Checking
|
||||
|
||||
TypeScript type checking is performed using `tsc --noEmit`.
|
||||
|
||||
### Type Check Command
|
||||
|
||||
```bash
|
||||
npm run type-check
|
||||
```
|
||||
|
||||
### Type Check Validation
|
||||
|
||||
The type-check command will:
|
||||
|
||||
- Exit with code 0 if no errors are found
|
||||
- Exit with non-zero code and print errors if type errors exist
|
||||
- Check all files in the `src/` directory as defined in `tsconfig.json`
|
||||
|
||||
**IMPORTANT**: Type-check on Windows may not show errors reliably. Always verify type-check results by running in the dev container.
|
||||
|
||||
### Verifying Type Check Works
|
||||
|
||||
To verify type-check is working correctly:
|
||||
|
||||
1. Run type-check in dev container: `podman exec -it flyer-crawler-dev npm run type-check`
|
||||
2. Check for output - errors will be displayed with file paths and line numbers
|
||||
3. No output + exit code 0 = no type errors
|
||||
|
||||
Example error output:
|
||||
|
||||
```
|
||||
src/pages/MyDealsPage.tsx:68:31 - error TS2339: Property 'store_name' does not exist on type 'WatchedItemDeal'.
|
||||
|
||||
68 <span>{deal.store_name}</span>
|
||||
~~~~~~~~~~
|
||||
```
|
||||
|
||||
## Pre-Commit Hooks
|
||||
|
||||
The project uses Husky and lint-staged for pre-commit validation:
|
||||
|
||||
```bash
|
||||
# .husky/pre-commit
|
||||
npx lint-staged
|
||||
```
|
||||
|
||||
Lint-staged configuration (`.lintstagedrc.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"*.{js,jsx,ts,tsx}": ["eslint --fix --no-color", "prettier --write"],
|
||||
"*.{json,md,css,html,yml,yaml}": ["prettier --write"]
|
||||
}
|
||||
```
|
||||
|
||||
**Note**: The `--no-color` flag prevents ANSI color codes from breaking file path links in git output.
|
||||
|
||||
## Test Suite Structure
|
||||
|
||||
### Unit Tests (~2900 tests)
|
||||
|
||||
Located throughout `src/` directory alongside source files with `.test.ts` or `.test.tsx` extensions.
|
||||
|
||||
```bash
|
||||
npm run test:unit
|
||||
```
|
||||
|
||||
### Integration Tests (5 test files)
|
||||
|
||||
Located in `src/tests/integration/`:
|
||||
|
||||
- `admin.integration.test.ts`
|
||||
- `flyer.integration.test.ts`
|
||||
- `price.integration.test.ts`
|
||||
- `public.routes.integration.test.ts`
|
||||
- `receipt.integration.test.ts`
|
||||
|
||||
Requires PostgreSQL and Redis services running.
|
||||
|
||||
```bash
|
||||
npm run test:integration
|
||||
```
|
||||
|
||||
### E2E Tests (3 test files)
|
||||
|
||||
Located in `src/tests/e2e/`:
|
||||
|
||||
- `deals-journey.e2e.test.ts`
|
||||
- `budget-journey.e2e.test.ts`
|
||||
- `receipt-journey.e2e.test.ts`
|
||||
|
||||
Requires all services (PostgreSQL, Redis, BullMQ workers) running.
|
||||
|
||||
```bash
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
## Test Result Interpretation
|
||||
|
||||
- Tests that **pass on Windows but fail on Linux** = **BROKEN tests** (must be fixed)
|
||||
- Tests that **fail on Windows but pass on Linux** = **PASSING tests** (acceptable)
|
||||
- Always use **Linux (dev container) results** as the source of truth
|
||||
|
||||
## Test Helpers
|
||||
|
||||
### Store Test Helpers
|
||||
|
||||
Located in `src/tests/utils/storeHelpers.ts`:
|
||||
|
||||
```typescript
|
||||
// Create a store with a location in one call
|
||||
const store = await createStoreWithLocation({
|
||||
storeName: 'Test Store',
|
||||
address: {
|
||||
address_line_1: '123 Main St',
|
||||
city: 'Toronto',
|
||||
province_state: 'ON',
|
||||
postal_code: 'M1M 1M1',
|
||||
},
|
||||
pool,
|
||||
log,
|
||||
});
|
||||
|
||||
// Cleanup stores and their locations
|
||||
await cleanupStoreLocations([storeId1, storeId2], pool, log);
|
||||
```
|
||||
|
||||
### Mock Factories
|
||||
|
||||
Located in `src/tests/utils/mockFactories.ts`:
|
||||
|
||||
```typescript
|
||||
// Create mock data for tests
|
||||
const mockStore = createMockStore({ name: 'Test Store' });
|
||||
const mockAddress = createMockAddress({ city: 'Toronto' });
|
||||
const mockStoreLocation = createMockStoreLocationWithAddress();
|
||||
const mockStoreWithLocations = createMockStoreWithLocations({
|
||||
locations: [{ address: { city: 'Toronto' } }],
|
||||
});
|
||||
```
|
||||
|
||||
## Known Integration Test Issues
|
||||
|
||||
See `CLAUDE.md` for documentation of common integration test issues and their solutions, including:
|
||||
|
||||
1. Vitest globalSetup context isolation
|
||||
2. BullMQ cleanup queue timing issues
|
||||
3. Cache invalidation after direct database inserts
|
||||
4. Unique filename requirements for file uploads
|
||||
5. Response format mismatches
|
||||
6. External service availability
|
||||
|
||||
## Continuous Integration
|
||||
|
||||
Tests run automatically on:
|
||||
|
||||
- Pre-commit (via Husky hooks)
|
||||
- Pull request creation/update (via Gitea CI/CD)
|
||||
- Merge to main branch (via Gitea CI/CD)
|
||||
|
||||
CI/CD configuration:
|
||||
|
||||
- `.gitea/workflows/deploy-to-prod.yml`
|
||||
- `.gitea/workflows/deploy-to-test.yml`
|
||||
|
||||
## Coverage Reports
|
||||
|
||||
Test coverage is tracked using Vitest's built-in coverage tools.
|
||||
|
||||
```bash
|
||||
npm run test:coverage
|
||||
```
|
||||
|
||||
Coverage reports are generated in the `coverage/` directory.
|
||||
|
||||
## Debugging Tests
|
||||
|
||||
### Enable Verbose Logging
|
||||
|
||||
```bash
|
||||
# Run tests with verbose output
|
||||
npm test -- --reporter=verbose
|
||||
|
||||
# Run specific test with logging
|
||||
DEBUG=* npm test -- --run src/path/to/test.test.ts
|
||||
```
|
||||
|
||||
### Using Vitest UI
|
||||
|
||||
```bash
|
||||
npm run test:ui
|
||||
```
|
||||
|
||||
Opens a browser-based test runner with filtering and debugging capabilities.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always run tests in dev container** - never trust Windows test results
|
||||
2. **Run type-check before committing** - catches TypeScript errors early
|
||||
3. **Use test helpers** - `createStoreWithLocation()`, mock factories, etc.
|
||||
4. **Clean up test data** - use cleanup helpers in `afterEach`/`afterAll`
|
||||
5. **Verify cache invalidation** - tests that insert data directly must invalidate cache
|
||||
6. **Use unique filenames** - file upload tests need timestamp-based filenames
|
||||
7. **Check exit codes** - `npm run type-check` returns 0 on success, non-zero on error
|
||||
Reference in New Issue
Block a user