from unittest.mock import patch import pytest from flask import Flask from werkzeug.datastructures import MultiDict from webmentions_ssg.forms import EndpointForm VALID_SOURCE = "https://source.example/post" VALID_TARGET = "https://dennisfink.me/blog/example/" @patch( "webmentions_ssg.forms.validators.ensure_public_url", new=lambda url: None, ) @pytest.mark.parametrize( ( "form_data", "invalid_field", "expected_error", ), [ pytest.param( { "target": VALID_TARGET, }, "source", "This field is required.", id="source-required", ), pytest.param( { "source": "not a URL", "target": VALID_TARGET, }, "source", "Invalid URL.", id="source-url", ), pytest.param( { "source": "ftp://source.example/post", "target": VALID_TARGET, }, "source", "source must begin with http or https", id="source-scheme", ), pytest.param( { "source": VALID_TARGET, "target": VALID_TARGET, }, "source", None, id="source-not-equal-to-target", ), pytest.param( { "source": VALID_SOURCE, }, "target", "This field is required.", id="target-required", ), pytest.param( { "source": VALID_SOURCE, "target": "not a URL", }, "target", "Invalid URL.", id="target-url", ), pytest.param( { "source": VALID_SOURCE, "target": "ftp://dennisfink.me/blog/example/", }, "target", "target must begin with http or https", id="target-scheme", ), pytest.param( { "source": VALID_SOURCE, "target": "https://example.com/post", }, "target", None, id="target-allowed-hostname", ), ], ) def test_endpoint_form_rejects_invalid_data( app: Flask, form_data: dict[str, str], invalid_field: str, expected_error: str | None, ) -> None: with app.test_request_context( "/endpoint", method="POST", ): form = EndpointForm( formdata=MultiDict(form_data), meta={"csrf": False}, ) assert not form.validate() assert invalid_field in form.errors if expected_error is not None: assert expected_error in form.errors[invalid_field] @patch( "webmentions_ssg.forms.validators.ensure_public_url", new=lambda url: None, ) def test_endpoint_form_accepts_valid_data( app: Flask, ) -> None: with app.test_request_context( "/endpoint", method="POST", ): form = EndpointForm( formdata=MultiDict( { "source": VALID_SOURCE, "target": VALID_TARGET, } ), meta={"csrf": False}, ) assert form.validate() assert form.errors == {}