From 7c69671923fb68725edabe1ef466c9da7bcd2470 Mon Sep 17 00:00:00 2001
From: Davide Silvestri <davide@baserow.io>
Date: Tue, 11 Mar 2025 14:51:04 +0100
Subject: [PATCH] Resolve "Duplicate view filtered on a collaborator"

---
 .../baserow/contrib/database/views/handler.py |  5 ++-
 .../database/api/rows/test_row_serializers.py | 21 +++++++----
 .../database/view/test_view_handler.py        | 37 +++++++++++++++++++
 changelog/entries/unreleased/bug/3017_.json   |  8 ++++
 4 files changed, 62 insertions(+), 9 deletions(-)
 create mode 100644 changelog/entries/unreleased/bug/3017_.json

diff --git a/backend/src/baserow/contrib/database/views/handler.py b/backend/src/baserow/contrib/database/views/handler.py
index ae728fa1d..f0c48afcd 100644
--- a/backend/src/baserow/contrib/database/views/handler.py
+++ b/backend/src/baserow/contrib/database/views/handler.py
@@ -874,7 +874,9 @@ class ViewHandler(metaclass=baserow_trace_methods(tracer)):
 
         view_type = view_type_registry.get_by_model(original_view)
 
-        cache = {}
+        cache = {
+            "workspace_id": workspace.id,
+        }
 
         # Use export/import to duplicate the view easily
         serialized = view_type.export_serialized(original_view, cache)
@@ -896,6 +898,7 @@ class ViewHandler(metaclass=baserow_trace_methods(tracer)):
         # the mapping remain the same. They haven't change because we're only
         # reimporting the view and not the table, fields, etc.
         id_mapping = {
+            "workspace_id": workspace.id,
             "database_fields": MirrorDict(),
             "database_field_select_options": MirrorDict(),
         }
diff --git a/backend/tests/baserow/contrib/database/api/rows/test_row_serializers.py b/backend/tests/baserow/contrib/database/api/rows/test_row_serializers.py
index f31cf4365..458ecd26d 100644
--- a/backend/tests/baserow/contrib/database/api/rows/test_row_serializers.py
+++ b/backend/tests/baserow/contrib/database/api/rows/test_row_serializers.py
@@ -1,6 +1,7 @@
 import json
 
 import pytest
+from pytest_unordered import unordered
 from rest_framework import serializers
 
 from baserow.contrib.database.api.rows.serializers import (
@@ -432,10 +433,12 @@ def test_get_row_serializer_with_user_field_names(data_fixture):
                         "value": "E",
                     },
                 ],
-                "formula_multiple_collaborators": [
-                    {"id": u2.id, "name": u2.first_name},
-                    {"id": u3.id, "name": u3.first_name},
-                ],
+                "formula_multiple_collaborators": unordered(
+                    [
+                        {"id": u2.id, "name": u2.first_name},
+                        {"id": u3.id, "name": u3.first_name},
+                    ]
+                ),
                 "formula_text": "test FORMULA",
                 "count": "3",
                 "rollup": "-122.222",
@@ -449,10 +452,12 @@ def test_get_row_serializer_with_user_field_names(data_fixture):
                 "multiple_collaborators_lookup": [
                     {
                         "id": 1,
-                        "value": [
-                            {"id": u2.id, "name": u2.first_name},
-                            {"id": u3.id, "name": u3.first_name},
-                        ],
+                        "value": unordered(
+                            [
+                                {"id": u2.id, "name": u2.first_name},
+                                {"id": u3.id, "name": u3.first_name},
+                            ]
+                        ),
                     },
                     {
                         "id": 2,
diff --git a/backend/tests/baserow/contrib/database/view/test_view_handler.py b/backend/tests/baserow/contrib/database/view/test_view_handler.py
index 953b22fb0..55e645eae 100755
--- a/backend/tests/baserow/contrib/database/view/test_view_handler.py
+++ b/backend/tests/baserow/contrib/database/view/test_view_handler.py
@@ -4383,3 +4383,40 @@ def test_get_queryset_apply_sorts(data_fixture):
 
     row_ids = [row.id for row in rows]
     assert row_ids == [row_3.id, row_2.id, row_1.id]
+
+
+@pytest.mark.django_db
+def test_can_duplicate_views_with_multiple_collaborator_has_filter(data_fixture):
+    user_1 = data_fixture.create_user()
+    user_2 = data_fixture.create_user()
+    workspace = data_fixture.create_workspace(users=[user_1, user_2])
+    database = data_fixture.create_database_application(workspace=workspace)
+    table = data_fixture.create_database_table(database=database)
+    field = data_fixture.create_multiple_collaborators_field(table=table)
+    grid = data_fixture.create_public_password_protected_grid_view(table=table, order=1)
+    view_filter = data_fixture.create_view_filter(
+        view=grid, field=field, type="multiple_collaborators_has", value=user_1.id
+    )
+
+    rows = RowHandler().force_create_rows(
+        user_1,
+        table,
+        [
+            {field.db_column: []},
+            {field.db_column: [{"id": user_1.id, "name": user_1.first_name}]},
+            {field.db_column: [{"id": user_2.id, "name": user_2.first_name}]},
+        ],
+    )
+
+    results = ViewHandler().get_queryset(grid)
+    assert len(results) == 1
+    assert list(getattr(results[0], field.db_column).values_list("id", flat=True)) == [
+        user_1.id
+    ]
+
+    new_grid = ViewHandler().duplicate_view(user_1, grid)
+    new_results = ViewHandler().get_queryset(new_grid)
+    assert len(new_results) == 1
+    assert list(
+        getattr(new_results[0], field.db_column).values_list("id", flat=True)
+    ) == [user_1.id]
diff --git a/changelog/entries/unreleased/bug/3017_.json b/changelog/entries/unreleased/bug/3017_.json
new file mode 100644
index 000000000..c6e62ce2a
--- /dev/null
+++ b/changelog/entries/unreleased/bug/3017_.json
@@ -0,0 +1,8 @@
+{
+    "type": "bug",
+    "message": "Fixed a bug that prevented duplicating views filtered by a collaborator correctly.",
+    "domain": "database",
+    "issue_number": 3017,
+    "bullet_points": [],
+    "created_at": "2025-03-10"
+}
\ No newline at end of file