> ## Documentation Index
> Fetch the complete documentation index at: https://docs.deploystack.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Backend End-to-End Testing

> Complete E2E testing setup with Jest, Supertest, and automated database cleanup for DeployStack Backend development.

This document outlines the setup and execution of end-to-end (E2E) tests for the DeployStack backend.

## Overview

The E2E tests are designed to verify the functionality of the backend API endpoints, ensuring they behave as expected from an external perspective. This includes testing API responses, database interactions, and overall application flow.

## Testing Framework and Libraries

* **Jest**: A delightful JavaScript Testing Framework with a focus on simplicity. Used as the primary test runner and assertion library.
* **Supertest**: An HTTP assertion library that allows for easy testing of Node.js HTTP servers. Used to make requests to our Fastify backend and verify responses.
* **ts-jest**: A Jest transformer with source map support that lets you use Jest to test projects written in TypeScript.
* **fs-extra**: Used for file system operations needed during test setup (e.g., cleaning up database files).

## Prerequisites

Before running the tests, ensure you have installed all dependencies:

```bash theme={null}
# Navigate to the backend service directory
cd services/backend

# Install dependencies (if you haven't already after recent changes)
npm install
```

## Test File Structure and Naming Convention

* All E2E test files are located in the `services/backend/tests/` directory.
* Test files must follow the naming convention: `<TEST_NAME>.e2e.test.ts`.
* Tests run sequentially in alphabetical order to ensure proper dependencies.

### Current Test Files (in execution order)

1. **`setup.e2e.test.ts`** - Database setup and initialization
2. **`user-registration.e2e.test.ts`** - User registration and role assignment
3. **`email-login.e2e.test.ts`** - Email login/logout and session management

## Running Tests

To execute the E2E test suite, run the following command from the `services/backend/` directory:

```bash theme={null}
npm run test:backend
```

Alternatively, you can run it from the root project directory:

```bash theme={null}
npm run test:backend
```

This command will:

1. Trigger Jest to find and execute all `*.e2e.test.ts` files within the `services/backend/tests/` directory.
2. Execute a global setup script (`services/backend/tests/e2e/globalSetup.ts`) before any tests run. This script:
   * Sets necessary environment variables for testing (e.g., `NODE_ENV=test`, a specific test port, a test encryption secret).
   * Clears any existing test database files from `tests/e2e/test-data/` and `persistent_data/` directories to ensure a clean state.
   * Programmatically starts the backend server on a dedicated test port.
3. Run the tests.
4. Execute a global teardown script (`services/backend/tests/globalTeardown.ts`) after all tests complete. This script stops the backend server.

## Environment Variables for Testing

The `globalSetup.ts` script automatically configures the following environment variables for the test run:

* `NODE_ENV`: set to `test`
* `PORT`: set to a dedicated test port (e.g., 3002)
* `DEPLOYSTACK_ENCRYPTION_SECRET`: set to a dummy secret (`test-super-secret-key-for-jest`)

## Database Isolation Strategy

The test suite uses a sophisticated database isolation strategy to ensure complete test independence:

### Test Database Location

* **Normal usage**: `persistent_data/database/deploystack.db`
* **Test usage**: `persistent_data/database-test/deploystack-{timestamp}.db`

### Timestamp-Based Isolation

Each test run creates a unique PostgreSQL database with a millisecond timestamp:

* Example: `deploystack-1704369600000`
* This ensures complete isolation between parallel test runs
* No conflicts when multiple developers run tests simultaneously
* Automatic cleanup through directory removal

### Benefits

* **Complete isolation**: Each test run gets a fresh database
* **Parallel test safety**: Multiple test runs won't interfere with each other
* **Easy cleanup**: The entire `database-test` directory can be safely removed
* **No manual intervention**: Tests are self-contained and don't require manual cleanup
* **Clear separation**: Test and production databases are completely separate

### Implementation Details

The database path selection is handled automatically in `src/db/config.ts`:

* Detects test environment via `NODE_ENV === 'test'`
* Generates unique timestamp-based filename for test databases
* Falls back to standard path for normal usage

