]> BookStack Code Mirror - bookstack/blob - tests/Exports/ZipImportTest.php
ZIP Imports: Added validation message display, added testing
[bookstack] / tests / Exports / ZipImportTest.php
1 <?php
2
3 namespace Tests\Exports;
4
5 use Illuminate\Http\UploadedFile;
6 use Illuminate\Testing\TestResponse;
7 use Tests\TestCase;
8 use ZipArchive;
9
10 class ZipImportTest extends TestCase
11 {
12     public function test_import_page_view()
13     {
14         $resp = $this->asAdmin()->get('/import');
15         $resp->assertSee('Import');
16         $this->withHtml($resp)->assertElementExists('form input[type="file"][name="file"]');
17     }
18
19     public function test_permissions_needed_for_import_page()
20     {
21         $user = $this->users->viewer();
22         $this->actingAs($user);
23
24         $resp = $this->get('/books');
25         $this->withHtml($resp)->assertLinkNotExists(url('/import'));
26         $resp = $this->get('/import');
27         $resp->assertRedirect('/');
28
29         $this->permissions->grantUserRolePermissions($user, ['content-import']);
30
31         $resp = $this->get('/books');
32         $this->withHtml($resp)->assertLinkExists(url('/import'));
33         $resp = $this->get('/import');
34         $resp->assertOk();
35         $resp->assertSeeText('Select ZIP file to upload');
36     }
37
38     public function test_zip_read_errors_are_shown_on_validation()
39     {
40         $invalidUpload = $this->files->uploadedImage('image.zip');
41
42         $this->asAdmin();
43         $resp = $this->runImportFromFile($invalidUpload);
44         $resp->assertRedirect('/import');
45
46         $resp = $this->followRedirects($resp);
47         $resp->assertSeeText('Could not read ZIP file');
48     }
49
50     public function test_error_shown_if_missing_data()
51     {
52         $zipFile = tempnam(sys_get_temp_dir(), 'bstest-');
53         $zip = new ZipArchive();
54         $zip->open($zipFile, ZipArchive::CREATE);
55         $zip->addFromString('beans', 'cat');
56         $zip->close();
57
58         $this->asAdmin();
59         $upload = new UploadedFile($zipFile, 'upload.zip', 'application/zip', null, true);
60         $resp = $this->runImportFromFile($upload);
61         $resp->assertRedirect('/import');
62
63         $resp = $this->followRedirects($resp);
64         $resp->assertSeeText('Could not find and decode ZIP data.json content.');
65     }
66
67     public function test_error_shown_if_no_importable_key()
68     {
69         $this->asAdmin();
70         $resp = $this->runImportFromFile($this->zipUploadFromData([
71             'instance' => []
72         ]));
73
74         $resp->assertRedirect('/import');
75         $resp = $this->followRedirects($resp);
76         $resp->assertSeeText('ZIP file data has no expected book, chapter or page content.');
77     }
78
79     public function test_zip_data_validation_messages_shown()
80     {
81         $this->asAdmin();
82         $resp = $this->runImportFromFile($this->zipUploadFromData([
83             'book' => [
84                 'id' => 4,
85                 'pages' => [
86                     'cat',
87                     [
88                         'name' => 'My inner page',
89                         'tags' => [
90                             [
91                                 'value' => 5
92                             ]
93                         ],
94                     ]
95                 ],
96             ]
97         ]));
98
99         $resp->assertRedirect('/import');
100         $resp = $this->followRedirects($resp);
101
102         $resp->assertSeeText('[book.name]: The name field is required.');
103         $resp->assertSeeText('[book.pages.0.0]: Data object expected but "string" found.');
104         $resp->assertSeeText('[book.pages.1.tags.0.name]: The name field is required.');
105         $resp->assertSeeText('[book.pages.1.tags.0.value]: The value must be a string.');
106     }
107
108     protected function runImportFromFile(UploadedFile $file): TestResponse
109     {
110         return $this->call('POST', '/import', [], [], ['file' => $file]);
111     }
112
113     protected function zipUploadFromData(array $data): UploadedFile
114     {
115         $zipFile = tempnam(sys_get_temp_dir(), 'bstest-');
116
117         $zip = new ZipArchive();
118         $zip->open($zipFile, ZipArchive::CREATE);
119         $zip->addFromString('data.json', json_encode($data));
120         $zip->close();
121
122         return new UploadedFile($zipFile, 'upload.zip', 'application/zip', null, true);
123     }
124 }