mirror of
https://github.com/sissbruecker/linkding.git
synced 2025-08-13 13:39:27 +02:00
Add bookmark assets API (#1003)
* Add list, details and download endpoints * Avoid using multiple DefaultRoute instances * Add upload endpoint * Add docs * Allow configuring max request content length * Add option for disabling uploads * Remove gzip field * Add delete endpoint
This commit is contained in:
@@ -1,14 +1,21 @@
|
||||
import random
|
||||
import gzip
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import shutil
|
||||
import tempfile
|
||||
from datetime import datetime
|
||||
from typing import List
|
||||
from unittest import TestCase
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import override_settings
|
||||
from django.utils import timezone
|
||||
from django.utils.crypto import get_random_string
|
||||
from rest_framework import status
|
||||
from rest_framework.authtoken.models import Token
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from bookmarks.models import Bookmark, BookmarkAsset, Tag
|
||||
@@ -17,6 +24,16 @@ from bookmarks.models import Bookmark, BookmarkAsset, Tag
|
||||
class BookmarkFactoryMixin:
|
||||
user = None
|
||||
|
||||
def setup_temp_assets_dir(self):
|
||||
self.assets_dir = tempfile.mkdtemp()
|
||||
self.settings_override = override_settings(LD_ASSET_FOLDER=self.assets_dir)
|
||||
self.settings_override.enable()
|
||||
self.addCleanup(self.cleanup_temp_assets_dir)
|
||||
|
||||
def cleanup_temp_assets_dir(self):
|
||||
shutil.rmtree(self.assets_dir)
|
||||
self.settings_override.disable()
|
||||
|
||||
def get_or_create_test_user(self):
|
||||
if self.user is None:
|
||||
self.user = User.objects.create_user(
|
||||
@@ -182,6 +199,24 @@ class BookmarkFactoryMixin:
|
||||
asset.save()
|
||||
return asset
|
||||
|
||||
def setup_asset_file(self, asset: BookmarkAsset, file_content: str = "test"):
|
||||
filepath = os.path.join(settings.LD_ASSET_FOLDER, asset.file)
|
||||
if asset.gzip:
|
||||
with gzip.open(filepath, "wb") as f:
|
||||
f.write(file_content.encode())
|
||||
else:
|
||||
with open(filepath, "w") as f:
|
||||
f.write(file_content)
|
||||
|
||||
def read_asset_file(self, asset: BookmarkAsset):
|
||||
filepath = os.path.join(settings.LD_ASSET_FOLDER, asset.file)
|
||||
with open(filepath, "rb") as f:
|
||||
return f.read()
|
||||
|
||||
def has_asset_file(self, asset: BookmarkAsset):
|
||||
filepath = os.path.join(settings.LD_ASSET_FOLDER, asset.file)
|
||||
return os.path.exists(filepath)
|
||||
|
||||
def setup_tag(self, user: User = None, name: str = ""):
|
||||
if user is None:
|
||||
user = self.get_or_create_test_user()
|
||||
@@ -290,6 +325,12 @@ class TagCloudTestMixin(TestCase, HtmlTestMixin):
|
||||
|
||||
|
||||
class LinkdingApiTestCase(APITestCase):
|
||||
def authenticate(self):
|
||||
self.api_token = Token.objects.get_or_create(
|
||||
user=self.get_or_create_test_user()
|
||||
)[0]
|
||||
self.client.credentials(HTTP_AUTHORIZATION="Token " + self.api_token.key)
|
||||
|
||||
def get(self, url, expected_status_code=status.HTTP_200_OK):
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, expected_status_code)
|
||||
|
@@ -1,12 +1,10 @@
|
||||
import datetime
|
||||
import gzip
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
from unittest import mock
|
||||
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.test import TestCase, override_settings
|
||||
from django.test import TestCase
|
||||
from django.utils import timezone
|
||||
|
||||
from bookmarks.models import BookmarkAsset
|
||||
@@ -17,12 +15,9 @@ from bookmarks.tests.helpers import BookmarkFactoryMixin, disable_logging
|
||||
class AssetServiceTestCase(TestCase, BookmarkFactoryMixin):
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.setup_temp_assets_dir()
|
||||
self.get_or_create_test_user()
|
||||
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.settings_override = override_settings(LD_ASSET_FOLDER=self.temp_dir)
|
||||
self.settings_override.enable()
|
||||
|
||||
self.html_content = "<html><body><h1>Hello, World!</h1></body></html>"
|
||||
self.mock_singlefile_create_snapshot_patcher = mock.patch(
|
||||
"bookmarks.services.singlefile.create_snapshot",
|
||||
@@ -35,12 +30,11 @@ class AssetServiceTestCase(TestCase, BookmarkFactoryMixin):
|
||||
)
|
||||
|
||||
def tearDown(self) -> None:
|
||||
shutil.rmtree(self.temp_dir)
|
||||
self.mock_singlefile_create_snapshot_patcher.stop()
|
||||
|
||||
def get_saved_snapshot_file(self):
|
||||
# look up first file in the asset folder
|
||||
files = os.listdir(self.temp_dir)
|
||||
files = os.listdir(self.assets_dir)
|
||||
if files:
|
||||
return files[0]
|
||||
|
||||
@@ -70,9 +64,9 @@ class AssetServiceTestCase(TestCase, BookmarkFactoryMixin):
|
||||
assets.create_snapshot(asset)
|
||||
|
||||
expected_temp_filename = "snapshot_2023-08-11_214511_https___example.com.tmp"
|
||||
expected_temp_filepath = os.path.join(self.temp_dir, expected_temp_filename)
|
||||
expected_temp_filepath = os.path.join(self.assets_dir, expected_temp_filename)
|
||||
expected_filename = "snapshot_2023-08-11_214511_https___example.com.html.gz"
|
||||
expected_filepath = os.path.join(self.temp_dir, expected_filename)
|
||||
expected_filepath = os.path.join(self.assets_dir, expected_filename)
|
||||
|
||||
# should call singlefile.create_snapshot with the correct arguments
|
||||
self.mock_singlefile_create_snapshot.assert_called_once_with(
|
||||
@@ -137,7 +131,7 @@ class AssetServiceTestCase(TestCase, BookmarkFactoryMixin):
|
||||
self.assertTrue(saved_file_name.endswith("_https___example.com.html.gz"))
|
||||
|
||||
# gzip file should contain the correct content
|
||||
with gzip.open(os.path.join(self.temp_dir, saved_file_name), "rb") as gz_file:
|
||||
with gzip.open(os.path.join(self.assets_dir, saved_file_name), "rb") as gz_file:
|
||||
self.assertEqual(gz_file.read().decode(), self.html_content)
|
||||
|
||||
# should create asset
|
||||
@@ -195,7 +189,7 @@ class AssetServiceTestCase(TestCase, BookmarkFactoryMixin):
|
||||
self.assertTrue(saved_file_name.endswith("_test_file.txt"))
|
||||
|
||||
# file should contain the correct content
|
||||
with open(os.path.join(self.temp_dir, saved_file_name), "rb") as file:
|
||||
with open(os.path.join(self.assets_dir, saved_file_name), "rb") as file:
|
||||
self.assertEqual(file.read(), file_content)
|
||||
|
||||
# should create asset
|
||||
|
@@ -230,6 +230,27 @@ class BookmarkActionViewTestCase(
|
||||
|
||||
mock_upload_asset.assert_not_called()
|
||||
|
||||
@override_settings(LD_DISABLE_ASSET_UPLOAD=True)
|
||||
def test_upload_asset_disabled(self):
|
||||
bookmark = self.setup_bookmark()
|
||||
file_content = b"file content"
|
||||
upload_file = SimpleUploadedFile("test.txt", file_content)
|
||||
|
||||
response = self.client.post(
|
||||
reverse("bookmarks:index.action"),
|
||||
{"upload_asset": bookmark.id, "upload_asset_file": upload_file},
|
||||
)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_upload_asset_without_file(self):
|
||||
bookmark = self.setup_bookmark()
|
||||
|
||||
response = self.client.post(
|
||||
reverse("bookmarks:index.action"),
|
||||
{"upload_asset": bookmark.id},
|
||||
)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_remove_asset(self):
|
||||
bookmark = self.setup_bookmark()
|
||||
asset = self.setup_asset(bookmark)
|
||||
|
@@ -11,19 +11,11 @@ from bookmarks.tests.helpers import (
|
||||
|
||||
class BookmarkAssetViewTestCase(TestCase, BookmarkFactoryMixin):
|
||||
def setUp(self) -> None:
|
||||
self.setup_temp_assets_dir()
|
||||
user = self.get_or_create_test_user()
|
||||
self.client.force_login(user)
|
||||
|
||||
def tearDown(self):
|
||||
temp_files = [
|
||||
f for f in os.listdir(settings.LD_ASSET_FOLDER) if f.startswith("temp")
|
||||
]
|
||||
for temp_file in temp_files:
|
||||
os.remove(os.path.join(settings.LD_ASSET_FOLDER, temp_file))
|
||||
|
||||
def setup_asset_file(self, filename):
|
||||
if not os.path.exists(settings.LD_ASSET_FOLDER):
|
||||
os.makedirs(settings.LD_ASSET_FOLDER)
|
||||
filepath = os.path.join(settings.LD_ASSET_FOLDER, filename)
|
||||
with open(filepath, "w") as f:
|
||||
f.write("test")
|
||||
|
@@ -1,9 +1,7 @@
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from django.conf import settings
|
||||
from django.test import TestCase, override_settings
|
||||
from django.test import TestCase
|
||||
|
||||
from bookmarks.services import bookmarks
|
||||
from bookmarks.tests.helpers import BookmarkFactoryMixin
|
||||
@@ -11,13 +9,7 @@ from bookmarks.tests.helpers import BookmarkFactoryMixin
|
||||
|
||||
class BookmarkAssetsTestCase(TestCase, BookmarkFactoryMixin):
|
||||
def setUp(self):
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.override = override_settings(LD_ASSET_FOLDER=self.temp_dir)
|
||||
self.override.enable()
|
||||
|
||||
def tearDown(self):
|
||||
self.override.disable()
|
||||
shutil.rmtree(self.temp_dir)
|
||||
self.setup_temp_assets_dir()
|
||||
|
||||
def setup_asset_file(self, filename):
|
||||
filepath = os.path.join(settings.LD_ASSET_FOLDER, filename)
|
||||
|
340
bookmarks/tests/test_bookmark_assets_api.py
Normal file
340
bookmarks/tests/test_bookmark_assets_api.py
Normal file
@@ -0,0 +1,340 @@
|
||||
import io
|
||||
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.test import override_settings
|
||||
from django.urls import reverse
|
||||
from rest_framework import status
|
||||
|
||||
from bookmarks.models import BookmarkAsset
|
||||
from bookmarks.tests.helpers import LinkdingApiTestCase, BookmarkFactoryMixin
|
||||
|
||||
|
||||
class BookmarkAssetsApiTestCase(LinkdingApiTestCase, BookmarkFactoryMixin):
|
||||
def setUp(self):
|
||||
self.setup_temp_assets_dir()
|
||||
|
||||
def assertAsset(self, asset: BookmarkAsset, data: dict):
|
||||
self.assertEqual(asset.id, data["id"])
|
||||
self.assertEqual(asset.bookmark.id, data["bookmark"])
|
||||
self.assertEqual(
|
||||
asset.date_created.isoformat().replace("+00:00", "Z"), data["date_created"]
|
||||
)
|
||||
self.assertEqual(asset.file_size, data["file_size"])
|
||||
self.assertEqual(asset.asset_type, data["asset_type"])
|
||||
self.assertEqual(asset.content_type, data["content_type"])
|
||||
self.assertEqual(asset.display_name, data["display_name"])
|
||||
self.assertEqual(asset.status, data["status"])
|
||||
|
||||
def test_asset_list(self):
|
||||
self.authenticate()
|
||||
|
||||
bookmark1 = self.setup_bookmark(url="https://example1.com")
|
||||
bookmark1_assets = [
|
||||
self.setup_asset(bookmark=bookmark1),
|
||||
self.setup_asset(bookmark=bookmark1),
|
||||
self.setup_asset(bookmark=bookmark1),
|
||||
]
|
||||
|
||||
bookmark2 = self.setup_bookmark(url="https://example2.com")
|
||||
bookmark2_assets = [
|
||||
self.setup_asset(bookmark=bookmark2),
|
||||
self.setup_asset(bookmark=bookmark2),
|
||||
self.setup_asset(bookmark=bookmark2),
|
||||
]
|
||||
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-list", kwargs={"bookmark_id": bookmark1.id}
|
||||
)
|
||||
response = self.get(url, expected_status_code=status.HTTP_200_OK)
|
||||
self.assertEqual(len(response.data["results"]), 3)
|
||||
self.assertAsset(bookmark1_assets[0], response.data["results"][0])
|
||||
self.assertAsset(bookmark1_assets[1], response.data["results"][1])
|
||||
self.assertAsset(bookmark1_assets[2], response.data["results"][2])
|
||||
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-list", kwargs={"bookmark_id": bookmark2.id}
|
||||
)
|
||||
response = self.get(url, expected_status_code=status.HTTP_200_OK)
|
||||
self.assertEqual(len(response.data["results"]), 3)
|
||||
self.assertAsset(bookmark2_assets[0], response.data["results"][0])
|
||||
self.assertAsset(bookmark2_assets[1], response.data["results"][1])
|
||||
self.assertAsset(bookmark2_assets[2], response.data["results"][2])
|
||||
|
||||
def test_asset_list_only_returns_assets_for_own_bookmarks(self):
|
||||
self.authenticate()
|
||||
|
||||
other_user = self.setup_user()
|
||||
bookmark = self.setup_bookmark(user=other_user)
|
||||
self.setup_asset(bookmark=bookmark)
|
||||
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-list", kwargs={"bookmark_id": bookmark.id}
|
||||
)
|
||||
self.get(url, expected_status_code=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_asset_list_requires_authentication(self):
|
||||
bookmark = self.setup_bookmark()
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-list", kwargs={"bookmark_id": bookmark.id}
|
||||
)
|
||||
self.get(url, expected_status_code=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def test_asset_detail(self):
|
||||
self.authenticate()
|
||||
|
||||
bookmark = self.setup_bookmark()
|
||||
asset = self.setup_asset(
|
||||
bookmark=bookmark,
|
||||
asset_type=BookmarkAsset.TYPE_UPLOAD,
|
||||
file="cats.png",
|
||||
file_size=1234,
|
||||
content_type="image/png",
|
||||
display_name="cats.png",
|
||||
status=BookmarkAsset.STATUS_PENDING,
|
||||
gzip=False,
|
||||
)
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-detail",
|
||||
kwargs={"bookmark_id": asset.bookmark.id, "pk": asset.id},
|
||||
)
|
||||
response = self.get(url, expected_status_code=status.HTTP_200_OK)
|
||||
self.assertAsset(asset, response.data)
|
||||
|
||||
def test_asset_detail_only_returns_asset_for_own_bookmarks(self):
|
||||
self.authenticate()
|
||||
|
||||
other_user = self.setup_user()
|
||||
bookmark = self.setup_bookmark(user=other_user)
|
||||
asset = self.setup_asset(bookmark=bookmark)
|
||||
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-detail",
|
||||
kwargs={"bookmark_id": asset.bookmark.id, "pk": asset.id},
|
||||
)
|
||||
self.get(url, expected_status_code=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_asset_detail_requires_authentication(self):
|
||||
bookmark = self.setup_bookmark()
|
||||
asset = self.setup_asset(bookmark=bookmark)
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-detail",
|
||||
kwargs={"bookmark_id": asset.bookmark.id, "pk": asset.id},
|
||||
)
|
||||
self.get(url, expected_status_code=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def test_asset_download_with_snapshot_asset(self):
|
||||
self.authenticate()
|
||||
|
||||
file_content = """
|
||||
<html>
|
||||
<head>
|
||||
<title>Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Test</h1>
|
||||
</body>
|
||||
"""
|
||||
bookmark = self.setup_bookmark()
|
||||
asset = self.setup_asset(
|
||||
bookmark=bookmark,
|
||||
asset_type=BookmarkAsset.TYPE_SNAPSHOT,
|
||||
display_name="Snapshot from today",
|
||||
content_type="text/html",
|
||||
gzip=True,
|
||||
)
|
||||
self.setup_asset_file(asset=asset, file_content=file_content)
|
||||
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-download",
|
||||
kwargs={"bookmark_id": asset.bookmark.id, "pk": asset.id},
|
||||
)
|
||||
response = self.get(url, expected_status_code=status.HTTP_200_OK)
|
||||
|
||||
self.assertEqual(response["Content-Type"], "text/html")
|
||||
self.assertEqual(
|
||||
response["Content-Disposition"],
|
||||
'attachment; filename="Snapshot from today.html"',
|
||||
)
|
||||
content = b"".join(response.streaming_content).decode("utf-8")
|
||||
self.assertEqual(content, file_content)
|
||||
|
||||
def test_asset_download_with_uploaded_asset(self):
|
||||
self.authenticate()
|
||||
|
||||
file_content = "some file content"
|
||||
bookmark = self.setup_bookmark()
|
||||
asset = self.setup_asset(
|
||||
bookmark=bookmark,
|
||||
asset_type=BookmarkAsset.TYPE_UPLOAD,
|
||||
display_name="cats.png",
|
||||
content_type="image/png",
|
||||
gzip=False,
|
||||
)
|
||||
self.setup_asset_file(asset=asset, file_content=file_content)
|
||||
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-download",
|
||||
kwargs={"bookmark_id": asset.bookmark.id, "pk": asset.id},
|
||||
)
|
||||
response = self.get(url, expected_status_code=status.HTTP_200_OK)
|
||||
|
||||
self.assertEqual(response["Content-Type"], "image/png")
|
||||
self.assertEqual(
|
||||
response["Content-Disposition"],
|
||||
'attachment; filename="cats.png"',
|
||||
)
|
||||
content = b"".join(response.streaming_content).decode("utf-8")
|
||||
self.assertEqual(content, file_content)
|
||||
|
||||
def test_asset_download_with_missing_file(self):
|
||||
self.authenticate()
|
||||
|
||||
bookmark = self.setup_bookmark()
|
||||
asset = self.setup_asset(
|
||||
bookmark=bookmark,
|
||||
asset_type=BookmarkAsset.TYPE_UPLOAD,
|
||||
display_name="cats.png",
|
||||
content_type="image/png",
|
||||
gzip=False,
|
||||
)
|
||||
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-download",
|
||||
kwargs={"bookmark_id": asset.bookmark.id, "pk": asset.id},
|
||||
)
|
||||
self.get(url, expected_status_code=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_asset_download_only_returns_asset_for_own_bookmarks(self):
|
||||
self.authenticate()
|
||||
|
||||
other_user = self.setup_user()
|
||||
bookmark = self.setup_bookmark(user=other_user)
|
||||
asset = self.setup_asset(bookmark=bookmark)
|
||||
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-download",
|
||||
kwargs={"bookmark_id": asset.bookmark.id, "pk": asset.id},
|
||||
)
|
||||
self.get(url, expected_status_code=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_asset_download_requires_authentication(self):
|
||||
bookmark = self.setup_bookmark()
|
||||
asset = self.setup_asset(bookmark=bookmark)
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-download",
|
||||
kwargs={"bookmark_id": asset.bookmark.id, "pk": asset.id},
|
||||
)
|
||||
self.get(url, expected_status_code=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def create_upload_body(self):
|
||||
url = "https://example.com"
|
||||
file_content = b"dummy content"
|
||||
file = io.BytesIO(file_content)
|
||||
file.name = "snapshot.html"
|
||||
|
||||
return {"url": url, "file": file}
|
||||
|
||||
def test_upload_asset(self):
|
||||
self.authenticate()
|
||||
|
||||
bookmark = self.setup_bookmark()
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-upload", kwargs={"bookmark_id": bookmark.id}
|
||||
)
|
||||
file_content = b"test file content"
|
||||
file_name = "test.txt"
|
||||
file = SimpleUploadedFile(file_name, file_content, content_type="text/plain")
|
||||
|
||||
response = self.client.post(url, {"file": file}, format="multipart")
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
|
||||
asset = BookmarkAsset.objects.get(id=response.data["id"])
|
||||
self.assertEqual(asset.bookmark, bookmark)
|
||||
self.assertEqual(asset.display_name, file_name)
|
||||
self.assertEqual(asset.asset_type, BookmarkAsset.TYPE_UPLOAD)
|
||||
self.assertEqual(asset.content_type, "text/plain")
|
||||
self.assertEqual(asset.file_size, len(file_content))
|
||||
self.assertFalse(asset.gzip)
|
||||
|
||||
content = self.read_asset_file(asset)
|
||||
self.assertEqual(content, file_content)
|
||||
|
||||
def test_upload_asset_with_missing_file(self):
|
||||
self.authenticate()
|
||||
|
||||
bookmark = self.setup_bookmark()
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-upload", kwargs={"bookmark_id": bookmark.id}
|
||||
)
|
||||
|
||||
response = self.client.post(url, {}, format="multipart")
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def test_upload_asset_only_works_for_own_bookmarks(self):
|
||||
self.authenticate()
|
||||
|
||||
other_user = self.setup_user()
|
||||
bookmark = self.setup_bookmark(user=other_user)
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-upload", kwargs={"bookmark_id": bookmark.id}
|
||||
)
|
||||
|
||||
response = self.client.post(url, {}, format="multipart")
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_upload_asset_requires_authentication(self):
|
||||
bookmark = self.setup_bookmark()
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-upload", kwargs={"bookmark_id": bookmark.id}
|
||||
)
|
||||
|
||||
response = self.client.post(url, {}, format="multipart")
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
@override_settings(LD_DISABLE_ASSET_UPLOAD=True)
|
||||
def test_upload_asset_disabled(self):
|
||||
self.authenticate()
|
||||
bookmark = self.setup_bookmark()
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-upload", kwargs={"bookmark_id": bookmark.id}
|
||||
)
|
||||
response = self.client.post(url, {}, format="multipart")
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
def test_delete_asset(self):
|
||||
self.authenticate()
|
||||
|
||||
bookmark = self.setup_bookmark()
|
||||
asset = self.setup_asset(bookmark=bookmark)
|
||||
self.setup_asset_file(asset=asset)
|
||||
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-detail",
|
||||
kwargs={"bookmark_id": asset.bookmark.id, "pk": asset.id},
|
||||
)
|
||||
self.delete(url, expected_status_code=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
self.assertFalse(BookmarkAsset.objects.filter(id=asset.id).exists())
|
||||
self.assertFalse(self.has_asset_file(asset))
|
||||
|
||||
def test_delete_asset_only_works_for_own_bookmarks(self):
|
||||
self.authenticate()
|
||||
|
||||
other_user = self.setup_user()
|
||||
bookmark = self.setup_bookmark(user=other_user)
|
||||
asset = self.setup_asset(bookmark=bookmark)
|
||||
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-detail",
|
||||
kwargs={"bookmark_id": asset.bookmark.id, "pk": asset.id},
|
||||
)
|
||||
self.delete(url, expected_status_code=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_delete_asset_requires_authentication(self):
|
||||
bookmark = self.setup_bookmark()
|
||||
asset = self.setup_asset(bookmark=bookmark)
|
||||
url = reverse(
|
||||
"bookmarks:bookmark_asset-detail",
|
||||
kwargs={"bookmark_id": asset.bookmark.id, "pk": asset.id},
|
||||
)
|
||||
self.delete(url, expected_status_code=status.HTTP_401_UNAUTHORIZED)
|
@@ -668,6 +668,18 @@ class BookmarkDetailsModalTestCase(TestCase, BookmarkFactoryMixin, HtmlTestMixin
|
||||
self.assertIsNone(create_snapshot)
|
||||
self.assertIsNotNone(upload_asset)
|
||||
|
||||
@override_settings(LD_DISABLE_ASSET_UPLOAD=True)
|
||||
def test_asset_list_actions_visibility_with_uploads_disabled(self):
|
||||
bookmark = self.setup_bookmark()
|
||||
|
||||
soup = self.get_index_details_modal(bookmark)
|
||||
create_snapshot = soup.find(
|
||||
"button", {"type": "submit", "name": "create_html_snapshot"}
|
||||
)
|
||||
upload_asset = soup.find("button", {"type": "submit", "name": "upload_asset"})
|
||||
self.assertIsNone(create_snapshot)
|
||||
self.assertIsNone(upload_asset)
|
||||
|
||||
def test_asset_without_file(self):
|
||||
bookmark = self.setup_bookmark()
|
||||
asset = self.setup_asset(bookmark)
|
||||
|
@@ -5,6 +5,7 @@ from collections import OrderedDict
|
||||
from unittest.mock import patch, ANY
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import override_settings
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from rest_framework import status
|
||||
@@ -1285,3 +1286,13 @@ class BookmarksApiTestCase(LinkdingApiTestCase, BookmarkFactoryMixin):
|
||||
self.assertEqual(
|
||||
response.data["error"], "Both 'url' and 'file' parameters are required."
|
||||
)
|
||||
|
||||
@override_settings(LD_DISABLE_ASSET_UPLOAD=True)
|
||||
def test_singlefile_upload_disabled(self):
|
||||
self.authenticate()
|
||||
self.client.post(
|
||||
reverse("bookmarks:bookmark-singlefile"),
|
||||
self.create_singlefile_upload_body(),
|
||||
format="multipart",
|
||||
expected_status_code=status.HTTP_403_FORBIDDEN,
|
||||
)
|
||||
|
Reference in New Issue
Block a user