Commit dffc67d3 authored by Seb's avatar Seb
Browse files

Added tests for template tag, index and add views

parent 759e4c69
...@@ -3,3 +3,4 @@ ...@@ -3,3 +3,4 @@
dist/ dist/
./settings.py ./settings.py
venv/ venv/
tests.sqlite3
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.urlresolvers import reverse
from django.test import TestCase
from wagtail.tests.utils import WagtailTestUtils
from wagtail.wagtailcore.models import Collection
from tests.utils import create_test_video_file
from wagtailvideos.models import Video
class TestVideoIndexView(TestCase, WagtailTestUtils):
def setUp(self):
self.login()
def get(self, params={}):
return self.client.get(reverse('wagtailvideos:index'), params)
def test_simple(self):
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'wagtailvideos/videos/index.html')
self.assertContains(response, "Add a video")
def test_search(self):
response = self.get({'q': "Hello"})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['query_string'], "Hello")
def test_pagination(self):
pages = ['0', '1', '-1', '9999', 'Not a page']
for page in pages:
response = self.get({'p': page})
self.assertEqual(response.status_code, 200)
def test_ordering(self):
orderings = ['title', '-created_at']
for ordering in orderings:
response = self.get({'ordering': ordering})
self.assertEqual(response.status_code, 200)
class TestVidoAddView(TestCase, WagtailTestUtils):
def setUp(self):
self.login()
def get(self, params={}):
return self.client.get(reverse('wagtailvideos:add'), params)
def post(self, post_data={}):
return self.client.post(reverse('wagtailvideos:add'), post_data)
def test_get(self):
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'wagtailvideos/videos/add.html')
# as standard, only the root collection exists and so no 'Collection' option
# is displayed on the form
self.assertNotContains(response, '<label for="id_collection">')
# Ensure the form supports file uploads
self.assertContains(response, 'enctype="multipart/form-data"')
def test_get_with_collections(self):
root_collection = Collection.get_first_root_node()
collection_name = "Takeflight manifesto"
root_collection.add_child(name=collection_name)
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'wagtailvideos/videos/add.html')
self.assertContains(response, '<label for="id_collection">')
self.assertContains(response, collection_name)
def test_add(self):
video_file = create_test_video_file()
title = "Test Video"
response = self.post({
'title': title,
'file': SimpleUploadedFile('small.mp4', video_file.read(), "video/mp4"),
})
# Should redirect back to index
self.assertRedirects(response, reverse('wagtailvideos:index'))
# Check that the image was created
videos = Video.objects.filter(title=title)
self.assertEqual(videos.count(), 1)
# Test that extra fields were populated from post_save signal
video = videos.first()
self.assertTrue(video.thumbnail)
self.assertTrue(video.duration)
self.assertTrue(video.file_size)
# Test that it was placed in the root collection
root_collection = Collection.get_first_root_node()
self.assertEqual(video.collection, root_collection)
def test_add_no_file_selected(self):
response = self.post({
'title': "nothing here",
})
# Shouldn't redirect anywhere
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'wagtailvideos/videos/add.html')
# The form should have an error
self.assertFormError(response, 'form', 'file', "This field is required.")
import unittest from django.template import Context, Template, TemplateSyntaxError
from django.test import TestCase from django.test import TestCase
from tests.utils import create_test_video from tests.utils import create_test_video_file
from wagtailvideos.models import Video from wagtailvideos.models import Video
...@@ -10,9 +9,25 @@ class TestVideoTag(TestCase): ...@@ -10,9 +9,25 @@ class TestVideoTag(TestCase):
def setUp(self): def setUp(self):
self.video = Video.objects.create( self.video = Video.objects.create(
title="Test Video", title="Test Video",
file=create_test_video() file=create_test_video_file()
) )
def test_whatever(self): def render_video_tag(self, video, attrs=''):
print(self.video.file.path) temp = Template('{% load wagtailvideos_tags %}{% video video_obj ' + attrs + ' %}')
pass context = Context({'video_obj':video})
return temp.render(context)
def test_video_tag(self):
tag = self.render_video_tag(self.video)
self.assertTrue(self.video.url in tag)
def test_extra_attributes(self):
tag = self.render_video_tag(self.video, attrs='controls width=560')
self.assertTrue('controls' in tag)
self.assertTrue('width="560"' in tag)
def test_bad_video(self):
try:
self.render_video_tag(None)
except TemplateSyntaxError as e:
self.assertEqual(str(e), 'video tag requires a Video object as the first parameter')
...@@ -5,6 +5,6 @@ from django.core.files import File ...@@ -5,6 +5,6 @@ from django.core.files import File
import tests import tests
def create_test_video(): def create_test_video_file():
video_file = open(os.path.join(tests.__path__[0], 'small.mp4'), 'rb') video_file = open(os.path.join(tests.__path__[0], 'small.mp4'), 'rb')
return File(video_file, name='small.mp4') return File(video_file, name='small.mp4')
...@@ -117,7 +117,7 @@ class AbstractVideo(CollectionMember, TagSearchable): ...@@ -117,7 +117,7 @@ class AbstractVideo(CollectionMember, TagSearchable):
file_path = self.file.path file_path = self.file.path
try: try:
show_format = subprocess.check_output(['ffprobe', '-i', file_path, '-show_format']) show_format = subprocess.check_output(['ffprobe', '-i', file_path, '-show_format', '-v', 'quiet'])
show_format = show_format.decode("utf-8") show_format = show_format.decode("utf-8")
# show_format comes out in key=value pairs seperated by newlines # show_format comes out in key=value pairs seperated by newlines
duration = re.findall(r'([duration^=]+)=([^=]+)(?:\n|$)', show_format)[0][1] duration = re.findall(r'([duration^=]+)=([^=]+)(?:\n|$)', show_format)[0][1]
...@@ -141,7 +141,7 @@ class AbstractVideo(CollectionMember, TagSearchable): ...@@ -141,7 +141,7 @@ class AbstractVideo(CollectionMember, TagSearchable):
FNULL = open(os.devnull, 'r') FNULL = open(os.devnull, 'r')
subprocess.check_call([ subprocess.check_call([
'ffmpeg', 'ffmpeg',
'-hide_banner', '-v', 'quiet',
'-itsoffset', '-4', '-itsoffset', '-4',
'-i', file_path, '-i', file_path,
'-vcodec', 'mjpeg', '-vcodec', 'mjpeg',
......
...@@ -37,6 +37,9 @@ class VideoNode(template.Node): ...@@ -37,6 +37,9 @@ class VideoNode(template.Node):
def render(self, context): def render(self, context):
video = self.video.resolve(context) video = self.video.resolve(context)
if not video:
raise template.TemplateSyntaxError("video tag requires a Video object as the first parameter")
sources = ["<source src='{0}' type='video/{1}'>" sources = ["<source src='{0}' type='video/{1}'>"
.format(video.url, video.file_ext)] # TODO get mimetype properly (extension is not always reliable) .format(video.url, video.file_ext)] # TODO get mimetype properly (extension is not always reliable)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment