Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# AuthenticationWebService Testing Guide

## Architecture Overview

**Stack**: Express.js (v5) + CouchDB (v3.5.1) + Node.js (v25)

**Services**:
- **Auth App**: HTTPS server on port 3183
- **CouchDB**: HTTP on 5984, HTTPS on 6984
- **CouchDB Credentials**: `admin` / `none`

## Docker Setup

### Key Files
- `docker-compose.yml` - Orchestrates couchdb + app services
- `Dockerfile` - Builds the Node.js app container
- `Dockerfile-couchdb` - Builds CouchDB with custom config
- `config/default.js` - Default configuration with environment variable support
- `config/local.js` - Local overrides (takes precedence in `config` package)
- `config/localhost.js` - Localhost-specific config (NODE_ENV=localhost)

### Configuration Precedence

The `config` npm package loads files in this order:
1. `config/default.js` (base)
2. `config/{NODE_ENV}.js` (e.g., `localhost.js`)
3. `config/local.js` (**highest precedence**)

**Critical**: `config/local.js` overrides everything, including environment-specific configs. So if you have a `config/local.js` file, it will override the `config/localhost.js` file.

### Environment Variables

- `NODE_ENV=localhost` - Set in Dockerfile, determines which config file to load

## Running Tests

### Local Docker Testing

```bash
cd AuthenticationWebService

# Start services (rebuilds if needed)
docker compose up -d --build

# Run setup (creates test databases)
SOURCE_URL=https://public:none@corpusdev.example.org npm run setup

# Run E2E tests against Docker containers
npm run test:deprecated:e2e

# Stop services
docker compose down
```

### NPM Scripts

| Script | Description |
|--------|-------------|
| `test:docker` | Full Docker test suite (setup + e2e) |
| `test:docker:no-cache` | Same but forces rebuild without cache |
| `setup` | Initialize CouchDB databases for testing |
| `test:deprecated:e2e` | E2E tests for deprecated API routes |
| `test:deprecated:coverage` | Coverage report for deprecated routes |
| `start` | Start the auth service (non-Docker) |

### Test Suites

**`test/routes/deprecated-spec.js`** (39 tests):
- `/register` - User registration (8 tests)
- `/login` - Authentication (6 tests)
- `/changepassword` - Password changes (3 tests)
- `/forgotpassword` - Password reset (3 tests)
- `/addroletouser` - Role management (6 tests)
- `/updateroles` - Bulk role updates (2 tests)
- `/corpusteam` - Corpus team permissions (4 tests)
- `/newcorpus` - Corpus creation (4 tests)
- `/syncDetails` - User corpus sync (1 test)

**Test Environment**:
- Uses `replay` library for HTTP mocking (bloody mode = record/replay)
- Creates test users: `testuser1-9`, `testingdisabledusers`, `testingprototype`, etc.
- Tests against `https://localhost:3183` (app in Docker)
- CouchDB fixtures in `test/fixtures/`

## Common Issues & Solutions

### Issue: Tests fail with 500 errors (error codes 816, 1289)

**Root Cause**: App container can't connect to CouchDB service.

**Symptoms**:
```
"Server erred, please report this 816"
"Server is not responding for request to query corpus permissions. Please report this 1289"
```

**Solution**: Ensure `COUCHDB_URL=http://couchdb:5984` is set in `docker-compose.yml` and both `config/default.js` and `config/local.js` support `process.env.COUCHDB_URL`.

### Issue: Config changes not reflected in container

**Root Cause**: Docker uses cached image with old config files.

**Solution**: Rebuild with `--build` flag:
```bash
docker compose up -d --build
```

### Issue: `config/local.js` overrides Docker settings

**Root Cause**: `config/local.js` has highest precedence and hardcodes `localhost:5984`.

**Solution**: Update `config/local.js` to use environment variable:
```javascript
module.exports = {
usersDbConnection: {
url: process.env.COUCHDB_URL || "http://localhost:5984"
}
};
```

## GitHub Actions CI

The `.github/workflows/node.js.yml` workflow runs:

1. **Integration tests** - Unit tests with mocked HTTP
2. **Deploy job**:
- Creates `config/localhost.js` with `http://couchdb:5984`
- Starts Docker Compose services
- Runs setup to initialize databases
- Runs E2E tests against containerized app
- Switches to `http://localhost:5984` for local tests
- Runs integration tests with app outside container
- Runs UI tests with Playwright

**Key difference from local**: GitHub Actions creates `config/localhost.js` dynamically before building, ensuring correct CouchDB URL.

## Verification Commands

```bash
# Check config is correct inside container
docker compose exec app node -e "const config = require('config'); console.log(config.usersDbConnection);"

# Check environment variables
docker compose exec app printenv | grep COUCHDB

# View app logs
docker compose logs app --tail 50

# View CouchDB logs
docker compose logs couchdb --tail 50

# Check running containers
docker ps
```

