import os from textwrap import dedent import pytest from campaigns.connectors.db.jinjasql import JinjaSQL @pytest.fixture def jsql() -> JinjaSQL: return JinjaSQL(os.path.dirname(__file__)) def test_prepare_query_named_param_style(jsql: JinjaSQL) -> None: event_id = "1000" fan_ids = (1, 2, 3, 4, 5) template = """ SELECT * FROM event WHERE id = {{ event_id }} AND fan_id IN {{ fan_ids }} """.strip() query, bind_params = jsql.prepare_query( template, context={"event_id": event_id, "fan_ids": fan_ids} ) expected_query = """ SELECT * FROM event WHERE id = :event_id_1 AND fan_id IN :fan_ids_2 """.strip() assert query == expected_query assert bind_params == { "event_id_1": event_id, "fan_ids_2": fan_ids, } def test_prepare_query_nested_named_param_style(jsql: JinjaSQL) -> None: timeframe = { "start": "2021-12-12", "end": "2021-12-12", } template = """ SELECT * FROM event WHERE created_at >= {{ timeframe.start }} AND created_at <= {{ timeframe.end }} """.strip() query, bind_params = jsql.prepare_query( template, context={ "timeframe": timeframe, }, ) expected_query = """ SELECT * FROM event WHERE created_at >= :timeframe__start_1 AND created_at <= :timeframe__end_2 """.strip() assert query == expected_query assert bind_params == { "timeframe__start_1": timeframe["start"], "timeframe__end_2": timeframe["end"], } def test_prepare_query_from_file(jsql: JinjaSQL) -> None: event_id = "1000" fan_ids = (1, 2, 3, 4, 5) date = "2022-06-10" query, bind_params = jsql.prepare_query( "data/get-events.sql", context={ "event_id": event_id, "fan_ids": fan_ids, "date": date, }, ) expected_query = dedent( """ SELECT * FROM event WHERE id = :event_id_1 AND fan_id IN :fan_ids_2 AND date = :date_3 """ ).strip() assert query == expected_query assert bind_params == { "event_id_1": event_id, "fan_ids_2": fan_ids, "date_3": date, } def test_prepare_query_empty_identifier_quote_char(jsql: JinjaSQL) -> None: query, bind_params = jsql.prepare_query( "SELECT * FROM {{ table_name | identifier }}", context={"table_name": "users"}, identifier_quote_char="", ) assert query == "SELECT * FROM users" assert bind_params == {} def test_prepare_query_identifier_quote_char(jsql: JinjaSQL) -> None: query, bind_params = jsql.prepare_query( dedent( """ SELECT * FROM {{ table_name | identifier }} WHERE id IN {{ user_ids | inclause}} """ ).strip(), context={"table_name": "users", "user_ids": [1, 2, 3]}, identifier_quote_char='"', ) expected_query = dedent( """ SELECT * FROM "users" WHERE id IN (:inclause_1,:inclause_2,:inclause_3) """ ).strip() assert query == expected_query assert bind_params == { "inclause_1": 1, "inclause_2": 2, "inclause_3": 3, } def test_prepare_query_nested_inclause(jsql: JinjaSQL) -> None: query, bind_params = jsql.prepare_query( dedent( """ SELECT * FROM user WHERE param_1 IN {{ criteria.params_1 | inclause}} AND param_2 IN {{ criteria.params_2 | inclause}} """ ).strip(), context={ "criteria": { "params_1": (1, 2), "params_2": (3, 4), } }, ) expected_query = dedent( """ SELECT * FROM user WHERE param_1 IN (:inclause_1,:inclause_2) AND param_2 IN (:inclause_3,:inclause_4) """ ).strip() assert query == expected_query assert bind_params == { "inclause_1": 1, "inclause_2": 2, "inclause_3": 3, "inclause_4": 4, }