# Testing Guide

## Overview

This document describes how to run tests for my.experimenta.science and how to use test credentials.

---

## Test Credentials

Test credentials are stored in environment variables to keep them out of the codebase while making them accessible for automated tests.

**📖 For complete credentials and testing guide, see: [`docs/TESTING.md`](../docs/TESTING.md)**

### Setup

1. **Copy .env.example to .env:**
   ```bash
   cp .env.example .env
   ```

2. **Set test credentials in .env:**

   See [`docs/TESTING.md`](../docs/TESTING.md) for current test credentials.

   ```env
   TEST_USER_EMAIL=<see-docs-TESTING-md>
   TEST_USER_PASSWORD=<see-docs-TESTING-md>
   ```

3. **Verify configuration:**
   ```bash
   # Start dev server
   pnpm dev

   # In another terminal, test the credentials endpoint
   curl http://localhost:3000/api/test/credentials
   ```

   Expected output:
   ```json
   {
     "email": "bm@noxware.de",
     "password": "%654321qQ!"
   }
   ```

---

## Using Test Credentials in Tests

### Method 1: Via API Endpoint (Recommended for E2E tests)

```typescript
// tests/e2e/example.spec.ts
import { test, expect } from '@playwright/test'

test('login flow', async ({ page }) => {
  // Fetch test credentials from API
  const response = await fetch('http://localhost:3000/api/test/credentials')

  if (!response.ok) {
    test.skip() // Skip if credentials not configured
    return
  }

  const { email, password } = await response.json()

  // Use credentials in test
  await page.goto('/auth')
  await page.fill('input[type="email"]', email)
  await page.fill('input[type="password"]', password)
  await page.click('button[type="submit"]')

  // Assert login success
  await expect(page).toHaveURL('/')
})
```

### Method 2: Via Server Utility (For server-side tests)

```typescript
// tests/unit/auth.test.ts
import { describe, it, expect } from 'vitest'
import { getTestCredentials } from '~/server/utils/test-helpers'

describe('Authentication', () => {
  it('should login with test credentials', async () => {
    const { email, password } = getTestCredentials()

    // Use credentials in test
    const response = await $fetch('/api/auth/login', {
      method: 'POST',
      body: { email, password },
    })

    expect(response.success).toBe(true)
  })
})
```

### Method 3: Via Environment Variables (Direct access)

```typescript
// For tests that need direct access
const email = process.env.TEST_USER_EMAIL
const password = process.env.TEST_USER_PASSWORD

if (!email || !password) {
  console.warn('Test credentials not configured, skipping test')
  return
}
```

---

## Security Notes

### ⚠️ Important Security Considerations

1. **Development Only:**
   - Test credentials should ONLY be used in development/staging
   - The `/api/test/credentials` endpoint returns 404 in production
   - Never commit real credentials to Git

2. **Environment Variables:**
   - `.env` is in `.gitignore` and never committed
   - `.env.example` contains example/documentation only (not real passwords)
   - Each developer should create their own `.env` file locally

3. **Production Safety:**
   - The test credentials endpoint is automatically disabled in production
   - Server utility warns if used in production environment
   - Test files are excluded from production builds

4. **Credential Rotation:**
   - Test credentials can be changed at any time in `.env`
   - All tests will automatically use the updated credentials
   - No code changes required when credentials change

---

## Running Tests

### Unit Tests (Vitest)

```bash
# Run all unit tests
pnpm test

# Run with coverage
pnpm test:coverage

# Watch mode
pnpm test:watch
```

### E2E Tests (Playwright)

```bash
# Run all E2E tests
pnpm test:e2e

# Run specific test file
pnpm test:e2e tests/e2e/auth-login.example.spec.ts

# Run in UI mode (visual debugger)
pnpm test:e2e --ui

# Run in headed mode (see browser)
pnpm test:e2e --headed
```

### Before Running Tests

1. ✅ Ensure `.env` is configured with test credentials
2. ✅ Start the dev server: `pnpm dev`
3. ✅ Start database: `docker-compose up -d` (if using Docker)
4. ✅ Run migrations: `pnpm db:migrate`

---

## Test Structure

```
tests/
├── README.md                          # This file
├── e2e/                              # End-to-end tests (Playwright)
│   └── auth-login.example.spec.ts    # Example E2E test with credentials
└── unit/                             # Unit tests (Vitest)
    └── (to be added)
```

---

## Example Tests

See `tests/e2e/auth-login.example.spec.ts` for a complete example of using test credentials in E2E tests.

---

## Troubleshooting

### "Test credentials not configured" Error

**Cause:** `TEST_USER_EMAIL` or `TEST_USER_PASSWORD` not set in `.env`

**Solution:**
```bash
# 1. Check if .env exists
ls -la .env

# 2. If not, copy from example
cp .env.example .env

# 3. Edit .env and set credentials
# TEST_USER_EMAIL=bm@noxware.de
# TEST_USER_PASSWORD=%654321qQ!

# 4. Restart dev server
```

### API Endpoint Returns 404

**Cause:** Server is running in production mode

**Solution:** Test credentials endpoint is only available in development. Set:
```bash
NODE_ENV=development
```

### Tests Fail with "Invalid Credentials"

**Possible causes:**
1. Wrong credentials in `.env`
2. Test user doesn't exist in Cidaas
3. Cidaas staging environment is down

**Solution:**
- Verify credentials work manually by logging in at `/auth`
- Check Cidaas staging status
- Contact team lead for valid test account

---

## Best Practices

1. **Always check if credentials are configured:**
   ```typescript
   if (!response.ok) {
     test.skip() // Don't fail, just skip
     return
   }
   ```

2. **Use the API endpoint for E2E tests:**
   - Cleaner separation of concerns
   - Easier to mock/stub in CI/CD
   - Works across different test frameworks

3. **Clean up test data:**
   ```typescript
   test.afterEach(async () => {
     // Logout after each test
     await $fetch('/api/auth/logout', { method: 'POST' })
   })
   ```

4. **Isolate tests:**
   - Each test should be independent
   - Don't rely on state from previous tests
   - Use `test.beforeEach` to reset state

---

## CI/CD Integration

For GitLab CI/CD, add test credentials as environment variables:

```yaml
# .gitlab-ci.yml
test:
  stage: test
  variables:
    TEST_USER_EMAIL: $CI_TEST_USER_EMAIL  # Set in GitLab CI/CD settings
    TEST_USER_PASSWORD: $CI_TEST_USER_PASSWORD
  script:
    - pnpm install
    - pnpm test
    - pnpm test:e2e
```

Set `CI_TEST_USER_EMAIL` and `CI_TEST_USER_PASSWORD` as protected variables in:
**GitLab → Settings → CI/CD → Variables**

---

## Questions?

- Check `CLAUDE.md` for authentication patterns
- Check `docs/CIDAAS_INTEGRATION.md` for Cidaas setup
- Ask in team chat or create an issue
