test_get_sql_results_oauth2's `query = mocker.MagicMock(select_as_cta=False,
database=database)` left `limit` and `select_as_cta_used` as unconfigured
auto-mocks. `execute_sql_statements` unconditionally calls `apply_limit`
before ever reaching the mocked OAuth2 error, and `apply_limit` does
`query.limit > sql_max_row` once `SQLLAB_CTAS_NO_LIMIT` is false -- an
unconfigured MagicMock has no real `__gt__`, so this raised `TypeError:
'>' not supported between instances of 'MagicMock' and 'int'` instead of
ever reaching the OAuth2 path.
Root-caused with a side-by-side instrumented run against master pinned to
SQLAlchemy 1.4.54 + Flask-SQLAlchemy 2.5.1 (byte-identical sql_lab.py and
test file): there, `flask.current_app` inside `apply_limit` resolved to
an unrelated, already-initialized `superset.app` singleton (config
SQLLAB_CTAS_NO_LIMIT=True) instead of this test's own fixture app
(SQLLAB_CTAS_NO_LIMIT=False), so `apply_limit` took its
`select_as_cta_used and sqllab_ctas_no_limit` early-return path before
ever touching `query.limit` -- masking the gap by accident. Under
Flask-SQLAlchemy 3.x, `current_app` correctly resolves to the test's own
pushed app context, so the early return no longer fires and the
underspecified mock's real gap is exposed. This is not a SQLAlchemy 2.0
semantic break in application code; it's an under-specified test double
that only ever worked because of unrelated cross-test app-identity
bleed in the old environment.
Set `limit=None` and `select_as_cta_used=False` on the mock, matching
the real `Query` model's actual column defaults (`Column(Integer)` is
nullable/None; `Column(Boolean, default=False)`), so `apply_limit`
behaves the same way it would for a genuine freshly-queried `Query` row.
With the mock now correctly reaching the OAuth2 path inside the right
app context, the generated redirect URL correctly reflects this test's
own `SERVER_NAME=example.com` fixture config rather than Flask's
"localhost" default that leaked in from the wrong app previously --
update the two hardcoded `http://localhost/...` expectations to
`http://example.com/...` to match.