diff --git a/CHANGES.rst b/CHANGES.rst
index b838bbc..0c045e1 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,6 +1,11 @@
Release 1.0.0 (dev)
-------------------
+**Backward incompatible changes:**
+
+- filter `embed_video_tags.embed` has been removed
+
+Backward compatible changes:
*No changes yet.*
diff --git a/docs/examples.rst b/docs/examples.rst
index 2431d2d..ae4efb9 100644
--- a/docs/examples.rst
+++ b/docs/examples.rst
@@ -48,34 +48,16 @@ Default sizes are ``tiny`` (420x315), ``small`` (480x360), ``medium`` (640x480),
{% video my_video '100% x 50%' %}
-Some backends (e.g. YouTube) allow configuration of the embedding via passing
-query parameters. To specify the parameters:
+It is possible to set backend options via parameters in template tag. It is
+useful for example to enforce HTTPS protocol or set different query appended
+to url.
::
- {% video item.video 'small' rel=0 %}
-
- {% video item.video 'small' start=2 stop=5 repeat=1 %}
-
- {% video item.video rel=0 as my_video %}
- URL: {{ my_video.url }}
- Thumbnail: {{ my_video.thumbnail }}
- Backend: {{ my_video.backend }}
- {% video my_video 'small' %}
+ {% video my_video query="rel=0&wmode=transparent" is_secure=True %}
+ {{ video.url }} {# always with https #}
{% endvideo %}
-Parameters may also be template variables:
-
-::
-
- {% video item.video 'small' start=item.start stop=item.stop repeat=item.repeat %}
-
-
-.. tip::
-
- You can provide default values for the query string that's included in the
- embedded URL by updating your Django settings file.
-
.. tip::
@@ -96,7 +78,7 @@ Parameters may also be template variables:
backend (:py:data:`~embed_video.backends.VideoBackend.template_name`).
.. versionadded:: 0.9
-
+
``template_name`` has been added in version 0.9.
diff --git a/embed_video/backends.py b/embed_video/backends.py
index 5eb1595..f755ab2 100644
--- a/embed_video/backends.py
+++ b/embed_video/backends.py
@@ -1,24 +1,21 @@
import re
-import requests
+import sys
import json
+import requests
-try:
- # Python <= 2.7
- import urlparse
- from urllib import urlencode
-except ImportError:
- # support for py3
+if sys.version_info.major == 3:
import urllib.parse as urlparse
- from urllib.parse import urlencode
+else:
+ import urlparse
-from django.conf import settings
+from django.http import QueryDict
from django.template.loader import render_to_string
from django.utils.functional import cached_property
from django.utils.safestring import mark_safe
-from django.utils.datastructures import SortedDict
from .utils import import_by_path
-from .settings import EMBED_VIDEO_BACKENDS, EMBED_VIDEO_TIMEOUT
+from .settings import EMBED_VIDEO_BACKENDS, EMBED_VIDEO_TIMEOUT, \
+ EMBED_VIDEO_YOUTUBE_DEFAULT_QUERY
class EmbedVideoException(Exception):
@@ -112,7 +109,12 @@ class VideoBackend(object):
``{{ width }}``, ``{{ height }}``
"""
- def __init__(self, url, is_secure=False, query=None):
+ default_query = ''
+ """
+ Default query string or `QueryDict` appended to url
+ """
+
+ def __init__(self, url, is_secure=False):
"""
First it tries to load data from cache and if it don't succeed, run
:py:meth:`init` and then save it to cache.
@@ -120,22 +122,17 @@ class VideoBackend(object):
self.is_secure = is_secure
self.backend = self.__class__.__name__
self._url = url
- self.update_query(query)
-
- def update_query(self, query=None):
- self._query = SortedDict(self.get_default_query())
- if query is not None:
- self._query.update(query)
+ self.query = QueryDict(self.default_query, mutable=True)
@cached_property
def code(self):
return self.get_code()
- @cached_property
+ @property
def url(self):
return self.get_url()
- @cached_property
+ @property
def protocol(self):
return 'https' if self.allow_https and self.is_secure else 'http'
@@ -147,6 +144,16 @@ class VideoBackend(object):
def info(self):
return self.get_info()
+ @property
+ def query(self):
+ return self._query
+
+ @query.setter
+ def query(self, value):
+ self._query = value \
+ if isinstance(value, QueryDict) \
+ else QueryDict(value, mutable=True)
+
@classmethod
def is_valid(cls, url):
"""
@@ -168,8 +175,7 @@ class VideoBackend(object):
Returns URL folded from :py:data:`pattern_url` and parsed code.
"""
url = self.pattern_url.format(code=self.code, protocol=self.protocol)
- if self._query:
- url += '?' + urlencode(self._query, doseq=True)
+ url += '?' + self.query.urlencode() if self.query else ''
return mark_safe(url)
def get_thumbnail_url(self):
@@ -193,12 +199,9 @@ class VideoBackend(object):
def get_info(self):
raise NotImplementedError
- def get_default_query(self):
- # Derive backend name from class name
- backend_name = self.__class__.__name__[:-7].upper()
- default = getattr(self, 'default_query', {})
- settings_key = 'EMBED_VIDEO_{0}_QUERY'.format(backend_name)
- return getattr(settings, settings_key, default).copy()
+ def set_options(self, options):
+ for key in options:
+ setattr(self, key, options[key])
class YoutubeBackend(VideoBackend):
@@ -225,7 +228,7 @@ class YoutubeBackend(VideoBackend):
pattern_url = '{protocol}://www.youtube.com/embed/{code}'
pattern_thumbnail_url = '{protocol}://img.youtube.com/vi/{code}/hqdefault.jpg'
- default_query = {'wmode': 'opaque'}
+ default_query = EMBED_VIDEO_YOUTUBE_DEFAULT_QUERY
def get_code(self):
code = super(YoutubeBackend, self).get_code()
diff --git a/embed_video/settings.py b/embed_video/settings.py
index 36eae7e..0d9a824 100644
--- a/embed_video/settings.py
+++ b/embed_video/settings.py
@@ -8,3 +8,6 @@ EMBED_VIDEO_BACKENDS = getattr(settings, 'EMBED_VIDEO_BACKENDS', (
))
EMBED_VIDEO_TIMEOUT = getattr(settings, 'EMBED_VIDEO_TIMEOUT', 10)
+
+EMBED_VIDEO_YOUTUBE_DEFAULT_QUERY = \
+ getattr(settings, 'EMBED_VIDEO_YOUTUBE_DEFAULT_QUERY', 'wmode=opaque')
diff --git a/embed_video/templates/embed_video/embed_code.html b/embed_video/templates/embed_video/embed_code.html
index 9349fd0..797e43b 100644
--- a/embed_video/templates/embed_video/embed_code.html
+++ b/embed_video/templates/embed_video/embed_code.html
@@ -1,2 +1 @@
-
+
diff --git a/embed_video/templatetags/embed_video_tags.py b/embed_video/templatetags/embed_video_tags.py
index 632f745..6773414 100644
--- a/embed_video/templatetags/embed_video_tags.py
+++ b/embed_video/templatetags/embed_video_tags.py
@@ -1,9 +1,8 @@
import re
import logging
import requests
-from collections import defaultdict
-from django.template import Library, Node, TemplateSyntaxError, Variable
+from django.template import Library, Node, TemplateSyntaxError
from django.utils.safestring import mark_safe
from django.utils.encoding import smart_str
@@ -14,8 +13,6 @@ register = Library()
logger = logging.getLogger(__name__)
-# Used for parsing keyword arguments passed in as key-value pairs
-kw_pat = re.compile(r'^(?P[\w]+)=(?P.+)$')
@register.tag('video')
@@ -28,25 +25,26 @@ class VideoNode(Node):
.. code-block:: html+django
- {% video URL [SIZE] %}
+ {% video URL [SIZE] [key1=value1, key2=value2...] %}
Or as a block:
.. code-block:: html+django
- {% video URL as VAR %}
+ {% video URL [SIZE] [key1=value1, key2=value2...] as VAR %}
...
{% endvideo %}
- Example:
+ Examples:
.. code-block:: html+django
+ {% video item.video %}
{% video item.video "large" %}
{% video item.video "340x200" %}
- {% video item.video "100% x 300" %}
+ {% video item.video "100% x 300" query="rel=0&wmode=opaque" %}
- {% video item.video as my_video %}
+ {% video item.video is_secure=True as my_video %}
URL: {{ my_video.url }}
Thumbnail: {{ my_video.thumbnail }}
Backend: {{ my_video.backend }}
@@ -57,62 +55,48 @@ class VideoNode(Node):
'[size] [key1=val1 key2=val2 ...] [as var] %}``'
default_size = 'small'
- re_size = re.compile('(?P\d+%?) *x *(?P\d+%?)')
+ re_size = re.compile('[\'"]?(?P\d+%?) *x *(?P\d+%?)[\'"]?')
+ re_option = re.compile(r'^(?P[\w]+)=(?P.+)$')
def __init__(self, parser, token):
- self.size = None
- self.bits = token.split_contents()
- self.query = None
+ self.parser = parser
+ self.bits = list(token.split_contents())
+ self.tag_name = str(self.pop_bit())
+ self.url = self.pop_bit()
- try:
- self.url = parser.compile_filter(self.bits[1])
- except IndexError:
- raise TemplateSyntaxError(self.error_msg)
-
- # Determine if the tag is being used as a context variable
- if self.bits[-2] == 'as':
- option_bits = self.bits[2:-2]
- self.nodelist_file = parser.parse(('endvideo',))
+ if len(self.bits) > 1 and self.bits[-2] == 'as':
+ del self.bits[-2]
+ self.variable_name = str(self.pop_bit(-1))
+ self.nodelist_file = parser.parse(('end' + self.tag_name, ))
parser.delete_first_token()
else:
- option_bits = self.bits[2:]
+ self.variable_name = None
- # Size must be the first argument and is only accepted when this is
- # used as a template tag (but not when used as a block tag)
- if len(option_bits) != 0 and '=' not in option_bits[0]:
- self.size = parser.compile_filter(option_bits[0])
- option_bits = option_bits[1:]
- else:
- self.size = self.default_size
+ self.size = self.pop_bit() if self.bits and '=' not in self.bits[0] else None
+ self.options = self.parse_options(self.bits)
- # Parse arguments passed in as KEY=VALUE pairs that will be added to
- # the URL as a GET query string
- if len(option_bits) != 0:
- self.query = defaultdict(list)
+ def pop_bit(self, index=0):
+ return self.parser.compile_filter(self.bits.pop(index))
- for bit in option_bits:
- match = kw_pat.match(bit)
- key = smart_str(match.group('key'))
- value = Variable(smart_str(match.group('value')))
- self.query[key].append(value)
+ def parse_options(self, bits):
+ options = {}
+ for bit in bits:
+ parsed_bit = self.re_option.match(bit)
+ key = smart_str(parsed_bit.group('key'))
+ value = self.parser.compile_filter(parsed_bit.group('value'))
+ options[key] = value
+ return options
def render(self, context):
- # Attempt to resolve any parameters passed in.
- if self.query is not None:
- resolved_query = defaultdict(list)
- for key, values in self.query.items():
- for value in values:
- resolved_value = value.resolve(context)
- resolved_query[key].append(resolved_value)
- else:
- resolved_query = None
-
url = self.url.resolve(context)
+ size = self.size.resolve(context) if self.size else None
+ options = self.resolve_options(context)
+
try:
- if self.size:
- return self.__render_embed(url, context, resolved_query)
- else:
- return self.__render_block(url, context, resolved_query)
+ if not self.variable_name:
+ return self.embed(url, size, context=context, **options)
+ backend = self.get_backend(url, context=context, **options)
+ return self.render_block(context, backend)
except requests.Timeout:
logger.exception('Timeout reached during rendering embed video (`{0}`)'.format(url))
except UnknownBackendException:
@@ -122,23 +106,22 @@ class VideoNode(Node):
return ''
- def __render_embed(self, url, context, query):
- size = self.size.resolve(context) \
- if hasattr(self.size, 'resolve') else self.size
- return self.embed(url, size, context=context, query=query)
-
- def __render_block(self, url, context, query):
- as_var = self.bits[-1]
+ def resolve_options(self, context):
+ options = {}
+ for key in self.options:
+ value = self.options[key]
+ options[key] = value.resolve(context)
+ return options
+ def render_block(self, context, backend):
context.push()
- context[as_var] = self.get_backend(url, context=context, query=query)
+ context[self.variable_name] = backend
output = self.nodelist_file.render(context)
context.pop()
-
return output
@staticmethod
- def get_backend(backend_or_url, context=None, query=None):
+ def get_backend(backend_or_url, context=None, **options):
"""
Returns instance of VideoBackend. If context is passed to the method
and request is secure, than the is_secure mark is set to backend.
@@ -151,22 +134,22 @@ class VideoNode(Node):
if context and 'request' in context:
backend.is_secure = context['request'].is_secure()
-
- backend.update_query(query)
+ if options:
+ backend.set_options(options)
return backend
- @staticmethod
- def embed(url, size, GET=None, context=None, query=None):
+ @classmethod
+ def embed(cls, url, size, context=None, **options):
"""
Direct render of embed video.
"""
- backend = VideoNode.get_backend(url, context=context, query=query)
- width, height = VideoNode.get_size(size)
+ backend = cls.get_backend(url, context=context, **options)
+ width, height = cls.get_size(size)
return mark_safe(backend.get_embed_code(width=width, height=height))
- @staticmethod
- def get_size(value):
+ @classmethod
+ def get_size(cls, value):
"""
Predefined sizes:
@@ -191,11 +174,12 @@ class VideoNode(Node):
'huge': (1280, 960),
}
+ value = value or cls.default_size
if value in sizes:
return sizes[value]
try:
- size = VideoNode.re_size.match(value)
+ size = cls.re_size.match(value)
return [size.group('width'), size.group('height')]
except AttributeError:
raise TemplateSyntaxError(
@@ -209,28 +193,3 @@ class VideoNode(Node):
def __repr__(self):
return '' % self.url
-
-
-@register.filter(is_safe=True)
-def embed(backend, size='small'):
- """
- .. warning::
- .. deprecated:: 0.7
- Use :py:func:`VideoNode.embed` instead.
-
- Same like :py:func:`VideoNode.embed` tag but **always uses insecure
- HTTP protocol**.
-
- Usage:
-
- .. code-block:: html+django
-
- {{ URL|embed:SIZE }}
-
- Example:
-
- .. code-block:: html+django
-
- {{ 'http://www.youtube.com/watch?v=guXyvo2FfLs'|embed:'large' }}
- """
- return VideoNode.embed(backend, size)
diff --git a/embed_video/tests/backends/__init__.py b/embed_video/tests/backends/__init__.py
new file mode 100644
index 0000000..72c1785
--- /dev/null
+++ b/embed_video/tests/backends/__init__.py
@@ -0,0 +1,17 @@
+from embed_video.backends import detect_backend
+
+
+class BackendTestMixin(object):
+ urls = []
+ instance = None
+
+ def test_detect(self):
+ for url in self.urls:
+ backend = detect_backend(url[0])
+ self.assertIsInstance(backend, self.instance)
+
+ def test_code(self):
+ for url in self.urls:
+ backend = self.instance(url[0])
+ self.assertEqual(backend.code, url[1])
+
diff --git a/embed_video/tests/tests_custom_backend.py b/embed_video/tests/backends/tests_custom_backend.py
similarity index 68%
rename from embed_video/tests/tests_custom_backend.py
rename to embed_video/tests/backends/tests_custom_backend.py
index 3246a50..2ffa587 100644
--- a/embed_video/tests/tests_custom_backend.py
+++ b/embed_video/tests/backends/tests_custom_backend.py
@@ -1,8 +1,15 @@
+import re
from unittest import TestCase
-from embed_video.backends import detect_backend
+from embed_video.backends import VideoBackend, detect_backend
-from .custom_backend import CustomBackend
+
+class CustomBackend(VideoBackend):
+ re_detect = re.compile(r'http://myvideo\.com/[0-9]+')
+ re_code = re.compile(r'http://myvideo\.com/(?P[0-9]+)')
+
+ pattern_url = '{protocol}://play.myvideo.com/c/{code}/'
+ pattern_thumbnail_url = '{protocol}://thumb.myvideo.com/c/{code}/'
class CustomBackendTestCase(TestCase):
@@ -27,4 +34,3 @@ class CustomBackendTestCase(TestCase):
def test_thumbnail(self):
self.assertEqual(self.backend.get_thumbnail_url(),
'http://thumb.myvideo.com/c/1530/')
-
diff --git a/embed_video/tests/backends/tests_soundcloud.py b/embed_video/tests/backends/tests_soundcloud.py
new file mode 100644
index 0000000..24e4d9b
--- /dev/null
+++ b/embed_video/tests/backends/tests_soundcloud.py
@@ -0,0 +1,55 @@
+import requests
+from mock import patch
+from unittest import TestCase
+
+from . import BackendTestMixin
+from embed_video.backends import SoundCloudBackend, VideoDoesntExistException
+
+
+class SoundCloudBackendTestCase(BackendTestMixin, TestCase):
+ urls = (
+ ('https://soundcloud.com/community/soundcloud-case-study-wildlife', '82244706'),
+ ('https://soundcloud.com/matej-roman/jaromir-nohavica-karel-plihal-mikymauz', '7834701'),
+ ('https://soundcloud.com/beny97/sets/jaromir-nohavica-prazska', '960591'),
+ ('https://soundcloud.com/corbel-keep/norah-jones-come-away-with', '22485933'),
+ )
+
+ instance = SoundCloudBackend
+
+ def setUp(self):
+ class FooBackend(SoundCloudBackend):
+ url = 'foobar'
+
+ def get_info(self):
+ return {
+ 'width': 123,
+ 'height': 321,
+ 'thumbnail_url': 'xyz',
+ 'html': u'\u003Ciframe width=\"100%\" height=\"400\" '
+ u'scrolling=\"no\" frameborder=\"no\" '
+ u'src=\"{0}\"\u003E\u003C/iframe\u003E'.format(self.url)
+ }
+
+ self.foo = FooBackend('abcd')
+
+ def test_width(self):
+ self.assertEqual(self.foo.width, 123)
+
+ def test_height(self):
+ self.assertEqual(self.foo.height, 321)
+
+ def test_get_thumbnail_url(self):
+ self.assertEqual(self.foo.get_thumbnail_url(), 'xyz')
+
+ def test_get_url(self):
+ self.assertEqual(self.foo.get_url(), self.foo.url)
+
+ @patch('embed_video.backends.EMBED_VIDEO_TIMEOUT', 0.000001)
+ def test_timeout_in_get_info(self):
+ backend = SoundCloudBackend('https://soundcloud.com/community/soundcloud-case-study-wildlife')
+ self.assertRaises(requests.Timeout, backend.get_info)
+
+ def test_invalid_url(self):
+ """ Check if bug #21 is fixed. """
+ backend = SoundCloudBackend('https://soundcloud.com/xyz/foo')
+ self.assertRaises(VideoDoesntExistException, backend.get_info)
diff --git a/embed_video/tests/backends/tests_videobackend.py b/embed_video/tests/backends/tests_videobackend.py
new file mode 100644
index 0000000..efb92b3
--- /dev/null
+++ b/embed_video/tests/backends/tests_videobackend.py
@@ -0,0 +1,20 @@
+from unittest import TestCase
+from embed_video.backends import UnknownBackendException, detect_backend, \
+ VideoBackend
+
+
+class VideoBackendTestCase(TestCase):
+ unknown_backend_urls = (
+ 'http://myurl.com/?video=http://www.youtube.com/watch?v=jsrRJyHBvzw',
+ 'http://myurl.com/?video=www.youtube.com/watch?v=jsrRJyHBvzw',
+ 'http://youtube.com.myurl.com/watch?v=jsrRJyHBvzw',
+ 'http://vimeo.com.myurl.com/72304002',
+ )
+
+ def test_detect_bad_urls(self):
+ for url in self.unknown_backend_urls:
+ self.assertRaises(UnknownBackendException, detect_backend, url)
+
+ def test_not_implemented_get_info(self):
+ backend = VideoBackend('http://www.example.com')
+ self.assertRaises(NotImplementedError, backend.get_info)
diff --git a/embed_video/tests/backends/tests_vimeo.py b/embed_video/tests/backends/tests_vimeo.py
new file mode 100644
index 0000000..ea3e0ca
--- /dev/null
+++ b/embed_video/tests/backends/tests_vimeo.py
@@ -0,0 +1,34 @@
+import requests
+from mock import patch
+from unittest import TestCase
+
+from . import BackendTestMixin
+from embed_video.backends import VimeoBackend, VideoDoesntExistException
+
+
+class VimeoBackendTestCase(BackendTestMixin, TestCase):
+ urls = (
+ ('http://vimeo.com/72304002', '72304002'),
+ ('https://vimeo.com/72304002', '72304002'),
+ ('http://www.vimeo.com/72304002', '72304002'),
+ ('https://www.vimeo.com/72304002', '72304002'),
+ ('http://player.vimeo.com/video/72304002', '72304002'),
+ ('https://player.vimeo.com/video/72304002', '72304002'),
+ )
+
+ instance = VimeoBackend
+
+ def test_vimeo_get_info_exception(self):
+ with self.assertRaises(VideoDoesntExistException):
+ backend = VimeoBackend('http://vimeo.com/123')
+ backend.get_info()
+
+ def test_get_thumbnail_url(self):
+ backend = VimeoBackend('http://vimeo.com/72304002')
+ self.assertEqual(backend.get_thumbnail_url(),
+ 'http://i.vimeocdn.com/video/446150690_640.jpg')
+
+ @patch('embed_video.backends.EMBED_VIDEO_TIMEOUT', 0.000001)
+ def test_timeout_in_get_info(self):
+ backend = VimeoBackend('http://vimeo.com/72304002')
+ self.assertRaises(requests.Timeout, backend.get_info)
diff --git a/embed_video/tests/backends/tests_youtube.py b/embed_video/tests/backends/tests_youtube.py
new file mode 100644
index 0000000..c48732f
--- /dev/null
+++ b/embed_video/tests/backends/tests_youtube.py
@@ -0,0 +1,42 @@
+from unittest import TestCase
+
+from . import BackendTestMixin
+from embed_video.backends import YoutubeBackend, UnknownIdException
+
+
+class YoutubeBackendTestCase(BackendTestMixin, TestCase):
+ urls = (
+ ('http://youtu.be/jsrRJyHBvzw', 'jsrRJyHBvzw'),
+ ('http://youtu.be/n17B_uFF4cA', 'n17B_uFF4cA'),
+ ('http://youtu.be/t-ZRX8984sc', 't-ZRX8984sc'),
+ ('https://youtu.be/t-ZRX8984sc', 't-ZRX8984sc'),
+ ('http://youtube.com/watch?v=jsrRJyHBvzw', 'jsrRJyHBvzw'),
+ ('https://youtube.com/watch?v=jsrRJyHBvzw', 'jsrRJyHBvzw'),
+ ('http://www.youtube.com/v/0zM3nApSvMg?rel=0', '0zM3nApSvMg'),
+ ('https://www.youtube.com/v/0zM3nApSvMg?rel=0', '0zM3nApSvMg'),
+ ('http://www.youtube.com/embed/0zM3nApSvMg?rel=0', '0zM3nApSvMg'),
+ ('https://www.youtube.com/embed/0zM3nApSvMg?rel=0', '0zM3nApSvMg'),
+ ('http://www.youtube.com/watch?v=jsrRJyHBvzw', 'jsrRJyHBvzw'),
+ ('https://www.youtube.com/watch?v=t-ZRX8984sc', 't-ZRX8984sc'),
+ ('http://www.youtube.com/watch?v=iwGFalTRHDA&feature=related', 'iwGFalTRHDA'),
+ ('https://www.youtube.com/watch?v=iwGFalTRHDA&feature=related', 'iwGFalTRHDA'),
+ ('http://www.youtube.com/watch?feature=player_embedded&v=2NpZbaAIXag', '2NpZbaAIXag'),
+ ('https://www.youtube.com/watch?feature=player_embedded&v=2NpZbaAIXag', '2NpZbaAIXag'),
+ ('https://www.youtube.com/watch?v=XPk521voaOE&feature=youtube_gdata_player', 'XPk521voaOE'),
+ ('http://www.youtube.com/watch?v=6xu00J3-g2s&list=PLb5n6wzDlPakFKvJ69rJ9AJW24Aaaki2z', '6xu00J3-g2s'),
+ ('https://m.youtube.com/#/watch?v=IAooXLAPoBQ', 'IAooXLAPoBQ'),
+ ('https://m.youtube.com/watch?v=IAooXLAPoBQ', 'IAooXLAPoBQ'),
+ ('http://www.youtube.com/edit?video_id=eBea01qmnOE', 'eBea01qmnOE')
+ )
+
+ instance = YoutubeBackend
+
+ def test_youtube_keyerror(self):
+ """ Test for issue #7 """
+ backend = self.instance('http://youtube.com/watch?id=5')
+ self.assertRaises(UnknownIdException, backend.get_code)
+
+ def test_thumbnail(self):
+ for url in self.urls:
+ backend = self.instance(url[0])
+ self.assertIn(url[1], backend.thumbnail)
diff --git a/embed_video/tests/custom_backend.py b/embed_video/tests/custom_backend.py
deleted file mode 100644
index be14bb8..0000000
--- a/embed_video/tests/custom_backend.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import re
-
-from embed_video.backends import VideoBackend
-
-
-class CustomBackend(VideoBackend):
- re_detect = re.compile(r'http://myvideo\.com/[0-9]+')
- re_code = re.compile(r'http://myvideo\.com/(?P[0-9]+)')
-
- pattern_url = '{protocol}://play.myvideo.com/c/{code}/'
- pattern_thumbnail_url = '{protocol}://thumb.myvideo.com/c/{code}/'
diff --git a/embed_video/tests/django_settings.py b/embed_video/tests/django_settings.py
index 00c05a8..e9b53cb 100644
--- a/embed_video/tests/django_settings.py
+++ b/embed_video/tests/django_settings.py
@@ -17,7 +17,7 @@ EMBED_VIDEO_BACKENDS = (
'embed_video.backends.YoutubeBackend',
'embed_video.backends.VimeoBackend',
'embed_video.backends.SoundCloudBackend',
- 'embed_video.tests.custom_backend.CustomBackend',
+ 'embed_video.tests.backends.tests_custom_backend.CustomBackend',
)
diff --git a/embed_video/tests/templatetags/__init__.py b/embed_video/tests/templatetags/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/embed_video/tests/templatetags/tests_embed_video_tags.py b/embed_video/tests/templatetags/tests_embed_video_tags.py
new file mode 100644
index 0000000..feab48d
--- /dev/null
+++ b/embed_video/tests/templatetags/tests_embed_video_tags.py
@@ -0,0 +1,285 @@
+from unittest import TestCase, skip
+from mock import Mock, patch
+import re
+
+from django.template import TemplateSyntaxError
+from django.http import HttpRequest
+from django.template.base import Template
+from django.template.context import RequestContext
+from django.test.client import RequestFactory
+from testfixtures import log_capture
+
+from embed_video.templatetags.embed_video_tags import VideoNode
+
+URL_PATTERN = re.compile(r'src="?\'?([^"\'>]*)"')
+
+
+class EmbedTestCase(TestCase):
+ def assertRenderedTemplate(self, template_string, output, context=None):
+ response = RequestContext(HttpRequest(), context)
+ rendered_output = Template(template_string).render(response)
+ self.assertEqual(rendered_output.strip(), output.strip())
+
+ def test_embed(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' as ytb %}
+ {% video ytb 'large' %}
+ {% endvideo %}
+ """
+ self.assertRenderedTemplate(
+ template,
+ ''
+ )
+
+ def test_embed_invalid_url(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video 'http://www.youtube.com/edit?abcd=efgh' as ytb %}
+ {{ ytb.url }}
+ {% endvideo %}
+ """
+ self.assertRenderedTemplate(template, '')
+
+ def test_embed_with_none_instance(self):
+ template = """
+ {% with None as my_video %}
+ {% load embed_video_tags %}
+ {% video my_video %}{% endwith %}
+ """
+ self.assertRenderedTemplate(template, '')
+
+ def test_embed_empty_string(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video '' 'large' %}
+ """
+ self.assertRenderedTemplate(template, '')
+
+ def test_direct_embed_tag(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video "http://www.youtube.com/watch?v=jsrRJyHBvzw" "large" %}
+ """
+ self.assertRenderedTemplate(
+ template,
+ ''
+ )
+
+ def test_direct_embed_tag_with_default_size(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video "http://www.youtube.com/watch?v=jsrRJyHBvzw" %}
+ """
+ self.assertRenderedTemplate(
+ template,
+ ''
+ )
+
+ def test_direct_embed_invalid_url(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video "https://soundcloud.com/xyz/foo" %}
+ """
+ self.assertRenderedTemplate(template, '')
+
+ def test_user_size(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' as ytb %}
+ {% video ytb '800x800' %}
+ {% endvideo %}
+ """
+ self.assertRenderedTemplate(
+ template,
+ ''
+ )
+
+ @skip
+ def test_wrong_size(self):
+ template = Template("""
+ {% load embed_video_tags %}
+ {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' 'so x huge' %}
+ """)
+ request = RequestContext(HttpRequest())
+ self.assertRaises(TemplateSyntaxError, template.render, request)
+
+ def test_tag_youtube(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' as ytb %}
+ {{ ytb.url }} {{ ytb.backend }}
+ {% endvideo %}
+ """
+ self.assertRenderedTemplate(
+ template,
+ 'http://www.youtube.com/embed/jsrRJyHBvzw?wmode=opaque '
+ 'YoutubeBackend'
+ )
+
+ def test_tag_vimeo(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video 'https://vimeo.com/72304002' as vimeo %}
+ {{ vimeo.url }} {{ vimeo.backend }} {{ vimeo.info.duration }}
+ {% endvideo %}
+ """
+ self.assertRenderedTemplate(
+ template, 'http://player.vimeo.com/video/72304002 VimeoBackend 176'
+ )
+
+ def test_tag_soundcloud(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video 'https://soundcloud.com/community/soundcloud-case-study-wildlife' as soundcloud %}
+ {{ soundcloud.url }} {{ soundcloud.backend }}
+ {% endvideo %}
+ """
+ self.assertRenderedTemplate(
+ template,
+ 'https://w.soundcloud.com/player/?visual=true&url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F82244706&show_artwork=true '
+ 'SoundCloudBackend'
+ )
+
+ @patch('embed_video.backends.EMBED_VIDEO_TIMEOUT', 0.000001)
+ @log_capture()
+ def test_empty_if_timeout(self, logs):
+ template = """
+ {% load embed_video_tags %}
+ {% video "http://vimeo.com/72304002" as my_video %}
+ {{ my_video.thumbnail }}
+ {% endvideo %}
+ """
+
+ self.assertRenderedTemplate(template, '')
+ logs.check(
+ ('requests.packages.urllib3.connectionpool', 'INFO', 'Starting new HTTP connection (1): vimeo.com'),
+ ('embed_video.templatetags.embed_video_tags', 'ERROR', 'Timeout reached during rendering embed video (`http://vimeo.com/72304002`)')
+ )
+
+ def test_relative_size(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video "http://vimeo.com/72304002" "80%x30%" %}
+ """
+ self.assertRenderedTemplate(
+ template,
+ ''
+ )
+
+ def test_allow_spaces_in_size(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video "http://vimeo.com/72304002" "80% x 300" %}
+ """
+ self.assertRenderedTemplate(
+ template,
+ ''
+ )
+
+ def test_embed_with_query(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' query="rel=1&wmode=transparent" as ytb %}
+ {{ ytb.url }}
+ {% endvideo %}
+ """
+ self.assertRenderedTemplate(
+ template,
+ 'http://www.youtube.com/embed/jsrRJyHBvzw?wmode=transparent&rel=1'
+ )
+
+ def test_direct_embed_with_query(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' query="rel=1&wmode=transparent" %}
+ """
+
+ self.assertRenderedTemplate(
+ template,
+ ''
+ )
+
+ def test_set_options(self):
+ template = """
+ {% load embed_video_tags %}
+ {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' "300x200" is_secure=True query="rel=1" %}
+ """
+ self.assertRenderedTemplate(
+ template,
+ ''
+ )
+
+ def test_size_as_variable(self):
+ template = """
+ {% load embed_video_tags %}
+ {% with size="500x200" %}
+ {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' size %}
+ {% endwith %}
+ """
+ self.assertRenderedTemplate(
+ template,
+ ''
+ )
+
+
+class EmbedVideoNodeTestCase(TestCase):
+ def setUp(self):
+ self.parser = Mock()
+ self.token = Mock(methods=['split_contents'])
+
+ def test_repr(self):
+ self.token.split_contents.return_value = (
+ 'video', 'http://youtu.be/v/1234', 'as', 'myvideo'
+ )
+ self.parser.compile_filter.return_value = u'some_url'
+
+ node = VideoNode(self.parser, self.token)
+ self.assertEqual(str(node), '')
+
+ def test_videonode_iter(self):
+ out = ['a', 'b', 'c', 'd']
+
+ class FooNode(VideoNode):
+ nodelist_file = out
+
+ def __init__(self):
+ pass
+
+ node = FooNode()
+ self.assertEqual(out, [x for x in node])
+
+ def test_get_backend_secure(self):
+ class SecureRequest(RequestFactory):
+ is_secure = lambda x: True
+
+ context = {'request': SecureRequest()}
+ backend = VideoNode.get_backend('http://www.youtube.com/watch?v=jsrRJyHBvzw', context)
+ self.assertTrue(backend.is_secure)
+
+ def test_get_backend_insecure(self):
+ class InsecureRequest(RequestFactory):
+ is_secure = lambda x: False
+
+ context = {'request': InsecureRequest()}
+ backend = VideoNode.get_backend('http://www.youtube.com/watch?v=jsrRJyHBvzw', context)
+ self.assertFalse(backend.is_secure)
+
diff --git a/embed_video/tests/tests_backend.py b/embed_video/tests/tests_backend.py
deleted file mode 100644
index e0f8c54..0000000
--- a/embed_video/tests/tests_backend.py
+++ /dev/null
@@ -1,157 +0,0 @@
-from unittest import TestCase
-from mock import patch
-import requests
-
-from ..backends import detect_backend, YoutubeBackend, VimeoBackend, \
- SoundCloudBackend, UnknownBackendException, VideoDoesntExistException, \
- UnknownIdException, VideoBackend
-
-
-class BackendTestMixin(object):
- def test_detect(self):
- for url in self.urls:
- backend = detect_backend(url[0])
- self.assertIsInstance(backend, self.instance)
-
- def test_code(self):
- for url in self.urls:
- backend = self.instance(url[0])
- self.assertEqual(backend.code, url[1])
-
-
-class VideoBackendTestCase(TestCase):
- unknown_backend_urls = (
- 'http://myurl.com/?video=http://www.youtube.com/watch?v=jsrRJyHBvzw',
- 'http://myurl.com/?video=www.youtube.com/watch?v=jsrRJyHBvzw',
- 'http://youtube.com.myurl.com/watch?v=jsrRJyHBvzw',
- 'http://vimeo.com.myurl.com/72304002',
- )
-
- def test_detect_bad_urls(self):
- for url in self.unknown_backend_urls:
- self.assertRaises(UnknownBackendException, detect_backend, url)
-
- def test_not_implemented_get_info(self):
- backend = VideoBackend('http://www.example.com')
- self.assertRaises(NotImplementedError, backend.get_info)
-
-
-class YoutubeBackendTestCase(BackendTestMixin, TestCase):
- urls = (
- ('http://youtu.be/jsrRJyHBvzw', 'jsrRJyHBvzw'),
- ('http://youtu.be/n17B_uFF4cA', 'n17B_uFF4cA'),
- ('http://youtu.be/t-ZRX8984sc', 't-ZRX8984sc'),
- ('https://youtu.be/t-ZRX8984sc', 't-ZRX8984sc'),
- ('http://youtube.com/watch?v=jsrRJyHBvzw', 'jsrRJyHBvzw'),
- ('https://youtube.com/watch?v=jsrRJyHBvzw', 'jsrRJyHBvzw'),
- ('http://www.youtube.com/v/0zM3nApSvMg?rel=0', '0zM3nApSvMg'),
- ('https://www.youtube.com/v/0zM3nApSvMg?rel=0', '0zM3nApSvMg'),
- ('http://www.youtube.com/embed/0zM3nApSvMg?rel=0', '0zM3nApSvMg'),
- ('https://www.youtube.com/embed/0zM3nApSvMg?rel=0', '0zM3nApSvMg'),
- ('http://www.youtube.com/watch?v=jsrRJyHBvzw', 'jsrRJyHBvzw'),
- ('https://www.youtube.com/watch?v=t-ZRX8984sc', 't-ZRX8984sc'),
- ('http://www.youtube.com/watch?v=iwGFalTRHDA&feature=related', 'iwGFalTRHDA'),
- ('https://www.youtube.com/watch?v=iwGFalTRHDA&feature=related', 'iwGFalTRHDA'),
- ('http://www.youtube.com/watch?feature=player_embedded&v=2NpZbaAIXag', '2NpZbaAIXag'),
- ('https://www.youtube.com/watch?feature=player_embedded&v=2NpZbaAIXag', '2NpZbaAIXag'),
- ('https://www.youtube.com/watch?v=XPk521voaOE&feature=youtube_gdata_player', 'XPk521voaOE'),
- ('http://www.youtube.com/watch?v=6xu00J3-g2s&list=PLb5n6wzDlPakFKvJ69rJ9AJW24Aaaki2z', '6xu00J3-g2s'),
- ('https://m.youtube.com/#/watch?v=IAooXLAPoBQ', 'IAooXLAPoBQ'),
- ('https://m.youtube.com/watch?v=IAooXLAPoBQ', 'IAooXLAPoBQ'),
- ('http://www.youtube.com/edit?video_id=eBea01qmnOE', 'eBea01qmnOE')
- )
-
- instance = YoutubeBackend
-
- def test_youtube_keyerror(self):
- """ Test for issue #7 """
- backend = self.instance('http://youtube.com/watch?id=5')
- self.assertRaises(UnknownIdException, backend.get_code)
-
- def test_thumbnail(self):
- for url in self.urls:
- backend = self.instance(url[0])
- self.assertIn(url[1], backend.thumbnail)
-
-
-class VimeoBackendTestCase(BackendTestMixin, TestCase):
- urls = (
- ('http://vimeo.com/72304002', '72304002'),
- ('https://vimeo.com/72304002', '72304002'),
- ('http://www.vimeo.com/72304002', '72304002'),
- ('https://www.vimeo.com/72304002', '72304002'),
- ('http://player.vimeo.com/video/72304002', '72304002'),
- ('https://player.vimeo.com/video/72304002', '72304002'),
- )
-
- instance = VimeoBackend
-
- def test_vimeo_get_info_exception(self):
- with self.assertRaises(VideoDoesntExistException):
- backend = VimeoBackend('http://vimeo.com/123')
- backend.get_info()
-
- def test_get_thumbnail_url(self):
- backend = VimeoBackend('http://vimeo.com/72304002')
- self.assertEqual(backend.get_thumbnail_url(),
- 'http://i.vimeocdn.com/video/446150690_640.jpg')
-
- @patch('embed_video.backends.EMBED_VIDEO_TIMEOUT', 0.000001)
- def test_timeout_in_get_info(self):
- backend = VimeoBackend('http://vimeo.com/72304002')
- self.assertRaises(requests.Timeout, backend.get_info)
-
-
-class SoundCloudBackendTestCase(BackendTestMixin, TestCase):
- urls = (
- ('https://soundcloud.com/community/soundcloud-case-study-wildlife', '82244706'),
- ('https://soundcloud.com/matej-roman/jaromir-nohavica-karel-plihal-mikymauz', '7834701'),
- ('https://soundcloud.com/beny97/sets/jaromir-nohavica-prazska', '960591'),
- ('https://soundcloud.com/corbel-keep/norah-jones-come-away-with', '22485933'),
- )
-
- instance = SoundCloudBackend
-
- def setUp(self):
- class FooBackend(SoundCloudBackend):
- url = 'foobar'
-
- def get_info(self):
- return {
- 'width': 123,
- 'height': 321,
- 'thumbnail_url': 'xyz',
- 'html': u'\u003Ciframe width=\"100%\" height=\"400\" '
- u'scrolling=\"no\" frameborder=\"no\" '
- u'src=\"{0}\"\u003E\u003C/iframe\u003E'.format(self.url)
- }
-
- self.foo = FooBackend('abcd')
-
- def test_width(self):
- self.assertEqual(self.foo.width, 123)
-
- def test_height(self):
- self.assertEqual(self.foo.height, 321)
-
- def test_get_thumbnail_url(self):
- self.assertEqual(self.foo.get_thumbnail_url(), 'xyz')
-
- def test_get_url(self):
- self.assertEqual(self.foo.get_url(), self.foo.url)
-
- def test_get_embed_code(self):
- self.assertEqual(self.foo.get_embed_code(100, 200),
- u'\n')
-
- @patch('embed_video.backends.EMBED_VIDEO_TIMEOUT', 0.000001)
- def test_timeout_in_get_info(self):
- backend = SoundCloudBackend('https://soundcloud.com/community/soundcloud-case-study-wildlife')
- self.assertRaises(requests.Timeout, backend.get_info)
-
- def test_invalid_url(self):
- """ Check if bug #21 is fixed. """
- backend = SoundCloudBackend('https://soundcloud.com/xyz/foo')
- self.assertRaises(VideoDoesntExistException, backend.get_info)
diff --git a/embed_video/tests/tests.py b/embed_video/tests/tests_init.py
similarity index 100%
rename from embed_video/tests/tests.py
rename to embed_video/tests/tests_init.py
diff --git a/embed_video/tests/tests_tags.py b/embed_video/tests/tests_tags.py
deleted file mode 100644
index 64f260f..0000000
--- a/embed_video/tests/tests_tags.py
+++ /dev/null
@@ -1,341 +0,0 @@
-from unittest import TestCase
-from mock import Mock, patch
-import re
-
-try:
- # Python <= 2.7
- import urlparse
-except ImportError:
- # Python 3
- import urllib.parse as urlparse
-
-from django.template import TemplateSyntaxError
-from django.http import HttpRequest
-from django.template.base import Template
-from django.template.context import RequestContext
-from django.test.utils import override_settings
-from django.test.client import RequestFactory
-from testfixtures import LogCapture
-
-from embed_video.templatetags.embed_video_tags import VideoNode
-
-URL_PATTERN = re.compile(r'src="?\'?([^"\'>]*)"')
-
-
-class EmbedVideoNodeTestCase(TestCase):
- def setUp(self):
- self.parser = Mock()
- self.token = Mock(methods=['split_contents'])
-
- @staticmethod
- def _grc(context=None):
- return RequestContext(HttpRequest(), context)
-
- def test_embed(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' as ytb %}
- {% video ytb 'large' %}
- {% endvideo %}
- """)
- rendered = u''''''
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_direct_embed(self):
- template = Template("""
- {% load embed_video_tags %}
- {{ 'http://www.youtube.com/watch?v=jsrRJyHBvzw'|embed:'large' }}
- """)
- rendered = u''''''
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_direct_embed_tag(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video "http://www.youtube.com/watch?v=jsrRJyHBvzw" "large" %}
- """)
- rendered = u''''''
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_direct_embed_tag_with_default_size(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video "http://www.youtube.com/watch?v=jsrRJyHBvzw" %}
- """)
- rendered = u''''''
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_user_size(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' as ytb %}
- {% video ytb '800x800' %}
- {% endvideo %}
- """)
- rendered = u''''''
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_wrong_size(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' 'so x huge' %}
- """)
- self.assertRaises(TemplateSyntaxError, template.render, self._grc())
-
- def test_tag_youtube(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' as ytb %}
- {{ ytb.url }}
- {% endvideo %}
- """)
- rendered = 'http://www.youtube.com/embed/jsrRJyHBvzw?wmode=opaque'
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_tag_youtube_invalid_url(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/edit?abcd=efgh' as ytb %}
- {{ ytb.url }}
- {% endvideo %}
- """)
- self.assertEqual(template.render(self._grc()).strip(), '')
-
- def test_tag_vimeo(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video 'https://vimeo.com/72304002' as vimeo %}
- {{ vimeo.url }}
- {% endvideo %}
- """)
- rendered = 'http://player.vimeo.com/video/72304002'
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_tag_backend_variable_vimeo(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video 'https://vimeo.com/72304002' as vimeo %}
- {{ vimeo.backend }}
- {% endvideo %}
- """)
- rendered = 'VimeoBackend'
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_tag_backend_variable_youtube(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/watch?v=jsrRJyHBvz' as youtube %}
- {{ youtube.backend }}
- {% endvideo %}
- """)
- rendered = 'YoutubeBackend'
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_tag_backend_variable_soundcloud(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video 'https://soundcloud.com/community/soundcloud-case-study-wildlife' as soundcloud %}
- {{ soundcloud.backend }}
- {% endvideo %}
- """)
- rendered = 'SoundCloudBackend'
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_syntax_error(self):
- self.token.split_contents.return_value = []
- self.assertRaises(TemplateSyntaxError, VideoNode, self.parser, self.token)
-
- def test_repr(self):
- self.token.split_contents.return_value = (
- 'video', 'http://youtu.be/v/1234', 'as', 'myvideo'
- )
- self.parser.compile_filter.return_value = u'some_url'
-
- node = VideoNode(self.parser, self.token)
- self.assertEqual(str(node), '')
-
- def test_videonode_iter(self):
- out = ['a', 'b', 'c', 'd']
-
- class FooNode(VideoNode):
- nodelist_file = out
-
- def __init__(self):
- pass
-
- node = FooNode()
- self.assertEqual(out, [x for x in node])
-
- def test_get_backend_secure(self):
- class SecureRequest(RequestFactory):
- is_secure = lambda x: True
-
- context = {'request': SecureRequest()}
- backend = VideoNode.get_backend('http://www.youtube.com/watch?v=jsrRJyHBvzw', context)
- self.assertTrue(backend.is_secure)
-
- def test_get_backend_insecure(self):
- class InsecureRequest(RequestFactory):
- is_secure = lambda x: False
-
- context = {'request': InsecureRequest()}
- backend = VideoNode.get_backend('http://www.youtube.com/watch?v=jsrRJyHBvzw', context)
- self.assertFalse(backend.is_secure)
-
- def test_no_video_provided(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video '' 'large' %}
- """)
- self.assertEqual(template.render(self._grc()).strip(), '')
-
- @patch('embed_video.backends.EMBED_VIDEO_TIMEOUT', 0.000001)
- def test_empty_if_timeout(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video "http://vimeo.com/72304002" as my_video %}
- {{ my_video.thumbnail }}
- {% endvideo %}
- """)
- with LogCapture() as logs:
- self.assertEqual(template.render(self._grc()).strip(), '')
- log = logs.records[-1]
- self.assertEqual(log.name, 'embed_video.templatetags.embed_video_tags')
- self.assertEqual(log.msg, 'Timeout reached during rendering embed video (`http://vimeo.com/72304002`)')
-
- def test_relative_size(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video "http://vimeo.com/72304002" "80%x30%" %}
- """)
- rendered = ''
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_allow_spaces_in_size(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video "http://vimeo.com/72304002" "80% x 300" %}
- """)
- rendered = ''
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_soundcloud_invalid_url(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video "https://soundcloud.com/xyz/foo" %}
- """)
- self.assertEqual(template.render(self._grc()).strip(), '')
-
- ##########################################################################
- # Tests for adding GET query via KEY=VALUE pairs
- ##########################################################################
-
- def _validate_GET_query(self, rendered, expected):
- # Use this functioon to test the KEY=VALUE optional arguments to the
- # templatetag because there's no guarantee that they will be appended
- # to the URL query string in a particular order. By default the
- # YouTube backend adds wmode=opaque to the query string, so be sure to
- # include that in the expected querystring dict.
- url = URL_PATTERN.search(rendered).group(1)
- result = urlparse.urlparse(url)
- qs = urlparse.parse_qs(result[4])
- self.assertEqual(qs, expected)
-
- @override_settings(EMBED_VIDEO_YOUTUBE_QUERY={'rel': 0, 'stop': 5})
- def test_embed_with_query_settings_override(self):
- # Test KEY=VALUE argument with default values provided by settings
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' %}
- """)
- expected = {
- 'rel': ['0'],
- 'stop': ['5'],
- }
- rendered = template.render(self._grc())
- self._validate_GET_query(rendered, expected)
-
- def test_embed_with_query_var(self):
- # Test KEY=VALUE argument with the value resolving to a context
- # variable.
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' rel=show_related loop=5 %}
- """)
- expected = {
- 'rel': ['0'],
- 'loop': ['5'],
- 'wmode': ['opaque']
- }
- context = {'show_related': 0}
- rendered = template.render(self._grc(context))
- self._validate_GET_query(rendered, expected)
-
- def test_embed_with_query_multiple(self):
- # Test multiple KEY=VALUE arguments
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' rel=0 loop=1 end=5 %}
- """)
- expected = {
- 'rel': ['0'],
- 'loop': ['1'],
- 'end': ['5'],
- 'wmode': ['opaque']
- }
- self._validate_GET_query(template.render(self._grc()), expected)
-
- def test_embed_with_query_multiple_list(self):
- # Test multiple KEY=VALUE arguments where the key is repeated multiple
- # times (this is valid in a URL query).
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' rel=0 loop=1 end=5 end=6 %}
- """)
- expected = {
- 'rel': ['0'],
- 'loop': ['1'],
- 'end': ['5', '6'],
- 'wmode': ['opaque']
- }
- self._validate_GET_query(template.render(self._grc()), expected)
-
- def test_tag_youtube_with_query(self):
- # Test KEY=VALUE arguments when used as a tag block.
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' rel=0 as ytb %}
- {{ ytb.url }}
- {% endvideo %}
- """)
- rendered = 'http://www.youtube.com/embed/jsrRJyHBvzw?wmode=opaque&rel=0'
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_embed_with_query_rel(self):
- template = Template("""
- {% load embed_video_tags %}
- {% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' rel=0 %}
- """)
- rendered = u''''''
- self.assertEqual(template.render(self._grc()).strip(), rendered)
-
- def test_none_variable_passed_to_tag(self):
- """
- Checks issue #24.
- """
- template = Template("""
- {% with None as my_video %}
- {% load embed_video_tags %}
- {% video my_video %}
- {% endwith %}
- """)
- self.assertEqual(template.render(self._grc()).strip(), '')
-