Validates EmbedBlock URLs against providers.

pull/4736/head
Bertrand Bordage 2018-04-30 12:40:42 +02:00 zatwierdzone przez Matt Westcott
rodzic 1247565d3d
commit 42caa586b4
4 zmienionych plików z 45 dodań i 13 usunięć

Wyświetl plik

@ -7,6 +7,7 @@ Changelog
* Added support for Django 2.1 (Ryan Verner, Matt Westcott)
* Added 'scale' image filter (Oliver Wilkerson)
* Added meta tag to prevent search engines from indexing admin pages (Karl Hobley)
* EmbedBlock now validates against recognised embed providers on save (Bertrand Bordage)
* Fix: Respect next param on login (Loic Teixeira)
* Fix: InlinePanel now handles relations that specify a related_query_name (Aram Dulyan)

Wyświetl plik

@ -24,6 +24,7 @@ Other features
* Added 'scale' image filter (Oliver Wilkerson)
* Added meta tag to prevent search engines from indexing admin pages (Karl Hobley)
* EmbedBlock now validates against recognised embed providers on save (Bertrand Bordage)
Bug fixes

Wyświetl plik

@ -1,3 +1,7 @@
from django.core.exceptions import ValidationError
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from wagtail.core import blocks
from wagtail.embeds.format import embed_to_frontend_html
@ -13,9 +17,13 @@ class EmbedValue:
def __init__(self, url):
self.url = url
def __str__(self):
@cached_property
def html(self):
return embed_to_frontend_html(self.url)
def __str__(self):
return self.html
class EmbedBlock(blocks.URLBlock):
def get_default(self):
@ -57,5 +65,10 @@ class EmbedBlock(blocks.URLBlock):
else:
return EmbedValue(value)
def clean(self, value):
if isinstance(value, EmbedValue) and not value.html:
raise ValidationError(_("Cannot find an embed for this URL."))
return super().clean(value)
class Meta:
icon = "media"

Wyświetl plik

@ -518,25 +518,42 @@ class TestEmbedBlock(TestCase):
self.assertIsInstance(block5.get_default(), EmbedValue)
self.assertEqual(block5.get_default().url, 'http://www.example.com/foo')
def test_clean(self):
required_block = EmbedBlock()
nonrequired_block = EmbedBlock(required=False)
def test_clean_required(self):
block = EmbedBlock()
# a valid EmbedValue should return the same value on clean
cleaned_value = required_block.clean(EmbedValue('http://www.example.com/foo'))
cleaned_value = block.clean(
EmbedValue('https://www.youtube.com/watch?v=_U79Wc965vw'))
self.assertIsInstance(cleaned_value, EmbedValue)
self.assertEqual(cleaned_value.url, 'http://www.example.com/foo')
self.assertEqual(cleaned_value.url,
'https://www.youtube.com/watch?v=_U79Wc965vw')
cleaned_value = nonrequired_block.clean(EmbedValue('http://www.example.com/foo'))
with self.assertRaisesMessage(ValidationError, ''):
block.clean(None)
def test_clean_non_required(self):
block = EmbedBlock(required=False)
cleaned_value = block.clean(
EmbedValue('https://www.youtube.com/watch?v=_U79Wc965vw'))
self.assertIsInstance(cleaned_value, EmbedValue)
self.assertEqual(cleaned_value.url, 'http://www.example.com/foo')
self.assertEqual(cleaned_value.url,
'https://www.youtube.com/watch?v=_U79Wc965vw')
# None should only be accepted for nonrequired blocks
cleaned_value = nonrequired_block.clean(None)
self.assertEqual(cleaned_value, None)
cleaned_value = block.clean(None)
self.assertIsNone(cleaned_value)
def test_clean_invalid_url(self):
non_required_block = EmbedBlock(required=False)
with self.assertRaises(ValidationError):
required_block.clean(None)
non_required_block.clean(
EmbedValue('http://no-oembed-here.com/something'))
required_block = EmbedBlock()
with self.assertRaises(ValidationError):
required_block.clean(
EmbedValue('http://no-oembed-here.com/something'))
class TestMediaEmbedHandler(TestCase):