aboutsummaryrefslogtreecommitdiff
path: root/tests/conftest.py
blob: 94ba65063c72493f4068e0baaec524992a8546de (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import uuid
from collections.abc import Callable, Iterator
from types import ModuleType

import httpx
import pytest
from flask import Flask
from flask.testing import FlaskClient

from webmentions_ssg import DATABASE as db
from webmentions_ssg import create_app
from webmentions_ssg.config import TestingConfig
from webmentions_ssg.models import ReceivedWebmention

HTTPHandler = Callable[
    [httpx.Request],
    httpx.Response,
]


@pytest.fixture
def app() -> Iterator[Flask]:
    """
    Create a new Flask application and in-memory database
    for every test.
    """

    application = create_app(TestingConfig)

    with application.app_context():
        db.create_all()

    yield application

    with application.app_context():
        db.session.remove()
        db.drop_all()
        db.engine.dispose()


@pytest.fixture
def client(app: Flask) -> FlaskClient:
    return app.test_client()


@pytest.fixture
def receiver_module(app: Flask) -> ModuleType:
    """
    Ensure the application and Huey extension are initialized
    before retrieving the tasks module.
    """

    from webmentions_ssg.tasks import receiver

    return receiver


@pytest.fixture
def views_module(app: Flask) -> ModuleType:
    from webmentions_ssg import views

    return views


@pytest.fixture
def make_webmention(
    app: Flask,
) -> Callable[..., uuid.UUID]:
    def create(
        *,
        source: str = "https://source.example/post",
        target: str = ("https://dennisfink.me/blog/example/"),
        status: str = "received",
        failure_reason: str | None = None,
    ) -> uuid.UUID:
        identifier = uuid.uuid7()

        with app.app_context():
            webmention = ReceivedWebmention(
                uuid=identifier,
                source=source,
                target=target,
                status=status,
                failure_reason=failure_reason,
            )

            db.session.add(webmention)
            db.session.commit()

        return identifier

    return create


@pytest.fixture
def install_httpx_mock(
    monkeypatch: pytest.MonkeyPatch,
    receiver_module: ModuleType,
) -> Callable[[HTTPHandler], None]:
    """
    Replace the HTTPX transport without replacing HTTPX itself.
    """

    real_client = httpx.Client

    def install(handler: HTTPHandler) -> None:
        transport = httpx.MockTransport(handler)

        def create_client(
            *args,
            **kwargs,
        ) -> httpx.Client:
            return real_client(
                *args,
                transport=transport,
                **kwargs,
            )

        monkeypatch.setattr(
            receiver_module.httpx,
            "Client",
            create_client,
        )

    return install