Files
xamxam/tests
Pontoporeia b12ae73e91 tests: fix SecurityTest fatal TypeError — update searchTheses call to use array params
SecurityTest::Test1 was calling $db->searchTheses($string) with a plain
string, but searchTheses() was refactored to require array $params when
the tag M2M work landed.  This caused an immediate PHP fatal TypeError
before any SQL ever ran, killing the entire Security test suite with
exit code 255 and masking all three tests.

Fix: pass each malicious payload via ['query' => $string] which is the
correct API and properly exercises the parameterised query path through
validateSearchParams() + buildSearchConditions().  Added a clarifying
comment explaining why the array form is required.

All 4 test suites now pass:
  - Database (Unit):   7/7
  - Rate Limit (Unit): 5/5
  - Search (Integration): 6/6
  - Security:          3/3
2026-03-26 18:54:20 +01:00
..
2026-02-05 20:16:19 +01:00

Post-ERG Test Suite

Centralized test suite for the Post-ERG thesis management system.

📁 Structure

tests/
├── run-tests.php           # Test runner (runs all tests)
├── Unit/                   # Unit tests
│   ├── DatabaseTest.php    # Database connection & queries
│   └── RateLimitTest.php   # Rate limiting functionality
├── Integration/            # Integration tests
│   └── SearchTest.php      # Search functionality
├── Security/               # Security tests
│   └── SecurityTest.php    # SQL injection & XSS protection
└── README.md              # This file

🚀 Running Tests

Run All Tests

# Using justfile (recommended)
just test

# Or directly
php tests/run-tests.php

Run Individual Tests

# Database test
php tests/Unit/DatabaseTest.php

# Search test
php tests/Integration/SearchTest.php

# Security test
php tests/Security/SecurityTest.php

# Rate limit test
php tests/Unit/RateLimitTest.php

Test Coverage

Unit Tests

DatabaseTest.php - Tests basic database operations:

  • Database connection
  • Count published theses
  • Get published theses
  • Get single thesis by ID

RateLimitTest.php - Tests rate limiting:

  • RateLimit initialization
  • check() method
  • sendHeaders() method
  • getResetTime() method
  • cleanup() method

Integration Tests

SearchTest.php - Tests search functionality:

  • Empty search query handling
  • Search for specific terms
  • Special characters in search

Security Tests

SecurityTest.php - Tests security measures:

  • SQL injection protection
  • Invalid ID rejection
  • XSS protection (output escaping)

📝 Writing New Tests

Test File Template

<?php
/**
 * Test Name
 * Description of what this tests
 */

require_once __DIR__ . '/../../lib/YourClass.php';

echo "Test Name\n";
echo "=========\n\n";

try {
    // Test 1
    echo "Test 1: Description\n";
    // ... test code ...
    echo "✓ PASS: Test passed\n\n";

    // Test 2
    echo "Test 2: Description\n";
    // ... test code ...
    echo "✓ PASS: Test passed\n\n";

    echo "✅ All tests passed!\n";
    return true;

} catch (Exception $e) {
    echo "❌ FAIL: " . $e->getMessage() . "\n";
    return false;
}

Guidelines

  1. Return Value: Return true for pass, false for fail
  2. Output Format: Use ✓ PASS: for successes, ❌ FAIL: for failures
  3. Exceptions: Catch and report exceptions clearly
  4. Dependencies: Require only what's needed via relative paths
  5. Location:
    • Unit/ - Tests for individual classes/functions
    • Integration/ - Tests for feature workflows
    • Security/ - Tests for security vulnerabilities

🔧 Test Database

Tests use the test database at database/test.db.

Setup Test Database

# Create from schema
just init-db

# Create with fixtures (sample data)
just fixtures

Reset Test Database

just reset-db

📊 Expected Output

Successful test run:

╔════════════════════════════════════════════╗
║         Post-ERG Test Suite                ║
╚════════════════════════════════════════════╝

┌─────────────────────────────────────────┐
│ Database (Unit)                         │
└─────────────────────────────────────────┘

✓ PASS: Database connection successful
✓ PASS: Found 16 published theses
...
✅ TEST PASSED

...

╔════════════════════════════════════════════╗
║              Test Summary                  ║
╠════════════════════════════════════════════╣
║ Total:   4                                 ║
║ Passed:  4 ✅                              ║
║ Failed:  0                                 ║
╚════════════════════════════════════════════╝

✅ All tests passed!

🐛 Debugging Failed Tests

Check Logs

# Application errors
tail -f error.log

# Test output
php tests/run-tests.php > test-output.txt 2>&1

Run Tests Individually

When a test fails, run it directly to see full output:

php tests/Unit/DatabaseTest.php

Check Database

# Open database
just query

# Check stats
just stats

🔄 Continuous Testing

Watch Mode (Future)

Could add file watching for auto-run:

# Future: auto-run tests on file change
just watch-tests

Pre-commit Hook (Future)

Add to .git/hooks/pre-commit:

#!/bin/bash
php tests/run-tests.php

To run tests: just test