3 use BookStack\Attachment;
5 use BookStack\Services\PermissionService;
7 class AttachmentTest extends TestCase
10 * Get a test file that can be uploaded
12 * @return \Illuminate\Http\UploadedFile
14 protected function getTestFile($fileName)
16 return new \Illuminate\Http\UploadedFile(base_path('tests/test-data/test-file.txt'), $fileName, 'text/plain', 55, null, true);
20 * Uploads a file with the given name.
22 * @param int $uploadedTo
23 * @return \Illuminate\Foundation\Testing\TestResponse
25 protected function uploadFile($name, $uploadedTo = 0)
27 $file = $this->getTestFile($name);
28 return $this->call('POST', '/attachments/upload', ['uploaded_to' => $uploadedTo], [], ['file' => $file], []);
32 * Get the expected upload path for a file.
36 protected function getUploadPath($fileName)
38 return 'uploads/files/' . Date('Y-m-M') . '/' . $fileName;
42 * Delete all uploaded files.
43 * To assist with cleanup.
45 protected function deleteUploads()
47 $fileService = $this->app->make(\BookStack\Services\AttachmentService::class);
48 foreach (\BookStack\Attachment::all() as $file) {
49 $fileService->deleteFile($file);
53 public function test_file_upload()
55 $page = Page::first();
57 $admin = $this->getAdmin();
58 $fileName = 'upload_test_file.txt';
62 'uploaded_to'=> $page->id,
65 'created_by' => $admin->id,
66 'updated_by' => $admin->id,
67 'path' => $this->getUploadPath($fileName)
70 $upload = $this->uploadFile($fileName, $page->id);
71 $upload->assertStatus(200);
72 $upload->assertJson($expectedResp);
73 $this->assertDatabaseHas('attachments', $expectedResp);
75 $this->deleteUploads();
78 public function test_file_display_and_access()
80 $page = Page::first();
82 $fileName = 'upload_test_file.txt';
84 $upload = $this->uploadFile($fileName, $page->id);
85 $upload->assertStatus(200);
86 $attachment = Attachment::orderBy('id', 'desc')->take(1)->first();
88 $pageGet = $this->get($page->getUrl());
89 $pageGet->assertSeeText($fileName);
90 $pageGet->assertSee($attachment->getUrl());
92 $attachmentGet = $this->get($attachment->getUrl());
93 $attachmentGet->assertSee('Hi, This is a test file for testing the upload process.');
95 $this->deleteUploads();
98 public function test_attaching_link_to_page()
100 $page = Page::first();
101 $admin = $this->getAdmin();
104 $linkReq = $this->call('POST', 'attachments/link', [
105 'link' => 'https://example.com',
106 'name' => 'Example Attachment Link',
107 'uploaded_to' => $page->id,
111 'path' => 'https://example.com',
112 'name' => 'Example Attachment Link',
113 'uploaded_to' => $page->id,
114 'created_by' => $admin->id,
115 'updated_by' => $admin->id,
121 $linkReq->assertStatus(200);
122 $linkReq->assertJson($expectedResp);
123 $this->assertDatabaseHas('attachments', $expectedResp);
124 $attachment = Attachment::orderBy('id', 'desc')->take(1)->first();
126 $pageGet = $this->get($page->getUrl());
127 $pageGet->assertSeeText('Example Attachment Link');
128 $pageGet->assertSee($attachment->getUrl());
130 $attachmentGet = $this->get($attachment->getUrl());
131 $attachmentGet->assertRedirect('https://example.com');
133 $this->deleteUploads();
136 public function test_attachment_updating()
138 $page = Page::first();
141 $this->call('POST', 'attachments/link', [
142 'link' => 'https://example.com',
143 'name' => 'Example Attachment Link',
144 'uploaded_to' => $page->id,
147 $attachmentId = \BookStack\Attachment::first()->id;
149 $update = $this->call('PUT', 'attachments/' . $attachmentId, [
150 'uploaded_to' => $page->id,
151 'name' => 'My new attachment name',
152 'link' => 'https://test.example.com'
156 'path' => 'https://test.example.com',
157 'name' => 'My new attachment name',
158 'uploaded_to' => $page->id
161 $update->assertStatus(200);
162 $update->assertJson($expectedResp);
163 $this->assertDatabaseHas('attachments', $expectedResp);
165 $this->deleteUploads();
168 public function test_file_deletion()
170 $page = Page::first();
172 $fileName = 'deletion_test.txt';
173 $this->uploadFile($fileName, $page->id);
175 $filePath = base_path('storage/' . $this->getUploadPath($fileName));
176 $this->assertTrue(file_exists($filePath), 'File at path ' . $filePath . ' does not exist');
178 $attachment = \BookStack\Attachment::first();
179 $this->delete($attachment->getUrl());
181 $this->assertDatabaseMissing('attachments', [
184 $this->assertFalse(file_exists($filePath), 'File at path ' . $filePath . ' was not deleted as expected');
186 $this->deleteUploads();
189 public function test_attachment_deletion_on_page_deletion()
191 $page = Page::first();
193 $fileName = 'deletion_test.txt';
194 $this->uploadFile($fileName, $page->id);
196 $filePath = base_path('storage/' . $this->getUploadPath($fileName));
198 $this->assertTrue(file_exists($filePath), 'File at path ' . $filePath . ' does not exist');
199 $this->assertDatabaseHas('attachments', [
203 $this->call('DELETE', $page->getUrl());
205 $this->assertDatabaseMissing('attachments', [
208 $this->assertFalse(file_exists($filePath), 'File at path ' . $filePath . ' was not deleted as expected');
210 $this->deleteUploads();
213 public function test_attachment_access_without_permission_shows_404()
215 $admin = $this->getAdmin();
216 $viewer = $this->getViewer();
217 $page = Page::first();
219 $this->actingAs($admin);
220 $fileName = 'permission_test.txt';
221 $this->uploadFile($fileName, $page->id);
222 $attachment = Attachment::orderBy('id', 'desc')->take(1)->first();
224 $page->restricted = true;
225 $page->permissions()->delete();
227 $this->app[PermissionService::class]->buildJointPermissionsForEntity($page);
228 $page->load('jointPermissions');
230 $this->actingAs($viewer);
231 $attachmentGet = $this->get($attachment->getUrl());
232 $attachmentGet->assertStatus(404);
233 $attachmentGet->assertSee("Attachment not found");
235 $this->deleteUploads();