diff --git a/backend/app/Controllers/ElementController.php b/backend/app/Controllers/ElementController.php index 9ad8ed8..1cfc205 100644 --- a/backend/app/Controllers/ElementController.php +++ b/backend/app/Controllers/ElementController.php @@ -57,7 +57,8 @@ class ElementController public function update(Request $request): JsonResponse { - $file = $this->uploadedFileInput($request, 'file'); + $iconImage = $this->uploadedFileInput($request, 'iconImage'); + $pdf = $this->uploadedFileInput($request, 'pdf'); try { $element = $this->updateElement->execute( @@ -70,14 +71,16 @@ class ElementController 'iconImageUrl', ), richText: $this->stringInput($request, 'richText'), - shortPdfPath: $this->stringInput($request, 'shortPdfPath'), - longPdfPath: $this->stringInput($request, 'longPdfPath'), + pdfPath: $this->stringInput($request, 'pdfPath'), youtubeUrl: $this->stringInput($request, 'youtubeUrl'), - fileType: $this->stringInput($request, 'fileType'), - fileContents: $file['contents'], - fileOriginalName: $file['originalName'], - fileMimeType: $file['mimeType'], - fileSizeBytes: $file['sizeBytes'], + iconImageContents: $iconImage['contents'], + iconImageOriginalName: $iconImage['originalName'], + iconImageMimeType: $iconImage['mimeType'], + iconImageSizeBytes: $iconImage['sizeBytes'], + pdfContents: $pdf['contents'], + pdfOriginalName: $pdf['originalName'], + pdfMimeType: $pdf['mimeType'], + pdfSizeBytes: $pdf['sizeBytes'], ) ); } catch (BadRequestException $exception) { @@ -173,8 +176,7 @@ class ElementController * description: string, * iconImageUrl: string|null, * richText: string, - * shortPdfPath: string|null, - * longPdfPath: string|null, + * pdfPath: string|null, * youtubeUrl: string|null, * } */ @@ -189,12 +191,8 @@ class ElementController 'element-icons/', ), 'richText' => $element->getRichText(), - 'shortPdfPath' => $this->storageUrl( - $element->getShortPdfPath(), - 'element-pdfs/', - ), - 'longPdfPath' => $this->storageUrl( - $element->getLongPdfPath(), + 'pdfPath' => $this->storageUrl( + $element->getPdfPath(), 'element-pdfs/', ), 'youtubeUrl' => $element->getYoutubeUrl(), diff --git a/backend/app/Element/CreateElementDto.php b/backend/app/Element/CreateElementDto.php index 3d41e23..b5a9b7f 100644 --- a/backend/app/Element/CreateElementDto.php +++ b/backend/app/Element/CreateElementDto.php @@ -12,8 +12,7 @@ class CreateElementDto public string $description, public ?string $iconImageUrl, public string $richText, - public ?string $shortPdfPath, - public ?string $longPdfPath, + public ?string $pdfPath, public ?string $youtubeUrl, public ?Element $parentElement, ) { diff --git a/backend/app/Element/Element.php b/backend/app/Element/Element.php index 7b07975..37be364 100644 --- a/backend/app/Element/Element.php +++ b/backend/app/Element/Element.php @@ -12,8 +12,7 @@ class Element private string $description, private ?string $iconImageUrl, private string $richText, - private ?string $shortPdfPath, - private ?string $longPdfPath, + private ?string $pdfPath, private ?string $youtubeUrl, private Set $set, private ?Element $parentElement, @@ -65,24 +64,14 @@ class Element $this->richText = $richText; } - public function getShortPdfPath(): ?string + public function getPdfPath(): ?string { - return $this->shortPdfPath; + return $this->pdfPath; } - public function setShortPdfPath(?string $shortPdfPath): void + public function setPdfPath(?string $pdfPath): void { - $this->shortPdfPath = $shortPdfPath; - } - - public function getLongPdfPath(): ?string - { - return $this->longPdfPath; - } - - public function setLongPdfPath(?string $longPdfPath): void - { - $this->longPdfPath = $longPdfPath; + $this->pdfPath = $pdfPath; } public function getYoutubeUrl(): ?string diff --git a/backend/app/Element/ElementModel.php b/backend/app/Element/ElementModel.php index 3a8a435..a71eb37 100644 --- a/backend/app/Element/ElementModel.php +++ b/backend/app/Element/ElementModel.php @@ -12,8 +12,7 @@ use Illuminate\Database\Eloquent\Model; * @property string $description * @property string|null $icon_image_url * @property string $rich_text - * @property string|null $short_pdf_path - * @property string|null $long_pdf_path + * @property string|null $pdf_path * @property string|null $youtube_url * @property int|null $parent_element_id * @@ -27,8 +26,7 @@ use Illuminate\Database\Eloquent\Model; * @method static Builder|ElementModel whereDescription($value) * @method static Builder|ElementModel whereIconImageUrl($value) * @method static Builder|ElementModel whereRichText($value) - * @method static Builder|ElementModel whereShortPdfPath($value) - * @method static Builder|ElementModel whereLongPdfPath($value) + * @method static Builder|ElementModel wherePdfPath($value) * @method static Builder|ElementModel whereYoutubeUrl($value) * * @mixin \Eloquent @@ -45,8 +43,7 @@ class ElementModel extends Model 'description', 'icon_image_url', 'rich_text', - 'short_pdf_path', - 'long_pdf_path', + 'pdf_path', 'youtube_url', 'parent_element_id', ]; diff --git a/backend/app/Element/EloquentElementRepository.php b/backend/app/Element/EloquentElementRepository.php index 771bc4c..379abe0 100644 --- a/backend/app/Element/EloquentElementRepository.php +++ b/backend/app/Element/EloquentElementRepository.php @@ -20,8 +20,7 @@ class EloquentElementRepository implements ElementRepository 'description' => $dto->description, 'icon_image_url' => $dto->iconImageUrl, 'rich_text' => $dto->richText, - 'short_pdf_path' => $dto->shortPdfPath, - 'long_pdf_path' => $dto->longPdfPath, + 'pdf_path' => $dto->pdfPath, 'youtube_url' => $dto->youtubeUrl, 'parent_element_id' => $dto->parentElement?->getId(), ]); @@ -32,8 +31,7 @@ class EloquentElementRepository implements ElementRepository description: $dto->description, iconImageUrl: $dto->iconImageUrl, richText: $dto->richText, - shortPdfPath: $dto->shortPdfPath, - longPdfPath: $dto->longPdfPath, + pdfPath: $dto->pdfPath, youtubeUrl: $dto->youtubeUrl, set: $dto->set, parentElement: $dto->parentElement, @@ -54,8 +52,7 @@ class EloquentElementRepository implements ElementRepository $model->description = $element->getDescription(); $model->icon_image_url = $element->getIconImageUrl(); $model->rich_text = $element->getRichText(); - $model->short_pdf_path = $element->getShortPdfPath(); - $model->long_pdf_path = $element->getLongPdfPath(); + $model->pdf_path = $element->getPdfPath(); $model->youtube_url = $element->getYoutubeUrl(); $model->parent_element_id = $element->getParentElement()?->getId(); $model->save(); @@ -140,8 +137,7 @@ class EloquentElementRepository implements ElementRepository description: $model->description, iconImageUrl: $model->icon_image_url, richText: $model->rich_text, - shortPdfPath: $model->short_pdf_path, - longPdfPath: $model->long_pdf_path, + pdfPath: $model->pdf_path, youtubeUrl: $model->youtube_url, set: $set, parentElement: $parentElement, diff --git a/backend/app/Element/UseCases/CreateElement/CreateElement.php b/backend/app/Element/UseCases/CreateElement/CreateElement.php index 3929bce..e91a0ac 100644 --- a/backend/app/Element/UseCases/CreateElement/CreateElement.php +++ b/backend/app/Element/UseCases/CreateElement/CreateElement.php @@ -35,12 +35,7 @@ class CreateElement ? null : $request->iconImageUrl; $richText = $request->richText ?? ''; - $shortPdfPath = $request->shortPdfPath === '' - ? null - : $request->shortPdfPath; - $longPdfPath = $request->longPdfPath === '' - ? null - : $request->longPdfPath; + $pdfPath = $request->pdfPath === '' ? null : $request->pdfPath; $youtubeUrl = $request->youtubeUrl === '' ? null : $request->youtubeUrl; @@ -61,8 +56,7 @@ class CreateElement description: $description, iconImageUrl: $iconImageUrl, richText: $richText, - shortPdfPath: $shortPdfPath, - longPdfPath: $longPdfPath, + pdfPath: $pdfPath, youtubeUrl: $youtubeUrl, parentElement: null, )); @@ -88,8 +82,7 @@ class CreateElement description: $description, iconImageUrl: $iconImageUrl, richText: $richText, - shortPdfPath: $shortPdfPath, - longPdfPath: $longPdfPath, + pdfPath: $pdfPath, youtubeUrl: $youtubeUrl, parentElement: $parentElement, )); diff --git a/backend/app/Element/UseCases/CreateElement/CreateElementRequest.php b/backend/app/Element/UseCases/CreateElement/CreateElementRequest.php index 3f6d53f..ef689cc 100644 --- a/backend/app/Element/UseCases/CreateElement/CreateElementRequest.php +++ b/backend/app/Element/UseCases/CreateElement/CreateElementRequest.php @@ -10,8 +10,7 @@ class CreateElementRequest public ?string $description, public ?string $iconImageUrl, public ?string $richText, - public ?string $shortPdfPath, - public ?string $longPdfPath, + public ?string $pdfPath, public ?string $youtubeUrl, public ?int $parentElementId, ) { diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateElement.php b/backend/app/Element/UseCases/UpdateElement/UpdateElement.php index 9f60f24..0533b16 100644 --- a/backend/app/Element/UseCases/UpdateElement/UpdateElement.php +++ b/backend/app/Element/UseCases/UpdateElement/UpdateElement.php @@ -9,23 +9,15 @@ use App\Exceptions\NotFoundException; class UpdateElement { - private const FILE_TYPE_ICON_IMAGE = 'iconImage'; - - private const FILE_TYPE_SHORT_PDF = 'shortPdf'; - - private const FILE_TYPE_LONG_PDF = 'longPdf'; - public function __construct( private UpdateTitle $updateTitle, private UpdateDescription $updateDescription, private UpdateIconImageUrl $updateIconImageUrl, private UpdateRichText $updateRichText, - private UpdateShortPdfPath $updateShortPdfPath, - private UpdateLongPdfPath $updateLongPdfPath, + private UpdatePdfPath $updatePdfPath, private UpdateYoutubeUrl $updateYoutubeUrl, private UpdateIconImage $updateIconImage, - private UpdateShortPdf $updateShortPdf, - private UpdateLongPdf $updateLongPdf, + private UpdatePdf $updatePdf, private ElementRepository $elementRepository, ) { } @@ -44,14 +36,10 @@ class UpdateElement && $request->description === null && $request->iconImageUrl === null && $request->richText === null - && $request->shortPdfPath === null - && $request->longPdfPath === null + && $request->pdfPath === null && $request->youtubeUrl === null - && $request->fileType === null - && $request->fileContents === null - && $request->fileOriginalName === null - && $request->fileMimeType === null - && $request->fileSizeBytes === null; + && $request->iconImageContents === null + && $request->pdfContents === null; if ($hasNoFields) { throw new BadRequestException('nothing to update'); } @@ -82,16 +70,10 @@ class UpdateElement richText: $request->richText, )); } - if ($request->shortPdfPath !== null) { - $this->updateShortPdfPath->execute(new UpdateShortPdfPathRequest( + if ($request->pdfPath !== null) { + $this->updatePdfPath->execute(new UpdatePdfPathRequest( id: $request->id, - shortPdfPath: $request->shortPdfPath, - )); - } - if ($request->longPdfPath !== null) { - $this->updateLongPdfPath->execute(new UpdateLongPdfPathRequest( - id: $request->id, - longPdfPath: $request->longPdfPath, + pdfPath: $request->pdfPath, )); } if ($request->youtubeUrl !== null) { @@ -100,8 +82,27 @@ class UpdateElement youtubeUrl: $request->youtubeUrl, )); } - if ($this->hasFileInput($request)) { - $this->updateFile($request); + if ($request->iconImageContents !== null) { + $this->updateIconImage->execute( + new UpdateIconImageRequest( + id: $request->id, + iconImageContents: $request->iconImageContents, + iconImageOriginalName: $request->iconImageOriginalName, + iconImageMimeType: $request->iconImageMimeType, + iconImageSizeBytes: $request->iconImageSizeBytes, + ) + ); + } + if ($request->pdfContents !== null) { + $this->updatePdf->execute( + new UpdatePdfRequest( + id: $request->id, + pdfContents: $request->pdfContents, + pdfOriginalName: $request->pdfOriginalName, + pdfMimeType: $request->pdfMimeType, + pdfSizeBytes: $request->pdfSizeBytes, + ) + ); } $element = $this->elementRepository->find($request->id); @@ -111,68 +112,4 @@ class UpdateElement return $element; } - - /** - * @throws BadRequestException - * @throws NotFoundException - */ - private function updateFile(UpdateElementRequest $request): void - { - if ($request->fileType === null) { - throw new BadRequestException('fileType is required'); - } - - if ($request->fileType === self::FILE_TYPE_ICON_IMAGE) { - $this->updateIconImage->execute( - new UpdateIconImageRequest( - id: $request->id, - fileContents: $request->fileContents, - fileOriginalName: $request->fileOriginalName, - fileMimeType: $request->fileMimeType, - fileSizeBytes: $request->fileSizeBytes, - ) - ); - - return; - } - - if ($request->fileType === self::FILE_TYPE_SHORT_PDF) { - $this->updateShortPdf->execute( - new UpdateShortPdfRequest( - id: $request->id, - fileContents: $request->fileContents, - fileOriginalName: $request->fileOriginalName, - fileMimeType: $request->fileMimeType, - fileSizeBytes: $request->fileSizeBytes, - ) - ); - - return; - } - - if ($request->fileType === self::FILE_TYPE_LONG_PDF) { - $this->updateLongPdf->execute( - new UpdateLongPdfRequest( - id: $request->id, - fileContents: $request->fileContents, - fileOriginalName: $request->fileOriginalName, - fileMimeType: $request->fileMimeType, - fileSizeBytes: $request->fileSizeBytes, - ) - ); - - return; - } - - throw new BadRequestException('fileType is invalid'); - } - - private function hasFileInput(UpdateElementRequest $request): bool - { - return $request->fileType !== null - || $request->fileContents !== null - || $request->fileOriginalName !== null - || $request->fileMimeType !== null - || $request->fileSizeBytes !== null; - } } diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateElementRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdateElementRequest.php index e734390..aa1aa06 100644 --- a/backend/app/Element/UseCases/UpdateElement/UpdateElementRequest.php +++ b/backend/app/Element/UseCases/UpdateElement/UpdateElementRequest.php @@ -10,14 +10,16 @@ class UpdateElementRequest public ?string $description, public ?string $iconImageUrl, public ?string $richText, - public ?string $shortPdfPath, - public ?string $longPdfPath, + public ?string $pdfPath, public ?string $youtubeUrl, - public ?string $fileType, - public ?string $fileContents, - public ?string $fileOriginalName, - public ?string $fileMimeType, - public ?int $fileSizeBytes, + public ?string $iconImageContents, + public ?string $iconImageOriginalName, + public ?string $iconImageMimeType, + public ?int $iconImageSizeBytes, + public ?string $pdfContents, + public ?string $pdfOriginalName, + public ?string $pdfMimeType, + public ?int $pdfSizeBytes, ) { } } diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateIconImage.php b/backend/app/Element/UseCases/UpdateElement/UpdateIconImage.php index 59dcaad..45d274f 100644 --- a/backend/app/Element/UseCases/UpdateElement/UpdateIconImage.php +++ b/backend/app/Element/UseCases/UpdateElement/UpdateIconImage.php @@ -36,17 +36,17 @@ class UpdateIconImage } if ( - $request->fileContents === null - || $request->fileOriginalName === null - || $request->fileMimeType === null - || $request->fileSizeBytes === null + $request->iconImageContents === null + || $request->iconImageOriginalName === null + || $request->iconImageMimeType === null + || $request->iconImageSizeBytes === null ) { throw new BadRequestException('icon image is required'); } if ( ! in_array( - $request->fileMimeType, + $request->iconImageMimeType, self::ALLOWED_MIME_TYPES, true, ) @@ -56,7 +56,7 @@ class UpdateIconImage ); } - if ($request->fileSizeBytes > self::MAX_SIZE_BYTES) { + if ($request->iconImageSizeBytes > self::MAX_SIZE_BYTES) { throw new BadRequestException( 'icon image must be 5MB or smaller', ); @@ -68,10 +68,10 @@ class UpdateIconImage } $iconImage = new FileToUpload( - contents: $request->fileContents, - originalName: $request->fileOriginalName, - mimeType: $request->fileMimeType, - sizeBytes: $request->fileSizeBytes, + contents: $request->iconImageContents, + originalName: $request->iconImageOriginalName, + mimeType: $request->iconImageMimeType, + sizeBytes: $request->iconImageSizeBytes, ); $path = $this->fileUploader->upload($iconImage, 'element-icons'); $element->setIconImageUrl($path); diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateIconImageRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdateIconImageRequest.php index ccf973d..a119053 100644 --- a/backend/app/Element/UseCases/UpdateElement/UpdateIconImageRequest.php +++ b/backend/app/Element/UseCases/UpdateElement/UpdateIconImageRequest.php @@ -6,10 +6,10 @@ class UpdateIconImageRequest { public function __construct( public ?int $id, - public ?string $fileContents, - public ?string $fileOriginalName, - public ?string $fileMimeType, - public ?int $fileSizeBytes, + public ?string $iconImageContents, + public ?string $iconImageOriginalName, + public ?string $iconImageMimeType, + public ?int $iconImageSizeBytes, ) { } } diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateLongPdfRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdateLongPdfRequest.php deleted file mode 100644 index eb891a6..0000000 --- a/backend/app/Element/UseCases/UpdateElement/UpdateLongPdfRequest.php +++ /dev/null @@ -1,15 +0,0 @@ -id === null) { throw new BadRequestException('id is required'); } if ( - $request->fileContents === null - || $request->fileOriginalName === null - || $request->fileMimeType === null - || $request->fileSizeBytes === null + $request->pdfContents === null + || $request->pdfOriginalName === null + || $request->pdfMimeType === null + || $request->pdfSizeBytes === null ) { throw new BadRequestException('pdf is required'); } if ( ! in_array( - $request->fileMimeType, + $request->pdfMimeType, self::ALLOWED_MIME_TYPES, true, ) @@ -52,7 +52,7 @@ class UpdateLongPdf throw new BadRequestException('pdf must be a pdf file'); } - if ($request->fileSizeBytes > self::MAX_SIZE_BYTES) { + if ($request->pdfSizeBytes > self::MAX_SIZE_BYTES) { throw new BadRequestException('pdf must be 10MB or smaller'); } @@ -62,13 +62,13 @@ class UpdateLongPdf } $pdf = new FileToUpload( - contents: $request->fileContents, - originalName: $request->fileOriginalName, - mimeType: $request->fileMimeType, - sizeBytes: $request->fileSizeBytes, + contents: $request->pdfContents, + originalName: $request->pdfOriginalName, + mimeType: $request->pdfMimeType, + sizeBytes: $request->pdfSizeBytes, ); - $path = $this->fileUploader->upload($pdf, 'element-pdfs/long'); - $element->setLongPdfPath($path); + $path = $this->fileUploader->upload($pdf, 'element-pdfs'); + $element->setPdfPath($path); return $this->elementRepository->update($element); } diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateLongPdfPath.php b/backend/app/Element/UseCases/UpdateElement/UpdatePdfPath.php similarity index 73% rename from backend/app/Element/UseCases/UpdateElement/UpdateLongPdfPath.php rename to backend/app/Element/UseCases/UpdateElement/UpdatePdfPath.php index ae04422..404c78b 100644 --- a/backend/app/Element/UseCases/UpdateElement/UpdateLongPdfPath.php +++ b/backend/app/Element/UseCases/UpdateElement/UpdatePdfPath.php @@ -8,7 +8,7 @@ use App\Exceptions\BadRequestException; use App\Exceptions\NotFoundException; use App\Shared\Files\FileUploader; -class UpdateLongPdfPath +class UpdatePdfPath { public function __construct( private ElementRepository $elementRepository, @@ -20,14 +20,14 @@ class UpdateLongPdfPath * @throws BadRequestException * @throws NotFoundException */ - public function execute(UpdateLongPdfPathRequest $request): Element + public function execute(UpdatePdfPathRequest $request): Element { if ($request->id === null) { throw new BadRequestException('id is required'); } - if ($request->longPdfPath === null) { - throw new BadRequestException('longPdfPath is required'); + if ($request->pdfPath === null) { + throw new BadRequestException('pdfPath is required'); } $element = $this->elementRepository->find($request->id); @@ -35,12 +35,12 @@ class UpdateLongPdfPath throw new NotFoundException('Element not found'); } - $longPdfPath = $this->nullableString($request->longPdfPath); - if ($longPdfPath === null) { - $this->deleteManagedFile($element->getLongPdfPath()); + $pdfPath = $this->nullableString($request->pdfPath); + if ($pdfPath === null) { + $this->deleteManagedFile($element->getPdfPath()); } - $element->setLongPdfPath($longPdfPath); + $element->setPdfPath($pdfPath); return $this->elementRepository->update($element); } diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateLongPdfPathRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdatePdfPathRequest.php similarity index 65% rename from backend/app/Element/UseCases/UpdateElement/UpdateLongPdfPathRequest.php rename to backend/app/Element/UseCases/UpdateElement/UpdatePdfPathRequest.php index 4f4a064..c48c47d 100644 --- a/backend/app/Element/UseCases/UpdateElement/UpdateLongPdfPathRequest.php +++ b/backend/app/Element/UseCases/UpdateElement/UpdatePdfPathRequest.php @@ -2,11 +2,11 @@ namespace App\Element\UseCases\UpdateElement; -class UpdateLongPdfPathRequest +class UpdatePdfPathRequest { public function __construct( public ?int $id, - public ?string $longPdfPath, + public ?string $pdfPath, ) { } } diff --git a/backend/app/Element/UseCases/UpdateElement/UpdatePdfRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdatePdfRequest.php new file mode 100644 index 0000000..98ac3bf --- /dev/null +++ b/backend/app/Element/UseCases/UpdateElement/UpdatePdfRequest.php @@ -0,0 +1,15 @@ +id === null) { - throw new BadRequestException('id is required'); - } - - if ( - $request->fileContents === null - || $request->fileOriginalName === null - || $request->fileMimeType === null - || $request->fileSizeBytes === null - ) { - throw new BadRequestException('pdf is required'); - } - - if ( - ! in_array( - $request->fileMimeType, - self::ALLOWED_MIME_TYPES, - true, - ) - ) { - throw new BadRequestException('pdf must be a pdf file'); - } - - if ($request->fileSizeBytes > self::MAX_SIZE_BYTES) { - throw new BadRequestException('pdf must be 10MB or smaller'); - } - - $element = $this->elementRepository->find($request->id); - if ($element === null) { - throw new NotFoundException('Element not found'); - } - - $pdf = new FileToUpload( - contents: $request->fileContents, - originalName: $request->fileOriginalName, - mimeType: $request->fileMimeType, - sizeBytes: $request->fileSizeBytes, - ); - $path = $this->fileUploader->upload($pdf, 'element-pdfs/short'); - $element->setShortPdfPath($path); - - return $this->elementRepository->update($element); - } -} diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateShortPdfPath.php b/backend/app/Element/UseCases/UpdateElement/UpdateShortPdfPath.php deleted file mode 100644 index ae4b4e3..0000000 --- a/backend/app/Element/UseCases/UpdateElement/UpdateShortPdfPath.php +++ /dev/null @@ -1,65 +0,0 @@ -id === null) { - throw new BadRequestException('id is required'); - } - - if ($request->shortPdfPath === null) { - throw new BadRequestException('shortPdfPath is required'); - } - - $element = $this->elementRepository->find($request->id); - if ($element === null) { - throw new NotFoundException('Element not found'); - } - - $shortPdfPath = $this->nullableString($request->shortPdfPath); - if ($shortPdfPath === null) { - $this->deleteManagedFile($element->getShortPdfPath()); - } - - $element->setShortPdfPath($shortPdfPath); - - return $this->elementRepository->update($element); - } - - private function nullableString(string $value): ?string - { - if ($value === '') { - return null; - } - - return $value; - } - - private function deleteManagedFile(?string $path): void - { - if ($path === null) { - return; - } - - $this->fileUploader->delete($path); - } -} diff --git a/backend/app/Element/UseCases/UpdateElement/UpdateShortPdfPathRequest.php b/backend/app/Element/UseCases/UpdateElement/UpdateShortPdfPathRequest.php deleted file mode 100644 index a10555f..0000000 --- a/backend/app/Element/UseCases/UpdateElement/UpdateShortPdfPathRequest.php +++ /dev/null @@ -1,12 +0,0 @@ -text('description')->default(''); $table->string('icon_image_url')->nullable(); $table->text('rich_text')->default(''); - $table->string('short_pdf_path')->nullable(); - $table->string('long_pdf_path')->nullable(); + $table->string('pdf_path')->nullable(); $table->string('youtube_url')->nullable(); $table->foreignId('parent_element_id') ->nullable() diff --git a/backend/database/seeders/ElementSeeder.php b/backend/database/seeders/ElementSeeder.php index ba5aded..c7df012 100644 --- a/backend/database/seeders/ElementSeeder.php +++ b/backend/database/seeders/ElementSeeder.php @@ -20,7 +20,7 @@ class ElementSeeder extends Seeder 'element-icons/baderech-haavodah-icon.png', ); $introductionPdfPath = $this->seedStorageFile( - 'element-pdfs/short/baderech.pdf', + 'element-pdfs/baderech.pdf', ); $rootElement = $elementRepository->create(new CreateElementDto( @@ -29,8 +29,7 @@ class ElementSeeder extends Seeder description: $baderechSet->getDescription(), iconImageUrl: $rootIconImageUrl, richText: '', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElement: null, )); @@ -45,7 +44,7 @@ class ElementSeeder extends Seeder . 'unlock the ability to live with strength, confidence, ' . 'and hope.', 'richText' => $this->introductionRichText(), - 'shortPdfPath' => $introductionPdfPath, + 'pdfPath' => $introductionPdfPath, ], [ 'title' => '2. Foundations', @@ -55,7 +54,7 @@ class ElementSeeder extends Seeder . 'ability to uplift the physical world with spiritual ' . 'intention.', 'richText' => '', - 'shortPdfPath' => null, + 'pdfPath' => null, ], [ 'title' => '3. Divine Plan', @@ -63,14 +62,14 @@ class ElementSeeder extends Seeder . 'generation and the call to remain hopeful, ' . 'optimistic, and resilient.', 'richText' => '', - 'shortPdfPath' => null, + 'pdfPath' => null, ], [ 'title' => '4. Architecture of the Soul', 'description' => "Becoming a Baal Da'at - A Master of " . 'Inner Awareness', 'richText' => '', - 'shortPdfPath' => null, + 'pdfPath' => null, ], [ 'title' => '5. Arba Yesodot', @@ -78,7 +77,7 @@ class ElementSeeder extends Seeder . 'Physical & Financial Health, Relationships, Wisdom ' . 'and Guidance.', 'richText' => '', - 'shortPdfPath' => null, + 'pdfPath' => null, ], [ 'title' => '6. Fluid Integration', @@ -86,7 +85,7 @@ class ElementSeeder extends Seeder . 'engender a shift in mindset, embed healthy routines, ' . 'positive life practices.', 'richText' => '', - 'shortPdfPath' => null, + 'pdfPath' => null, ], ]; @@ -98,8 +97,7 @@ class ElementSeeder extends Seeder description: $baderechChildElement['description'], iconImageUrl: null, richText: $baderechChildElement['richText'], - shortPdfPath: $baderechChildElement['shortPdfPath'], - longPdfPath: null, + pdfPath: $baderechChildElement['pdfPath'], youtubeUrl: null, parentElement: $rootElement, )); @@ -119,8 +117,7 @@ class ElementSeeder extends Seeder description: '', iconImageUrl: null, richText: '', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: 'https://www.youtube.com/watch?v=' . 'yHx-r4p6hHU&t=1s', parentElement: $introductionElement, diff --git a/backend/database/seeders/assets/element-pdfs/short/baderech.pdf b/backend/database/seeders/assets/element-pdfs/baderech.pdf similarity index 100% rename from backend/database/seeders/assets/element-pdfs/short/baderech.pdf rename to backend/database/seeders/assets/element-pdfs/baderech.pdf diff --git a/backend/tests/Fakes/FakeElementRepository.php b/backend/tests/Fakes/FakeElementRepository.php index 18f1a6b..9c08e1c 100644 --- a/backend/tests/Fakes/FakeElementRepository.php +++ b/backend/tests/Fakes/FakeElementRepository.php @@ -23,8 +23,7 @@ class FakeElementRepository implements ElementRepository description: $dto->description, iconImageUrl: $dto->iconImageUrl, richText: $dto->richText, - shortPdfPath: $dto->shortPdfPath, - longPdfPath: $dto->longPdfPath, + pdfPath: $dto->pdfPath, youtubeUrl: $dto->youtubeUrl, set: $dto->set, parentElement: $dto->parentElement, @@ -112,8 +111,7 @@ class FakeElementRepository implements ElementRepository description: $element->getDescription(), iconImageUrl: $element->getIconImageUrl(), richText: $element->getRichText(), - shortPdfPath: $element->getShortPdfPath(), - longPdfPath: $element->getLongPdfPath(), + pdfPath: $element->getPdfPath(), youtubeUrl: $element->getYoutubeUrl(), set: $element->getSet(), parentElement: $parentElement, diff --git a/backend/tests/Feature/DemoSeedDataTest.php b/backend/tests/Feature/DemoSeedDataTest.php index 4e96193..b802b2b 100644 --- a/backend/tests/Feature/DemoSeedDataTest.php +++ b/backend/tests/Feature/DemoSeedDataTest.php @@ -43,8 +43,7 @@ class DemoSeedDataTest extends TestCase Storage::disk('public')->assertExists( 'element-icons/baderech-haavodah-icon.png', ); - $this->assertNull($rootElement->getShortPdfPath()); - $this->assertNull($rootElement->getLongPdfPath()); + $this->assertNull($rootElement->getPdfPath()); $this->assertNull($rootElement->getYoutubeUrl()); $this->assertCount(6, $childElements); $this->assertSame( @@ -97,13 +96,10 @@ class DemoSeedDataTest extends TestCase $childElements[0]->getRichText(), ); $this->assertSame( - 'element-pdfs/short/baderech.pdf', - $childElements[0]->getShortPdfPath(), - ); - $this->assertNull($childElements[0]->getLongPdfPath()); - Storage::disk('public')->assertExists( - 'element-pdfs/short/baderech.pdf', + 'element-pdfs/baderech.pdf', + $childElements[0]->getPdfPath(), ); + Storage::disk('public')->assertExists('element-pdfs/baderech.pdf'); $introductionChildElements = $elementRepository->findByParentElement( $childElements[0], @@ -118,8 +114,7 @@ class DemoSeedDataTest extends TestCase $this->assertSame('', $introductionAudioElement->getDescription()); $this->assertNull($introductionAudioElement->getIconImageUrl()); $this->assertSame('', $introductionAudioElement->getRichText()); - $this->assertNull($introductionAudioElement->getShortPdfPath()); - $this->assertNull($introductionAudioElement->getLongPdfPath()); + $this->assertNull($introductionAudioElement->getPdfPath()); $this->assertSame( 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', $introductionAudioElement->getYoutubeUrl(), diff --git a/backend/tests/Feature/ElementsEndpointTest.php b/backend/tests/Feature/ElementsEndpointTest.php index cd17cd2..48292ce 100644 --- a/backend/tests/Feature/ElementsEndpointTest.php +++ b/backend/tests/Feature/ElementsEndpointTest.php @@ -5,10 +5,8 @@ namespace Tests\Feature; use App\Auth\CreateSessionDto; use App\Auth\SessionRepository; use App\Element\CreateElementDto; -use App\Element\Element; use App\Element\ElementRepository; use App\Set\CreateSetDto; -use App\Set\Set; use App\Set\SetRepository; use App\Shared\ValueObject\EmailAddress; use App\User\CreateUserDto; @@ -30,43 +28,41 @@ class ElementsEndpointTest extends TestCase . 'yHx-r4p6hHU&t=1s'; $setRepository = app(SetRepository::class); $elementRepository = app(ElementRepository::class); - $set = $this->createSet($setRepository); - $element = $this->createElement( - $elementRepository, - $set, - 'Baderech HaAvodah', - 'A structured path for growth', - '/assets/baderech-haavodah-icon.png', - '

A structured path for growth

', - '/assets/pdfs/baderech.pdf', - '/assets/pdfs/baderech-long.pdf', - $sampleYoutubeUrl, - null, - ); - $firstChildElement = $this->createElement( - $elementRepository, - $set, - 'Avodah Foundations', - 'Foundations for steady avodah', - null, - '

Foundations rich text

', - '/assets/pdfs/foundations.pdf', - null, - null, - $element, - ); - $secondChildElement = $this->createElement( - $elementRepository, - $set, - 'Daily Practice', - 'Daily practices for growth', - null, - '

Daily practice rich text

', - null, - null, - null, - $element, - ); + $set = $setRepository->create(new CreateSetDto( + name: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: '/assets/baderech-haavodah-icon.png', + )); + $element = $elementRepository->create(new CreateElementDto( + set: $set, + title: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: '/assets/baderech-haavodah-icon.png', + richText: '

A structured path for growth

', + pdfPath: '/assets/pdfs/baderech.pdf', + youtubeUrl: $sampleYoutubeUrl, + parentElement: null, + )); + $firstChildElement = $elementRepository->create(new CreateElementDto( + set: $set, + title: 'Avodah Foundations', + description: 'Foundations for steady avodah', + iconImageUrl: null, + richText: '

Foundations rich text

', + pdfPath: '/assets/pdfs/foundations.pdf', + youtubeUrl: null, + parentElement: $element, + )); + $secondChildElement = $elementRepository->create(new CreateElementDto( + set: $set, + title: 'Daily Practice', + description: 'Daily practices for growth', + iconImageUrl: null, + richText: '

Daily practice rich text

', + pdfPath: null, + youtubeUrl: null, + parentElement: $element, + )); $response = $this->getJson("/api/elements/{$element->getId()}"); @@ -90,8 +86,7 @@ class ElementsEndpointTest extends TestCase 'description' => 'A structured path for growth', 'iconImageUrl' => '/assets/baderech-haavodah-icon.png', 'richText' => '

A structured path for growth

', - 'shortPdfPath' => '/assets/pdfs/baderech.pdf', - 'longPdfPath' => '/assets/pdfs/baderech-long.pdf', + 'pdfPath' => '/assets/pdfs/baderech.pdf', 'youtubeUrl' => $sampleYoutubeUrl, ], ]); @@ -111,19 +106,21 @@ class ElementsEndpointTest extends TestCase { $setRepository = app(SetRepository::class); $elementRepository = app(ElementRepository::class); - $set = $this->createSet($setRepository); - $element = $this->createElement( - $elementRepository, - $set, - 'Baderech HaAvodah', - 'A structured path for growth', - '/assets/baderech-haavodah-icon.png', - '

A structured path for growth

', - '/assets/pdfs/baderech.pdf', - null, - null, - null, - ); + $set = $setRepository->create(new CreateSetDto( + name: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: '/assets/baderech-haavodah-icon.png', + )); + $element = $elementRepository->create(new CreateElementDto( + set: $set, + title: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: '/assets/baderech-haavodah-icon.png', + richText: '

A structured path for growth

', + pdfPath: '/assets/pdfs/baderech.pdf', + youtubeUrl: null, + parentElement: null, + )); $response = $this->postJson('/api/element/update', [ 'elementId' => $element->getId(), @@ -131,8 +128,7 @@ class ElementsEndpointTest extends TestCase 'description' => 'Updated description', 'iconImageUrl' => '/assets/updated-icon.png', 'richText' => '

Updated rich text

', - 'shortPdfPath' => '/assets/pdfs/updated.pdf', - 'longPdfPath' => '/assets/pdfs/updated-long.pdf', + 'pdfPath' => '/assets/pdfs/updated.pdf', 'youtubeUrl' => 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', ]); @@ -148,19 +144,21 @@ class ElementsEndpointTest extends TestCase . 'dQw4w9WgXcQ'; $setRepository = app(SetRepository::class); $elementRepository = app(ElementRepository::class); - $set = $this->createSet($setRepository); - $element = $this->createElement( - $elementRepository, - $set, - 'Baderech HaAvodah', - 'A structured path for growth', - '/assets/baderech-haavodah-icon.png', - '

A structured path for growth

', - '/assets/pdfs/baderech.pdf', - null, - null, - null, - ); + $set = $setRepository->create(new CreateSetDto( + name: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: '/assets/baderech-haavodah-icon.png', + )); + $element = $elementRepository->create(new CreateElementDto( + set: $set, + title: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: '/assets/baderech-haavodah-icon.png', + richText: '

A structured path for growth

', + pdfPath: '/assets/pdfs/baderech.pdf', + youtubeUrl: null, + parentElement: null, + )); $this->createSession('valid-token'); $response = $this->withCredentials() @@ -171,8 +169,7 @@ class ElementsEndpointTest extends TestCase 'description' => 'Updated description', 'iconImageUrl' => '/assets/updated-icon.png', 'richText' => '

Updated rich text

', - 'shortPdfPath' => '/assets/pdfs/updated.pdf', - 'longPdfPath' => '/assets/pdfs/updated-long.pdf', + 'pdfPath' => '/assets/pdfs/updated.pdf', 'youtubeUrl' => $sampleYoutubeUrl, ]); @@ -184,8 +181,7 @@ class ElementsEndpointTest extends TestCase 'description' => 'Updated description', 'iconImageUrl' => '/assets/updated-icon.png', 'richText' => '

Updated rich text

', - 'shortPdfPath' => '/assets/pdfs/updated.pdf', - 'longPdfPath' => '/assets/pdfs/updated-long.pdf', + 'pdfPath' => '/assets/pdfs/updated.pdf', 'youtubeUrl' => $sampleYoutubeUrl, ], ]); @@ -195,42 +191,6 @@ class ElementsEndpointTest extends TestCase '

Updated rich text

', $updatedElement->getRichText(), ); - $this->assertSame( - '/assets/pdfs/updated-long.pdf', - $updatedElement->getLongPdfPath(), - ); - } - - public function testAuthenticatedUpdateRejectsLegacyPdfPath(): void - { - $setRepository = app(SetRepository::class); - $elementRepository = app(ElementRepository::class); - $set = $this->createSet($setRepository); - $element = $this->createElement( - $elementRepository, - $set, - 'Baderech HaAvodah', - 'A structured path for growth', - null, - '

A structured path for growth

', - '/assets/pdfs/baderech.pdf', - '/assets/pdfs/baderech-long.pdf', - null, - null, - ); - $this->createSession('valid-token'); - - $response = $this->withCredentials() - ->withUnencryptedCookie('auth_token', 'valid-token') - ->postJson('/api/element/update', [ - 'elementId' => $element->getId(), - 'pdfPath' => '/assets/pdfs/legacy-updated.pdf', - ]); - - $response->assertBadRequest(); - $response->assertExactJson([ - 'error' => 'nothing to update', - ]); } public function testAuthenticatedUpdateClearsUploadedMedia(): void @@ -241,28 +201,26 @@ class ElementsEndpointTest extends TestCase 'icon bytes', ); Storage::disk('public')->put( - 'element-pdfs/short/original.pdf', - 'short pdf bytes', - ); - Storage::disk('public')->put( - 'element-pdfs/long/original-long.pdf', - 'long pdf bytes', + 'element-pdfs/original.pdf', + 'pdf bytes', ); $setRepository = app(SetRepository::class); $elementRepository = app(ElementRepository::class); - $set = $this->createSet($setRepository); - $element = $this->createElement( - $elementRepository, - $set, - 'Baderech HaAvodah', - 'A structured path for growth', - 'element-icons/original-icon.png', - '

A structured path for growth

', - 'element-pdfs/short/original.pdf', - 'element-pdfs/long/original-long.pdf', - null, - null, - ); + $set = $setRepository->create(new CreateSetDto( + name: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: '/assets/baderech-haavodah-icon.png', + )); + $element = $elementRepository->create(new CreateElementDto( + set: $set, + title: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: 'element-icons/original-icon.png', + richText: '

A structured path for growth

', + pdfPath: 'element-pdfs/original.pdf', + youtubeUrl: null, + parentElement: null, + )); $this->createSession('valid-token'); $response = $this->withCredentials() @@ -270,29 +228,22 @@ class ElementsEndpointTest extends TestCase ->postJson('/api/element/update', [ 'elementId' => $element->getId(), 'iconImageUrl' => '', - 'shortPdfPath' => '', - 'longPdfPath' => '', + 'pdfPath' => '', ]); $response->assertOk(); $body = $response->json(); $this->assertNull($body['element']['iconImageUrl']); - $this->assertNull($body['element']['shortPdfPath']); - $this->assertNull($body['element']['longPdfPath']); - $this->assertArrayNotHasKey('pdfPath', $body['element']); + $this->assertNull($body['element']['pdfPath']); $updatedElement = $elementRepository->find($element->getId()); $this->assertNotNull($updatedElement); $this->assertNull($updatedElement->getIconImageUrl()); - $this->assertNull($updatedElement->getShortPdfPath()); - $this->assertNull($updatedElement->getLongPdfPath()); + $this->assertNull($updatedElement->getPdfPath()); Storage::disk('public')->assertMissing( 'element-icons/original-icon.png', ); Storage::disk('public')->assertMissing( - 'element-pdfs/short/original.pdf', - ); - Storage::disk('public')->assertMissing( - 'element-pdfs/long/original-long.pdf', + 'element-pdfs/original.pdf', ); } @@ -300,26 +251,27 @@ class ElementsEndpointTest extends TestCase { $setRepository = app(SetRepository::class); $elementRepository = app(ElementRepository::class); - $set = $this->createSet($setRepository); - $element = $this->createElement( - $elementRepository, - $set, - 'Baderech HaAvodah', - 'A structured path for growth', - null, - '

A structured path for growth

', - null, - null, - null, - null, - ); + $set = $setRepository->create(new CreateSetDto( + name: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: '/assets/baderech-haavodah-icon.png', + )); + $element = $elementRepository->create(new CreateElementDto( + set: $set, + title: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: null, + richText: '

A structured path for growth

', + pdfPath: null, + youtubeUrl: null, + parentElement: null, + )); $response = $this->post( '/api/element/update', [ 'elementId' => (string) $element->getId(), - 'fileType' => 'iconImage', - 'file' => $this->iconImageUpload(), + 'iconImage' => $this->iconImageUpload(), ], ); @@ -329,24 +281,26 @@ class ElementsEndpointTest extends TestCase ]); } - public function testAuthenticatedIconImageUploadReturnsPayload(): void + public function testAuthenticatedIconImageUploadReturnsElementPayload(): void { Storage::fake('public'); $setRepository = app(SetRepository::class); $elementRepository = app(ElementRepository::class); - $set = $this->createSet($setRepository); - $element = $this->createElement( - $elementRepository, - $set, - 'Baderech HaAvodah', - 'A structured path for growth', - null, - '

A structured path for growth

', - null, - null, - null, - null, - ); + $set = $setRepository->create(new CreateSetDto( + name: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: '/assets/baderech-haavodah-icon.png', + )); + $element = $elementRepository->create(new CreateElementDto( + set: $set, + title: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: null, + richText: '

A structured path for growth

', + pdfPath: null, + youtubeUrl: null, + parentElement: null, + )); $this->createSession('valid-token'); $response = $this->withCredentials() @@ -355,8 +309,7 @@ class ElementsEndpointTest extends TestCase '/api/element/update', [ 'elementId' => (string) $element->getId(), - 'fileType' => 'iconImage', - 'file' => $this->iconImageUpload(), + 'iconImage' => $this->iconImageUpload(), ], ); @@ -378,30 +331,31 @@ class ElementsEndpointTest extends TestCase Storage::disk('public')->assertExists($updatedIconImageUrl); } - public function testShortPdfUploadRequiresAuthentication(): void + public function testPdfUploadRequiresAuthentication(): void { $setRepository = app(SetRepository::class); $elementRepository = app(ElementRepository::class); - $set = $this->createSet($setRepository); - $element = $this->createElement( - $elementRepository, - $set, - 'Baderech HaAvodah', - 'A structured path for growth', - null, - '

A structured path for growth

', - null, - null, - null, - null, - ); + $set = $setRepository->create(new CreateSetDto( + name: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: '/assets/baderech-haavodah-icon.png', + )); + $element = $elementRepository->create(new CreateElementDto( + set: $set, + title: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: null, + richText: '

A structured path for growth

', + pdfPath: null, + youtubeUrl: null, + parentElement: null, + )); $response = $this->post( '/api/element/update', [ 'elementId' => (string) $element->getId(), - 'fileType' => 'shortPdf', - 'file' => $this->pdfUpload(), + 'pdf' => $this->pdfUpload(), ], ); @@ -411,137 +365,51 @@ class ElementsEndpointTest extends TestCase ]); } - public function testAuthenticatedShortPdfUploadReturnsElementPayload(): void + public function testAuthenticatedPdfUploadReturnsElementPayload(): void { Storage::fake('public'); $setRepository = app(SetRepository::class); $elementRepository = app(ElementRepository::class); - $set = $this->createSet($setRepository); - $element = $this->createElement( - $elementRepository, - $set, - 'Baderech HaAvodah', - 'A structured path for growth', - null, - '

A structured path for growth

', - null, - null, - null, - null, - ); - $this->createSession('valid-token'); - - $response = $this->withCredentials() - ->withUnencryptedCookie('auth_token', 'valid-token') - ->post( - '/api/element/update', - [ - 'elementId' => (string) $element->getId(), - 'fileType' => 'shortPdf', - 'file' => $this->pdfUpload(), - ], - ); - - $response->assertOk(); - $body = $response->json(); - $this->assertSame($element->getId(), $body['element']['id']); - $this->assertStringContainsString( - '/storage/element-pdfs/short/', - $body['element']['shortPdfPath'], - ); - $this->assertArrayNotHasKey('pdfPath', $body['element']); - $updatedElement = $elementRepository->find($element->getId()); - $this->assertNotNull($updatedElement); - $updatedPdfPath = $updatedElement->getShortPdfPath(); - $this->assertIsString($updatedPdfPath); - $this->assertStringStartsWith( - 'element-pdfs/short/', - $updatedPdfPath, - ); - Storage::disk('public')->assertExists($updatedPdfPath); - } - - public function testAuthenticatedLongPdfUploadReturnsElementPayload(): void - { - Storage::fake('public'); - $setRepository = app(SetRepository::class); - $elementRepository = app(ElementRepository::class); - $set = $this->createSet($setRepository); - $element = $this->createElement( - $elementRepository, - $set, - 'Baderech HaAvodah', - 'A structured path for growth', - null, - '

A structured path for growth

', - null, - null, - null, - null, - ); - $this->createSession('valid-token'); - - $response = $this->withCredentials() - ->withUnencryptedCookie('auth_token', 'valid-token') - ->post( - '/api/element/update', - [ - 'elementId' => (string) $element->getId(), - 'fileType' => 'longPdf', - 'file' => $this->pdfUpload(), - ], - ); - - $response->assertOk(); - $body = $response->json(); - $this->assertSame($element->getId(), $body['element']['id']); - $this->assertStringContainsString( - '/storage/element-pdfs/long/', - $body['element']['longPdfPath'], - ); - $updatedElement = $elementRepository->find($element->getId()); - $this->assertNotNull($updatedElement); - $updatedPdfPath = $updatedElement->getLongPdfPath(); - $this->assertIsString($updatedPdfPath); - $this->assertStringStartsWith( - 'element-pdfs/long/', - $updatedPdfPath, - ); - Storage::disk('public')->assertExists($updatedPdfPath); - } - - private function createSet(SetRepository $setRepository): Set - { - return $setRepository->create(new CreateSetDto( + $set = $setRepository->create(new CreateSetDto( name: 'Baderech HaAvodah', description: 'A structured path for growth', iconImageUrl: '/assets/baderech-haavodah-icon.png', )); - } - - private function createElement( - ElementRepository $elementRepository, - Set $set, - string $title, - string $description, - ?string $iconImageUrl, - string $richText, - ?string $shortPdfPath, - ?string $longPdfPath, - ?string $youtubeUrl, - ?Element $parentElement, - ): Element { - return $elementRepository->create(new CreateElementDto( + $element = $elementRepository->create(new CreateElementDto( set: $set, - title: $title, - description: $description, - iconImageUrl: $iconImageUrl, - richText: $richText, - shortPdfPath: $shortPdfPath, - longPdfPath: $longPdfPath, - youtubeUrl: $youtubeUrl, - parentElement: $parentElement, + title: 'Baderech HaAvodah', + description: 'A structured path for growth', + iconImageUrl: null, + richText: '

A structured path for growth

', + pdfPath: null, + youtubeUrl: null, + parentElement: null, )); + $this->createSession('valid-token'); + + $response = $this->withCredentials() + ->withUnencryptedCookie('auth_token', 'valid-token') + ->post( + '/api/element/update', + [ + 'elementId' => (string) $element->getId(), + 'pdf' => $this->pdfUpload(), + ], + ); + + $response->assertOk(); + $body = $response->json(); + $this->assertSame($element->getId(), $body['element']['id']); + $this->assertStringContainsString( + '/storage/element-pdfs/', + $body['element']['pdfPath'], + ); + $updatedElement = $elementRepository->find($element->getId()); + $this->assertNotNull($updatedElement); + $updatedPdfPath = $updatedElement->getPdfPath(); + $this->assertIsString($updatedPdfPath); + $this->assertStringStartsWith('element-pdfs/', $updatedPdfPath); + Storage::disk('public')->assertExists($updatedPdfPath); } private function createSession(string $token): void diff --git a/backend/tests/Feature/SetsEndpointTest.php b/backend/tests/Feature/SetsEndpointTest.php index 2f8264b..c7c67c4 100644 --- a/backend/tests/Feature/SetsEndpointTest.php +++ b/backend/tests/Feature/SetsEndpointTest.php @@ -34,8 +34,7 @@ class SetsEndpointTest extends TestCase description: $baderechSet->getDescription(), iconImageUrl: null, richText: '', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElement: null, ) diff --git a/backend/tests/Unit/Controllers/ElementControllerTest.php b/backend/tests/Unit/Controllers/ElementControllerTest.php index 7d97527..5416d92 100644 --- a/backend/tests/Unit/Controllers/ElementControllerTest.php +++ b/backend/tests/Unit/Controllers/ElementControllerTest.php @@ -10,11 +10,9 @@ 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\UpdatePdf; +use App\Element\UseCases\UpdateElement\UpdatePdfPath; 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; @@ -42,18 +40,13 @@ class ElementControllerTest extends TestCase 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 UpdatePdfPath($this->elementRepo, $this->fileUploader), new UpdateYoutubeUrl($this->elementRepo), new UpdateIconImage( $this->elementRepo, $this->fileUploader, ), - new UpdateShortPdf( - $this->elementRepo, - $this->fileUploader, - ), - new UpdateLongPdf( + new UpdatePdf( $this->elementRepo, $this->fileUploader, ), @@ -76,7 +69,6 @@ class ElementControllerTest extends TestCase '/assets/baderech-icon.png', '

A structured path for growth

', '/assets/pdfs/baderech.pdf', - '/assets/pdfs/baderech-long.pdf', 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', null, ); @@ -88,7 +80,6 @@ class ElementControllerTest extends TestCase '

