CluPilotCloud/tests/Feature/WelcomeTest.php

71 lines
3.0 KiB
PHP

<?php
it('renders the public landing page with a sign-in link', function () {
$this->get('/')
->assertOk()
->assertSee('firmeneigene Cloud')
->assertSee(route('login'), false);
});
it('renders the legal placeholder pages', function (string $route) {
$this->get(route($route))->assertOk()->assertSee('CluPilot');
})->with(['legal.impressum', 'legal.datenschutz', 'legal.agb']);
it('serves the status page at its own address, not under legal', function () {
// It used to sit beside the imprint and the terms. Nothing about the
// current health of the platform is a legal document.
$this->get('/status')
->assertOk()
->assertSee(__('status.component.instances'))
->assertSee(__('status.component.backups'));
// The old address still works, permanently, for anything already linking it.
$this->get('/legal/status')->assertRedirect('/status');
});
it('reports a component it cannot see as unknown, never as operational', function () {
// A status page that reports green because nothing is being watched is
// worse than no status page: someone will believe it.
App\Models\Instance::factory()->create(['status' => 'active']);
$this->get('/status')
->assertOk()
->assertSee(__('status.state.unknown'))
->assertDontSee(__('status.overall.operational'));
});
it('does not call the estate protected when an instance has no backup at all', function () {
// Counting backup ROWS leaves an instance with no schedule out of the
// arithmetic entirely, and the page reports green because the backups that
// do exist happen to be fine.
$withBackup = App\Models\Instance::factory()->create(['status' => 'active']);
App\Models\Backup::query()->create([
'instance_id' => $withBackup->id, 'external_job_id' => 'job-1',
'schedule' => 'daily', 'status' => 'ok', 'last_ok_at' => now()->subHour(),
]);
App\Models\Instance::factory()->create(['status' => 'active']);
$this->get('/status')
->assertOk()
->assertSee(__('status.detail.backups', ['stale' => 1, 'total' => 2]));
});
it('serves the status page at the root of its own hostname, and the landing page everywhere else', function () {
// "status.clupilot.com/status" says the same word twice. And the generic
// `/` route is registered host-agnostically, so a domain-bound `/` has to
// come FIRST or Laravel matches the landing page on the status host.
config()->set('admin_access.status_host', 'status.example.test');
$router = new Illuminate\Routing\Router(app('events'), app());
Illuminate\Support\Facades\Route::swap($router);
require base_path('routes/web.php');
$router->getRoutes()->refreshNameLookups();
$matches = fn (string $host, string $path) => $router->getRoutes()
->match(Illuminate\Http\Request::create("http://{$host}{$path}", 'GET'))
->getActionName();
expect($matches('status.example.test', '/'))->toContain('StatusController')
->and($matches('www.example.test', '/'))->toContain('LandingController');
});