]> BookStack Code Mirror - bookstack/blob - tests/Uploads/AttachmentTest.php
New translations validation.php (German Informal)
[bookstack] / tests / Uploads / AttachmentTest.php
1 <?php namespace Tests;
2
3 use BookStack\Uploads\Attachment;
4 use BookStack\Entities\Page;
5 use BookStack\Auth\Permissions\PermissionService;
6
7 class AttachmentTest extends TestCase
8 {
9     /**
10      * Get a test file that can be uploaded
11      * @param $fileName
12      * @return \Illuminate\Http\UploadedFile
13      */
14     protected function getTestFile($fileName)
15     {
16         return new \Illuminate\Http\UploadedFile(base_path('tests/test-data/test-file.txt'), $fileName, 'text/plain', 55, null, true);
17     }
18
19     /**
20      * Uploads a file with the given name.
21      * @param $name
22      * @param int $uploadedTo
23      * @return \Illuminate\Foundation\Testing\TestResponse
24      */
25     protected function uploadFile($name, $uploadedTo = 0)
26     {
27         $file = $this->getTestFile($name);
28         return $this->call('POST', '/attachments/upload', ['uploaded_to' => $uploadedTo], [], ['file' => $file], []);
29     }
30
31     /**
32      * Delete all uploaded files.
33      * To assist with cleanup.
34      */
35     protected function deleteUploads()
36     {
37         $fileService = $this->app->make(\BookStack\Uploads\AttachmentService::class);
38         foreach (\BookStack\Uploads\Attachment::all() as $file) {
39             $fileService->deleteFile($file);
40         }
41     }
42
43     public function test_file_upload()
44     {
45         $page = Page::first();
46         $this->asAdmin();
47         $admin = $this->getAdmin();
48         $fileName = 'upload_test_file.txt';
49
50         $expectedResp = [
51             'name' => $fileName,
52             'uploaded_to'=> $page->id,
53             'extension' => 'txt',
54             'order' => 1,
55             'created_by' => $admin->id,
56             'updated_by' => $admin->id,
57         ];
58
59         $upload = $this->uploadFile($fileName, $page->id);
60         $upload->assertStatus(200);
61
62         $attachment = Attachment::query()->orderBy('id', 'desc')->first();
63         $expectedResp['path'] = $attachment->path;
64
65         $upload->assertJson($expectedResp);
66         $this->assertDatabaseHas('attachments', $expectedResp);
67
68         $this->deleteUploads();
69     }
70
71     public function test_file_upload_does_not_use_filename()
72     {
73         $page = Page::first();
74         $fileName = 'upload_test_file.txt';
75
76
77         $upload = $this->asAdmin()->uploadFile($fileName, $page->id);
78         $upload->assertStatus(200);
79
80         $attachment = Attachment::query()->orderBy('id', 'desc')->first();
81         $this->assertStringNotContainsString($fileName, $attachment->path);
82         $this->assertStringEndsWith('.txt', $attachment->path);
83     }
84
85     public function test_file_display_and_access()
86     {
87         $page = Page::first();
88         $this->asAdmin();
89         $fileName = 'upload_test_file.txt';
90
91         $upload = $this->uploadFile($fileName, $page->id);
92         $upload->assertStatus(200);
93         $attachment = Attachment::orderBy('id', 'desc')->take(1)->first();
94
95         $pageGet = $this->get($page->getUrl());
96         $pageGet->assertSeeText($fileName);
97         $pageGet->assertSee($attachment->getUrl());
98
99         $attachmentGet = $this->get($attachment->getUrl());
100         $attachmentGet->assertSee('Hi, This is a test file for testing the upload process.');
101
102         $this->deleteUploads();
103     }
104
105     public function test_attaching_link_to_page()
106     {
107         $page = Page::first();
108         $admin = $this->getAdmin();
109         $this->asAdmin();
110
111         $linkReq = $this->call('POST', 'attachments/link', [
112             'link' => 'https://example.com',
113             'name' => 'Example Attachment Link',
114             'uploaded_to' => $page->id,
115         ]);
116
117         $expectedResp = [
118             'path' => 'https://example.com',
119             'name' => 'Example Attachment Link',
120             'uploaded_to' => $page->id,
121             'created_by' => $admin->id,
122             'updated_by' => $admin->id,
123             'external' => true,
124             'order' => 1,
125             'extension' => ''
126         ];
127
128         $linkReq->assertStatus(200);
129         $linkReq->assertJson($expectedResp);
130         $this->assertDatabaseHas('attachments', $expectedResp);
131         $attachment = Attachment::orderBy('id', 'desc')->take(1)->first();
132
133         $pageGet = $this->get($page->getUrl());
134         $pageGet->assertSeeText('Example Attachment Link');
135         $pageGet->assertSee($attachment->getUrl());
136
137         $attachmentGet = $this->get($attachment->getUrl());
138         $attachmentGet->assertRedirect('https://example.com');
139
140         $this->deleteUploads();
141     }
142
143     public function test_attachment_updating()
144     {
145         $page = Page::first();
146         $this->asAdmin();
147
148         $this->call('POST', 'attachments/link', [
149             'link' => 'https://example.com',
150             'name' => 'Example Attachment Link',
151             'uploaded_to' => $page->id,
152         ]);
153
154         $attachmentId = \BookStack\Uploads\Attachment::first()->id;
155
156         $update = $this->call('PUT', 'attachments/' . $attachmentId, [
157             'uploaded_to' => $page->id,
158             'name' => 'My new attachment name',
159             'link' => 'https://test.example.com'
160         ]);
161
162         $expectedResp = [
163             'path' => 'https://test.example.com',
164             'name' => 'My new attachment name',
165             'uploaded_to' => $page->id
166         ];
167
168         $update->assertStatus(200);
169         $update->assertJson($expectedResp);
170         $this->assertDatabaseHas('attachments', $expectedResp);
171
172         $this->deleteUploads();
173     }
174
175     public function test_file_deletion()
176     {
177         $page = Page::first();
178         $this->asAdmin();
179         $fileName = 'deletion_test.txt';
180         $this->uploadFile($fileName, $page->id);
181
182         $attachment = Attachment::query()->orderBy('id', 'desc')->first();
183         $filePath = storage_path($attachment->path);
184         $this->assertTrue(file_exists($filePath), 'File at path ' . $filePath . ' does not exist');
185
186         $attachment = \BookStack\Uploads\Attachment::first();
187         $this->delete($attachment->getUrl());
188
189         $this->assertDatabaseMissing('attachments', [
190             'name' => $fileName
191         ]);
192         $this->assertFalse(file_exists($filePath), 'File at path ' . $filePath . ' was not deleted as expected');
193
194         $this->deleteUploads();
195     }
196
197     public function test_attachment_deletion_on_page_deletion()
198     {
199         $page = Page::first();
200         $this->asAdmin();
201         $fileName = 'deletion_test.txt';
202         $this->uploadFile($fileName, $page->id);
203
204         $attachment = Attachment::query()->orderBy('id', 'desc')->first();
205         $filePath = storage_path($attachment->path);
206
207         $this->assertTrue(file_exists($filePath), 'File at path ' . $filePath . ' does not exist');
208         $this->assertDatabaseHas('attachments', [
209             'name' => $fileName
210         ]);
211
212         $this->call('DELETE', $page->getUrl());
213
214         $this->assertDatabaseMissing('attachments', [
215             'name' => $fileName
216         ]);
217         $this->assertFalse(file_exists($filePath), 'File at path ' . $filePath . ' was not deleted as expected');
218
219         $this->deleteUploads();
220     }
221
222     public function test_attachment_access_without_permission_shows_404()
223     {
224         $admin = $this->getAdmin();
225         $viewer = $this->getViewer();
226         $page = Page::first(); /** @var Page $page */
227
228         $this->actingAs($admin);
229         $fileName = 'permission_test.txt';
230         $this->uploadFile($fileName, $page->id);
231         $attachment = Attachment::orderBy('id', 'desc')->take(1)->first();
232
233         $page->restricted = true;
234         $page->permissions()->delete();
235         $page->save();
236         $page->rebuildPermissions();
237         $page->load('jointPermissions');
238
239         $this->actingAs($viewer);
240         $attachmentGet = $this->get($attachment->getUrl());
241         $attachmentGet->assertStatus(404);
242         $attachmentGet->assertSee("Attachment not found");
243
244         $this->deleteUploads();
245     }
246 }