diff --git a/src/documents/tests/test_api_filter_by_custom_fields.py b/src/documents/tests/test_api_filter_by_custom_fields.py index b9637aa3e..67641fe3f 100644 --- a/src/documents/tests/test_api_filter_by_custom_fields.py +++ b/src/documents/tests/test_api_filter_by_custom_fields.py @@ -6,6 +6,7 @@ from unittest.mock import patch from urllib.parse import quote import time_machine +from django.db import connection from django.test import override_settings from django.utils import timezone from rest_framework.test import APITestCase @@ -20,6 +21,13 @@ from paperless_testing.dirs import DirectoriesMixin from paperless_testing.factories import UserFactory +def _exact_equal(value: str | None, expected: str) -> bool: + """`exact` follows the column collation, which is case insensitive on MariaDB.""" + if connection.vendor == "mysql" and value is not None: + return value.casefold() == expected.casefold() + return value == expected + + class DocumentWrapper: """ Allows Pythonic access to the custom fields associated with the wrapped document. @@ -287,7 +295,8 @@ class TestCustomFieldsSearch(DirectoriesMixin, APITestCase): self._assert_query_match_predicate( ["string_field", "exact", "paperless"], lambda document: ( - "string_field" in document and document["string_field"] == "paperless" + "string_field" in document + and _exact_equal(document["string_field"], "paperless") ), ) @@ -296,7 +305,10 @@ class TestCustomFieldsSearch(DirectoriesMixin, APITestCase): ["string_field", "in", ["paperless", "Paperless"]], lambda document: ( "string_field" in document - and document["string_field"] in ("paperless", "Paperless") + and any( + _exact_equal(document["string_field"], expected) + for expected in ("paperless", "Paperless") + ) ), ) @@ -761,7 +773,7 @@ class TestCustomFieldsSearch(DirectoriesMixin, APITestCase): lambda document: ( not ( "string_field" in document - and document["string_field"] == "paperless" + and _exact_equal(document["string_field"], "paperless") ) ), ) diff --git a/src/documents/tests/test_document_list_effective_content_annotation.py b/src/documents/tests/test_document_list_effective_content_annotation.py index 9a1b0978d..10d73dc29 100644 --- a/src/documents/tests/test_document_list_effective_content_annotation.py +++ b/src/documents/tests/test_document_list_effective_content_annotation.py @@ -242,9 +242,7 @@ class TestDocumentListEffectiveContentAnnotation: # Only the list query itself reads a content column: no extra query # for the skipped prefetch, none for a per-instance fallback content_queries = [ - query - for query in ctx.captured_queries - if '"documents_document"."content"' in query["sql"] + query for query in ctx.captured_queries if _content_column() in query["sql"] ] assert len(content_queries) == 1 @@ -365,6 +363,11 @@ def _get_document_queries( return [q for q in ctx.captured_queries if '"django_content_type"' not in q["sql"]] +def _content_column() -> str: + quote = connection.ops.quote_name + return f"{quote('documents_document')}.{quote('content')}" + + def _get_effective_content_fallback_queries( ctx: CaptureQueriesContext, ) -> list[dict[str, str]]: @@ -379,7 +382,7 @@ def _get_effective_content_fallback_queries( return [ q for q in ctx.captured_queries - if q["sql"].startswith('SELECT "documents_document"."content" FROM') + if q["sql"].startswith(f"SELECT {_content_column()} FROM") ]