diff --git a/src/conftest.py b/src/conftest.py index a8fc6aa65..187ca5982 100644 --- a/src/conftest.py +++ b/src/conftest.py @@ -31,6 +31,18 @@ def faker_session_locale() -> str: return "en_US" +@pytest.fixture(autouse=True) +def _fast_password_hasher(settings: Settings) -> None: + """Hash test passwords with MD5 instead of Django's default PBKDF2. + + PBKDF2 is deliberately slow, and every ``admin_user`` or + ``create_superuser`` call pays for it: about 600 ms each. No test depends + on the hash format, only on ``check_password`` and on the stored value + changing when the password does. + """ + settings.PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"] + + @pytest.fixture(autouse=True) def _clear_content_type_caches() -> None: """Clear Django's ContentType cache and guardian's lru_cache before each test. diff --git a/src/documents/tests/search/test_documented_syntax.py b/src/documents/tests/search/test_documented_syntax.py index 55d446e20..fbfdddfac 100644 --- a/src/documents/tests/search/test_documented_syntax.py +++ b/src/documents/tests/search/test_documented_syntax.py @@ -269,7 +269,7 @@ class TestDocumentedDateForms: yield @pytest.fixture - def dated(self, index_document: Callable[..., Document]) -> dict[str, int]: + def dated(self, backend: TantivyBackend) -> dict[str, int]: stamps = { "today": datetime(2026, 6, 15, 9, 0, tzinfo=UTC), "yesterday": datetime(2026, 6, 14, 9, 0, tzinfo=UTC), @@ -279,14 +279,14 @@ class TestDocumentedDateForms: "january": datetime(2026, 1, 10, 10, 0, tzinfo=UTC), "old": datetime(2005, 3, 4, 15, 30, tzinfo=UTC), } - return { - label: index_document( - title=label, - content="dated body", - added=stamp, - ).pk + docs = { + label: DocumentFactory(title=label, content="dated body", added=stamp) for label, stamp in stamps.items() } + with backend.batch_update() as batch: + for doc in docs.values(): + batch.add_or_update(doc) + return {label: doc.pk for label, doc in docs.items()} @pytest.mark.parametrize( ("query", "label"), diff --git a/src/documents/tests/test_workflows.py b/src/documents/tests/test_workflows.py index b20e81880..7364ec8c2 100644 --- a/src/documents/tests/test_workflows.py +++ b/src/documents/tests/test_workflows.py @@ -4192,7 +4192,11 @@ class TestWorkflows( expected_str = "Error occurred sending webhook" self.assertIn(expected_str, cm.output[0]) - def test_workflow_webhook_action_url_invalid_params_headers(self) -> None: + @mock.patch("documents.workflows.webhooks.send_webhook.apply_async") + def test_workflow_webhook_action_url_invalid_params_headers( + self, + mock_post, + ) -> None: """ GIVEN: - Document updated workflow with webhook action @@ -4201,6 +4205,7 @@ class TestWorkflows( - Document that matches is updated THEN: - Error is logged + - The webhook is still queued, with empty data and headers """ trigger = WorkflowTrigger.objects.create( type=WorkflowTrigger.WorkflowTriggerType.DOCUMENT_UPDATED, @@ -4237,6 +4242,11 @@ class TestWorkflows( expected_str = "Error occurred parsing webhook headers" self.assertIn(expected_str, cm.output[1]) + mock_post.assert_called_once() + kwargs = mock_post.call_args.kwargs["kwargs"] + self.assertEqual(kwargs["data"], {}) + self.assertEqual(kwargs["headers"], {}) + @mock.patch("httpx.Client.post") def test_workflow_webhook_send_webhook_task(self, mock_post) -> None: mock_post.return_value = mock.Mock(