+
{{ PostMeta(post, editable=true) }}
-
+
{{ post.name }}
{% if post.abstract -%}
-
+
{{ post.abstract }}
{%- endif %}
-
-
+
{{ post.text | safe }}
{{ UtterancesComments() }}
-
+
{% endblock content %}
diff --git a/tests/test_indieweb.py b/tests/test_indieweb.py
index 99197cd..296cbd5 100644
--- a/tests/test_indieweb.py
+++ b/tests/test_indieweb.py
@@ -3,12 +3,12 @@
from server import settings
-from .utils import find_rel_me_links, find_webmention_url
+from .utils import find_rel_me_links, find_webmention_url, parse_hcard, parse_hentry
@pytest.mark.asyncio
async def test_webmentions_url(client: httpx.AsyncClient) -> None:
- url = "https://florimond.dev"
+ url = "http://florimond.dev"
response = await client.get(url)
assert response.status_code == 200
html = response.text
@@ -19,10 +19,46 @@ async def test_webmentions_url(client: httpx.AsyncClient) -> None:
@pytest.mark.asyncio
async def test_rel_me_links(client: httpx.AsyncClient) -> None:
- url = "https://florimond.dev"
+ url = "http://florimond.dev"
response = await client.get(url)
assert response.status_code == 200
html = response.text
urls = find_rel_me_links(html)
assert urls == [link["href"] for link in settings.SOCIAL_LINKS]
+
+
+@pytest.mark.asyncio
+async def test_hcard(client: httpx.AsyncClient) -> None:
+ url = "http://florimond.dev"
+ response = await client.get(url)
+ assert response.status_code == 200
+ html = response.text
+
+ hcard = parse_hcard(html)
+
+ assert hcard == {
+ "p-name": "http://florimond.dev/en/",
+ "u-url": "http://florimond.dev/en/",
+ "u-photo": "http://florimond.dev/static/img/me.png",
+ }
+
+
+@pytest.mark.asyncio
+async def test_hentry(client: httpx.AsyncClient) -> None:
+ url = "http://florimond.dev/en/posts/2018/07/let-the-journey-begin"
+ response = await client.get(url)
+ assert response.status_code == 200
+ html = response.text
+
+ hentry = parse_hentry(html)
+
+ assert hentry["p-name"].strip() == "Let the Journey begin"
+ assert hentry["p-summary"].strip() == (
+ "Hi! My name is Florimond. "
+ "I will be your captain for the length of this journey. 👨✈️"
+ )
+ assert hentry["p-author"] == "http://florimond.dev/en/"
+ assert hentry["h-card"] == "http://florimond.dev/en/"
+ assert hentry["dt-published"] == "2018-07-25"
+ assert hentry["e-content"].startswith("Welcome to CodeSail!")
diff --git a/tests/utils.py b/tests/utils.py
index cb9be1d..9b0e30a 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -74,3 +74,86 @@ def find_rel_me_links(html: str) -> list[str]:
parser.feed(html)
return [href for tag, rel, href in parser.rels if tag == "a" and rel == "me"]
+
+
+class HCardParser(HTMLParser):
+ def __init__(self) -> None:
+ super().__init__()
+ self.hcard: dict = {}
+ self._in_hcard = False
+
+ def handle_starttag(self, tag: str, attrs: list) -> None:
+ attr = dict(attrs)
+
+ classattr = attr.get("class", "")
+
+ if "h-card" in classattr:
+ self._in_hcard = True
+
+ if self._in_hcard:
+ if tag == "img" and "u-photo" in classattr:
+ self.hcard["u-photo"] = attr["src"]
+
+ if tag == "a" and "p-name" in classattr:
+ self.hcard["p-name"] = attr["href"]
+
+ if tag == "a" and "u-url" in classattr:
+ self.hcard["u-url"] = attr["href"]
+
+
+def parse_hcard(html: str) -> dict:
+ parser = HCardParser()
+ parser.feed(html)
+ return parser.hcard
+
+
+class HEntryParser(HTMLParser):
+ def __init__(self) -> None:
+ super().__init__()
+ self.hentry: dict = {}
+ self._in_hentry = False
+ self._field = ""
+
+ def handle_starttag(self, tag: str, attrs: list) -> None:
+ attr = dict(attrs)
+
+ classattr = attr.get("class", "")
+
+ if tag == "article" and "h-entry" in classattr:
+ self._in_hentry = True
+
+ if self._in_hentry:
+ if tag == "h1" and "p-name" in classattr:
+ assert not self._field
+ self._field = "p-name"
+
+ if "p-summary" in classattr:
+ assert not self._field
+ self._field = "p-summary"
+
+ if tag == "a" and "p-author" in classattr:
+ self.hentry["p-author"] = attr["href"]
+
+ if tag == "a" and "h-card" in classattr:
+ self.hentry["h-card"] = attr["href"]
+
+ if tag == "time" and "dt-published" in classattr:
+ self.hentry["dt-published"] = attr["datetime"]
+
+ if "e-content" in classattr:
+ assert not self._field
+ self._field = "e-content"
+
+ def handle_data(self, data: str) -> None:
+ if self._field:
+ self.hentry[self._field] = data
+
+ def handle_endtag(self, _: str) -> None:
+ if self._field:
+ self._field = ""
+
+
+def parse_hentry(html: str) -> dict:
+ parser = HEntryParser()
+ parser.feed(html)
+ return parser.hentry