]> BookStack Code Mirror - bookstack/commitdiff
ZIP Imports: Started testing core import logic
authorDan Brown <redacted>
Sat, 16 Nov 2024 16:12:45 +0000 (16:12 +0000)
committerDan Brown <redacted>
Sat, 16 Nov 2024 16:12:45 +0000 (16:12 +0000)
Fixed image size handling, and lack of attachment reference replacements
during testing.

app/Exports/ZipExports/ZipImportReferences.php
app/Exports/ZipExports/ZipImportRunner.php
app/Uploads/ImageService.php
tests/Exports/ZipImportRunnerTest.php
tests/Exports/ZipTestHelper.php

index b23d5e72b159a5684dc318de77b7d1069f84bf81..da0581df6f543ce33c79b0fc7085fd819bf35f77 100644 (file)
@@ -97,10 +97,12 @@ class ZipImportReferences
         } else if ($model instanceof Image) {
             if ($model->type === 'gallery') {
                 $this->imageResizer->loadGalleryThumbnailsForImage($model, false);
-                return $model->thumbs['gallery'] ?? $model->url;
+                return $model->thumbs['display'] ?? $model->url;
             }
 
             return $model->url;
+        } else if ($model instanceof Attachment) {
+            return $model->getUrl(false);
         }
 
         return null;
index c5b9da319096d7a03cf4d80a11d50b7f9829f417..27d859e5915ea4c4ef37907cfa001af243cf667c 100644 (file)
@@ -233,6 +233,10 @@ class ZipImportRunner
             $file,
             $exportImage->type,
             $page->id,
+            null,
+            null,
+            true,
+            $exportImage->name,
         );
 
         $this->references->addImage($image, $exportImage->id);
index 5c455cf86336b346b7e53e9647b7f7ee52e23e2d..038e6aa417c839b8f794038ec2bd40545f71e111 100644 (file)
@@ -33,9 +33,10 @@ class ImageService
         int $uploadedTo = 0,
         int $resizeWidth = null,
         int $resizeHeight = null,
