fix(maintenance): auto-expiry + adaptive markdown height + tests
- Auto-expiry: expired events auto-end on GET /events via task manager - Height: _estimate_markdown_height adapted to unit=8px scale with padding detection - CRITICAL-1: removed dead import remove_chart_from_position (QA finding) - CRITICAL-2: added chart alive check in ensure_banner_chart (QA finding) - CRITICAL-3: fixed test assertions update_markdown_chart → update_banner_on_dashboard - @POST contract: fixed return range [2,12] → [19,200] - Tests: 8 new tests (auto-expiry + layout height)
This commit is contained in:
118
backend/tests/test_sql_table_extractor.py
Normal file
118
backend/tests/test_sql_table_extractor.py
Normal file
@@ -0,0 +1,118 @@
|
||||
# #region test_sql_table_extractor [C:3] [TYPE TestModule] [SEMANTICS test, sql, table, extractor, pytest]
|
||||
# @BRIEF Unit tests for SqlTableExtractor — T017. Verifies three-phase extraction of schema.table references from SQL+Jinja.
|
||||
# @LAYER Test
|
||||
# @RELATION BINDS_TO -> [SqlTableExtractorModule]
|
||||
# @TEST_CONTRACT: extract_tables_from_sql(str) -> set[str]
|
||||
# @TEST_EDGE: empty_input -> returns empty set
|
||||
# @TEST_EDGE: no_schema_qualified_tables -> returns empty set
|
||||
# @TEST_EDGE: string_literal_false_positive -> filtered out by sqlparse
|
||||
# @TEST_FIXTURE: simple_select -> INLINE_SQL: "SELECT * FROM raw.sales"
|
||||
# @TEST_FIXTURE: jinja_expr -> INLINE_SQL: "SELECT * FROM {{ source('raw', 'sales') }}"
|
||||
import pytest
|
||||
|
||||
from src.services.sql_table_extractor import extract_tables_from_sql
|
||||
|
||||
|
||||
class TestExtractTablesFromSql:
|
||||
"""T017: Unit tests for SqlTableExtractor.extract_tables_from_sql()."""
|
||||
|
||||
# #region test_simple_select [C:2] [TYPE Function]
|
||||
# @BRIEF Happy path: simple SELECT with FROM schema.table.
|
||||
def test_simple_select(self):
|
||||
sql = "SELECT * FROM raw.sales"
|
||||
result = extract_tables_from_sql(sql)
|
||||
assert result == {"raw.sales"}
|
||||
# #endregion test_simple_select
|
||||
|
||||
# #region test_multiple_tables [C:2] [TYPE Function]
|
||||
# @BRIEF JOIN with multiple schema-qualified tables.
|
||||
def test_multiple_tables(self):
|
||||
sql = "SELECT a.id, b.name FROM raw.sales a JOIN raw.inventory b ON a.id = b.sale_id"
|
||||
result = extract_tables_from_sql(sql)
|
||||
assert result == {"raw.sales", "raw.inventory"}
|
||||
# #endregion test_multiple_tables
|
||||
|
||||
# #region test_empty_input [C:2] [TYPE Function]
|
||||
# @BRIEF Empty string returns empty set.
|
||||
def test_empty_input(self):
|
||||
assert extract_tables_from_sql("") == set()
|
||||
assert extract_tables_from_sql(" ") == set()
|
||||
assert extract_tables_from_sql(None) == set()
|
||||
# #endregion test_empty_input
|
||||
|
||||
# #region test_no_schema_qualified_tables [C:2] [TYPE Function]
|
||||
# @BRIEF Unqualified table names are NOT matched.
|
||||
def test_no_schema_qualified_tables(self):
|
||||
sql = "SELECT * FROM sales"
|
||||
result = extract_tables_from_sql(sql)
|
||||
assert result == set()
|
||||
# #endregion test_no_schema_qualified_tables
|
||||
|
||||
# #region test_case_insensitive [C:2] [TYPE Function]
|
||||
# @BRIEF Matching is case-insensitive; result is lowercased.
|
||||
def test_case_insensitive(self):
|
||||
sql = "SELECT * FROM RAW.Sales JOIN Raw.Inventory ON ..."
|
||||
result = extract_tables_from_sql(sql)
|
||||
assert result == {"raw.sales", "raw.inventory"}
|
||||
# #endregion test_case_insensitive
|
||||
|
||||
# #region test_string_literal_false_positive [C:2] [TYPE Function]
|
||||
# @BRIEF Date literal like '2026.04.30' must NOT be matched as schema.table.
|
||||
def test_string_literal_false_positive(self):
|
||||
sql = "SELECT * FROM raw.sales WHERE date = '2026.04.30'"
|
||||
result = extract_tables_from_sql(sql)
|
||||
assert result == {"raw.sales"}
|
||||
# #endregion test_string_literal_false_positive
|
||||
|
||||
# #region test_jinja_string_concat [C:2] [TYPE Function]
|
||||
# @BRIEF Table reference inside Jinja {{ 'raw.sales' }} as a direct string.
|
||||
def test_jinja_string_concat(self):
|
||||
sql = "SELECT * FROM {{ 'raw.sales' }}"
|
||||
result = extract_tables_from_sql(sql)
|
||||
assert result == {"raw.sales"}
|
||||
# #endregion test_jinja_string_concat
|
||||
|
||||
# #region test_jinja_set_block [C:2] [TYPE Function]
|
||||
# @BRIEF Table name in Jinja {% set %} block string value.
|
||||
def test_jinja_set_block(self):
|
||||
sql = """
|
||||
{% set tables = ['raw.sales', 'raw.inventory'] %}
|
||||
SELECT * FROM raw.sales
|
||||
"""
|
||||
result = extract_tables_from_sql(sql)
|
||||
assert result == {"raw.sales", "raw.inventory"}
|
||||
# #endregion test_jinja_set_block
|
||||
|
||||
# #region test_mixed_jinja_and_sql [C:2] [TYPE Function]
|
||||
# @BRIEF Mixed Jinja string and plain SQL schema.table references.
|
||||
def test_mixed_jinja_and_sql(self):
|
||||
sql = """
|
||||
{% set source_table = 'raw.orders' %}
|
||||
SELECT * FROM raw.orders o
|
||||
JOIN raw.products p ON o.id = p.product_id
|
||||
"""
|
||||
result = extract_tables_from_sql(sql)
|
||||
assert result == {"raw.orders", "raw.products"}
|
||||
# #endregion test_mixed_jinja_and_sql
|
||||
|
||||
# #region test_cte_with_schema_tables [C:2] [TYPE Function]
|
||||
# @BRIEF CTE body with schema-qualified table references.
|
||||
def test_cte_with_schema_tables(self):
|
||||
sql = """
|
||||
WITH active_sales AS (
|
||||
SELECT * FROM raw.sales WHERE amount > 100
|
||||
)
|
||||
SELECT * FROM active_sales
|
||||
"""
|
||||
result = extract_tables_from_sql(sql)
|
||||
assert result == {"raw.sales"}
|
||||
# #endregion test_cte_with_schema_tables
|
||||
|
||||
# #region test_jinja_comment_excluded [C:2] [TYPE Function]
|
||||
# @BRIEF Jinja comment {# ... #} content should not produce table extraction (no string patterns inside comments).
|
||||
def test_jinja_comment_excluded(self):
|
||||
sql = "SELECT * FROM raw.sales {# this references raw.archived #}"
|
||||
result = extract_tables_from_sql(sql)
|
||||
assert result == {"raw.sales"}
|
||||
# #endregion test_jinja_comment_excluded
|
||||
# #endregion test_sql_table_extractor
|
||||
Reference in New Issue
Block a user