|
27 | 27 |
|
28 | 28 | from collections.abc import Generator |
29 | 29 | from datetime import datetime |
| 30 | +from unittest.mock import patch |
30 | 31 |
|
31 | 32 | import pytest |
32 | 33 | from sqlalchemy import Column, ForeignKey, Integer, String |
@@ -90,6 +91,18 @@ def _synthetic_tables(session: Session) -> Generator[None, None, None]: |
90 | 91 | _TestBase.metadata.drop_all(session.get_bind()) |
91 | 92 |
|
92 | 93 |
|
| 94 | +@pytest.fixture(autouse=True) |
| 95 | +def _soft_delete_gate_on() -> Generator[None, None, None]: |
| 96 | + """The ``do_orm_execute`` visibility listener is gated by the temporary |
| 97 | + ``SOFT_DELETE`` rollout flag (sc-111230), default off. These tests exercise |
| 98 | + the listener's filtering, so enable the gate for the whole module. The |
| 99 | + gate-off (listener-noop) behaviour is pinned separately by |
| 100 | + ``test_listener_noop_when_gate_off``. |
| 101 | + """ |
| 102 | + with patch("superset.models.helpers.is_feature_enabled", return_value=True): |
| 103 | + yield |
| 104 | + |
| 105 | + |
93 | 106 | @pytest.mark.usefixtures("_synthetic_tables") |
94 | 107 | def test_soft_delete_sets_deleted_at(app_context: None, session: Session) -> None: |
95 | 108 | """soft_delete() sets deleted_at to a non-null datetime.""" |
@@ -167,6 +180,31 @@ def test_global_filter_excludes_soft_deleted_rows( |
167 | 180 | assert result is None |
168 | 181 |
|
169 | 182 |
|
| 183 | +@pytest.mark.usefixtures("_synthetic_tables") |
| 184 | +def test_listener_noop_when_gate_off(app_context: None, session: Session) -> None: |
| 185 | + """With the ``SOFT_DELETE`` gate OFF, the listener attaches no criteria, so a |
| 186 | + soft-deleted row is NOT hidden — the substrate is dark (sc-111230). (While |
| 187 | + the gate is off the delete path also doesn't create such rows; this pins the |
| 188 | + listener side.)""" |
| 189 | + obj = _SoftDeletable(name="visible_when_gate_off") |
| 190 | + session.add(obj) |
| 191 | + session.flush() |
| 192 | + obj_id = obj.id |
| 193 | + |
| 194 | + obj.soft_delete() |
| 195 | + session.flush() |
| 196 | + session.expire_all() |
| 197 | + |
| 198 | + with patch("superset.models.helpers.is_feature_enabled", return_value=False): |
| 199 | + result = ( |
| 200 | + session.query(_SoftDeletable) |
| 201 | + .filter(_SoftDeletable.id == obj_id) |
| 202 | + .one_or_none() |
| 203 | + ) |
| 204 | + assert result is not None |
| 205 | + assert result.id == obj_id |
| 206 | + |
| 207 | + |
170 | 208 | @pytest.mark.usefixtures("_synthetic_tables") |
171 | 209 | def test_listener_adapts_criteria_to_aliased_table_in_joins( |
172 | 210 | app_context: None, session: Session |
|
0 commit comments