aboutsummaryrefslogtreecommitdiff
path: root/tests/test_models.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tests/test_models.py148
1 files changed, 148 insertions, 0 deletions
diff --git a/tests/test_models.py b/tests/test_models.py
new file mode 100644
index 0000000..2fa2cb8
--- /dev/null
+++ b/tests/test_models.py
@@ -0,0 +1,148 @@
+# SPDX-FileCopyrightText: 2026 Dennis Fink <me+coding@dennisfink.me>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+import uuid
+from collections.abc import Callable
+from datetime import UTC, datetime
+
+import pytest
+
+from webmentions_ssg.models import (
+ ReceivedWebmention,
+ SentWebmention,
+ Source,
+ User,
+ uuid7_to_datetime,
+)
+
+
+def test_user_repr() -> None:
+ user = User(username="admin", password="secret")
+ assert repr(user) == "<User admin>"
+
+
+def test_user_password_is_write_only() -> None:
+ user = User(username="admin", password="secret")
+ with pytest.raises(AttributeError, match="Password is write-only"):
+ _ = user.password
+
+
+def test_user_password_is_hashed_and_can_be_checked() -> None:
+ user = User(username="admin", password="secret")
+ assert user.password_hash != "secret"
+ assert user.check_password("secret")
+ assert not user.check_password("wrong")
+
+
+@pytest.mark.parametrize(
+ ("status", "expected"),
+ [
+ ("received", False),
+ ("verifying", False),
+ ("verified", True),
+ ("failed", False),
+ ("deleted", False),
+ ],
+)
+def test_received_webmention_verified(status: str, expected: bool) -> None:
+ webmention = ReceivedWebmention(
+ uuid=uuid.uuid7(),
+ source="https://source.example/post",
+ target="https://dennisfink.me/blog/example/",
+ status=status,
+ )
+
+ assert webmention.verified is expected
+
+
+@pytest.mark.parametrize(
+ ("desired_revision", "processed_revision", "expected"),
+ [(1, None, True), (1, 0, True), (2, 1, True), (1, 1, False), (1, 2, False)],
+)
+def test_sent_webmention_pending(
+ desired_revision: int, processed_revision: int | None, expected: bool
+) -> None:
+ webmention = SentWebmention(
+ target="https://example.com/post",
+ desired_revision=desired_revision,
+ processed_revision=processed_revision,
+ )
+ assert webmention.pending is expected
+
+
+def test_uuid7_to_datetime() -> None:
+ identifier = uuid.uuid7()
+ timestamp = uuid7_to_datetime(identifier)
+
+ assert timestamp.tzinfo is UTC
+ assert timestamp.timestamp() == pytest.approx(identifier.time / 1000)
+
+
+@pytest.mark.parametrize(
+ "factory",
+ [
+ pytest.param(
+ lambda identifier: ReceivedWebmention(
+ uuid=identifier,
+ source="https://source.example/post",
+ target="https://dennisfink.me/blog/example/",
+ ),
+ id="received-webmention",
+ ),
+ pytest.param(
+ lambda identifier: Source(
+ uuid=identifier,
+ path="example/index.html",
+ url="https://dennisfink.me/blog/example/",
+ content_hash="0" * 32,
+ revision=1,
+ last_seen_at=datetime.now(UTC),
+ revised_at=datetime.now(UTC),
+ ),
+ id="source",
+ ),
+ pytest.param(
+ lambda identifier: SentWebmention(
+ uuid=identifier, target="https://example.com/post", desired_revision=1
+ ),
+ id="sent-webmention",
+ ),
+ ],
+)
+def test_created_at_comes_from_uuid7_timestamp(
+ factory: Callable[[uuid.UUID], ReceivedWebmention | Source | SentWebmention],
+) -> None:
+ identifier = uuid.uuid7()
+ model = factory(identifier)
+ assert model.created_at == uuid7_to_datetime(identifier)
+
+
+def test_received_webmention_repr() -> None:
+ webmention = ReceivedWebmention(
+ uuid=uuid.uuid7(),
+ source="https://source.example/post",
+ target="https://dennisfink.me/blog/example/",
+ )
+
+ assert repr(webmention) == (
+ "<ReceivedWebmention 'https://source.example/post' -> "
+ "'https://dennisfink.me/blog/example/'>"
+ )
+
+
+def test_source_repr() -> None:
+ source = Source(
+ path="example/index.html",
+ url="https://dennisfink.me/blog/example/",
+ content_hash="0" * 32,
+ revision=1,
+ last_seen_at=datetime.now(UTC),
+ revised_at=datetime.now(UTC),
+ )
+ assert repr(source) == "<Source 'https://dennisfink.me/blog/example/'>"
+
+
+def test_sent_webmention_repr() -> None:
+ webmention = SentWebmention(target="https://example.com/post", desired_revision=1)
+ assert repr(webmention) == "<SentWebmention 'https://example.com/post'>"