Web app: new entities (Image, RenderedAsset, SharedImage, Token, DeviceImageHistory), enums, repositories, controllers, message handlers, migrations, tests, frontend upload/library/sticker UI, Vue components. Firmware: EPD background screen binaries + gen scripts, setup_bg header. Infra: ddev config, test bundle, gitignore coverage dir. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Functional\Controller;
|
||||
|
||||
use App\Entity\Device;
|
||||
use App\Enum\DeviceModel;
|
||||
use App\Enum\Orientation;
|
||||
use App\Tests\Functional\AppWebTestCase;
|
||||
|
||||
class SetupControllerTest extends AppWebTestCase
|
||||
{
|
||||
private const MAC = 'AA:BB:CC:00:11:22';
|
||||
|
||||
// S-01: anonymous GET /setup/{mac} → 200 (shows login/register form)
|
||||
public function test_setup_index_anonymous_renders(): void
|
||||
{
|
||||
$this->client->request('GET', '/setup/' . self::MAC);
|
||||
$this->assertResponseIsSuccessful();
|
||||
}
|
||||
|
||||
// S-02: authenticated with named device → redirects to spa (/)
|
||||
public function test_setup_index_authenticated_named_device_redirects_to_spa(): void
|
||||
{
|
||||
$user = $this->createUser('setup02@example.com');
|
||||
|
||||
$device = new Device();
|
||||
$device->setMac(self::MAC);
|
||||
$device->setName('Living Room');
|
||||
$device->setUser($user);
|
||||
$this->em()->persist($device);
|
||||
$this->em()->flush();
|
||||
|
||||
$this->loginAs($user);
|
||||
$this->client->request('GET', '/setup/' . self::MAC);
|
||||
|
||||
$this->assertResponseRedirects('/');
|
||||
}
|
||||
|
||||
// S-03: authenticated with no existing device (new link) → redirects to configure
|
||||
public function test_setup_index_authenticated_new_device_redirects_to_configure(): void
|
||||
{
|
||||
$user = $this->createUser('setup03@example.com');
|
||||
$this->loginAs($user);
|
||||
|
||||
$this->client->request('GET', '/setup/' . self::MAC);
|
||||
|
||||
$this->assertResponseRedirects('/setup/' . self::MAC . '/configure');
|
||||
}
|
||||
|
||||
// S-04: POST /setup/{mac}/register with valid data → creates user, links device, redirects to configure
|
||||
public function test_setup_register_creates_user_and_redirects_to_configure(): void
|
||||
{
|
||||
$this->client->request('POST', '/setup/' . self::MAC . '/register', [
|
||||
'registration_form' => [
|
||||
'email' => 'setupnew@example.com',
|
||||
'plainPassword' => [
|
||||
'first' => 'securepass123',
|
||||
'second' => 'securepass123',
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertResponseRedirects('/setup/' . self::MAC . '/configure');
|
||||
}
|
||||
|
||||
// S-05: POST /setup/{mac}/configure with valid name → saves device, redirects to spa
|
||||
public function test_setup_configure_saves_name_and_redirects_to_spa(): void
|
||||
{
|
||||
$user = $this->createUser('setup05@example.com');
|
||||
|
||||
$device = new Device();
|
||||
$device->setMac(self::MAC);
|
||||
$device->setUser($user);
|
||||
$this->em()->persist($device);
|
||||
$this->em()->flush();
|
||||
|
||||
$deviceId = $device->getId();
|
||||
|
||||
$this->loginAs($user);
|
||||
$this->client->request('POST', '/setup/' . self::MAC . '/configure', [
|
||||
'name' => 'Kitchen Frame',
|
||||
'orientation' => 'landscape',
|
||||
'rotation_interval_minutes' => '1440',
|
||||
'uniqueness_window' => '10',
|
||||
]);
|
||||
|
||||
$this->assertResponseRedirects('/');
|
||||
|
||||
$this->em()->clear();
|
||||
$saved = $this->em()->find(Device::class, $deviceId);
|
||||
$this->assertSame('Kitchen Frame', $saved->getName());
|
||||
}
|
||||
|
||||
// S-06: POST /setup/{mac}/login with valid credentials → redirects to configure
|
||||
public function test_login_valid_credentials_redirects_to_configure(): void
|
||||
{
|
||||
$this->createUser('setuplogin@example.com', 'testpass');
|
||||
|
||||
$this->client->request('POST', '/setup/' . self::MAC . '/login', [
|
||||
'_username' => 'setuplogin@example.com',
|
||||
'_password' => 'testpass',
|
||||
]);
|
||||
|
||||
$this->assertResponseRedirects('/setup/' . self::MAC . '/configure');
|
||||
}
|
||||
|
||||
// S-07: POST /setup/{mac}/login with wrong password → redirects to index
|
||||
public function test_login_invalid_credentials_redirects_to_index(): void
|
||||
{
|
||||
$this->createUser('setupbadlogin@example.com', 'testpass');
|
||||
|
||||
$this->client->request('POST', '/setup/' . self::MAC . '/login', [
|
||||
'_username' => 'setupbadlogin@example.com',
|
||||
'_password' => 'wrongpass',
|
||||
]);
|
||||
|
||||
$this->assertResponseRedirects('/setup/' . self::MAC);
|
||||
}
|
||||
|
||||
// S-08: authenticated GET /setup/{mac}/configure → 200
|
||||
public function test_configure_get_renders_form(): void
|
||||
{
|
||||
$user = $this->createUser('setupconfigget@example.com');
|
||||
|
||||
$device = new Device();
|
||||
$device->setMac(self::MAC);
|
||||
$device->setUser($user);
|
||||
$this->em()->persist($device);
|
||||
$this->em()->flush();
|
||||
|
||||
$this->loginAs($user);
|
||||
$this->client->request('GET', '/setup/' . self::MAC . '/configure');
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
}
|
||||
|
||||
// S-09: POST /setup/{mac}/configure with empty name → 200 (re-renders form with error)
|
||||
public function test_configure_post_empty_name_renders_error(): void
|
||||
{
|
||||
$user = $this->createUser('setupconfigerr@example.com');
|
||||
|
||||
$device = new Device();
|
||||
$device->setMac(self::MAC);
|
||||
$device->setUser($user);
|
||||
$this->em()->persist($device);
|
||||
$this->em()->flush();
|
||||
|
||||
$this->loginAs($user);
|
||||
$this->client->request('POST', '/setup/' . self::MAC . '/configure', [
|
||||
'name' => '',
|
||||
'orientation' => 'landscape',
|
||||
]);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
}
|
||||
|
||||
// S-10: POST /setup/{mac}/register with invalid form data → re-renders registration page
|
||||
public function test_setup_register_invalid_form_renders_page(): void
|
||||
{
|
||||
// Valid email (avoids TypeError) but mismatched passwords → form is invalid
|
||||
$this->client->request('POST', '/setup/' . self::MAC . '/register', [
|
||||
'registration_form' => [
|
||||
'email' => 'setup-invalid@example.com',
|
||||
'plainPassword' => [
|
||||
'first' => 'password123',
|
||||
'second' => 'different456',
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
// Symfony 7 returns 422 for submitted-but-invalid forms
|
||||
$this->assertResponseStatusCodeSame(422);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user