codeant-ai-for-open-source[bot] commented on code in PR #34565:
URL: https://github.com/apache/superset/pull/34565#discussion_r2621613929
##########
superset/views/base.py:
##########
@@ -523,7 +522,10 @@ def cached_common_bootstrap_data( # pylint:
disable=unused-argument
def common_bootstrap_payload() -> dict[str, Any]:
- return cached_common_bootstrap_data(utils.get_user_id(), get_locale())
+ locale = get_locale()
+ # Convert locale to string for proper cache key hashing
+ locale_str = str(locale) if locale else None
+ return cached_common_bootstrap_data(utils.get_user_id(), locale_str)
Review Comment:
**Suggestion:** The updated `common_bootstrap_payload` now returns only the
cached bootstrap data and no longer includes Flask flash messages, and the
module no longer exposes a `get_flashed_messages` symbol; this breaks the
existing contract relied on by tests (and likely the frontend) that expect
`flash_messages` in the payload and a patchable
`superset.views.base.get_flashed_messages`, causing tests to fail and flash
notifications to disappear from the client. [logic error]
**Severity Level:** Minor ⚠️
```suggestion
def get_flashed_messages() -> list[Any]:
"""
Wrapper around Flask's get_flashed_messages so that this module
exposes a patchable symbol and can be used without importing it
at the top level.
"""
from flask import get_flashed_messages as _get_flashed_messages
return _get_flashed_messages()
def common_bootstrap_payload() -> dict[str, Any]:
locale = get_locale()
# Convert locale to string for proper cache key hashing
locale_str = str(locale) if locale else None
data = cached_common_bootstrap_data(utils.get_user_id(), locale_str)
# Include flash messages in the payload for the frontend
return {**data, "flash_messages": get_flashed_messages()}
```
<details>
<summary><b>Why it matters? ⭐ </b></summary>
The tests (tests/unit_tests/views/test_base.py) patch
superset.views.base.get_flashed_messages and expect the payload to include a
"flash_messages" key. A repository-wide search shows usages in the tests that
mock get_flashed_messages and assert the flash_messages field is present.
Removing that symbol and the flash messages from the payload will break those
tests and likely remove flash notifications from the frontend. The proposed
improved_code restores a module-level get_flashed_messages wrapper and
re-inserts flash messages into the returned payload, directly addressing the
broken contract.
</details>
<details>
<summary><b>Prompt for AI Agent 🤖 </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset/views/base.py
**Line:** 524:528
**Comment:**
*Logic Error: The updated `common_bootstrap_payload` now returns only
the cached bootstrap data and no longer includes Flask flash messages, and the
module no longer exposes a `get_flashed_messages` symbol; this breaks the
existing contract relied on by tests (and likely the frontend) that expect
`flash_messages` in the payload and a patchable
`superset.views.base.get_flashed_messages`, causing tests to fail and flash
notifications to disappear from the client.
Validate the correctness of the flagged issue. If correct, How can I resolve
this? If you propose a fix, implement it and please make it concise.
```
</details>
##########
tests/unit_tests/views/test_base.py:
##########
@@ -0,0 +1,110 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""Tests for superset.views.base module"""
+
+from unittest.mock import MagicMock, patch
+
+
+@patch("superset.views.base.utils.get_user_id", return_value=1)
+@patch("superset.views.base.get_flashed_messages", return_value=[])
Review Comment:
**Suggestion:** The patch decorator targets
`superset.views.base.get_flashed_messages`, but this attribute does not exist
on the `superset.views.base` module, so test collection will raise an
AttributeError; using `create=True` allows patch to create the attribute
without failing even though the module does not define it. [logic error]
**Severity Level:** Minor ⚠️
```suggestion
@patch("superset.views.base.get_flashed_messages", return_value=[],
create=True)
```
<details>
<summary><b>Why it matters? ⭐ </b></summary>
If superset.views.base does not define get_flashed_messages at
import/test-collection time, patch(... ) without create=True will raise an
AttributeError during test collection. A quick repo search did not find any
definition of get_flashed_messages, so allowing patch to create the attribute
is defensive and prevents spurious test failures. This fixes a real
test-collection problem, not a cosmetic change.
</details>
<details>
<summary><b>Prompt for AI Agent 🤖 </b></summary>
```mdx
This is a comment left during a code review.
**Path:** tests/unit_tests/views/test_base.py
**Line:** 23:23
**Comment:**
*Logic Error: The patch decorator targets
`superset.views.base.get_flashed_messages`, but this attribute does not exist
on the `superset.views.base` module, so test collection will raise an
AttributeError; using `create=True` allows patch to create the attribute
without failing even though the module does not define it.
Validate the correctness of the flagged issue. If correct, How can I resolve
this? If you propose a fix, implement it and please make it concise.
```
</details>
##########
tests/integration_tests/security_tests.py:
##########
@@ -136,31 +168,47 @@ def setUp(self):
s.schema_perm = ds.schema_perm
create_schema_perm("[examples].[temp_schema]")
gamma_user = security_manager.find_user(username="gamma")
- gamma_user.roles.append(security_manager.find_role(SCHEMA_ACCESS_ROLE))
+ if gamma_user:
+
gamma_user.roles.append(security_manager.find_role(SCHEMA_ACCESS_ROLE))
db.session.commit()
def tearDown(self):
- ds = (
- db.session.query(SqlaTable)
- .filter_by(table_name="wb_health_population", schema="temp_schema")
- .first()
- )
- schema_perm = ds.schema_perm
- ds.schema = get_example_default_schema()
- ds.schema_perm = None
- ds_slices = (
- db.session.query(Slice)
- .filter_by(datasource_type=DatasourceType.TABLE)
- .filter_by(datasource_id=ds.id)
- .all()
- )
- for s in ds_slices:
- s.schema_perm = None
+ # Ensure the session is in a good state before teardown
+ try:
+ db.session.rollback()
+ except Exception: # noqa: S110
+ pass # Ignore rollback errors in teardown
+
+ try:
+ ds = (
+ db.session.query(SqlaTable)
+ .filter_by(table_name="wb_health_population",
schema="temp_schema")
+ .first()
+ )
+ if ds:
+ schema_perm = ds.schema_perm
+ ds.schema = get_example_default_schema()
+ ds.schema_perm = None
+ ds_slices = (
+ db.session.query(Slice)
+ .filter_by(datasource_type=DatasourceType.TABLE)
+ .filter_by(datasource_id=ds.id)
+ .all()
+ )
+ for s in ds_slices:
+ s.schema_perm = None
- delete_schema_perm(schema_perm)
- db.session.delete(security_manager.find_role(SCHEMA_ACCESS_ROLE))
- db.session.commit()
- super().tearDown()
+ delete_schema_perm(schema_perm)
Review Comment:
**Suggestion:** The new `tearDown` logic assumes `delete_schema_perm` will
delete the schema permission corresponding to `schema_perm`, but
`delete_schema_perm` ignores its argument and always operates on a hard-coded
value, so the permission created in `setUp` is never removed and the wrong
permission may be deleted, causing cross-test leakage of schema permissions.
[logic error]
**Severity Level:** Minor ⚠️
```suggestion
if schema_perm:
pv = security_manager.find_permission_view_menu(
"schema_access", schema_perm
)
if pv is not None:
security_manager.del_permission_role(
security_manager.find_role(SCHEMA_ACCESS_ROLE),
pv
)
security_manager.del_permission_view_menu(
"schema_access", schema_perm
)
```
<details>
<summary><b>Why it matters? ⭐ </b></summary>
The file's delete_schema_perm implementation (present in the current file)
ignores its argument and always looks up/deletes "[examples].[2]". That means
delete_schema_perm(schema_perm) in tearDown won't remove the permission created
with "[examples].[temp_schema]" in setUp, causing permission leakage across
tests. The improved code explicitly finds the permission view menu for the
actual schema_perm and removes it — this fixes a real cleanup bug.
</details>
<details>
<summary><b>Prompt for AI Agent 🤖 </b></summary>
```mdx
This is a comment left during a code review.
**Path:** tests/integration_tests/security_tests.py
**Line:** 201:201
**Comment:**
*Logic Error: The new `tearDown` logic assumes `delete_schema_perm`
will delete the schema permission corresponding to `schema_perm`, but
`delete_schema_perm` ignores its argument and always operates on a hard-coded
value, so the permission created in `setUp` is never removed and the wrong
permission may be deleted, causing cross-test leakage of schema permissions.
Validate the correctness of the flagged issue. If correct, How can I resolve
this? If you propose a fix, implement it and please make it concise.
```
</details>
##########
tests/integration_tests/security_tests.py:
##########
@@ -123,6 +149,12 @@ def setUp(self):
.filter_by(table_name="wb_health_population", schema=schema)
.first()
)
+
+ if not ds:
+ # If the table doesn't exist, skip this test setup
+ # This can happen if the example data isn't loaded
+ return
Review Comment:
**Suggestion:** In `setUp`, returning early when the `wb_health_population`
table is missing skips the setup but still runs the tests, so tests that assume
the schema/permissions are configured will fail with misleading assertions
instead of being explicitly marked as skipped when example data is absent.
[logic error]
**Severity Level:** Minor ⚠️
```suggestion
self.skipTest(
"Example data not loaded; skipping schema-access tests in
TestRolePermission.setUp"
)
```
<details>
<summary><b>Why it matters? ⭐ </b></summary>
Silently returning from setUp leaves the TestCase instance in a partially
initialized state while tests still execute; this can produce confusing
failures rather than marking tests as skipped. Calling self.skipTest(...) in
setUp is the right unittest pattern to explicitly skip the test when required
test data is absent.
</details>
<details>
<summary><b>Prompt for AI Agent 🤖 </b></summary>
```mdx
This is a comment left during a code review.
**Path:** tests/integration_tests/security_tests.py
**Line:** 156:156
**Comment:**
*Logic Error: In `setUp`, returning early when the
`wb_health_population` table is missing skips the setup but still runs the
tests, so tests that assume the schema/permissions are configured will fail
with misleading assertions instead of being explicitly marked as skipped when
example data is absent.
Validate the correctness of the flagged issue. If correct, How can I resolve
this? If you propose a fix, implement it and please make it concise.
```
</details>
##########
tests/unit_tests/views/test_base.py:
##########
@@ -0,0 +1,110 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""Tests for superset.views.base module"""
+
+from unittest.mock import MagicMock, patch
+
+
+@patch("superset.views.base.utils.get_user_id", return_value=1)
+@patch("superset.views.base.get_flashed_messages", return_value=[])
+@patch(
+ "superset.views.base.cached_common_bootstrap_data", return_value={"test":
"data"}
+)
+@patch("superset.views.base.get_locale")
+def test_common_bootstrap_payload_passes_locale_string(
+ mock_get_locale, mock_cached, mock_flash, mock_user_id
+):
+ """Test that common_bootstrap_payload converts locale to string"""
+ # Mock get_locale to return a Locale-like object with __str__
+ mock_locale = MagicMock()
+ mock_locale.__str__ = lambda self: "de_DE"
Review Comment:
**Suggestion:** The test intends to simulate a Locale-like object whose
string representation is `"de_DE"`, but assigning `mock_locale.__str__ = lambda
self: "de_DE"` does not affect how `str(mock_locale)` is computed, so
`common_bootstrap_payload` will receive the wrong locale string and the
assertion on the cached call will fail; configuring the mock's `__str__` return
value correctly makes `str(mock_locale)` return `"de_DE"`. [logic error]
**Severity Level:** Minor ⚠️
```suggestion
mock_locale.__str__.return_value = "de_DE"
```
<details>
<summary><b>Why it matters? ⭐ </b></summary>
Assigning a lambda to mock_locale.__str__ does not set up MagicMock's
descriptor behavior so that str(mock_locale) returns the expected value.
Setting mock_locale.__str__.return_value = "de_DE" or using type('X', (),
{'__str__': lambda s: 'de_DE'}) would reliably make str(...) produce "de_DE".
This is a real correctness fix for the test's intent.
</details>
<details>
<summary><b>Prompt for AI Agent 🤖 </b></summary>
```mdx
This is a comment left during a code review.
**Path:** tests/unit_tests/views/test_base.py
**Line:** 34:34
**Comment:**
*Logic Error: The test intends to simulate a Locale-like object whose
string representation is `"de_DE"`, but assigning `mock_locale.__str__ = lambda
self: "de_DE"` does not affect how `str(mock_locale)` is computed, so
`common_bootstrap_payload` will receive the wrong locale string and the
assertion on the cached call will fail; configuring the mock's `__str__` return
value correctly makes `str(mock_locale)` return `"de_DE"`.
Validate the correctness of the flagged issue. If correct, How can I resolve
this? If you propose a fix, implement it and please make it concise.
```
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]