import re
import unittest
from unittest.mock import MagicMock, patch
import markdown
from mdx_oembed import endpoints
from mdx_oembed.inlinepatterns import OEMBED_LINK_RE, _is_image_url, _sanitize_html
# ---------------------------------------------------------------------------
# Regex tests
# ---------------------------------------------------------------------------
class TestOEmbedRegex(unittest.TestCase):
"""Tests for the raw OEMBED_LINK_RE pattern."""
def setUp(self):
self.re = re.compile(OEMBED_LINK_RE)
# --- should NOT match (relative URLs) ---
def test_ignore_relative_image_link(self):
assert self.re.search("") is None
# --- should match (absolute URLs — image filtering is in Python now) ---
def test_match_absolute_url(self):
m = self.re.search("")
assert m is not None
def test_match_youtube_link(self):
m = self.re.search("")
assert m is not None
assert m.group(2) == "http://www.youtube.com/watch?v=ABC"
def test_match_youtube_short_link(self):
m = self.re.search("")
assert m is not None
def test_match_https(self):
m = self.re.search("")
assert m is not None
def test_match_protocol_relative(self):
m = self.re.search("")
assert m is not None
def test_alt_text_captured(self):
m = self.re.search("")
assert m is not None
assert m.group(1) == "my alt text"
# ---------------------------------------------------------------------------
# Image URL detection
# ---------------------------------------------------------------------------
class TestIsImageUrl(unittest.TestCase):
def test_common_extensions(self):
for ext in ("png", "jpg", "jpeg", "gif", "webp", "avif", "svg", "bmp", "tiff", "ico"):
assert _is_image_url(f"http://example.com/photo.{ext}") is True, ext
def test_case_insensitive(self):
assert _is_image_url("http://example.com/Photo.PNG") is True
assert _is_image_url("http://example.com/photo.JpEg") is True
def test_query_string_ignored(self):
assert _is_image_url("http://example.com/photo.jpg?size=large") is True
def test_non_image(self):
assert _is_image_url("http://www.youtube.com/watch?v=ABC") is False
def test_no_extension(self):
assert _is_image_url("http://example.com/embed") is False
# ---------------------------------------------------------------------------
# HTML sanitization
# ---------------------------------------------------------------------------
class TestSanitizeHtml(unittest.TestCase):
def test_allows_iframe(self):
html = ''
result = _sanitize_html(html)
assert ""):
"""Create a mock OEmbedConsumer that returns the given HTML."""
consumer = MagicMock()
response = MagicMock()
response.get = lambda key, default=None: {"html": html_response, "type": "video"}.get(key, default)
response.__getitem__ = lambda self_inner, key: {"html": html_response, "type": "video"}[key]
consumer.embed.return_value = response
return consumer
def _make_photo_consumer(photo_url="https://example.com/photo.jpg", width=640, height=480):
consumer = MagicMock()
data = {"type": "photo", "url": photo_url, "width": width, "height": height}
response = MagicMock()
response.get = lambda key, default=None: data.get(key, default)
response.__getitem__ = lambda self_inner, key: data[key]
consumer.embed.return_value = response
return consumer
def _make_failing_consumer(exc_class=Exception, msg="fail"):
consumer = MagicMock()
consumer.embed.side_effect = exc_class(msg)
return consumer
class TestOEmbedExtension(unittest.TestCase):
"""Integration tests with mocked oEmbed consumer."""
def _convert(self, text, consumer=None, **ext_config):
"""Helper: convert markdown with a mocked consumer."""
if consumer is None:
consumer = _make_mock_consumer()
with patch("mdx_oembed.extension.oembed.OEmbedConsumer", return_value=consumer):
md = markdown.Markdown(
extensions=["oembed"],
extension_configs={"oembed": ext_config} if ext_config else {},
)
return md.convert(text)
# --- basic embedding ---
def test_youtube_embed(self):
output = self._convert("")
assert "", "type": "video"}
resp.get = lambda key, default=None: data.get(key, default)
resp.__getitem__ = lambda self_inner, key: data[key]
return resp
raise _oembed.OEmbedNoEndpoint("nope")
consumer = MagicMock()
consumer.embed.side_effect = side_effect
with patch("mdx_oembed.extension.oembed.OEmbedConsumer", return_value=consumer):
md = markdown.Markdown(
extensions=["oembed"],
extension_configs={
"oembed": {"allowed_endpoints": [endpoints.YOUTUBE]},
},
)
yt_output = md.convert("")
assert "