Foundations rich text

', '/assets/pdfs/foundations.pdf', null, - null, $element, ); $secondChildElement = $this->createElement( @@ -99,7 +90,6 @@ class ElementControllerTest extends TestCase '

Daily practice rich text

', null, null, - null, $element, ); @@ -123,13 +113,8 @@ class ElementControllerTest extends TestCase ); $this->assertSame( '/assets/pdfs/baderech.pdf', - $body['element']['shortPdfPath'], + $body['element']['pdfPath'], ); - $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'], @@ -173,13 +158,21 @@ class ElementControllerTest extends TestCase public function testUpdateWithIconImageReturnsElementPayload(): void { $set = $this->createSet(1, 'Baderech'); - $element = $this->createEmptyElement($set); + $element = $this->createElement( + $set, + 'Baderech HaAvodah', + 'A structured path for growth', + null, + '

A structured path for growth

', + null, + null, + null, + ); $fixturePath = __DIR__ . '/../../fixtures/icon.png'; $request = new Request([], [ 'elementId' => (string) $element->getId(), - 'fileType' => 'iconImage', ], [], [], [ - 'file' => new UploadedFile( + 'iconImage' => new UploadedFile( $fixturePath, 'icon.png', 'image/png', @@ -203,16 +196,24 @@ class ElementControllerTest extends TestCase ); } - public function testUpdateWithShortPdfReturnsElementPayload(): void + public function testUpdateWithPdfReturnsElementPayload(): void { $set = $this->createSet(1, 'Baderech'); - $element = $this->createEmptyElement($set); + $element = $this->createElement( + $set, + 'Baderech HaAvodah', + 'A structured path for growth', + null, + '

A structured path for growth

', + null, + null, + null, + ); $fixturePath = __DIR__ . '/../../fixtures/baderech.pdf'; $request = new Request([], [ 'elementId' => (string) $element->getId(), - 'fileType' => 'shortPdf', ], [], [], [ - 'file' => new UploadedFile( + 'pdf' => new UploadedFile( $fixturePath, 'baderech.pdf', 'application/pdf', @@ -227,45 +228,11 @@ class ElementControllerTest extends TestCase $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'], + 'https://test.local/storage/element-pdfs/fake-baderech.pdf', + $body['element']['pdfPath'], ); $this->assertSame( - 'element-pdfs/long', + 'element-pdfs', $this->fileUploader->uploads[0]['folder'], ); } @@ -280,29 +247,13 @@ class ElementControllerTest extends TestCase ); } - private function createEmptyElement(DomainSet $set): Element - { - return $this->createElement( - $set, - 'Baderech HaAvodah', - 'A structured path for growth', - null, - '

A structured path for growth

', - null, - null, - null, - null, - ); - } - private function createElement( DomainSet $set, string $title, string $description, ?string $iconImageUrl, string $richText, - ?string $shortPdfPath, - ?string $longPdfPath, + ?string $pdfPath, ?string $youtubeUrl, ?Element $parentElement, ): Element { @@ -312,8 +263,7 @@ class ElementControllerTest extends TestCase description: $description, iconImageUrl: $iconImageUrl, richText: $richText, - shortPdfPath: $shortPdfPath, - longPdfPath: $longPdfPath, + pdfPath: $pdfPath, youtubeUrl: $youtubeUrl, parentElement: $parentElement, )); diff --git a/backend/tests/Unit/Element/ElementTest.php b/backend/tests/Unit/Element/ElementTest.php index b57eaa5..89e9c84 100644 --- a/backend/tests/Unit/Element/ElementTest.php +++ b/backend/tests/Unit/Element/ElementTest.php @@ -22,8 +22,7 @@ class ElementTest extends TestCase description: 'Root description', iconImageUrl: null, richText: '

Root rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, set: $set, parentElement: null, @@ -34,8 +33,7 @@ class ElementTest extends TestCase description: 'Child description', iconImageUrl: '/assets/child-icon.svg', richText: '

Child rich text

', - shortPdfPath: '/assets/pdfs/child.pdf', - longPdfPath: '/assets/pdfs/child-long.pdf', + pdfPath: '/assets/pdfs/child.pdf', youtubeUrl: 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', set: $set, parentElement: $rootElement, @@ -57,11 +55,7 @@ class ElementTest extends TestCase ); $this->assertSame( '/assets/pdfs/child.pdf', - $childElement->getShortPdfPath(), - ); - $this->assertSame( - '/assets/pdfs/child-long.pdf', - $childElement->getLongPdfPath(), + $childElement->getPdfPath(), ); $this->assertSame( 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', @@ -70,8 +64,7 @@ class ElementTest extends TestCase $this->assertSame($set, $childElement->getSet()); $this->assertSame($rootElement, $childElement->getParentElement()); $this->assertNull($rootElement->getIconImageUrl()); - $this->assertNull($rootElement->getShortPdfPath()); - $this->assertNull($rootElement->getLongPdfPath()); + $this->assertNull($rootElement->getPdfPath()); $this->assertNull($rootElement->getYoutubeUrl()); $this->assertNull($rootElement->getParentElement()); } @@ -90,8 +83,7 @@ class ElementTest extends TestCase description: 'Original description', iconImageUrl: '/assets/original.svg', richText: '

Original

', - shortPdfPath: '/assets/pdfs/original.pdf', - longPdfPath: '/assets/pdfs/original-long.pdf', + pdfPath: '/assets/pdfs/original.pdf', youtubeUrl: 'https://www.youtube.com/watch?v=yHx-r4p6hHU', set: $set, parentElement: null, @@ -101,16 +93,14 @@ class ElementTest extends TestCase $element->setDescription('Updated description'); $element->setIconImageUrl(null); $element->setRichText('

Updated

'); - $element->setShortPdfPath(null); - $element->setLongPdfPath(null); + $element->setPdfPath(null); $element->setYoutubeUrl(null); $this->assertSame('Updated', $element->getTitle()); $this->assertSame('Updated description', $element->getDescription()); $this->assertNull($element->getIconImageUrl()); $this->assertSame('

Updated

', $element->getRichText()); - $this->assertNull($element->getShortPdfPath()); - $this->assertNull($element->getLongPdfPath()); + $this->assertNull($element->getPdfPath()); $this->assertNull($element->getYoutubeUrl()); } } diff --git a/backend/tests/Unit/Element/UseCases/CreateElementTest.php b/backend/tests/Unit/Element/UseCases/CreateElementTest.php index d13234b..09ad0d8 100644 --- a/backend/tests/Unit/Element/UseCases/CreateElementTest.php +++ b/backend/tests/Unit/Element/UseCases/CreateElementTest.php @@ -50,8 +50,7 @@ class CreateElementTest extends TestCase description: 'Root description', iconImageUrl: '/assets/root-icon.svg', richText: '

Root rich text

', - shortPdfPath: '/assets/pdfs/root.pdf', - longPdfPath: '/assets/pdfs/root-long.pdf', + pdfPath: '/assets/pdfs/root.pdf', youtubeUrl: 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', parentElementId: null, )); @@ -64,14 +63,7 @@ class CreateElementTest extends TestCase $element->getIconImageUrl(), ); $this->assertSame('

Root rich text

', $element->getRichText()); - $this->assertSame( - '/assets/pdfs/root.pdf', - $element->getShortPdfPath(), - ); - $this->assertSame( - '/assets/pdfs/root-long.pdf', - $element->getLongPdfPath(), - ); + $this->assertSame('/assets/pdfs/root.pdf', $element->getPdfPath()); $this->assertSame( 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', $element->getYoutubeUrl(), @@ -90,8 +82,7 @@ class CreateElementTest extends TestCase description: 'Root description', iconImageUrl: null, richText: '

Root rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElementId: null, ) @@ -104,8 +95,7 @@ class CreateElementTest extends TestCase description: 'Child description', iconImageUrl: '/assets/child-icon.svg', richText: '

