import polars as pl SCHEMA = pl.Schema( { "uid": pl.String, "objet": pl.String, "acheteur_id": pl.String, "montant": pl.Float64, "dureeMois": pl.Int64, "dateNotification": pl.Date, } ) def test_empty_filter_returns_true(): from src.utils.table_sql import filter_query_to_sql where, params = filter_query_to_sql("", SCHEMA) assert where == "TRUE" assert params == [] def test_icontains_string_is_case_insensitive_like(): from src.utils.table_sql import filter_query_to_sql where, params = filter_query_to_sql("{objet} icontains travaux", SCHEMA) assert where == '"objet" IS NOT NULL AND "objet" <> \'\' AND "objet" ILIKE ?' assert params == ["%travaux%"] def test_icontains_with_trailing_wildcard_is_starts_with(): from src.utils.table_sql import filter_query_to_sql where, params = filter_query_to_sql( "{acheteur_id} icontains 24350013900189*", SCHEMA ) assert ( where == '"acheteur_id" IS NOT NULL AND "acheteur_id" <> \'\' AND "acheteur_id" ILIKE ?' ) assert params == ["24350013900189%"] def test_icontains_with_leading_wildcard_is_ends_with(): from src.utils.table_sql import filter_query_to_sql where, params = filter_query_to_sql("{uid} icontains *2024", SCHEMA) assert where == '"uid" IS NOT NULL AND "uid" <> \'\' AND "uid" ILIKE ?' assert params == ["%2024"] def test_numeric_greater_than(): from src.utils.table_sql import filter_query_to_sql where, params = filter_query_to_sql("{montant} i> 40000", SCHEMA) assert where == '"montant" IS NOT NULL AND "montant" > ?' assert params == [40000.0] def test_numeric_less_than(): from src.utils.table_sql import filter_query_to_sql where, params = filter_query_to_sql("{montant} i< 1000", SCHEMA) assert where == '"montant" IS NOT NULL AND "montant" < ?' assert params == [1000.0] def test_numeric_equality_via_icontains(): from src.utils.table_sql import filter_query_to_sql where, params = filter_query_to_sql("{dureeMois} icontains 12", SCHEMA) assert where == '"dureeMois" IS NOT NULL AND "dureeMois" = ?' assert params == [12] def test_date_column_treated_as_string_ilike(): from src.utils.table_sql import filter_query_to_sql where, params = filter_query_to_sql("{dateNotification} icontains 2024*", SCHEMA) assert "ILIKE" in where assert params == ["2024%"] def test_multiple_filters_joined_by_and(): from src.utils.table_sql import filter_query_to_sql filter_query = "{objet} icontains voirie && {montant} i> 40000" where, params = filter_query_to_sql(filter_query, SCHEMA) assert " AND " in where assert params == ["%voirie%", 40000.0] def test_invalid_numeric_value_is_skipped(): from src.utils.table_sql import filter_query_to_sql where, params = filter_query_to_sql("{montant} i> notanumber", SCHEMA) assert where == "TRUE" assert params == [] def test_unknown_column_is_skipped(): from src.utils.table_sql import filter_query_to_sql where, params = filter_query_to_sql("{inexistant} icontains foo", SCHEMA) assert where == "TRUE" assert params == [] def test_sort_by_empty(): from src.utils.table_sql import sort_by_to_sql assert sort_by_to_sql([], SCHEMA) == "" assert sort_by_to_sql(None, SCHEMA) == "" def test_sort_by_single_column_desc(): from src.utils.table_sql import sort_by_to_sql result = sort_by_to_sql([{"column_id": "montant", "direction": "desc"}], SCHEMA) assert result == '"montant" DESC NULLS LAST' def test_sort_by_multiple_columns_preserves_order(): from src.utils.table_sql import sort_by_to_sql result = sort_by_to_sql( [ {"column_id": "dateNotification", "direction": "desc"}, {"column_id": "montant", "direction": "asc"}, ], SCHEMA, ) assert result == '"dateNotification" DESC NULLS LAST, "montant" ASC NULLS LAST' def test_sort_by_ignores_unknown_column(): from src.utils.table_sql import sort_by_to_sql result = sort_by_to_sql([{"column_id": "fake", "direction": "asc"}], SCHEMA) assert result == ""