-        bool $keepRatio = true
+        bool $keepRatio = true,
+        string $imageName = '',
     ): Image {
-        $imageName = $uploadedFile->getClientOriginalName();
+        $imageName = $imageName ?: $uploadedFile->getClientOriginalName();
         $imageData = file_get_contents($uploadedFile->getRealPath());
 
         if ($resizeWidth !== null || $resizeHeight !== null) {
index 7bdd8ecbb6586982899dc6feb28018e60b30921f..f07b3f41b424a1c64f2b6de6f9195df7ca1e6539 100644 (file)
@@ -2,7 +2,10 @@
 
 namespace Tests\Exports;
 
+use BookStack\Entities\Models\Book;
+use BookStack\Entities\Models\Page;
 use BookStack\Exports\ZipExports\ZipImportRunner;
+use BookStack\Uploads\Image;
 use Tests\TestCase;
 
 class ZipImportRunnerTest extends TestCase
@@ -15,6 +18,155 @@ class ZipImportRunnerTest extends TestCase
         $this->runner = app()->make(ZipImportRunner::class);
     }
 
+    public function test_book_import()
+    {
+        $testImagePath = $this->files->testFilePath('test-image.png');
+        $testFilePath = $this->files->testFilePath('test-file.txt');
+        $import = ZipTestHelper::importFromData([], [
+            'book' => [
+                'id' => 5,
+                'name' => 'Import test',
+                'cover' => 'book_cover_image',
+                'description_html' => '<p><a href="[[bsexport:page:3]]">Link to chapter page</a></p>',
+                'tags' => [
+                    ['name' => 'Animal', 'value' => 'Cat'],
+                    ['name' => 'Category', 'value' => 'Test'],
+                ],
+                'chapters' => [
+                    [
+                        'id' => 6,
+                        'name' => 'Chapter A',
+                        'description_html' => '<p><a href="[[bsexport:book:5]]">Link to book</a></p>',
+                        'priority' => 1,
+                        'tags' => [
+                            ['name' => 'Reviewed'],
+                            ['name' => 'Category', 'value' => 'Test Chapter'],
+                        ],
+                        'pages' => [
+                            [
+                                'id' => 3,
+                                'name' => 'Page A',
+                                'priority' => 6,
+                                'html' => '
+<p><a href="[[bsexport:page:3]]">Link to self</a></p>
+<p><a href="[[bsexport:image:1]]">Link to cat image</a></p>
+<p><a href="[[bsexport:attachment:4]]">Link to text attachment</a></p>',
+                                'tags' => [
+                                    ['name' => 'Unreviewed'],
+                                ],
+                                'attachments' => [
+                                    [
+                                        'id' => 4,
+                                        'name' => 'Text attachment',
+                                        'file' => 'file_attachment'
+                                    ],
+                                    [
+                                        'name' => 'Cats',
+                                        'link' => 'https://example.com/cats',
+                                    ]
+                                ],
+                                'images' => [
+                                    [
+                                        'id' => 1,
+                                        'name' => 'Cat',
+                                        'type' => 'gallery',
+                                        'file' => 'cat_image'
+                                    ],
+                                    [
+                                        'id' => 2,
+                                        'name' => 'Dog Drawing',
+                                        'type' => 'drawio',
+                                        'file' => 'dog_image'
+                                    ]
+                                ],
+                            ],
+                        ],
+                    ],
+                    [
+                        'name' => 'Chapter child B',
+                        'priority' => 5,
+                    ]
+                ],
+                'pages' => [
+                    [
+                        'name' => 'Page C',
+                        'markdown' => '[Link to text]([[bsexport:attachment:4]]?scale=big)',
+                        'priority' => 3,
+                    ]
+                ],
+            ],
+        ], [
+            'book_cover_image' => $testImagePath,
+            'file_attachment'  => $testFilePath,
+            'cat_image' => $testImagePath,
+            'dog_image' => $testImagePath,
+        ]);
+
+        $this->asAdmin();
+        /** @var Book $book */
+        $book = $this->runner->run($import);
+
+        // Book checks
+        $this->assertEquals('Import test', $book->name);
+        $this->assertFileExists(public_path($book->cover->path));
+        $this->assertCount(2, $book->tags);
+        $this->assertEquals('Cat', $book->tags()->first()->value);
+        $this->assertCount(2, $book->chapters);
+        $this->assertEquals(1, $book->directPages()->count());
+
+        // Chapter checks
+        $chapterA = $book->chapters()->where('name', 'Chapter A')->first();
+        $this->assertCount(2, $chapterA->tags);
+        $firstChapterTag = $chapterA->tags()->first();
+        $this->assertEquals('Reviewed', $firstChapterTag->name);
+        $this->assertEquals('', $firstChapterTag->value);
+        $this->assertCount(1, $chapterA->pages);
+
+        // Page checks
+        /** @var Page $pageA */
+        $pageA = $chapterA->pages->first();
+        $this->assertEquals('Page A', $pageA->name);
+        $this->assertCount(1, $pageA->tags);
+        $firstPageTag = $pageA->tags()->first();
+        $this->assertEquals('Unreviewed', $firstPageTag->name);
+        $this->assertCount(2, $pageA->attachments);
+        $firstAttachment = $pageA->attachments->first();
+        $this->assertEquals('Text attachment', $firstAttachment->name);
+        $this->assertFileEquals($testFilePath, storage_path($firstAttachment->path));
+        $this->assertFalse($firstAttachment->external);
+        $secondAttachment = $pageA->attachments->last();
+        $this->assertEquals('Cats', $secondAttachment->name);
+        $this->assertEquals('https://example.com/cats', $secondAttachment->path);
+        $this->assertTrue($secondAttachment->external);
+        $pageAImages = Image::where('uploaded_to', '=', $pageA->id)->whereIn('type', ['gallery', 'drawio'])->get();
+        $this->assertCount(2, $pageAImages);
+        $this->assertEquals('Cat', $pageAImages[0]->name);
+        $this->assertEquals('gallery', $pageAImages[0]->type);
+        $this->assertFileEquals($testImagePath, public_path($pageAImages[0]->path));
+        $this->assertEquals('Dog Drawing', $pageAImages[1]->name);
+        $this->assertEquals('drawio', $pageAImages[1]->type);
+
+        // Book order check
+        $children = $book->getDirectVisibleChildren()->values()->all();
+        $this->assertEquals($children[0]->name, 'Chapter A');
+        $this->assertEquals($children[1]->name, 'Page C');
+        $this->assertEquals($children[2]->name, 'Chapter child B');
+
+        // Reference checks
+        $textAttachmentUrl = $firstAttachment->getUrl();
+        $this->assertStringContainsString($pageA->getUrl(), $book->description_html);
+        $this->assertStringContainsString($book->getUrl(), $chapterA->description_html);
+        $this->assertStringContainsString($pageA->getUrl(), $pageA->html);
+        $this->assertStringContainsString($pageAImages[0]->getThumb(1680, null, true), $pageA->html);
+        $this->assertStringContainsString($firstAttachment->getUrl(), $pageA->html);
+
+        // Reference in converted markdown
+        $pageC = $children[1];
+        $this->assertStringContainsString("href=\"{$textAttachmentUrl}?scale=big\"", $pageC->html);
+
+        ZipTestHelper::deleteZipForImport($import);
+    }
+
     // TODO - Test full book import
     // TODO - Test full chapter import
     // TODO - Test full page import
index 3a9b34354542957c0d66525c979df9235ad53b41..2196f361c178d7b68bc499402eb6c8d220f947f9 100644 (file)
@@ -8,7 +8,7 @@ use ZipArchive;
 
 class ZipTestHelper
 {
-    public static function importFromData(array $importData, array $zipData): Import
+    public static function importFromData(array $importData, array $zipData, array $files = []): Import
     {
         if (isset($zipData['book'])) {
             $importData['type'] = 'book';
@@ -19,7 +19,7 @@ class ZipTestHelper
         }
 
         $import = Import::factory()->create($importData);
-        $zip = static::zipUploadFromData($zipData);
+        $zip = static::zipUploadFromData($zipData, $files);
         rename($zip->getRealPath(), storage_path($import->path));
 
         return $import;
@@ -33,13 +33,18 @@ class ZipTestHelper
         }
     }
 
-    public static function zipUploadFromData(array $data): UploadedFile
+    public static function zipUploadFromData(array $data, array $files = []): UploadedFile
     {
         $zipFile = tempnam(sys_get_temp_dir(), 'bstest-');
 
         $zip = new ZipArchive();
         $zip->open($zipFile, ZipArchive::CREATE);
         $zip->addFromString('data.json', json_encode($data));
+
+        foreach ($files as $name => $file) {
+            $zip->addFile($file, "files/$name");
+        }
+
         $zip->close();
 
         return new UploadedFile($zipFile, 'upload.zip', 'application/zip', null, true);