Skip to content

Add a basic End-to-End (E2E) test for full application flow (index.php) #4

@charlesroper

Description

@charlesroper

Background

The current test suite is comprehensive for unit and integration testing, but all database tests currently use PDO mocks (DatabaseOperationsTest.php). Additionally, the main entry point (index.php) is completely untested.

The Problem

Because we are mocking the database and omitting index.php from the test suite, we don't have automated proof that:

  1. The SQL queries are syntactically valid for the real SQLite driver.
  2. The data maps correctly from the real db/imd25.sqlite3 database to the HTML table.
  3. The full application stack works end-to-end.

The Solution

Add a lightweight E2E test using PHPUnit. There is no need for a heavy browser-testing framework like Cypress or Selenium. We can simulate a request using $_GET and output buffering, include index.php, and assert against the generated HTML.

(Note: To make this work in a CLI test environment, index.php will need to be slightly refactored to use $_GET['p'] instead of filter_input(INPUT_GET, 'p'), as filter_input cannot be mocked during a CLI script execution. This aligns with the proposed issue #2 refactor).

Proposed Test Implementation

Create a new file tests/E2E/IndexPageTest.php:

<?php

declare(strict_types=1);

namespace Tests\E2E;

use PHPUnit\Framework\TestCase;

class IndexPageTest extends TestCase
{
    protected function tearDown(): void
    {
        // Clean up global state after each test
        unset($_GET['p']);
        unset($_GET['d']);
    }

    public function testIndexPageRendersCorrectResultsForValidPostcode(): void
    {
        // 1. Arrange: Simulate the GET request
        $_GET['p'] = 'SW1A 1AA';
        $_GET['d'] = '10'; // Max decile

        // 2. Act: Execute index.php and capture the output
        ob_start();
        include __DIR__ . '/../../index.php';
        $output = ob_get_clean();

        // 3. Assert: Verify the HTML contains the expected real database output
        $this->assertStringContainsString('<td>SW1A 1AA</td>', $output);
        $this->assertStringContainsString('<td>Westminster 001A</td>', $output);
        
        // Assert the page rendered fully without fatal errors
        $this->assertStringContainsString('</html>', $output);
    }
    
    public function testIndexPageHandlesLimitExceeded(): void
    {
        // Create 901 postcodes
        $postcodes = array_fill(0, 901, 'SW1A 1AA');
        $_GET['p'] = implode("\n", $postcodes);
        
        ob_start();
        include __DIR__ . '/../../index.php';
        $output = ob_get_clean();
        
        $this->assertStringContainsString('You have entered more than 900 postcodes', $output);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions