initial
This commit is contained in:
303
tests/plugins/images/test_views.py
Normal file
303
tests/plugins/images/test_views.py
Normal file
@@ -0,0 +1,303 @@
|
||||
import base64
|
||||
import os
|
||||
import re
|
||||
from io import BytesIO
|
||||
|
||||
from django.core.files.uploadedfile import InMemoryUploadedFile
|
||||
from django.urls import reverse
|
||||
from PIL import Image
|
||||
from wiki.core.plugins import registry as plugin_registry
|
||||
from wiki.models import URLPath
|
||||
from wiki.plugins.images import models
|
||||
from wiki.plugins.images.wiki_plugin import ImagePlugin
|
||||
|
||||
from ...base import ArticleWebTestUtils
|
||||
from ...base import DjangoClientTestBase
|
||||
from ...base import RequireRootArticleMixin
|
||||
from ...base import wiki_override_settings
|
||||
|
||||
|
||||
class ImageTests(
|
||||
RequireRootArticleMixin, ArticleWebTestUtils, DjangoClientTestBase
|
||||
):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.article = self.root_article
|
||||
# A black 1x1 gif
|
||||
self.test_data = "R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="
|
||||
|
||||
def _create_gif_filestream_from_base64(self, str_base64, **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.gif")
|
||||
data = base64.b64decode(str_base64)
|
||||
filedata = BytesIO(data)
|
||||
filestream = InMemoryUploadedFile(
|
||||
filedata, None, filename, "image", len(data), None
|
||||
)
|
||||
return filestream
|
||||
|
||||
def _create_test_image(self, path):
|
||||
# Get the form index
|
||||
plugin_index = -1
|
||||
for cnt, plugin_instance in enumerate(plugin_registry.get_sidebar()):
|
||||
if isinstance(plugin_instance, ImagePlugin):
|
||||
plugin_index = cnt
|
||||
break
|
||||
self.assertGreaterEqual(
|
||||
plugin_index, 0, msg="Image plugin not activated"
|
||||
)
|
||||
base_edit_url = reverse("wiki:edit", kwargs={"path": path})
|
||||
url = base_edit_url + f"?f=form{plugin_index:d}"
|
||||
filestream = self._create_gif_filestream_from_base64(self.test_data)
|
||||
response = self.client.post(
|
||||
url,
|
||||
{
|
||||
"unsaved_article_title": self.article.current_revision.title,
|
||||
"unsaved_article_content": self.article.current_revision.content,
|
||||
"image": filestream,
|
||||
"images_save": "1",
|
||||
},
|
||||
)
|
||||
self.assertRedirects(response, base_edit_url)
|
||||
|
||||
def test_index(self):
|
||||
url = reverse("wiki:images_index", kwargs={"path": ""})
|
||||
response = self.client.get(
|
||||
url,
|
||||
)
|
||||
self.assertContains(response, "Images")
|
||||
|
||||
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_image("")
|
||||
# Check the object was created.
|
||||
image = models.Image.objects.get()
|
||||
image_revision = image.current_revision.imagerevision
|
||||
self.assertEqual(image_revision.get_filename(), "test.gif")
|
||||
self.assertEqual(
|
||||
image_revision.image.file.read(), base64.b64decode(self.test_data)
|
||||
)
|
||||
|
||||
def get_article(self, cont, image):
|
||||
urlpath = URLPath.create_urlpath(
|
||||
URLPath.root(), "html_image", title="TestImage", content=cont
|
||||
)
|
||||
if image:
|
||||
self._create_test_image(urlpath.path)
|
||||
return urlpath.article.render()
|
||||
|
||||
def test_image_missing(self):
|
||||
output = self.get_article("[image:1]", False)
|
||||
expected = (
|
||||
'<figure class="thumbnail"><a href="">'
|
||||
'<div class="caption"><em>Image not found</em></div>'
|
||||
'</a><figcaption class="caption"></figcaption></figure>'
|
||||
)
|
||||
self.assertEqual(output, expected)
|
||||
|
||||
def test_image_default(self):
|
||||
output = self.get_article("[image:1]", True)
|
||||
image_rev = models.Image.objects.get().current_revision.imagerevision
|
||||
expected = re.compile(
|
||||
r'<figure class="thumbnail">'
|
||||
r'<a href="' + re.escape(image_rev.image.url) + '">'
|
||||
r'<img src="/?cache/.*\.jpg" alt="test\.gif">'
|
||||
r'</a><figcaption class="caption"></figcaption></figure>'
|
||||
)
|
||||
self.assertRegex(output, expected)
|
||||
|
||||
def test_image_large_right(self):
|
||||
output = self.get_article("[image:1 align:right size:large]", True)
|
||||
image_rev = models.Image.objects.get().current_revision.imagerevision
|
||||
expected = re.compile(
|
||||
r'<figure class="thumbnail float-right">'
|
||||
r'<a href="' + re.escape(image_rev.image.url) + '">'
|
||||
r'<img src="/?cache/.*\.jpg" alt="test\.gif"></a>'
|
||||
r'<figcaption class="caption"></figcaption></figure>'
|
||||
)
|
||||
self.assertRegex(output, expected)
|
||||
|
||||
def test_image_orig(self):
|
||||
output = self.get_article("[image:1 size:orig]", True)
|
||||
image_rev = models.Image.objects.get().current_revision.imagerevision
|
||||
expected = (
|
||||
'<figure class="thumbnail">'
|
||||
'<a href="' + image_rev.image.url + '">'
|
||||
'<img src="' + image_rev.image.url + '" alt="test.gif"></a>'
|
||||
'<figcaption class="caption"></figcaption></figure>'
|
||||
)
|
||||
self.assertEqual(output, expected)
|
||||
|
||||
# https://gist.github.com/guillaumepiot/817a70706587da3bd862835c59ef584e
|
||||
def generate_photo_file(self):
|
||||
file = BytesIO()
|
||||
image = Image.new("RGBA", size=(100, 100), color=(155, 0, 0))
|
||||
image.save(file, "gif")
|
||||
file.name = "test.gif"
|
||||
file.seek(0)
|
||||
return file
|
||||
|
||||
def test_add_revision(self):
|
||||
self._create_test_image(path="")
|
||||
image = models.Image.objects.get()
|
||||
before_edit_rev = image.current_revision.revision_number
|
||||
|
||||
response = self.client.post(
|
||||
reverse(
|
||||
"wiki:images_add_revision",
|
||||
kwargs={
|
||||
"article_id": self.root_article,
|
||||
"image_id": image.pk,
|
||||
"path": "",
|
||||
},
|
||||
),
|
||||
data={"image": self.generate_photo_file()},
|
||||
)
|
||||
self.assertRedirects(
|
||||
response, reverse("wiki:edit", kwargs={"path": ""})
|
||||
)
|
||||
image = models.Image.objects.get()
|
||||
self.assertEqual(models.Image.objects.count(), 1)
|
||||
self.assertEqual(
|
||||
image.current_revision.previous_revision.revision_number,
|
||||
before_edit_rev,
|
||||
)
|
||||
|
||||
def test_delete_restore_revision(self):
|
||||
self._create_test_image(path="")
|
||||
image = models.Image.objects.get()
|
||||
before_edit_rev = image.current_revision.revision_number
|
||||
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
"wiki:images_delete",
|
||||
kwargs={
|
||||
"article_id": self.root_article,
|
||||
"image_id": image.pk,
|
||||
"path": "",
|
||||
},
|
||||
),
|
||||
)
|
||||
self.assertRedirects(
|
||||
response, reverse("wiki:images_index", kwargs={"path": ""})
|
||||
)
|
||||
image = models.Image.objects.get()
|
||||
self.assertEqual(models.Image.objects.count(), 1)
|
||||
self.assertEqual(
|
||||
image.current_revision.previous_revision.revision_number,
|
||||
before_edit_rev,
|
||||
)
|
||||
self.assertIs(image.current_revision.deleted, True)
|
||||
|
||||
# RESTORE
|
||||
before_edit_rev = image.current_revision.revision_number
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
"wiki:images_restore",
|
||||
kwargs={
|
||||
"article_id": self.root_article,
|
||||
"image_id": image.pk,
|
||||
"path": "",
|
||||
},
|
||||
),
|
||||
)
|
||||
self.assertRedirects(
|
||||
response, reverse("wiki:images_index", kwargs={"path": ""})
|
||||
)
|
||||
image = models.Image.objects.get()
|
||||
self.assertEqual(models.Image.objects.count(), 1)
|
||||
self.assertEqual(
|
||||
image.current_revision.previous_revision.revision_number,
|
||||
before_edit_rev,
|
||||
)
|
||||
self.assertFalse(image.current_revision.deleted)
|
||||
|
||||
def test_purge(self):
|
||||
"""
|
||||
Tests that an image is really purged
|
||||
"""
|
||||
self._create_test_image(path="")
|
||||
image = models.Image.objects.get()
|
||||
image_revision = image.current_revision.imagerevision
|
||||
f_path = image_revision.image.file.name
|
||||
|
||||
self.assertIs(os.path.exists(f_path), True)
|
||||
|
||||
response = self.client.post(
|
||||
reverse(
|
||||
"wiki:images_purge",
|
||||
kwargs={
|
||||
"article_id": self.root_article,
|
||||
"image_id": image.pk,
|
||||
"path": "",
|
||||
},
|
||||
),
|
||||
data={"confirm": True},
|
||||
)
|
||||
self.assertRedirects(
|
||||
response, reverse("wiki:images_index", kwargs={"path": ""})
|
||||
)
|
||||
self.assertEqual(models.Image.objects.count(), 0)
|
||||
self.assertIs(os.path.exists(f_path), False)
|
||||
|
||||
def test_add_revision_purge_image(self):
|
||||
"""
|
||||
Tests that an image with more than one revision is really purged
|
||||
"""
|
||||
# use another test to stage this one
|
||||
self.test_add_revision()
|
||||
|
||||
image = models.Image.objects.get()
|
||||
image_revision = image.current_revision.imagerevision
|
||||
f_path = image_revision.image.file.name
|
||||
|
||||
self.assertIs(os.path.exists(f_path), True)
|
||||
|
||||
response = self.client.post(
|
||||
reverse(
|
||||
"wiki:images_purge",
|
||||
kwargs={
|
||||
"article_id": self.root_article,
|
||||
"image_id": image.pk,
|
||||
"path": "",
|
||||
},
|
||||
),
|
||||
data={"confirm": True},
|
||||
)
|
||||
self.assertRedirects(
|
||||
response, reverse("wiki:images_index", kwargs={"path": ""})
|
||||
)
|
||||
self.assertEqual(models.Image.objects.count(), 0)
|
||||
self.assertIs(os.path.exists(f_path), False)
|
||||
|
||||
@wiki_override_settings(ACCOUNT_HANDLING=True)
|
||||
def test_login_on_revision_add(self):
|
||||
self._create_test_image(path="")
|
||||
self.client.logout()
|
||||
image = models.Image.objects.get()
|
||||
url = reverse(
|
||||
"wiki:images_add_revision",
|
||||
kwargs={
|
||||
"article_id": self.root_article,
|
||||
"image_id": image.pk,
|
||||
"path": "",
|
||||
},
|
||||
)
|
||||
response = self.client.post(
|
||||
url, data={"image": self.generate_photo_file()}
|
||||
)
|
||||
self.assertRedirects(
|
||||
response, "{}?next={}".format(reverse("wiki:login"), url)
|
||||
)
|
||||
Reference in New Issue
Block a user