# WebTerm Test Suite

This directory contains the unit and integration tests for the socktop webterm project.

## Test Structure

Tests are organized into separate files by module:

### `event_tests.rs`
Tests for the `event` module, covering:
- **IO message creation**: Testing conversion from Bytes, String, and &str
- **IO equality and cloning**: Verifying proper equality checks and clone behavior
- **Binary and Unicode data**: Testing handling of binary data and Unicode strings
- **ChildDied events**: Testing the ChildDied event structure

**Total tests**: 11

### `terminado_tests.rs`
Comprehensive tests for the Terminado protocol implementation:
- **Serialization**: Converting TerminadoMessage to JSON format
  - `stdin`, `stdout`, and `set_size` (resize) messages
  - Special characters, Unicode, and empty strings
- **Deserialization**: Parsing JSON into TerminadoMessage
  - Valid message formats
  - Error handling for invalid JSON, wrong types, wrong lengths
- **Round-trip testing**: Serialize → Deserialize → Compare
- **Error cases**: Testing all failure modes
  - Invalid JSON
  - Wrong array lengths
  - Non-string types where strings expected
  - Unknown message types

**Total tests**: 38

### `config_tests.rs`
Integration tests verifying configuration constants and relationships:
- **Timeout values**: Heartbeat, client timeout, idle timeout
- **Timeout relationships**: Ensuring timeouts have logical relationships
- **PTY configuration**: Initial size, buffer sizes
- **Path validation**: Template paths, static paths, endpoints
- **Network configuration**: Default ports, hosts
- **Size boundaries**: Terminal size limits and validation

**Total tests**: 17

### `security_tests.rs`
Comprehensive security tests for command sanitization and validation:
- **Command path validation**: Absolute paths, no path traversal, no shell metacharacters
- **Shell injection prevention**: Detecting and rejecting injection attempts
- **Environment variable security**: Sanitizing TERM and other env vars
- **Whitelist enforcement**: Only allowing approved shell commands
- **Path traversal prevention**: Blocking `..`, `./`, `~` patterns
- **Input validation**: Length limits, null byte detection, control characters
- **File descriptor security**: No redirection operators in commands
- **Unicode and special characters**: ASCII-only enforcement
- **Dangerous directory prevention**: Blocking execution from `/tmp`, `/var/tmp`, etc.
- **Command execution logging**: Ensuring commands are safely loggable
- **Integration with Command::new()**: Verifying safe process spawning
- **Complete security checklist**: Comprehensive validation of all security requirements

**Total tests**: 28 (plus 11 in `src/security.rs`)

## Running Tests

### Run all tests
```bash
cargo test --all-targets --all-features
```

### Run specific test file
```bash
cargo test --test event_tests
cargo test --test terminado_tests
cargo test --test config_tests
```

### Run with output
```bash
cargo test -- --nocapture
```

### Run specific test
```bash
cargo test test_serialize_resize
```

## Test Coverage

Current test coverage includes:

- ✅ **Event handling**: IO messages and ChildDied events
- ✅ **Protocol parsing**: Terminado message serialization/deserialization
- ✅ **Configuration validation**: Timeout relationships and constants
- ✅ **Error handling**: Invalid input parsing and edge cases
- ✅ **Data types**: Binary data, Unicode, special characters
- ✅ **Security validation**: Command sanitization, injection prevention, whitelist enforcement

## CI/CD Integration

Tests run automatically in the Gitea Actions workflow:

1. **Test Job**: Runs `cargo test --all-targets --all-features`
2. **Lint Job**: Runs after tests pass
3. **Build Job**: Runs after linting passes
4. **Deploy Job**: Runs after build passes

## Adding New Tests

When adding new tests:

1. Choose the appropriate test file based on the module being tested
2. Follow the existing test naming convention: `test_<feature>_<scenario>`
3. Group related tests together with comments
4. Include both success and failure cases
5. Test edge cases (empty strings, zero values, max values, etc.)
6. Add documentation comments for complex test scenarios

### Example Test Structure
```rust
#[test]
fn test_feature_success_case() {
    // Arrange
    let input = setup_test_data();
    
    // Act
    let result = function_under_test(input);
    
    // Assert
    assert_eq!(result, expected_value);
}

#[test]
fn test_feature_error_case() {
    let invalid_input = "invalid";
    let result = function_under_test(invalid_input);
    assert!(result.is_err());
}
```

## Test Guidelines

- **Fast**: Unit tests should run in milliseconds
- **Isolated**: Each test should be independent
- **Deterministic**: Tests should always produce the same result
- **Clear**: Test names should clearly describe what is being tested
- **Comprehensive**: Test happy paths, error paths, and edge cases

## Clippy Allowances

Some tests use `#![allow(clippy::assertions_on_constants)]` because they document expected constant values for configuration. This is intentional and helps verify that constants maintain reasonable values.

## Security Features

The test suite includes comprehensive security validation to prevent:
- Shell injection attacks
- Path traversal attempts
- Command injection via metacharacters
- Null byte injection
- Execution from untrusted directories
- Unicode/encoding tricks
- Environment variable injection

The `security` module provides `validate_command()` and `validate_env_value()` functions that are used by the server to validate all commands before execution.

## Total Test Count

- **Unit tests** (in src/):
  - terminado.rs: 6 tests
  - security.rs: 11 tests
- **Integration tests** (in tests/):
  - event_tests.rs: 11 tests
  - terminado_tests.rs: 38 tests
  - config_tests.rs: 17 tests
  - security_tests.rs: 28 tests
- **Total**: 111 tests

All tests must pass before code can be merged.