## Test Data

**Sample Users** (from `config/default.js`):
- `public` - Public access
- `lingllama` / `teammatetiger` - Field linguist users
- `alakazou` / `valeriebilleentete` - Gamified users

**Test Corpora**:
- Created dynamically during tests
- Format: `{username}-{title_as_url}`
- Example: `testuser6-testing_v3_32_01`

## Success Criteria

✅ All 39 tests passing in ~5 minutes
✅ No 500 errors or "Server erred" messages
✅ App logs show: `Using corpus url: http://admin:none@couchdb:5984`
✅ Test output shows corpus creation and role management working
2 changes: 1 addition & 1 deletion config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ module.exports = {
},
url: 'https://localhost:3183',
usersDbConnection: {
url: 'http://localhost:5984',
url: process.env.COUCHDB_URL || 'http://localhost:5984',
dbname: 'theuserscouch',
},
couchKeys: {
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ services:
ports:
- 3183:3183
environment:
- FOO=too
- COUCHDB_URL=http://couchdb:5984
3 changes: 2 additions & 1 deletion etc/local.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ credentials = true
attachments_enable = true
; https://docs.couchdb.org/en/stable/cve/2021-38295.html
; use nginx instead to allow only signed couchapps when on deployed server
attachments_header_value = "child-src 'self' data: blob:; default-src 'self'; connect-src 'self' https://corpusdev.example.com https://localhost:3183 https://www.google-analytics.com; img-src 'self' data: https://secure.gravatar.com; font-src 'self' https://themes.googleusercontent.com; script-src 'self' 'unsafe-eval' https://www.google-analytics.com; style-src 'self' 'unsafe-inline';"
; " quotes are in the csp and need to be removed
attachments_header_value = "child-src 'self' data: blob:; default-src 'self'; connect-src 'self' https://corpusdev.example.com https://localhost:3183 https://www.google-analytics.com; img-src 'self' data: https://secure.gravatar.com; font-src 'self' https://themes.googleusercontent.com; script-src 'self' https://localhost:6984 'unsafe-eval' https://www.google-analytics.com; style-src 'self' 'unsafe-inline';"
Comment on lines +12 to +13

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This comment correctly notes that the quotes in the attachments_header_value should be removed, but they are still present on the next line. The quotes will likely cause the Content Security Policy to be invalid. Please remove the quotes from the value, and you can remove this comment as well.

attachments_header_value = child-src 'self' data: blob:; default-src 'self'; connect-src 'self' https://corpusdev.example.com https://localhost:3183 https://www.google-analytics.com; img-src 'self' data: https://secure.gravatar.com; font-src 'self' https://themes.googleusercontent.com; script-src 'self' https://localhost:6984 'unsafe-eval' https://www.google-analytics.com; style-src 'self' 'unsafe-inline';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The Content Security Policy includes 'unsafe-eval' and 'unsafe-inline'. These directives significantly weaken the security of your application and should be avoided as they create openings for Cross-Site Scripting (XSS) attacks.

  • 'unsafe-inline' allows inline <script> and <style> tags, as well as inline event handlers (e.g., onclick). Consider moving all scripts and styles to external files.
  • 'unsafe-eval' allows the use of eval() and similar functions. It's best to refactor any code that relies on these.

Even for a local development configuration, it's a security best practice to have a strict CSP. This helps catch potential issues before they reach production.


[couchdb]
single_node=true
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@
},
"scripts": {
"docker:build": "docker build -t fielddb-auth .",
"test:docker": "echo 'module.exports = { usersDbConnection: { url: \"http://couchdb:5984\" } };' > config/localhost.js && docker compose up -d && sleep 3 && docker compose logs && npm run setup && npm run test:deprecated:e2e",
"test:docker:no-cache": "echo 'module.exports = { usersDbConnection: { url: \"http://couchdb:5984\" } };' > config/localhost.js && docker compose build --no-cache && docker compose up -d && sleep 15 && docker compose logs && npm run setup && npm run test:deprecated:e2e",
"test:docker": "echo 'module.exports = { usersDbConnection: { url: \"http://couchdb:5984\" } };' > config/localhost.js && cp config/localhost.js config/local.js && docker compose up -d && sleep 3 && docker compose logs && npm run setup && npm run test:deprecated:e2e",
"test:docker:no-cache": "echo 'module.exports = { usersDbConnection: { url: \"http://couchdb:5984\" } };' > config/localhost.js && cp config/localhost.js config/local.js && docker compose build --no-cache && docker compose up -d && sleep 15 && docker compose logs && npm run setup && npm run test:deprecated:e2e",
"coverage": "NODE_ENV=test BUNYAN_LOG_LEVEL=FATAL nyc npm test",
"lint": "eslint ",
"lint:ci": "eslint .",
Expand Down
Loading