Files
Classeo/backend/tests/Unit/Scolarite/Application/Command/UploadSubmissionAttachment/UploadSubmissionAttachmentHandlerTest.php
Mathias STRASSER 713e408773
Some checks failed
CI / Naming Conventions (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Frontend Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Build Check (push) Has been cancelled
feat: Provisionner automatiquement un nouvel établissement
Lorsqu'un super-admin crée un établissement via l'interface, le système
doit automatiquement créer la base tenant, exécuter les migrations,
créer le premier utilisateur admin et envoyer l'invitation — le tout
de manière asynchrone pour ne pas bloquer la réponse HTTP.

Ce mécanisme rend chaque établissement opérationnel dès sa création
sans intervention manuelle sur l'infrastructure.
2026-04-10 15:24:27 +02:00

139 lines
4.6 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Unit\Scolarite\Application\Command\UploadSubmissionAttachment;
use App\Administration\Domain\Model\User\UserId;
use App\Scolarite\Application\Command\UploadSubmissionAttachment\UploadSubmissionAttachmentCommand;
use App\Scolarite\Application\Command\UploadSubmissionAttachment\UploadSubmissionAttachmentHandler;
use App\Scolarite\Application\Port\FileStorage;
use App\Scolarite\Domain\Exception\RenduDejaSoumisException;
use App\Scolarite\Domain\Model\Homework\HomeworkId;
use App\Scolarite\Domain\Model\HomeworkSubmission\HomeworkSubmission;
use App\Scolarite\Infrastructure\Persistence\InMemory\InMemoryHomeworkSubmissionRepository;
use App\Shared\Domain\Clock;
use App\Shared\Domain\Tenant\TenantId;
use DateTimeImmutable;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
final class UploadSubmissionAttachmentHandlerTest extends TestCase
{
private const string TENANT_ID = '550e8400-e29b-41d4-a716-446655440001';
private const string HOMEWORK_ID = '550e8400-e29b-41d4-a716-446655440050';
private const string STUDENT_ID = '550e8400-e29b-41d4-a716-446655440060';
private InMemoryHomeworkSubmissionRepository $submissionRepository;
private string $tempFile;
protected function setUp(): void
{
$this->submissionRepository = new InMemoryHomeworkSubmissionRepository();
$this->tempFile = tempnam(sys_get_temp_dir(), 'e2e_upload_');
file_put_contents($this->tempFile, 'fake PDF content');
}
protected function tearDown(): void
{
if (file_exists($this->tempFile)) {
unlink($this->tempFile);
}
}
#[Test]
public function itUploadsAttachmentForDraftSubmission(): void
{
$submission = $this->createDraftSubmission();
$this->submissionRepository->save($submission);
$handler = $this->createHandler();
$command = new UploadSubmissionAttachmentCommand(
tenantId: self::TENANT_ID,
submissionId: (string) $submission->id,
filename: 'devoir.pdf',
mimeType: 'application/pdf',
fileSize: 1024,
tempFilePath: $this->tempFile,
);
$attachment = $handler($command);
self::assertSame('devoir.pdf', $attachment->filename);
self::assertSame('application/pdf', $attachment->mimeType);
self::assertSame(1024, $attachment->fileSize);
self::assertStringContainsString('submissions/', $attachment->filePath);
}
#[Test]
public function itRejectsUploadOnSubmittedSubmission(): void
{
$submission = $this->createDraftSubmission();
$submission->soumettre(
dueDate: new DateTimeImmutable('2026-04-15'),
now: new DateTimeImmutable('2026-03-24 11:00:00'),
);
$this->submissionRepository->save($submission);
$handler = $this->createHandler();
$command = new UploadSubmissionAttachmentCommand(
tenantId: self::TENANT_ID,
submissionId: (string) $submission->id,
filename: 'devoir.pdf',
mimeType: 'application/pdf',
fileSize: 1024,
tempFilePath: $this->tempFile,
);
$this->expectException(RenduDejaSoumisException::class);
$handler($command);
}
private function createDraftSubmission(): HomeworkSubmission
{
return HomeworkSubmission::creerBrouillon(
tenantId: TenantId::fromString(self::TENANT_ID),
homeworkId: HomeworkId::fromString(self::HOMEWORK_ID),
studentId: UserId::fromString(self::STUDENT_ID),
responseHtml: '<p>Ma réponse</p>',
now: new DateTimeImmutable('2026-03-24 10:00:00'),
);
}
private function createHandler(): UploadSubmissionAttachmentHandler
{
$fileStorage = new class implements FileStorage {
public function upload(string $path, mixed $content, string $mimeType): string
{
return $path;
}
public function delete(string $path): void
{
}
public function readStream(string $path): mixed
{
/** @var resource $stream */
$stream = fopen('php://memory', 'r+');
return $stream;
}
};
$clock = new class implements Clock {
public function now(): DateTimeImmutable
{
return new DateTimeImmutable('2026-03-24 10:00:00');
}
};
return new UploadSubmissionAttachmentHandler(
$this->submissionRepository,
$fileStorage,
$clock,
);
}
}