diff --git a/app/Http/Controllers/FileController.php b/app/Http/Controllers/FileController.php
index 2518d6cd3..88200ae65 100644
--- a/app/Http/Controllers/FileController.php
+++ b/app/Http/Controllers/FileController.php
@@ -34,7 +34,6 @@ class FileController extends Controller
*/
public function upload(Request $request)
{
- // TODO - ensure uploads are deleted on page delete.
$this->validate($request, [
'uploaded_to' => 'required|integer|exists:pages,id',
'file' => 'required|file'
diff --git a/resources/assets/js/controllers.js b/resources/assets/js/controllers.js
index 78b3684d6..f098e0130 100644
--- a/resources/assets/js/controllers.js
+++ b/resources/assets/js/controllers.js
@@ -639,6 +639,7 @@ module.exports = function (ngApp, events) {
* @param fileLink
*/
$scope.attachLinkSubmit = function(file) {
+ file.uploaded_to = pageId;
$http.post('/files/link', file).then(resp => {
$scope.files.unshift(resp.data);
events.emit('success', 'Link attached');
diff --git a/resources/views/pages/sidebar-tree-list.blade.php b/resources/views/pages/sidebar-tree-list.blade.php
index bf0e5761a..f6b834f07 100644
--- a/resources/views/pages/sidebar-tree-list.blade.php
+++ b/resources/views/pages/sidebar-tree-list.blade.php
@@ -1,7 +1,7 @@
- @if ($page->files->count() > 0)
+ @if (isset($page) && $page->files->count() > 0)
Attachments
@foreach($page->files as $file)
diff --git a/tests/AttachmentTest.php b/tests/AttachmentTest.php
new file mode 100644
index 000000000..f22faa740
--- /dev/null
+++ b/tests/AttachmentTest.php
@@ -0,0 +1,201 @@
+getTestFile($name);
+ return $this->call('POST', '/files/upload', ['uploaded_to' => $uploadedTo], [], ['file' => $file], []);
+ }
+
+ /**
+ * Get the expected upload path for a file.
+ * @param $fileName
+ * @return string
+ */
+ protected function getUploadPath($fileName)
+ {
+ return 'uploads/files/' . Date('Y-m-M') . '/' . $fileName;
+ }
+
+ /**
+ * Delete all uploaded files.
+ * To assist with cleanup.
+ */
+ protected function deleteUploads()
+ {
+ $fileService = $this->app->make(\BookStack\Services\FileService::class);
+ foreach (\BookStack\File::all() as $file) {
+ $fileService->deleteFile($file);
+ }
+ }
+
+ public function test_file_upload()
+ {
+ $page = \BookStack\Page::first();
+ $this->asAdmin();
+ $admin = $this->getAdmin();
+ $fileName = 'upload_test_file.txt';
+
+ $expectedResp = [
+ 'name' => $fileName,
+ 'uploaded_to'=> $page->id,
+ 'extension' => 'txt',
+ 'order' => 1,
+ 'created_by' => $admin->id,
+ 'updated_by' => $admin->id,
+ 'path' => $this->getUploadPath($fileName)
+ ];
+
+ $this->uploadFile($fileName, $page->id);
+ $this->assertResponseOk();
+ $this->seeJsonContains($expectedResp);
+ $this->seeInDatabase('files', $expectedResp);
+
+ $this->deleteUploads();
+ }
+
+ public function test_file_display_and_access()
+ {
+ $page = \BookStack\Page::first();
+ $this->asAdmin();
+ $admin = $this->getAdmin();
+ $fileName = 'upload_test_file.txt';
+
+ $this->uploadFile($fileName, $page->id);
+ $this->assertResponseOk();
+ $this->visit($page->getUrl())
+ ->seeLink($fileName)
+ ->click($fileName)
+ ->see('Hi, This is a test file for testing the upload process.');
+
+ $this->deleteUploads();
+ }
+
+ public function test_attaching_link_to_page()
+ {
+ $page = \BookStack\Page::first();
+ $admin = $this->getAdmin();
+ $this->asAdmin();
+
+ $this->call('POST', 'files/link', [
+ 'link' => 'https://example.com',
+ 'name' => 'Example Attachment Link',
+ 'uploaded_to' => $page->id,
+ ]);
+
+ $expectedResp = [
+ 'path' => 'https://example.com',
+ 'name' => 'Example Attachment Link',
+ 'uploaded_to' => $page->id,
+ 'created_by' => $admin->id,
+ 'updated_by' => $admin->id,
+ 'external' => true,
+ 'order' => 1,
+ 'extension' => ''
+ ];
+
+ $this->assertResponseOk();
+ $this->seeJsonContains($expectedResp);
+ $this->seeInDatabase('files', $expectedResp);
+
+ $this->visit($page->getUrl())->seeLink('Example Attachment Link')
+ ->click('Example Attachment Link')->seePageIs('https://example.com');
+
+ $this->deleteUploads();
+ }
+
+ public function test_attachment_updating()
+ {
+ $page = \BookStack\Page::first();
+ $this->asAdmin();
+
+ $this->call('POST', 'files/link', [
+ 'link' => 'https://example.com',
+ 'name' => 'Example Attachment Link',
+ 'uploaded_to' => $page->id,
+ ]);
+
+ $attachmentId = \BookStack\File::first()->id;
+
+ $this->call('PUT', 'files/' . $attachmentId, [
+ 'uploaded_to' => $page->id,
+ 'name' => 'My new attachment name',
+ 'link' => 'https://test.example.com'
+ ]);
+
+ $expectedResp = [
+ 'path' => 'https://test.example.com',
+ 'name' => 'My new attachment name',
+ 'uploaded_to' => $page->id
+ ];
+
+ $this->assertResponseOk();
+ $this->seeJsonContains($expectedResp);
+ $this->seeInDatabase('files', $expectedResp);
+
+ $this->deleteUploads();
+ }
+
+ public function test_file_deletion()
+ {
+ $page = \BookStack\Page::first();
+ $this->asAdmin();
+ $fileName = 'deletion_test.txt';
+ $this->uploadFile($fileName, $page->id);
+
+ $filePath = base_path('storage/' . $this->getUploadPath($fileName));
+
+ $this->assertTrue(file_exists($filePath), 'File at path ' . $filePath . ' does not exist');
+
+ $attachmentId = \BookStack\File::first()->id;
+ $this->call('DELETE', 'files/' . $attachmentId);
+
+ $this->dontSeeInDatabase('files', [
+ 'name' => $fileName
+ ]);
+ $this->assertFalse(file_exists($filePath), 'File at path ' . $filePath . ' was not deleted as expected');
+
+ $this->deleteUploads();
+ }
+
+ public function test_attachment_deletion_on_page_deletion()
+ {
+ $page = \BookStack\Page::first();
+ $this->asAdmin();
+ $fileName = 'deletion_test.txt';
+ $this->uploadFile($fileName, $page->id);
+
+ $filePath = base_path('storage/' . $this->getUploadPath($fileName));
+
+ $this->assertTrue(file_exists($filePath), 'File at path ' . $filePath . ' does not exist');
+ $this->seeInDatabase('files', [
+ 'name' => $fileName
+ ]);
+
+ $this->call('DELETE', $page->getUrl());
+
+ $this->dontSeeInDatabase('files', [
+ 'name' => $fileName
+ ]);
+ $this->assertFalse(file_exists($filePath), 'File at path ' . $filePath . ' was not deleted as expected');
+
+ $this->deleteUploads();
+ }
+}
diff --git a/tests/ImageTest.php b/tests/ImageTest.php
index d9acd4b71..234988ba4 100644
--- a/tests/ImageTest.php
+++ b/tests/ImageTest.php
@@ -10,7 +10,7 @@ class ImageTest extends TestCase
*/
protected function getTestImage($fileName)
{
- return new \Illuminate\Http\UploadedFile(base_path('tests/test-image.jpg'), $fileName, 'image/jpeg', 5238);
+ return new \Illuminate\Http\UploadedFile(base_path('tests/test-data/test-image.jpg'), $fileName, 'image/jpeg', 5238);
}
/**
diff --git a/tests/test-data/test-file.txt b/tests/test-data/test-file.txt
new file mode 100644
index 000000000..4c1f41af9
--- /dev/null
+++ b/tests/test-data/test-file.txt
@@ -0,0 +1 @@
+Hi, This is a test file for testing the upload process.
\ No newline at end of file
diff --git a/tests/test-image.jpg b/tests/test-data/test-image.jpg
similarity index 100%
rename from tests/test-image.jpg
rename to tests/test-data/test-image.jpg