## Console Logging in Tests

Unlike the main source code, **console.log statements are allowed in test files** for debugging and test output purposes. However, they are strictly prohibited in source code (`src/` directory).

### CI/CD Enforcement

The project includes automated checks that:

* ✅ **Allow** `console.log`, `console.error`, etc. in test files (`tests/` directory)
* ❌ **Block** any console statements in source code (`src/` directory)
* 🚫 **Prevent PRs from merging** if console statements are found in source code

This check runs automatically on:

* All pull requests to the main branch
* Backend release workflows

### For Source Code Logging

When writing source code (not tests), always use the structured Fastify logger instead:

```typescript theme={null}
// ❌ Don't use in source code
console.log('User created:', user);

// ✅ Use in source code
server.log.info('User created', { userId: user.id });
```

See the [Backend Logging Guide](/development/backend/logging) for complete logging best practices.

## Writing New Tests

When adding new E2E tests:

1. Create a new file in `services/backend/tests/` following the `<TEST_NAME>.e2e.test.ts` naming convention.

2. Import `request` from `supertest` and the `FastifyInstance` type if needed.

3. Access the globally available test server instance via `global.__TEST_SERVER__`.

4. Use `describe` and `it` blocks from Jest to structure your tests.

5. Use `supertest` to make requests to your API:

   ```typescript theme={null}
   import request from 'supertest';
   import { FastifyInstance } from 'fastify';

   describe('GET /api/some-endpoint', () => {
     let server: FastifyInstance;

     beforeAll(() => {
       server = global.__TEST_SERVER__;
     });

     it('should return a 200 OK for a valid request', async () => {
       const response = await request(server.server).get('/api/some-endpoint');
       expect(response.status).toBe(200);
       // Add more assertions on response.body, headers, etc.
     });
   });
   ```

6. Remember that `globalSetup.ts` cleans the database state before tests. If your tests rely on specific pre-existing data beyond the initial setup, you'll need to create that data within your test or a `beforeEach` block.

## Current Test Suites

### 1. `1-setup.e2e.test.ts`

* **Purpose**: Verifies the initial database setup functionality.
* **Key Checks**:
  * Ensures the test database directory does not exist before setup.
  * Calls `POST /api/db/setup` with `{"type": "postgresql"}`.
  * Verifies the API response indicates successful setup initiation and includes `database_type: "postgresql"`.
  * Checks that the PostgreSQL test database is created.
  * Calls `GET /api/db/status` and verifies the response shows `configured: true`, `initialized: true`, and `dialect: "postgresql"`.
  * Validates global settings initialization without errors.
  * Confirms all migrations are applied successfully.
  * Tests proper error handling for duplicate setup attempts.

### 2. `user-registration.e2e.test.ts`

* **Purpose**: Tests user registration functionality and role assignment logic.
* **Key Checks**:
  * Registers the first user and verifies they receive `global_admin` role.
  * Registers a second user and verifies they receive `global_user` role.
  * Confirms both users exist in the database with correct roles.
  * Validates that default teams are created for both users.
  * Tests duplicate email and username prevention.
  * Stores user IDs and session cookies for subsequent tests.

### 3. `email-login.e2e.test.ts`

* **Purpose**: Tests email-based authentication, session management, and logout functionality.
* **Key Checks**:
  * Logs in both users with email and password.
  * Verifies user sessions exist and work correctly.
  * Tests invalid login attempts (wrong email/password).
  * Logs out both users and confirms session invalidation.
  * Verifies no active sessions remain after logout.
  * Tests graceful handling of logout without valid session.
  * Confirms users can re-login after logout.

## Troubleshooting

* **`Cannot find module 'supertest'` (or similar type errors)**: Ensure you have run `npm install` in the `services/backend` directory after the testing dependencies were added to `package.json`.
* **Port conflicts**: The tests run on a dedicated port (defaulted to 3002 in `globalSetup.ts`). Ensure this port is free.
* **Database state**: Tests are designed to run against a clean database. `globalSetup.ts` handles this. If you encounter issues related to database state, ensure no other processes are interfering with `services/backend/persistent_data/`.
