codeant-ai-for-open-source[bot] commented on code in PR #41968:
URL: https://github.com/apache/superset/pull/41968#discussion_r3564787023


##########
tests/integration_tests/security/row_level_security_tests.py:
##########
@@ -469,6 +469,58 @@ def 
test_rls_tables_related_api_with_filter_matching_birth(self):
         assert all("birth" in table_name.lower() for table_name in 
received_tables)
         assert len(result) >= 1  # At least birth_names should be returned
 
+    @pytest.mark.usefixtures("load_birth_names_data")
+    def test_rls_tables_related_api_returns_all_masked_matches(self):
+        """
+        Regression for #29707: the RLS dataset selector's async search must
+        return *every* dataset whose name matches the typed mask, not a
+        truncated subset. The reporter had two "birth" datasets (birth_names
+        and birth_france_by_region) and searching "birth" showed an
+        incomplete list. This exercises the backend ``related/tables``
+        endpoint that feeds that selector to prove whether the search-by-mask
+        lookup is the culprit.
+        """
+        self.login(ADMIN_USERNAME)
+
+        birth_names = self.get_table(name="birth_names")
+        # Create a sibling dataset whose name also contains the "birth" mask,
+        # mirroring the two-dataset scenario from the issue.
+        sibling = SqlaTable(
+            table_name="birth_france_by_region",
+            database=birth_names.database,
+            schema=birth_names.schema,
+        )
+        db.session.add(sibling)
+        db.session.commit()
+
+        try:
+            # Datasets in the metadata DB that match the "birth" mask.
+            expected = {
+                t.name
+                for t in db.session.query(SqlaTable)
+                .filter(SqlaTable.table_name.ilike("%birth%"))
+                .all()
+            }
+            # Both datasets must be present in the ground truth for the
+            # assertion below to be meaningful.
+            bare_names = {name.split(".")[-1] for name in expected}
+            assert "birth_names" in bare_names
+            assert "birth_france_by_region" in bare_names
+
+            params = rison.dumps({"filter": "birth", "page": 0, "page_size": 
100})
+            rv = 
self.client.get(f"/api/v1/rowlevelsecurity/related/tables?q={params}")
+            assert rv.status_code == 200
+            data = json.loads(rv.data.decode("utf-8"))
+            received = {table["text"] for table in data["result"]}
+
+            # The masked search must return *all* matching datasets, and the
+            # advertised count must not under-report them.
+            assert received == expected
+            assert data["count"] == len(expected)

Review Comment:
   **Suggestion:** Using sets for `expected` and `received` drops duplicate 
display names, but `data["count"]` represents row count from the API. If two 
datasets share the same rendered `text` (for example same table/schema name 
across databases), this test will undercount expected matches and fail 
incorrectly. Preserve multiplicity (e.g., compare sorted lists or IDs) when 
validating `count` semantics. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   ⚠️ RLS related-tables test may fail with duplicate dataset names.
   ⚠️ CI for RLS backend can be flaky on multi-database setups.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. In a Superset instance backed by this code, create or import two SQL 
datasets that
   share the same rendered name/text (for example same `schema` and 
`table_name` on different
   databases), which is allowed because `SqlaTable` only enforces uniqueness on
   `(database_id, catalog, schema, table_name)` (see
   `superset/connectors/sqla/models.py:64-72`), while the `name` hybrid 
property at
   `superset/connectors/sqla/models.py:5-7` returns just `schema + "." + 
table_name` or
   `table_name`.
   
   2. As an ADMIN user, run
   
`TestRowLevelSecurityWithRelatedAPI.test_rls_tables_related_api_returns_all_masked_matches`
   in `tests/integration_tests/security/row_level_security_tests.py:43-94`, 
which logs in
   (line 54) and builds `expected` by querying all matching `SqlaTable` rows via
   
`db.session.query(SqlaTable).filter(SqlaTable.table_name.ilike("%birth%")).all()`
 and
   projecting to a set of `t.name` (lines 68-74).
   
   3. The test then calls `GET /api/v1/rowlevelsecurity/related/tables` with 
the same mask
   (lines 81-83), which is handled by `BaseSupersetModelRestApi.related()` in
   `superset/views/base_api.py:600-679`. That method uses 
`datamodel.query(...)` to retrieve
   matched rows and returns `count=total_rows` and a `result` list built by
   `_get_result_from_rows()` at `superset/views/base_api.py:13-23`, where each 
row’s `text`
   is derived from `_get_text_for_model()` in 
`superset/views/base_api.py:462-467`.
   
   4. Because the test collapses both sides to sets (`expected = {t.name, ...}` 
at lines
   68-74 and `received = {table["text"] for table in data["result"]}` at line 
85), any
   duplicate names/texts are deduplicated before the final assertion `assert 
data["count"] ==
   len(expected)` at line 90. In a scenario with duplicate display names, the 
API correctly
   reports `count` equal to the number of rows, but `len(expected)` reflects 
only the number
   of distinct names, causing this regression test to fail even though backend 
counting and
   pagination are correct.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=65a44aa9dc484bbcbf96a4efa872ce81&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=65a44aa9dc484bbcbf96a4efa872ce81&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** tests/integration_tests/security/row_level_security_tests.py
   **Line:** 498:519
   **Comment:**
        *Logic Error: Using sets for `expected` and `received` drops duplicate 
display names, but `data["count"]` represents row count from the API. If two 
datasets share the same rendered `text` (for example same table/schema name 
across databases), this test will undercount expected matches and fail 
incorrectly. Preserve multiplicity (e.g., compare sorted lists or IDs) when 
validating `count` semantics.
   
   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.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41968&comment_hash=4b68b5ac48c1bc166e0e15025a88244862bce01530c691a1cb2193d2b943906e&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41968&comment_hash=4b68b5ac48c1bc166e0e15025a88244862bce01530c691a1cb2193d2b943906e&reaction=dislike'>👎</a>



-- 
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]

Reply via email to