Child rich text

', - shortPdfPath: '/assets/pdfs/child.pdf', - longPdfPath: '/assets/pdfs/child-long.pdf', + pdfPath: '/assets/pdfs/child.pdf', youtubeUrl: 'https://youtu.be/yHx-r4p6hHU', parentElementId: $rootElement->getId(), ) @@ -126,11 +116,7 @@ class CreateElementTest extends TestCase ); $this->assertSame( '/assets/pdfs/child.pdf', - $childElement->getShortPdfPath(), - ); - $this->assertSame( - '/assets/pdfs/child-long.pdf', - $childElement->getLongPdfPath(), + $childElement->getPdfPath(), ); $this->assertSame( 'https://youtu.be/yHx-r4p6hHU', @@ -152,8 +138,7 @@ class CreateElementTest extends TestCase description: null, iconImageUrl: null, richText: null, - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElementId: null, )); @@ -161,8 +146,7 @@ class CreateElementTest extends TestCase $this->assertSame('', $element->getDescription()); $this->assertNull($element->getIconImageUrl()); $this->assertSame('', $element->getRichText()); - $this->assertNull($element->getShortPdfPath()); - $this->assertNull($element->getLongPdfPath()); + $this->assertNull($element->getPdfPath()); $this->assertNull($element->getYoutubeUrl()); } @@ -176,8 +160,7 @@ class CreateElementTest extends TestCase description: 'Root description', iconImageUrl: '', richText: '

