diff options
Diffstat (limited to '')
| -rw-r--r-- | tests/test_models.py | 148 |
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'>" |
