# SPDX-FileCopyrightText: 2026 Dennis Fink # # 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) == "" 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) == ( " " "'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) == "" def test_sent_webmention_repr() -> None: webmention = SentWebmention(target="https://example.com/post", desired_revision=1) assert repr(webmention) == ""