Root rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElementId: null, )); @@ -185,7 +168,7 @@ class CreateElementTest extends TestCase $this->assertNull($element->getIconImageUrl()); } - public function testCreatesElementWithNullPdfPathsWhenBlank(): void + public function testCreatesElementWithNullPdfPathWhenBlank(): void { $set = $this->createSet('Daily learning'); @@ -195,14 +178,12 @@ class CreateElementTest extends TestCase description: 'Root description', iconImageUrl: null, richText: '

Root rich text

', - shortPdfPath: '', - longPdfPath: '', + pdfPath: '', youtubeUrl: null, parentElementId: null, )); - $this->assertNull($element->getShortPdfPath()); - $this->assertNull($element->getLongPdfPath()); + $this->assertNull($element->getPdfPath()); } public function testCreatesElementWithNullYoutubeUrlWhenBlank(): void @@ -215,8 +196,7 @@ class CreateElementTest extends TestCase description: 'Root description', iconImageUrl: null, richText: '

Root rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: '', parentElementId: null, )); @@ -235,8 +215,7 @@ class CreateElementTest extends TestCase description: 'Root description', iconImageUrl: null, richText: '

Root rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElementId: null, )); @@ -253,8 +232,7 @@ class CreateElementTest extends TestCase description: 'Root description', iconImageUrl: null, richText: '

