This commit is contained in:
lwark
2025-09-17 07:52:16 -05:00
commit a2ff72dda8
584 changed files with 52247 additions and 0 deletions

View File

View File

@@ -0,0 +1,38 @@
import os
import tempfile
from wiki.models import URLPath
from wiki.plugins.attachments import models
from tests.core.test_commands import TestManagementCommands
class TestAttachmentManagementCommands(TestManagementCommands):
"""
Add some more data
"""
def setUp(self):
super().setUp()
self.test_file = tempfile.NamedTemporaryFile(
"w", delete=False, suffix=".txt"
)
self.test_file.write("test")
self.child1 = URLPath.create_urlpath(
self.root, "test-slug", title="Test 1"
)
self.attachment1 = models.Attachment.objects.create(
article=self.child1.article
)
self.attachment1_revision1 = models.AttachmentRevision.objects.create(
attachment=self.attachment1,
file=self.test_file.name,
)
def tearDown(self):
os.unlink(self.test_file.name)
super().tearDown()

View File

@@ -0,0 +1,42 @@
from wiki.plugins.attachments.models import Attachment
from wiki.plugins.attachments.models import AttachmentRevision
from tests.base import RequireRootArticleMixin
from tests.base import TestBase
class AttachmentRevisionTests(RequireRootArticleMixin, TestBase):
def setUp(self):
super().setUp()
self.attachment = Attachment.objects.create(
article=self.root_article,
original_filename="blah.txt",
)
self.revision = AttachmentRevision.objects.create(
attachment=self.attachment,
file=None,
description="muh",
revision_number=1,
)
def test_revision_no_file(self):
# Intentionally, there are no asserts, as the test just needs to
# target an if-branch in the pre-delete signal for AttachmentRevision
self.revision.delete()
def test_revision_file_size(self):
self.assertIsNone(self.revision.get_size())
def test_get_filename_no_file(self):
self.assertIsNone(self.revision.get_filename())
def test_str(self):
self.assertEqual(
str(self.revision),
"%s: %s (r%d)"
% (
"Root Article",
"blah.txt",
1,
),
)

View File

@@ -0,0 +1,183 @@
from io import BytesIO
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.urls import reverse
from wiki.models import URLPath
from ...base import ArticleWebTestUtils
from ...base import DjangoClientTestBase
from ...base import RequireRootArticleMixin
class AttachmentTests(
RequireRootArticleMixin, ArticleWebTestUtils, DjangoClientTestBase
):
def setUp(self):
super().setUp()
self.article = self.root_article
self.test_data = "This is a plain text file"
self.test_description = "My file"
def _createTxtFilestream(self, strData, **kwargs):
"""
Helper function to create filestream for upload.
Parameters :
strData : str, test string data
Optional Arguments :
filename : str, Defaults to 'test.txt'
"""
filename = kwargs.get("filename", "test.txt")
data = strData.encode("utf-8")
filedata = BytesIO(data)
filestream = InMemoryUploadedFile(
filedata, None, filename, "text", len(data), None
)
return filestream
def _create_test_attachment(self, path):
url = reverse("wiki:attachments_index", kwargs={"path": path})
filestream = self._createTxtFilestream(self.test_data)
response = self.client.post(
url,
{
"description": self.test_description,
"file": filestream,
"save": "1",
},
)
self.assertRedirects(response, url)
def test_upload(self):
"""
Tests that simple file upload uploads correctly
Uploading a file should preserve the original filename.
Uploading should not modify file in any way.
"""
self._create_test_attachment("")
# Check the object was created.
attachment = self.article.shared_plugins_set.all()[0].attachment
self.assertEqual(attachment.original_filename, "test.txt")
self.assertEqual(
attachment.current_revision.file.file.read(),
self.test_data.encode("utf-8"),
)
def test_replace(self):
"""
Tests that previous revisions are not deleted
Tests that only the most recent revision is deleted when
"replace" is checked.
"""
# Upload initial file
url = reverse("wiki:attachments_index", kwargs={"path": ""})
data = "This is a plain text file"
filestream = self._createTxtFilestream(data)
self.client.post(
url, {"description": "My file", "file": filestream, "save": "1"}
)
attachment = self.article.shared_plugins_set.all()[0].attachment
# uploading for the first time should mean that there is only one revision.
self.assertEqual(attachment.attachmentrevision_set.count(), 1)
# Change url to replacement page.
url = reverse(
"wiki:attachments_replace",
kwargs={
"attachment_id": attachment.id,
"article_id": self.article.id,
},
)
# Upload replacement without removing revisions
replacement_data = data + " And this is my edit"
replacement_filestream = self._createTxtFilestream(replacement_data)
self.client.post(
url,
{
"description": "Replacement upload",
"file": replacement_filestream,
},
)
attachment = self.article.shared_plugins_set.all()[0].attachment
# Revision count should be two
self.assertEqual(attachment.attachmentrevision_set.count(), 2)
# Original filenames should not be modified
self.assertEqual(attachment.original_filename, "test.txt")
# Latest revision should equal replacment_data
self.assertEqual(
attachment.current_revision.file.file.read(),
replacement_data.encode("utf-8"),
)
first_replacement = attachment.current_revision
# Upload another replacement, this time removing most recent revision
replacement_data2 = data + " And this is a different edit"
replacement_filestream2 = self._createTxtFilestream(replacement_data2)
self.client.post(
url,
{
"description": "Replacement upload",
"file": replacement_filestream2,
"replace": "on",
},
)
attachment = self.article.shared_plugins_set.all()[0].attachment
# Revision count should still be two
self.assertEqual(attachment.attachmentrevision_set.count(), 2)
# Latest revision should equal replacment_data2
self.assertEqual(
attachment.current_revision.file.file.read(),
replacement_data2.encode("utf-8"),
)
# The first replacement should no longer be in the filehistory
self.assertNotIn(
first_replacement, attachment.attachmentrevision_set.all()
)
def test_search(self):
"""
Call the search view
"""
self._create_test_attachment("")
url = reverse("wiki:attachments_search", kwargs={"path": ""})
response = self.client.get(url, {"query": self.test_description})
self.assertContains(response, self.test_description)
def get_article(self, cont):
urlpath = URLPath.create_urlpath(
URLPath.root(), "html_attach", title="TestAttach", content=cont
)
self._create_test_attachment(urlpath.path)
return urlpath.article.render()
def test_render(self):
output = self.get_article("[attachment:1]")
expected = (
r'<span class="attachment"><a href=".*attachments/download/1/"'
r' title="Click to download test\.txt">\s*test\.txt\s*</a>'
)
self.assertRegex(output, expected)
def test_render_missing(self):
output = self.get_article("[attachment:2]")
expected = r'<span class="attachment attachment-deleted">\s*Attachment with ID #2 is deleted.\s*</span>'
self.assertRegex(output, expected)
def test_render_title(self):
output = self.get_article('[attachment:1 title:"Test title"]')
expected = (
r'<span class="attachment"><a href=".*attachments/download/1/"'
r' title="Click to download test\.txt">\s*Test title\s*</a>'
)
self.assertRegex(output, expected)
def test_render_title_size(self):
output = self.get_article('[attachment:1 title:"Test title 2" size]')
expected = (
r'<span class="attachment"><a href=".*attachments/download/1/"'
r' title="Click to download test\.txt">\s*Test title 2 \[25[^b]bytes\]\s*</a>'
)
self.assertRegex(output, expected)