lthn.io/app/Core/Tests/Feature/ErrorPagesTest.php

167 lines
5.3 KiB
PHP
Raw Permalink Normal View History

<?php
/*
* Core PHP Framework
*
* Licensed under the European Union Public Licence (EUPL) v1.2.
* See LICENSE file for details.
*/
declare(strict_types=1);
/**
* Error Pages Tests (TASK-010 Phase 3)
*
* Tests for static error pages in public/errors/.
* Error handling is configured in bootstrap/app.php.
*/
use App\Support\HadesEncrypt;
use Core\Tenant\Models\User;
use Illuminate\Support\Facades\Config;
describe('Static Error Files', function () {
it('has 404.html error page', function () {
$path = public_path('errors/404.html');
expect(file_exists($path))->toBeTrue();
$content = file_get_contents($path);
expect($content)->toContain('Host UK');
expect($content)->toContain('Page not found');
expect($content)->toContain('404');
});
it('has 500.html error page', function () {
$path = public_path('errors/500.html');
expect(file_exists($path))->toBeTrue();
$content = file_get_contents($path);
expect($content)->toContain('Host UK');
expect($content)->toContain('Something went wrong');
expect($content)->toContain('HADES_PLACEHOLDER');
});
it('has 503.html error page', function () {
$path = public_path('errors/503.html');
expect(file_exists($path))->toBeTrue();
$content = file_get_contents($path);
expect($content)->toContain('Host UK');
});
it('has coming-soon.html maintenance page', function () {
$path = public_path('errors/coming-soon.html');
expect(file_exists($path))->toBeTrue();
$content = file_get_contents($path);
expect($content)->toContain('Host UK');
});
});
describe('404 Error Page', function () {
it('returns 404 status for non-existent routes', function () {
$this->get('/this-route-definitely-does-not-exist-xyz123')
->assertNotFound();
});
it('renders custom 404 page in production mode', function () {
// Temporarily disable debug mode to trigger custom error page
Config::set('app.debug', false);
$response = $this->get('/this-route-definitely-does-not-exist-xyz123');
$response->assertNotFound();
$response->assertSee('Page not found');
$response->assertSee('Host UK');
});
it('includes link back to homepage on 404', function () {
Config::set('app.debug', false);
$response = $this->get('/non-existent-page-test');
$response->assertNotFound();
// Check for home link (href="/")
$response->assertSee('href="/"', false);
});
});
describe('403 Error Page', function () {
it('returns 403 for forbidden access', function () {
// Create a regular user (not hades)
$user = User::factory()->create([
'account_type' => 'apollo',
]);
// Try to access Hades-only dev API
$this->actingAs($user)
->getJson('/hub/api/dev/logs')
->assertForbidden();
});
});
describe('500 Error Page', function () {
it('has HADES placeholder for encrypted stack traces', function () {
$path = public_path('errors/500.html');
$content = file_get_contents($path);
// The placeholder is used to inject encrypted error data
expect($content)->toContain('<!-- HADES_PLACEHOLDER -->');
});
it('uses Host UK brand styling', function () {
$path = public_path('errors/500.html');
$content = file_get_contents($path);
// Should have brand colours and styling
expect($content)->toContain('Host UK');
expect($content)->toContain('Something went wrong');
// Should have a way to contact support or return home
expect($content)->toContain('href="/"');
});
});
describe('Error Page Brand Consistency', function () {
it('all error pages use Host UK branding', function () {
$errorPages = ['404.html', '500.html', '503.html', 'coming-soon.html'];
foreach ($errorPages as $page) {
$path = public_path("errors/{$page}");
expect(file_exists($path))->toBeTrue();
$content = file_get_contents($path);
expect($content)
->toContain('Host UK')
->and($content)->toContain('host.uk.com');
}
});
it('error pages do not expose stack traces', function () {
// Verify the static files don't contain any PHP code or stack trace patterns
$errorPages = ['404.html', '500.html', '503.html'];
foreach ($errorPages as $page) {
$path = public_path("errors/{$page}");
$content = file_get_contents($path);
expect($content)
->not->toContain('<?php')
->and($content)->not->toContain('Stack trace:')
->and($content)->not->toContain('vendor/laravel');
}
});
});
describe('HADES Encryption', function () {
it('HadesEncrypt class exists and is functional', function () {
expect(class_exists(HadesEncrypt::class))->toBeTrue();
// Test encryption with a sample exception
$exception = new Exception('Test error message');
$encrypted = HadesEncrypt::encrypt($exception);
// Should return encrypted string or null if no public key
expect($encrypted === null || is_string($encrypted))->toBeTrue();
});
});