Root rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElementId: null, )); @@ -271,8 +249,7 @@ class CreateElementTest extends TestCase description: 'Root description', iconImageUrl: null, richText: '

Root rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElementId: null, )); @@ -293,8 +270,7 @@ class CreateElementTest extends TestCase description: 'Child description', iconImageUrl: null, richText: '

Child rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElementId: 99, )); @@ -309,8 +285,7 @@ class CreateElementTest extends TestCase description: 'Root description', iconImageUrl: null, richText: '

Root rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElementId: null, )); @@ -326,8 +301,7 @@ class CreateElementTest extends TestCase description: 'Another root description', iconImageUrl: null, richText: '

Another root rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElementId: null, )); @@ -344,8 +318,7 @@ class CreateElementTest extends TestCase description: 'Parent root description', iconImageUrl: null, richText: '

Parent root rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElementId: null, ) @@ -362,8 +335,7 @@ class CreateElementTest extends TestCase description: 'Invalid child description', iconImageUrl: null, richText: '

Invalid child rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElementId: $parentElement->getId(), )); diff --git a/backend/tests/Unit/Element/UseCases/GetElementTest.php b/backend/tests/Unit/Element/UseCases/GetElementTest.php index d4053f5..ff066de 100644 --- a/backend/tests/Unit/Element/UseCases/GetElementTest.php +++ b/backend/tests/Unit/Element/UseCases/GetElementTest.php @@ -60,7 +60,7 @@ class GetElementTest extends TestCase ); $this->assertSame( '/assets/pdfs/baderech.pdf', - $foundElement->getShortPdfPath(), + $foundElement->getPdfPath(), ); $this->assertSame( 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', @@ -191,7 +191,7 @@ class GetElementTest extends TestCase string $description, ?string $iconImageUrl, string $richText, - ?string $shortPdfPath, + ?string $pdfPath, ?string $youtubeUrl, ?Element $parentElement, ): Element { @@ -201,8 +201,7 @@ class GetElementTest extends TestCase description: $description, iconImageUrl: $iconImageUrl, richText: $richText, - shortPdfPath: $shortPdfPath, - longPdfPath: null, + pdfPath: $pdfPath, youtubeUrl: $youtubeUrl, parentElement: $parentElement, )); diff --git a/backend/tests/Unit/Element/UseCases/UpdateElementFieldsTest.php b/backend/tests/Unit/Element/UseCases/UpdateElementFieldsTest.php index 1d83906..ca39700 100644 --- a/backend/tests/Unit/Element/UseCases/UpdateElementFieldsTest.php +++ b/backend/tests/Unit/Element/UseCases/UpdateElementFieldsTest.php @@ -8,10 +8,8 @@ use App\Element\UseCases\UpdateElement\UpdateDescription; use App\Element\UseCases\UpdateElement\UpdateDescriptionRequest; use App\Element\UseCases\UpdateElement\UpdateIconImageUrl; use App\Element\UseCases\UpdateElement\UpdateIconImageUrlRequest; -use App\Element\UseCases\UpdateElement\UpdateLongPdfPath; -use App\Element\UseCases\UpdateElement\UpdateLongPdfPathRequest; -use App\Element\UseCases\UpdateElement\UpdateShortPdfPath; -use App\Element\UseCases\UpdateElement\UpdateShortPdfPathRequest; +use App\Element\UseCases\UpdateElement\UpdatePdfPath; +use App\Element\UseCases\UpdateElement\UpdatePdfPathRequest; use App\Element\UseCases\UpdateElement\UpdateRichText; use App\Element\UseCases\UpdateElement\UpdateRichTextRequest; use App\Element\UseCases\UpdateElement\UpdateTitle; @@ -136,26 +134,19 @@ class UpdateElementFieldsTest extends TestCase ); } - public function testUpdateShortPdfPathClearsEmptyString(): void + public function testUpdatePdfPathClearsEmptyString(): void { $element = $this->createFilledElement(); - $updateShortPdfPath = new UpdateShortPdfPath( + $updatePdfPath = new UpdatePdfPath( $this->elementRepo, $this->fileUploader, ); - $updatedElement = $updateShortPdfPath->execute( - new UpdateShortPdfPathRequest( - id: $element->getId(), - shortPdfPath: '', - ) + $updatedElement = $updatePdfPath->execute( + new UpdatePdfPathRequest(id: $element->getId(), pdfPath: '') ); - $this->assertNull($updatedElement->getShortPdfPath()); - $this->assertSame( - '/assets/pdfs/original-long.pdf', - $updatedElement->getLongPdfPath(), - ); + $this->assertNull($updatedElement->getPdfPath()); $this->assertSame($element->getTitle(), $updatedElement->getTitle()); $this->assertSame( ['/assets/pdfs/original.pdf'], @@ -163,33 +154,6 @@ class UpdateElementFieldsTest extends TestCase ); } - public function testUpdateLongPdfPathClearsEmptyString(): void - { - $element = $this->createFilledElement(); - $updateLongPdfPath = new UpdateLongPdfPath( - $this->elementRepo, - $this->fileUploader, - ); - - $updatedElement = $updateLongPdfPath->execute( - new UpdateLongPdfPathRequest( - id: $element->getId(), - longPdfPath: '', - ) - ); - - $this->assertSame( - '/assets/pdfs/original.pdf', - $updatedElement->getShortPdfPath(), - ); - $this->assertNull($updatedElement->getLongPdfPath()); - $this->assertSame($element->getTitle(), $updatedElement->getTitle()); - $this->assertSame( - ['/assets/pdfs/original-long.pdf'], - $this->fileUploader->deletedPaths, - ); - } - public function testUpdateYoutubeUrlClearsEmptyString(): void { $element = $this->createFilledElement(); @@ -211,14 +175,12 @@ class UpdateElementFieldsTest extends TestCase return $this->createElementWithMedia( '/assets/original-icon.png', '/assets/pdfs/original.pdf', - '/assets/pdfs/original-long.pdf', ); } private function createElementWithMedia( ?string $iconImageUrl, - ?string $shortPdfPath, - ?string $longPdfPath, + ?string $pdfPath, ): Element { $set = new DomainSet( id: 1, @@ -233,8 +195,7 @@ class UpdateElementFieldsTest extends TestCase description: 'Original description', iconImageUrl: $iconImageUrl, richText: '

Original rich text

', - shortPdfPath: $shortPdfPath, - longPdfPath: $longPdfPath, + pdfPath: $pdfPath, youtubeUrl: 'https://www.youtube.com/watch?v=yHx-r4p6hHU', parentElement: null, )); diff --git a/backend/tests/Unit/Element/UseCases/UpdateElementTest.php b/backend/tests/Unit/Element/UseCases/UpdateElementTest.php index 6804e7a..8d823e3 100644 --- a/backend/tests/Unit/Element/UseCases/UpdateElementTest.php +++ b/backend/tests/Unit/Element/UseCases/UpdateElementTest.php @@ -9,11 +9,9 @@ use App\Element\UseCases\UpdateElement\UpdateElement; use App\Element\UseCases\UpdateElement\UpdateElementRequest; 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\UpdatePdfPath; +use App\Element\UseCases\UpdateElement\UpdatePdf; 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\Exceptions\BadRequestException; @@ -40,18 +38,13 @@ class UpdateElementTest extends TestCase 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 UpdatePdfPath($this->elementRepo, $this->fileUploader), new UpdateYoutubeUrl($this->elementRepo), new UpdateIconImage( $this->elementRepo, $this->fileUploader, ), - new UpdateShortPdf( - $this->elementRepo, - $this->fileUploader, - ), - new UpdateLongPdf( + new UpdatePdf( $this->elementRepo, $this->fileUploader, ), @@ -69,7 +62,6 @@ class UpdateElementTest extends TestCase '/assets/original-icon.png', '

Original rich text

', '/assets/pdfs/original.pdf', - '/assets/pdfs/original-long.pdf', 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', null, ); @@ -81,14 +73,16 @@ class UpdateElementTest extends TestCase description: 'Updated description', iconImageUrl: '/assets/updated-icon.png', richText: '

