395 lines
13 KiB
PHP
395 lines
13 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\Controllers;
|
|
|
|
use App\Controllers\ElementController;
|
|
use App\Element\CreateElementDto;
|
|
use App\Element\Element;
|
|
use App\Element\UseCases\CreateChildElement\CreateChildElement;
|
|
use App\Element\UseCases\DeleteChildElement\DeleteChildElement;
|
|
use App\Element\UseCases\GetElement\GetElement;
|
|
use App\Element\UseCases\ReorderChildElements\ReorderChildElements;
|
|
use App\Element\UseCases\UpdateElement\UpdateDescription;
|
|
use App\Element\UseCases\UpdateElement\UpdateElement;
|
|
use App\Element\UseCases\UpdateElement\UpdateIconImage;
|
|
use App\Element\UseCases\UpdateElement\UpdateIconImageUrl;
|
|
use App\Element\UseCases\UpdateElement\UpdateLongPdf;
|
|
use App\Element\UseCases\UpdateElement\UpdateLongPdfPath;
|
|
use App\Element\UseCases\UpdateElement\UpdateRichText;
|
|
use App\Element\UseCases\UpdateElement\UpdateShortPdf;
|
|
use App\Element\UseCases\UpdateElement\UpdateShortPdfPath;
|
|
use App\Element\UseCases\UpdateElement\UpdateTitle;
|
|
use App\Element\UseCases\UpdateElement\UpdateYoutubeUrl;
|
|
use App\Set\Set as DomainSet;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Tests\Fakes\FakeElementRepository;
|
|
use Tests\Fakes\FakeFileUploader;
|
|
use Tests\TestCase;
|
|
|
|
class ElementControllerTest extends TestCase
|
|
{
|
|
private ElementController $controller;
|
|
|
|
private FakeElementRepository $elementRepo;
|
|
|
|
private FakeFileUploader $fileUploader;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->elementRepo = new FakeElementRepository();
|
|
$this->fileUploader = new FakeFileUploader();
|
|
$getElement = new GetElement($this->elementRepo);
|
|
$updateElement = new UpdateElement(
|
|
new UpdateTitle($this->elementRepo),
|
|
new UpdateDescription($this->elementRepo),
|
|
new UpdateIconImageUrl($this->elementRepo, $this->fileUploader),
|
|
new UpdateRichText($this->elementRepo),
|
|
new UpdateShortPdfPath($this->elementRepo, $this->fileUploader),
|
|
new UpdateLongPdfPath($this->elementRepo, $this->fileUploader),
|
|
new UpdateYoutubeUrl($this->elementRepo),
|
|
new UpdateIconImage(
|
|
$this->elementRepo,
|
|
$this->fileUploader,
|
|
),
|
|
new UpdateShortPdf(
|
|
$this->elementRepo,
|
|
$this->fileUploader,
|
|
),
|
|
new UpdateLongPdf(
|
|
$this->elementRepo,
|
|
$this->fileUploader,
|
|
),
|
|
$this->elementRepo,
|
|
);
|
|
$this->controller = new ElementController(
|
|
$getElement,
|
|
new CreateChildElement($this->elementRepo),
|
|
new DeleteChildElement($this->elementRepo, $this->fileUploader),
|
|
new ReorderChildElements($this->elementRepo),
|
|
$updateElement,
|
|
$this->fileUploader,
|
|
);
|
|
}
|
|
|
|
public function testShowReturnsElementPayload(): void
|
|
{
|
|
$set = $this->createSet(1, 'Baderech');
|
|
$element = $this->createElement(
|
|
$set,
|
|
'Baderech HaAvodah',
|
|
'A structured path for growth',
|
|
'/assets/baderech-icon.png',
|
|
'<p>A structured path for growth</p>',
|
|
'/assets/pdfs/baderech.pdf',
|
|
'/assets/pdfs/baderech-long.pdf',
|
|
'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s',
|
|
null,
|
|
);
|
|
$firstChildElement = $this->createElement(
|
|
$set,
|
|
'Avodah Foundations',
|
|
'Foundations for steady avodah',
|
|
null,
|
|
'<p>Foundations rich text</p>',
|
|
'/assets/pdfs/foundations.pdf',
|
|
null,
|
|
null,
|
|
$element,
|
|
);
|
|
$secondChildElement = $this->createElement(
|
|
$set,
|
|
'Daily Practice',
|
|
'Daily practices for growth',
|
|
null,
|
|
'<p>Daily practice rich text</p>',
|
|
null,
|
|
null,
|
|
null,
|
|
$element,
|
|
);
|
|
|
|
$response = $this->controller->show($element->getId());
|
|
|
|
$this->assertEquals(200, $response->getStatusCode());
|
|
$body = json_decode($response->getContent(), true);
|
|
$this->assertSame($element->getId(), $body['element']['id']);
|
|
$this->assertSame('Baderech HaAvodah', $body['element']['title']);
|
|
$this->assertSame(
|
|
'A structured path for growth',
|
|
$body['element']['description'],
|
|
);
|
|
$this->assertSame(
|
|
'<p>A structured path for growth</p>',
|
|
$body['element']['richText'],
|
|
);
|
|
$this->assertSame(
|
|
'/assets/baderech-icon.png',
|
|
$body['element']['iconImageUrl'],
|
|
);
|
|
$this->assertSame(
|
|
'/assets/pdfs/baderech.pdf',
|
|
$body['element']['shortPdfPath'],
|
|
);
|
|
$this->assertSame(
|
|
'/assets/pdfs/baderech-long.pdf',
|
|
$body['element']['longPdfPath'],
|
|
);
|
|
$this->assertArrayNotHasKey('pdfPath', $body['element']);
|
|
$this->assertSame(
|
|
'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s',
|
|
$body['element']['youtubeUrl'],
|
|
);
|
|
$this->assertNull($body['parentElement']);
|
|
$this->assertSame([
|
|
[
|
|
'id' => $firstChildElement->getId(),
|
|
'title' => 'Avodah Foundations',
|
|
'description' => 'Foundations for steady avodah',
|
|
],
|
|
[
|
|
'id' => $secondChildElement->getId(),
|
|
'title' => 'Daily Practice',
|
|
'description' => 'Daily practices for growth',
|
|
],
|
|
], $body['childElements']);
|
|
$this->assertSame([
|
|
[
|
|
'id' => $element->getId(),
|
|
'title' => 'Baderech HaAvodah',
|
|
'description' => 'A structured path for growth',
|
|
],
|
|
], $body['siblingElements']);
|
|
}
|
|
|
|
public function testShowReturnsSameParentSiblingPayload(): void
|
|
{
|
|
$set = $this->createSet(1, 'Baderech');
|
|
$parentElement = $this->createElement(
|
|
$set,
|
|
'Baderech HaAvodah',
|
|
'A structured path for growth',
|
|
null,
|
|
'',
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
);
|
|
$firstChildElement = $this->createElement(
|
|
$set,
|
|
'Avodah Foundations',
|
|
'Foundations for steady avodah',
|
|
null,
|
|
'<p>Foundations rich text</p>',
|
|
null,
|
|
null,
|
|
null,
|
|
$parentElement,
|
|
);
|
|
$secondChildElement = $this->createElement(
|
|
$set,
|
|
'Daily Practice',
|
|
'Daily practices for growth',
|
|
null,
|
|
'',
|
|
null,
|
|
null,
|
|
null,
|
|
$parentElement,
|
|
);
|
|
|
|
$response = $this->controller->show($firstChildElement->getId());
|
|
|
|
$this->assertEquals(200, $response->getStatusCode());
|
|
$body = json_decode($response->getContent(), true);
|
|
$this->assertSame([
|
|
'id' => $parentElement->getId(),
|
|
'title' => 'Baderech HaAvodah',
|
|
'description' => 'A structured path for growth',
|
|
], $body['parentElement']);
|
|
$this->assertSame([
|
|
[
|
|
'id' => $firstChildElement->getId(),
|
|
'title' => 'Avodah Foundations',
|
|
'description' => 'Foundations for steady avodah',
|
|
],
|
|
[
|
|
'id' => $secondChildElement->getId(),
|
|
'title' => 'Daily Practice',
|
|
'description' => 'Daily practices for growth',
|
|
],
|
|
], $body['siblingElements']);
|
|
}
|
|
|
|
public function testShowReturns400WhenIdMissing(): void
|
|
{
|
|
$response = $this->controller->show(null);
|
|
|
|
$this->assertEquals(400, $response->getStatusCode());
|
|
$this->assertSame(
|
|
['error' => 'id is required'],
|
|
json_decode($response->getContent(), true),
|
|
);
|
|
}
|
|
|
|
public function testShowReturns404WhenElementDoesNotExist(): void
|
|
{
|
|
$response = $this->controller->show(999);
|
|
|
|
$this->assertEquals(404, $response->getStatusCode());
|
|
$this->assertSame(
|
|
['error' => 'Element not found'],
|
|
json_decode($response->getContent(), true),
|
|
);
|
|
}
|
|
|
|
public function testUpdateWithIconImageReturnsElementPayload(): void
|
|
{
|
|
$set = $this->createSet(1, 'Baderech');
|
|
$element = $this->createEmptyElement($set);
|
|
$fixturePath = __DIR__ . '/../../fixtures/icon.png';
|
|
$request = new Request([], [
|
|
'elementId' => (string) $element->getId(),
|
|
'fileType' => 'iconImage',
|
|
], [], [], [
|
|
'file' => new UploadedFile(
|
|
$fixturePath,
|
|
'icon.png',
|
|
'image/png',
|
|
null,
|
|
true,
|
|
),
|
|
], ['REQUEST_METHOD' => 'POST']);
|
|
|
|
$response = $this->controller->update($request);
|
|
|
|
$this->assertEquals(200, $response->getStatusCode());
|
|
$body = json_decode($response->getContent(), true);
|
|
$this->assertSame($element->getId(), $body['element']['id']);
|
|
$this->assertSame(
|
|
'https://test.local/storage/element-icons/fake-icon.png',
|
|
$body['element']['iconImageUrl'],
|
|
);
|
|
$this->assertSame(
|
|
'element-icons',
|
|
$this->fileUploader->uploads[0]['folder'],
|
|
);
|
|
}
|
|
|
|
public function testUpdateWithShortPdfReturnsElementPayload(): void
|
|
{
|
|
$set = $this->createSet(1, 'Baderech');
|
|
$element = $this->createEmptyElement($set);
|
|
$fixturePath = __DIR__ . '/../../fixtures/baderech.pdf';
|
|
$request = new Request([], [
|
|
'elementId' => (string) $element->getId(),
|
|
'fileType' => 'shortPdf',
|
|
], [], [], [
|
|
'file' => new UploadedFile(
|
|
$fixturePath,
|
|
'baderech.pdf',
|
|
'application/pdf',
|
|
null,
|
|
true,
|
|
),
|
|
], ['REQUEST_METHOD' => 'POST']);
|
|
|
|
$response = $this->controller->update($request);
|
|
|
|
$this->assertEquals(200, $response->getStatusCode());
|
|
$body = json_decode($response->getContent(), true);
|
|
$this->assertSame($element->getId(), $body['element']['id']);
|
|
$this->assertSame(
|
|
'https://test.local/storage/element-pdfs/short/fake-baderech.pdf',
|
|
$body['element']['shortPdfPath'],
|
|
);
|
|
$this->assertArrayNotHasKey('pdfPath', $body['element']);
|
|
$this->assertSame(
|
|
'element-pdfs/short',
|
|
$this->fileUploader->uploads[0]['folder'],
|
|
);
|
|
}
|
|
|
|
public function testUpdateWithLongPdfReturnsElementPayload(): void
|
|
{
|
|
$set = $this->createSet(1, 'Baderech');
|
|
$element = $this->createEmptyElement($set);
|
|
$fixturePath = __DIR__ . '/../../fixtures/baderech.pdf';
|
|
$request = new Request([], [
|
|
'elementId' => (string) $element->getId(),
|
|
'fileType' => 'longPdf',
|
|
], [], [], [
|
|
'file' => new UploadedFile(
|
|
$fixturePath,
|
|
'baderech.pdf',
|
|
'application/pdf',
|
|
null,
|
|
true,
|
|
),
|
|
], ['REQUEST_METHOD' => 'POST']);
|
|
|
|
$response = $this->controller->update($request);
|
|
|
|
$this->assertEquals(200, $response->getStatusCode());
|
|
$body = json_decode($response->getContent(), true);
|
|
$this->assertSame($element->getId(), $body['element']['id']);
|
|
$this->assertSame(
|
|
'https://test.local/storage/element-pdfs/long/fake-baderech.pdf',
|
|
$body['element']['longPdfPath'],
|
|
);
|
|
$this->assertSame(
|
|
'element-pdfs/long',
|
|
$this->fileUploader->uploads[0]['folder'],
|
|
);
|
|
}
|
|
|
|
private function createSet(int $id, string $name): DomainSet
|
|
{
|
|
return new DomainSet(
|
|
id: $id,
|
|
name: $name,
|
|
description: "$name description",
|
|
iconImageUrl: '/assets/baderech-icon.png',
|
|
);
|
|
}
|
|
|
|
private function createEmptyElement(DomainSet $set): Element
|
|
{
|
|
return $this->createElement(
|
|
$set,
|
|
'Baderech HaAvodah',
|
|
'A structured path for growth',
|
|
null,
|
|
'<p>A structured path for growth</p>',
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
);
|
|
}
|
|
|
|
private function createElement(
|
|
DomainSet $set,
|
|
string $title,
|
|
string $description,
|
|
?string $iconImageUrl,
|
|
string $richText,
|
|
?string $shortPdfPath,
|
|
?string $longPdfPath,
|
|
?string $youtubeUrl,
|
|
?Element $parentElement,
|
|
): Element {
|
|
return $this->elementRepo->create(new CreateElementDto(
|
|
set: $set,
|
|
title: $title,
|
|
description: $description,
|
|
iconImageUrl: $iconImageUrl,
|
|
richText: $richText,
|
|
shortPdfPath: $shortPdfPath,
|
|
longPdfPath: $longPdfPath,
|
|
youtubeUrl: $youtubeUrl,
|
|
parentElement: $parentElement,
|
|
));
|
|
}
|
|
}
|