Updated rich text

', - shortPdfPath: '/assets/pdfs/updated.pdf', - longPdfPath: '/assets/pdfs/updated-long.pdf', + pdfPath: '/assets/pdfs/updated.pdf', youtubeUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', - fileType: null, - fileContents: null, - fileOriginalName: null, - fileMimeType: null, - fileSizeBytes: null, + iconImageContents: null, + iconImageOriginalName: null, + iconImageMimeType: null, + iconImageSizeBytes: null, + pdfContents: null, + pdfOriginalName: null, + pdfMimeType: null, + pdfSizeBytes: null, ) ); @@ -108,11 +102,7 @@ class UpdateElementTest extends TestCase ); $this->assertSame( '/assets/pdfs/updated.pdf', - $updatedElement->getShortPdfPath(), - ); - $this->assertSame( - '/assets/pdfs/updated-long.pdf', - $updatedElement->getLongPdfPath(), + $updatedElement->getPdfPath(), ); $this->assertSame( 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', @@ -134,7 +124,6 @@ class UpdateElementTest extends TestCase '/assets/original-icon.png', '

Original rich text

', '/assets/pdfs/original.pdf', - '/assets/pdfs/original-long.pdf', 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', null, ); @@ -146,20 +135,21 @@ class UpdateElementTest extends TestCase description: 'Updated description', iconImageUrl: '', richText: '

Updated rich text

', - shortPdfPath: '', - longPdfPath: '', + pdfPath: '', youtubeUrl: '', - fileType: null, - fileContents: null, - fileOriginalName: null, - fileMimeType: null, - fileSizeBytes: null, + iconImageContents: null, + iconImageOriginalName: null, + iconImageMimeType: null, + iconImageSizeBytes: null, + pdfContents: null, + pdfOriginalName: null, + pdfMimeType: null, + pdfSizeBytes: null, ) ); $this->assertNull($updatedElement->getIconImageUrl()); - $this->assertNull($updatedElement->getShortPdfPath()); - $this->assertNull($updatedElement->getLongPdfPath()); + $this->assertNull($updatedElement->getPdfPath()); $this->assertNull($updatedElement->getYoutubeUrl()); } @@ -173,7 +163,6 @@ class UpdateElementTest extends TestCase '/assets/original-icon.png', '

Original rich text

', '/assets/pdfs/original.pdf', - '/assets/pdfs/original-long.pdf', 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', null, ); @@ -185,14 +174,16 @@ class UpdateElementTest extends TestCase description: null, iconImageUrl: null, richText: null, - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, - fileType: null, - fileContents: null, - fileOriginalName: null, - fileMimeType: null, - fileSizeBytes: null, + iconImageContents: null, + iconImageOriginalName: null, + iconImageMimeType: null, + iconImageSizeBytes: null, + pdfContents: null, + pdfOriginalName: null, + pdfMimeType: null, + pdfSizeBytes: null, ) ); @@ -211,11 +202,7 @@ class UpdateElementTest extends TestCase ); $this->assertSame( '/assets/pdfs/original.pdf', - $updatedElement->getShortPdfPath(), - ); - $this->assertSame( - '/assets/pdfs/original-long.pdf', - $updatedElement->getLongPdfPath(), + $updatedElement->getPdfPath(), ); $this->assertSame( 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', @@ -223,7 +210,7 @@ class UpdateElementTest extends TestCase ); } - public function testRoutesUploadedFilesByFileType(): void + public function testUpdatesUploadedFiles(): void { $set = $this->createSet(1, 'Baderech'); $element = $this->createElement( @@ -235,39 +222,8 @@ class UpdateElementTest extends TestCase null, null, null, - null, ); - $this->updateElement->execute(new UpdateElementRequest( - id: $element->getId(), - title: null, - description: null, - iconImageUrl: null, - richText: null, - shortPdfPath: null, - longPdfPath: null, - youtubeUrl: null, - fileType: 'iconImage', - fileContents: 'binary-image-bytes', - fileOriginalName: 'icon.png', - fileMimeType: 'image/png', - fileSizeBytes: 1024, - )); - $this->updateElement->execute(new UpdateElementRequest( - id: $element->getId(), - title: null, - description: null, - iconImageUrl: null, - richText: null, - shortPdfPath: null, - longPdfPath: null, - youtubeUrl: null, - fileType: 'shortPdf', - fileContents: 'binary-short-pdf-bytes', - fileOriginalName: 'baderech.pdf', - fileMimeType: 'application/pdf', - fileSizeBytes: 1024, - )); $updatedElement = $this->updateElement->execute( new UpdateElementRequest( id: $element->getId(), @@ -275,14 +231,16 @@ class UpdateElementTest extends TestCase description: null, iconImageUrl: null, richText: null, - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, - fileType: 'longPdf', - fileContents: 'binary-long-pdf-bytes', - fileOriginalName: 'baderech-long.pdf', - fileMimeType: 'application/pdf', - fileSizeBytes: 1024, + iconImageContents: 'binary-image-bytes', + iconImageOriginalName: 'icon.png', + iconImageMimeType: 'image/png', + iconImageSizeBytes: 1024, + pdfContents: 'binary-pdf-bytes', + pdfOriginalName: 'baderech.pdf', + pdfMimeType: 'application/pdf', + pdfSizeBytes: 1024, ) ); @@ -291,69 +249,17 @@ class UpdateElementTest extends TestCase $updatedElement->getIconImageUrl(), ); $this->assertSame( - 'element-pdfs/short/fake-baderech.pdf', - $updatedElement->getShortPdfPath(), - ); - $this->assertSame( - 'element-pdfs/long/fake-baderech-long.pdf', - $updatedElement->getLongPdfPath(), + 'element-pdfs/fake-baderech.pdf', + $updatedElement->getPdfPath(), ); $this->assertSame( 'element-icons', $this->fileUploader->uploads[0]['folder'], ); $this->assertSame( - 'element-pdfs/short', + 'element-pdfs', $this->fileUploader->uploads[1]['folder'], ); - $this->assertSame( - 'element-pdfs/long', - $this->fileUploader->uploads[2]['folder'], - ); - } - - public function testThrowsWhenFileTypeMissingForUpload(): void - { - $this->expectException(BadRequestException::class); - $this->expectExceptionMessage('fileType is required'); - - $this->updateElement->execute(new UpdateElementRequest( - id: 1, - title: null, - description: null, - iconImageUrl: null, - richText: null, - shortPdfPath: null, - longPdfPath: null, - youtubeUrl: null, - fileType: null, - fileContents: 'binary-image-bytes', - fileOriginalName: 'icon.png', - fileMimeType: 'image/png', - fileSizeBytes: 1024, - )); - } - - public function testThrowsWhenFileTypeInvalid(): void - { - $this->expectException(BadRequestException::class); - $this->expectExceptionMessage('fileType is invalid'); - - $this->updateElement->execute(new UpdateElementRequest( - id: 1, - title: null, - description: null, - iconImageUrl: null, - richText: null, - shortPdfPath: null, - longPdfPath: null, - youtubeUrl: null, - fileType: 'audio', - fileContents: 'binary-audio-bytes', - fileOriginalName: 'shiur.mp3', - fileMimeType: 'audio/mpeg', - fileSizeBytes: 1024, - )); } public function testThrowsWhenIdMissing(): void @@ -367,14 +273,16 @@ class UpdateElementTest extends TestCase description: 'Updated description', iconImageUrl: null, richText: '

Updated rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, - fileType: null, - fileContents: null, - fileOriginalName: null, - fileMimeType: null, - fileSizeBytes: null, + iconImageContents: null, + iconImageOriginalName: null, + iconImageMimeType: null, + iconImageSizeBytes: null, + pdfContents: null, + pdfOriginalName: null, + pdfMimeType: null, + pdfSizeBytes: null, )); } @@ -389,14 +297,16 @@ class UpdateElementTest extends TestCase description: null, iconImageUrl: null, richText: null, - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, - fileType: null, - fileContents: null, - fileOriginalName: null, - fileMimeType: null, - fileSizeBytes: null, + iconImageContents: null, + iconImageOriginalName: null, + iconImageMimeType: null, + iconImageSizeBytes: null, + pdfContents: null, + pdfOriginalName: null, + pdfMimeType: null, + pdfSizeBytes: null, )); } @@ -411,14 +321,16 @@ class UpdateElementTest extends TestCase description: 'Updated description', iconImageUrl: null, richText: '

Updated rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, - fileType: null, - fileContents: null, - fileOriginalName: null, - fileMimeType: null, - fileSizeBytes: null, + iconImageContents: null, + iconImageOriginalName: null, + iconImageMimeType: null, + iconImageSizeBytes: null, + pdfContents: null, + pdfOriginalName: null, + pdfMimeType: null, + pdfSizeBytes: null, )); } @@ -433,14 +345,16 @@ class UpdateElementTest extends TestCase description: 'Updated description', iconImageUrl: null, richText: '

Updated rich text

', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, - fileType: null, - fileContents: null, - fileOriginalName: null, - fileMimeType: null, - fileSizeBytes: null, + iconImageContents: null, + iconImageOriginalName: null, + iconImageMimeType: null, + iconImageSizeBytes: null, + pdfContents: null, + pdfOriginalName: null, + pdfMimeType: null, + pdfSizeBytes: null, )); } @@ -460,8 +374,7 @@ class UpdateElementTest extends TestCase string $description, ?string $iconImageUrl, string $richText, - ?string $shortPdfPath, - ?string $longPdfPath, + ?string $pdfPath, ?string $youtubeUrl, ?Element $parentElement, ): Element { @@ -471,8 +384,7 @@ class UpdateElementTest extends TestCase description: $description, iconImageUrl: $iconImageUrl, richText: $richText, - shortPdfPath: $shortPdfPath, - longPdfPath: $longPdfPath, + pdfPath: $pdfPath, youtubeUrl: $youtubeUrl, parentElement: $parentElement, )); diff --git a/backend/tests/Unit/Element/UseCases/UpdateIconImageTest.php b/backend/tests/Unit/Element/UseCases/UpdateIconImageTest.php index 2aef04a..af8ae7f 100644 --- a/backend/tests/Unit/Element/UseCases/UpdateIconImageTest.php +++ b/backend/tests/Unit/Element/UseCases/UpdateIconImageTest.php @@ -33,19 +33,19 @@ class UpdateIconImageTest extends TestCase /** * @return array{ - * fileContents: string, - * fileOriginalName: string, - * fileMimeType: string, - * fileSizeBytes: int + * iconImageContents: string, + * iconImageOriginalName: string, + * iconImageMimeType: string, + * iconImageSizeBytes: int * } */ private function imageArgs(): array { return [ - 'fileContents' => 'binary-image-bytes', - 'fileOriginalName' => 'icon.png', - 'fileMimeType' => 'image/png', - 'fileSizeBytes' => 1024, + 'iconImageContents' => 'binary-image-bytes', + 'iconImageOriginalName' => 'icon.png', + 'iconImageMimeType' => 'image/png', + 'iconImageSizeBytes' => 1024, ]; } @@ -97,10 +97,10 @@ class UpdateIconImageTest extends TestCase $this->useCase->execute( new UpdateIconImageRequest( id: 1, - fileContents: null, - fileOriginalName: null, - fileMimeType: null, - fileSizeBytes: null, + iconImageContents: null, + iconImageOriginalName: null, + iconImageMimeType: null, + iconImageSizeBytes: null, ) ); } @@ -115,10 +115,10 @@ class UpdateIconImageTest extends TestCase $this->useCase->execute( new UpdateIconImageRequest( id: 1, - fileContents: 'not-an-image', - fileOriginalName: 'icon.pdf', - fileMimeType: 'application/pdf', - fileSizeBytes: 1024, + iconImageContents: 'not-an-image', + iconImageOriginalName: 'icon.pdf', + iconImageMimeType: 'application/pdf', + iconImageSizeBytes: 1024, ) ); } @@ -131,10 +131,10 @@ class UpdateIconImageTest extends TestCase $this->useCase->execute( new UpdateIconImageRequest( id: 1, - fileContents: 'big', - fileOriginalName: 'icon.png', - fileMimeType: 'image/png', - fileSizeBytes: 6 * 1024 * 1024, + iconImageContents: 'big', + iconImageOriginalName: 'icon.png', + iconImageMimeType: 'image/png', + iconImageSizeBytes: 6 * 1024 * 1024, ) ); } @@ -167,8 +167,7 @@ class UpdateIconImageTest extends TestCase description: 'Original description', iconImageUrl: null, richText: '', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElement: null, )); diff --git a/backend/tests/Unit/Element/UseCases/UpdateLongPdfTest.php b/backend/tests/Unit/Element/UseCases/UpdateLongPdfTest.php deleted file mode 100644 index ba34617..0000000 --- a/backend/tests/Unit/Element/UseCases/UpdateLongPdfTest.php +++ /dev/null @@ -1,95 +0,0 @@ -elementRepository = new FakeElementRepository(); - $this->fileUploader = new FakeFileUploader(); - $this->useCase = new UpdateLongPdf( - $this->elementRepository, - $this->fileUploader, - ); - } - - public function testUploadsLongPdfAndStoresPath(): void - { - $element = $this->createElement(); - - $updatedElement = $this->useCase->execute( - new UpdateLongPdfRequest( - id: $element->getId(), - fileContents: 'binary-pdf-bytes', - fileOriginalName: 'baderech-long.pdf', - fileMimeType: 'application/pdf', - fileSizeBytes: 1024, - ) - ); - - $this->assertNull($updatedElement->getShortPdfPath()); - $this->assertSame( - 'element-pdfs/long/fake-baderech-long.pdf', - $updatedElement->getLongPdfPath(), - ); - $this->assertSame( - 'element-pdfs/long', - $this->fileUploader->uploads[0]['folder'], - ); - } - - public function testDisallowedMimeThrowsBadRequest(): void - { - $this->expectException(BadRequestException::class); - $this->expectExceptionMessage('pdf must be a pdf file'); - - $this->useCase->execute( - new UpdateLongPdfRequest( - id: 1, - fileContents: 'not-a-pdf', - fileOriginalName: 'icon.png', - fileMimeType: 'image/png', - fileSizeBytes: 1024, - ) - ); - } - - private function createElement(): Element - { - $set = new DomainSet( - id: 1, - name: 'Baderech', - description: 'Baderech description', - iconImageUrl: '/assets/baderech-icon.png', - ); - - return $this->elementRepository->create(new CreateElementDto( - set: $set, - title: 'Original title', - description: 'Original description', - iconImageUrl: null, - richText: '', - shortPdfPath: null, - longPdfPath: null, - youtubeUrl: null, - parentElement: null, - )); - } -} diff --git a/backend/tests/Unit/Element/UseCases/UpdateShortPdfTest.php b/backend/tests/Unit/Element/UseCases/UpdatePdfTest.php similarity index 65% rename from backend/tests/Unit/Element/UseCases/UpdateShortPdfTest.php rename to backend/tests/Unit/Element/UseCases/UpdatePdfTest.php index 9cea03a..9a3b30b 100644 --- a/backend/tests/Unit/Element/UseCases/UpdateShortPdfTest.php +++ b/backend/tests/Unit/Element/UseCases/UpdatePdfTest.php @@ -4,8 +4,8 @@ namespace Tests\Unit\Element\UseCases; use App\Element\CreateElementDto; use App\Element\Element; -use App\Element\UseCases\UpdateElement\UpdateShortPdf; -use App\Element\UseCases\UpdateElement\UpdateShortPdfRequest; +use App\Element\UseCases\UpdateElement\UpdatePdf; +use App\Element\UseCases\UpdateElement\UpdatePdfRequest; use App\Exceptions\BadRequestException; use App\Exceptions\NotFoundException; use App\Set\Set as DomainSet; @@ -13,19 +13,19 @@ use Tests\Fakes\FakeElementRepository; use Tests\Fakes\FakeFileUploader; use Tests\TestCase; -class UpdateShortPdfTest extends TestCase +class UpdatePdfTest extends TestCase { private FakeElementRepository $elementRepository; private FakeFileUploader $fileUploader; - private UpdateShortPdf $useCase; + private UpdatePdf $useCase; protected function setUp(): void { $this->elementRepository = new FakeElementRepository(); $this->fileUploader = new FakeFileUploader(); - $this->useCase = new UpdateShortPdf( + $this->useCase = new UpdatePdf( $this->elementRepository, $this->fileUploader, ); @@ -33,46 +33,45 @@ class UpdateShortPdfTest extends TestCase /** * @return array{ - * fileContents: string, - * fileOriginalName: string, - * fileMimeType: string, - * fileSizeBytes: int + * pdfContents: string, + * pdfOriginalName: string, + * pdfMimeType: string, + * pdfSizeBytes: int * } */ private function pdfArgs(): array { return [ - 'fileContents' => 'binary-pdf-bytes', - 'fileOriginalName' => 'baderech.pdf', - 'fileMimeType' => 'application/pdf', - 'fileSizeBytes' => 1024, + 'pdfContents' => 'binary-pdf-bytes', + 'pdfOriginalName' => 'baderech.pdf', + 'pdfMimeType' => 'application/pdf', + 'pdfSizeBytes' => 1024, ]; } - public function testUploadsShortPdfAndStoresPath(): void + public function testUploadsPdfAndStoresPath(): void { $element = $this->createElement(); $updatedElement = $this->useCase->execute( - new UpdateShortPdfRequest( + new UpdatePdfRequest( ...$this->pdfArgs(), id: $element->getId(), ) ); $this->assertSame( - 'element-pdfs/short/fake-baderech.pdf', - $updatedElement->getShortPdfPath(), + 'element-pdfs/fake-baderech.pdf', + $updatedElement->getPdfPath(), ); - $this->assertNull($updatedElement->getLongPdfPath()); $storedElement = $this->elementRepository->find($element->getId()); $this->assertNotNull($storedElement); $this->assertSame( - 'element-pdfs/short/fake-baderech.pdf', - $storedElement->getShortPdfPath(), + 'element-pdfs/fake-baderech.pdf', + $storedElement->getPdfPath(), ); $this->assertSame( - 'element-pdfs/short', + 'element-pdfs', $this->fileUploader->uploads[0]['folder'], ); } @@ -83,7 +82,7 @@ class UpdateShortPdfTest extends TestCase $this->expectExceptionMessage('id is required'); $this->useCase->execute( - new UpdateShortPdfRequest( + new UpdatePdfRequest( ...$this->pdfArgs(), id: null, ) @@ -96,12 +95,12 @@ class UpdateShortPdfTest extends TestCase $this->expectExceptionMessage('pdf is required'); $this->useCase->execute( - new UpdateShortPdfRequest( + new UpdatePdfRequest( id: 1, - fileContents: null, - fileOriginalName: null, - fileMimeType: null, - fileSizeBytes: null, + pdfContents: null, + pdfOriginalName: null, + pdfMimeType: null, + pdfSizeBytes: null, ) ); } @@ -112,12 +111,12 @@ class UpdateShortPdfTest extends TestCase $this->expectExceptionMessage('pdf must be a pdf file'); $this->useCase->execute( - new UpdateShortPdfRequest( + new UpdatePdfRequest( id: 1, - fileContents: 'not-a-pdf', - fileOriginalName: 'icon.png', - fileMimeType: 'image/png', - fileSizeBytes: 1024, + pdfContents: 'not-a-pdf', + pdfOriginalName: 'icon.png', + pdfMimeType: 'image/png', + pdfSizeBytes: 1024, ) ); } @@ -128,12 +127,12 @@ class UpdateShortPdfTest extends TestCase $this->expectExceptionMessage('pdf must be 10MB or smaller'); $this->useCase->execute( - new UpdateShortPdfRequest( + new UpdatePdfRequest( id: 1, - fileContents: 'big', - fileOriginalName: 'baderech.pdf', - fileMimeType: 'application/pdf', - fileSizeBytes: 11 * 1024 * 1024, + pdfContents: 'big', + pdfOriginalName: 'baderech.pdf', + pdfMimeType: 'application/pdf', + pdfSizeBytes: 11 * 1024 * 1024, ) ); } @@ -144,7 +143,7 @@ class UpdateShortPdfTest extends TestCase $this->expectExceptionMessage('Element not found'); $this->useCase->execute( - new UpdateShortPdfRequest( + new UpdatePdfRequest( ...$this->pdfArgs(), id: 999, ) @@ -166,8 +165,7 @@ class UpdateShortPdfTest extends TestCase description: 'Original description', iconImageUrl: null, richText: '', - shortPdfPath: null, - longPdfPath: null, + pdfPath: null, youtubeUrl: null, parentElement: null, )); diff --git a/frontend/rabbi_gerzi/cypress/e2e/admin-element.cy.ts b/frontend/rabbi_gerzi/cypress/e2e/admin-element.cy.ts index c6ab389..38dc7a1 100644 --- a/frontend/rabbi_gerzi/cypress/e2e/admin-element.cy.ts +++ b/frontend/rabbi_gerzi/cypress/e2e/admin-element.cy.ts @@ -126,45 +126,28 @@ describe('admin element editing', () => { .and('have.attr', 'src') .and('include', '/storage/element-icons/') - cy.get('[data-cy="admin-element-short-pdf-input"]').selectFile( + cy.get('[data-cy="admin-element-pdf-input"]').selectFile( 'public/assets/pdfs/baderech.pdf', { force: true }, ) cy.wait('@updateElement') - cy.get('[data-cy="admin-element-short-pdf-status"]') + cy.get('[data-cy="admin-element-pdf-status"]') .should('be.visible') - .and('contain.text', 'Short PDF updated') - cy.get('[data-cy="admin-element-current-short-pdf"]') + .and('contain.text', 'PDF updated') + cy.get('[data-cy="admin-element-current-pdf"]') .should('be.visible') .and('have.attr', 'href') - .and('include', '/storage/element-pdfs/short/') - - cy.get('[data-cy="admin-element-long-pdf-input"]').selectFile( - 'public/assets/pdfs/baderech.pdf', - { force: true }, - ) - cy.wait('@updateElement') - cy.get('[data-cy="admin-element-long-pdf-status"]') - .should('be.visible') - .and('contain.text', 'Long PDF updated') - cy.get('[data-cy="admin-element-current-long-pdf"]') - .should('be.visible') - .and('have.attr', 'href') - .and('include', '/storage/element-pdfs/long/') + .and('include', '/storage/element-pdfs/') cy.contains('header.site-header a', 'View Element').click() cy.get('[data-cy="element-icon"]') .should('be.visible') .and('have.attr', 'src') .and('include', '/storage/element-icons/') - cy.get('[data-cy="element-short-pdf-link"]') + cy.get('[data-cy="element-pdf-link"]') .should('be.visible') .and('have.attr', 'href') - .and('include', '/storage/element-pdfs/short/') - cy.get('[data-cy="element-long-pdf-link"]') - .should('be.visible') - .and('have.attr', 'href') - .and('include', '/storage/element-pdfs/long/') + .and('include', '/storage/element-pdfs/') cy.resetDb() }) @@ -180,12 +163,7 @@ describe('admin element editing', () => { { force: true }, ) cy.wait('@updateElement') - cy.get('[data-cy="admin-element-short-pdf-input"]').selectFile( - 'public/assets/pdfs/baderech.pdf', - { force: true }, - ) - cy.wait('@updateElement') - cy.get('[data-cy="admin-element-long-pdf-input"]').selectFile( + cy.get('[data-cy="admin-element-pdf-input"]').selectFile( 'public/assets/pdfs/baderech.pdf', { force: true }, ) @@ -199,26 +177,17 @@ describe('admin element editing', () => { cy.get('[data-cy="admin-element-current-icon"]').should('not.exist') cy.contains('No icon image').should('be.visible') - cy.contains('button', 'Remove short PDF').click() + cy.contains('button', 'Remove PDF').click() cy.wait('@updateElement') - cy.get('[data-cy="admin-element-short-pdf-status"]') + cy.get('[data-cy="admin-element-pdf-status"]') .should('be.visible') - .and('contain.text', 'Short PDF removed') - cy.get('[data-cy="admin-element-current-short-pdf"]').should('not.exist') - cy.contains('No short PDF').should('be.visible') - - cy.contains('button', 'Remove long PDF').click() - cy.wait('@updateElement') - cy.get('[data-cy="admin-element-long-pdf-status"]') - .should('be.visible') - .and('contain.text', 'Long PDF removed') - cy.get('[data-cy="admin-element-current-long-pdf"]').should('not.exist') - cy.contains('No long PDF').should('be.visible') + .and('contain.text', 'PDF removed') + cy.get('[data-cy="admin-element-current-pdf"]').should('not.exist') + cy.contains('No PDF').should('be.visible') cy.contains('header.site-header a', 'View Element').click() cy.get('[data-cy="element-icon"]').should('not.exist') - cy.get('[data-cy="element-short-pdf-link"]').should('not.exist') - cy.get('[data-cy="element-long-pdf-link"]').should('not.exist') + cy.get('[data-cy="element-pdf-link"]').should('not.exist') cy.resetDb() }) diff --git a/frontend/rabbi_gerzi/cypress/e2e/media.cy.ts b/frontend/rabbi_gerzi/cypress/e2e/media.cy.ts index 805be28..e0f361a 100644 --- a/frontend/rabbi_gerzi/cypress/e2e/media.cy.ts +++ b/frontend/rabbi_gerzi/cypress/e2e/media.cy.ts @@ -51,8 +51,7 @@ describe('media page sets', () => { cy.get('[data-cy="element-rich-text"]').should('not.exist') cy.get('[data-cy="element-youtube-embed"]') .should('not.exist') - cy.get('[data-cy="element-short-pdf-link"]').should('not.exist') - cy.get('[data-cy="element-long-pdf-link"]').should('not.exist') + cy.get('[data-cy="element-pdf-link"]').should('not.exist') cy.get('[data-cy="child-element-list"]').should('be.visible') cy.get('[data-cy="child-element-list"]') .should( @@ -117,14 +116,13 @@ describe('media page sets', () => { ) .should('have.css', 'text-align', 'center') cy.get('[data-cy="element-youtube-embed"]').should('not.exist') - cy.contains('[data-cy="element-short-pdf-link"]', 'View Short PDF') - .as('shortPdfLink') + cy.contains('[data-cy="element-pdf-link"]', 'View PDF') + .as('pdfLink') .should('be.visible') .and('have.attr', 'target', '_blank') - cy.get('@shortPdfLink') + cy.get('@pdfLink') .and('have.attr', 'href') - .and('include', '/storage/element-pdfs/short/baderech.pdf') - cy.get('[data-cy="element-long-pdf-link"]').should('not.exist') + .and('include', '/storage/element-pdfs/baderech.pdf') cy.contains('[data-cy="child-element-link"]', introductionAudioTitle) .as('introductionAudioLink') .should('have.attr', 'href', '/element/8') @@ -134,8 +132,7 @@ describe('media page sets', () => { cy.contains('h1', introductionAudioTitle).should('be.visible') cy.get('[data-cy="element-icon"]').should('not.exist') cy.get('[data-cy="element-rich-text"]').should('not.exist') - cy.get('[data-cy="element-short-pdf-link"]').should('not.exist') - cy.get('[data-cy="element-long-pdf-link"]').should('not.exist') + cy.get('[data-cy="element-pdf-link"]').should('not.exist') cy.get('[data-cy="child-element-list"]').should('not.exist') cy.get('[data-cy="element-youtube-embed"]') .should('be.visible') diff --git a/frontend/rabbi_gerzi/src/stores/elements.ts b/frontend/rabbi_gerzi/src/stores/elements.ts index 20cca63..3155637 100644 --- a/frontend/rabbi_gerzi/src/stores/elements.ts +++ b/frontend/rabbi_gerzi/src/stores/elements.ts @@ -1,4 +1,4 @@ -import { ref, type Ref } from 'vue' +import { ref } from 'vue' import { defineStore } from 'pinia' export interface ChildElement { @@ -10,13 +10,10 @@ export interface ChildElement { export interface Element extends ChildElement { iconImageUrl: string | null richText: string - shortPdfPath: string | null - longPdfPath: string | null + pdfPath: string | null youtubeUrl: string | null } -type ElementFileType = 'iconImage' | 'shortPdf' | 'longPdf' - interface ElementResponse { element: Element childElements: ChildElement[] @@ -38,8 +35,7 @@ interface ElementPatchInput { description?: string iconImageUrl?: string richText?: string - shortPdfPath?: string - longPdfPath?: string + pdfPath?: string youtubeUrl?: string } @@ -57,8 +53,7 @@ export const useElementsStore = defineStore('elements', () => { const error = ref(null) const isSaving = ref(false) const isUploadingIconImage = ref(false) - const isUploadingShortPdf = ref(false) - const isUploadingLongPdf = ref(false) + const isUploadingPdf = ref(false) const saveError = ref(null) async function fetchElement(elementId: string): Promise { @@ -94,35 +89,16 @@ export const useElementsStore = defineStore('elements', () => { } } - async function updateElement( - elementId: string, - input: UpdateElementInput, - ): Promise { + async function updateElement(elementId: string, input: UpdateElementInput): Promise { return await saveElementPatch(elementId, input, 'Could not save element') } async function clearElementIconImage(elementId: string): Promise { - return await saveElementPatch( - elementId, - { iconImageUrl: '' }, - 'Could not remove icon image', - ) + return await saveElementPatch(elementId, { iconImageUrl: '' }, 'Could not remove icon image') } - async function clearElementShortPdf(elementId: string): Promise { - return await saveElementPatch( - elementId, - { shortPdfPath: '' }, - 'Could not remove short PDF', - ) - } - - async function clearElementLongPdf(elementId: string): Promise { - return await saveElementPatch( - elementId, - { longPdfPath: '' }, - 'Could not remove long PDF', - ) + async function clearElementPdf(elementId: string): Promise { + return await saveElementPatch(elementId, { pdfPath: '' }, 'Could not remove PDF') } async function saveElementPatch( @@ -150,64 +126,14 @@ export const useElementsStore = defineStore('elements', () => { } } - async function uploadElementIconImage( - elementId: string, - file: File, - ): Promise { - return await uploadElementFile( - elementId, - file, - 'iconImage', - isUploadingIconImage, - 'Could not upload icon image', - 'Network error - could not upload icon image', - ) - } - - async function uploadElementShortPdf( - elementId: string, - file: File, - ): Promise { - return await uploadElementFile( - elementId, - file, - 'shortPdf', - isUploadingShortPdf, - 'Could not upload short PDF', - 'Network error - could not upload short PDF', - ) - } - - async function uploadElementLongPdf( - elementId: string, - file: File, - ): Promise { - return await uploadElementFile( - elementId, - file, - 'longPdf', - isUploadingLongPdf, - 'Could not upload long PDF', - 'Network error - could not upload long PDF', - ) - } - - async function uploadElementFile( - elementId: string, - file: File, - fileType: ElementFileType, - isUploadingFile: Ref, - failureMessage: string, - networkErrorMessage: string, - ): Promise { + async function uploadElementIconImage(elementId: string, file: File): Promise { saveError.value = null - isUploadingFile.value = true + isUploadingIconImage.value = true try { const formData = new FormData() formData.append('elementId', elementId) - formData.append('fileType', fileType) - formData.append('file', file) + formData.append('iconImage', file) const response = await fetch(ELEMENT_UPDATE_URL, { method: 'POST', headers: { Accept: 'application/json' }, @@ -215,12 +141,36 @@ export const useElementsStore = defineStore('elements', () => { body: formData, }) - return await handleElementResponse(response, failureMessage) + return await handleElementResponse(response, 'Could not upload icon image') } catch { - saveError.value = networkErrorMessage + saveError.value = 'Network error - could not upload icon image' return false } finally { - isUploadingFile.value = false + isUploadingIconImage.value = false + } + } + + async function uploadElementPdf(elementId: string, file: File): Promise { + saveError.value = null + isUploadingPdf.value = true + + try { + const formData = new FormData() + formData.append('elementId', elementId) + formData.append('pdf', file) + const response = await fetch(ELEMENT_UPDATE_URL, { + method: 'POST', + headers: { Accept: 'application/json' }, + credentials: 'include', + body: formData, + }) + + return await handleElementResponse(response, 'Could not upload PDF') + } catch { + saveError.value = 'Network error - could not upload PDF' + return false + } finally { + isUploadingPdf.value = false } } @@ -253,10 +203,7 @@ export const useElementsStore = defineStore('elements', () => { return true } - async function errorMessage( - response: Response, - fallbackMessage: string, - ): Promise { + async function errorMessage(response: Response, fallbackMessage: string): Promise { try { const data: ErrorResponse = await response.json() return data.error ?? fallbackMessage @@ -272,16 +219,13 @@ export const useElementsStore = defineStore('elements', () => { error, isSaving, isUploadingIconImage, - isUploadingShortPdf, - isUploadingLongPdf, + isUploadingPdf, saveError, fetchElement, updateElement, uploadElementIconImage, - uploadElementShortPdf, - uploadElementLongPdf, + uploadElementPdf, clearElementIconImage, - clearElementShortPdf, - clearElementLongPdf, + clearElementPdf, } }) diff --git a/frontend/rabbi_gerzi/src/views/AdminElementPage.vue b/frontend/rabbi_gerzi/src/views/AdminElementPage.vue index 261bac3..37f03ff 100644 --- a/frontend/rabbi_gerzi/src/views/AdminElementPage.vue +++ b/frontend/rabbi_gerzi/src/views/AdminElementPage.vue @@ -14,23 +14,13 @@ interface ElementForm { const route = useRoute() const elementsStore = useElementsStore() -const { - element, - isLoading, - error, - isSaving, - isUploadingIconImage, - isUploadingShortPdf, - isUploadingLongPdf, - saveError, -} = storeToRefs(elementsStore) +const { element, isLoading, error, isSaving, isUploadingIconImage, isUploadingPdf, saveError } = + storeToRefs(elementsStore) const savedMessage = ref(null) const iconImageStatus = ref(null) -const shortPdfStatus = ref(null) -const longPdfStatus = ref(null) +const pdfStatus = ref(null) const iconImageInput = ref(null) -const shortPdfInput = ref(null) -const longPdfInput = ref(null) +const pdfInput = ref(null) const form = reactive({ title: '', @@ -66,8 +56,7 @@ watch( savedMessage.value = null iconImageStatus.value = null - shortPdfStatus.value = null - longPdfStatus.value = null + pdfStatus.value = null void elementsStore.fetchElement(currentElementId) }, { immediate: true }, @@ -106,12 +95,8 @@ function chooseIconImage(): void { iconImageInput.value?.click() } -function chooseShortPdf(): void { - shortPdfInput.value?.click() -} - -function chooseLongPdf(): void { - longPdfInput.value?.click() +function choosePdf(): void { + pdfInput.value?.click() } async function handleIconImageChange(changeEvent: Event): Promise { @@ -122,10 +107,7 @@ async function handleIconImageChange(changeEvent: Event): Promise { savedMessage.value = null iconImageStatus.value = null - const uploaded = await elementsStore.uploadElementIconImage( - elementId.value, - selectedFile, - ) + const uploaded = await elementsStore.uploadElementIconImage(elementId.value, selectedFile) resetInput(changeEvent) if (uploaded) { @@ -133,41 +115,19 @@ async function handleIconImageChange(changeEvent: Event): Promise { } } -async function handleShortPdfChange(changeEvent: Event): Promise { +async function handlePdfChange(changeEvent: Event): Promise { const selectedFile = selectedInputFile(changeEvent) if (selectedFile === null || elementId.value === '') { return } savedMessage.value = null - shortPdfStatus.value = null - const uploaded = await elementsStore.uploadElementShortPdf( - elementId.value, - selectedFile, - ) + pdfStatus.value = null + const uploaded = await elementsStore.uploadElementPdf(elementId.value, selectedFile) resetInput(changeEvent) if (uploaded) { - shortPdfStatus.value = 'Short PDF updated' - } -} - -async function handleLongPdfChange(changeEvent: Event): Promise { - const selectedFile = selectedInputFile(changeEvent) - if (selectedFile === null || elementId.value === '') { - return - } - - savedMessage.value = null - longPdfStatus.value = null - const uploaded = await elementsStore.uploadElementLongPdf( - elementId.value, - selectedFile, - ) - resetInput(changeEvent) - - if (uploaded) { - longPdfStatus.value = 'Long PDF updated' + pdfStatus.value = 'PDF updated' } } @@ -184,29 +144,16 @@ async function handleRemoveIconImage(): Promise { } } -async function handleRemoveShortPdf(): Promise { +async function handleRemovePdf(): Promise { if (elementId.value === '') { return } savedMessage.value = null - shortPdfStatus.value = null - const removed = await elementsStore.clearElementShortPdf(elementId.value) + pdfStatus.value = null + const removed = await elementsStore.clearElementPdf(elementId.value) if (removed) { - shortPdfStatus.value = 'Short PDF removed' - } -} - -async function handleRemoveLongPdf(): Promise { - if (elementId.value === '') { - return - } - - savedMessage.value = null - longPdfStatus.value = null - const removed = await elementsStore.clearElementLongPdf(elementId.value) - if (removed) { - longPdfStatus.value = 'Long PDF removed' + pdfStatus.value = 'PDF removed' } } @@ -239,9 +186,7 @@ function resetInput(changeEvent: Event): void {

Edit Element

-

- Loading element... -

+

Loading element...

{{ error }}

-
+