Skip to content

Commit e361d89

Browse files
authored
feat(view-sharing): Double write position to new table in PUT endpoint (#86153)
This PR updates the `PUT` `/group-search-views/` endpoint to double write the positions parameter to the new table created in [this PR](#86065). This is necessary to ensure the tables stay in sync before backfilling.
1 parent 24c89af commit e361d89

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

src/sentry/issues/endpoints/organization_group_search_views.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
GroupSearchViewValidatorResponse,
2020
)
2121
from sentry.models.groupsearchview import DEFAULT_TIME_FILTER, GroupSearchView
22+
from sentry.models.groupsearchviewstarred import GroupSearchViewStarred
2223
from sentry.models.organization import Organization
2324
from sentry.models.project import Project
2425
from sentry.models.savedsearch import SortOptions
@@ -239,6 +240,12 @@ def _update_existing_view(
239240
gsv.time_filters = view["timeFilters"]
240241

241242
gsv.save()
243+
GroupSearchViewStarred.objects.update_or_create(
244+
organization=org,
245+
user_id=user_id,
246+
group_search_view=gsv,
247+
defaults={"position": position},
248+
)
242249
except GroupSearchView.DoesNotExist:
243250
# It is possible – though unlikely under normal circumstances – for a view to come in that
244251
# doesn't exist anymore. If, for example, the user has the issue stream open in separate
@@ -263,3 +270,10 @@ def _create_view(
263270
)
264271
if "projects" in view:
265272
gsv.projects.set(view["projects"] or [])
273+
274+
GroupSearchViewStarred.objects.create(
275+
organization=org,
276+
user_id=user_id,
277+
group_search_view=gsv,
278+
position=position,
279+
)

tests/sentry/issues/endpoints/test_organization_group_search_views.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from sentry.api.serializers.rest_framework.groupsearchview import GroupSearchViewValidatorResponse
66
from sentry.issues.endpoints.organization_group_search_views import DEFAULT_VIEWS
77
from sentry.models.groupsearchview import GroupSearchView
8+
from sentry.models.groupsearchviewstarred import GroupSearchViewStarred
89
from sentry.testutils.cases import APITestCase, TransactionTestCase
910
from sentry.testutils.helpers.features import with_feature
1011

@@ -159,9 +160,18 @@ def setUp(self) -> None:
159160
@with_feature({"organizations:issue-stream-custom-views": True})
160161
@with_feature({"organizations:global-views": True})
161162
def test_deletes_missing_views(self) -> None:
163+
starred_views = GroupSearchViewStarred.objects.filter(
164+
organization=self.organization, user_id=self.user.id
165+
)
166+
167+
# Verify that no starred views exist initially
168+
assert len(starred_views) == 0
169+
162170
views = self.client.get(self.url).data
163171

164172
update_custom_view_three = views[2]
173+
# Store the ID of the view we're going to delete
174+
deleted_view_id = views[1]["id"]
165175

166176
views.pop(1)
167177
response = self.get_success_response(self.organization.slug, views=views)
@@ -175,6 +185,22 @@ def test_deletes_missing_views(self) -> None:
175185
assert are_views_equal(response.data[0], views[0])
176186
assert are_views_equal(response.data[1], update_custom_view_three)
177187

188+
starred_views = GroupSearchViewStarred.objects.filter(
189+
organization=self.organization, user_id=self.user.id
190+
)
191+
assert len(starred_views) == len(response.data)
192+
for idx, view in enumerate(response.data):
193+
assert starred_views[idx].position == idx
194+
assert starred_views[idx].position == view["position"]
195+
assert str(starred_views[idx].group_search_view.id) == view["id"]
196+
197+
# Verify that the deleted view is no longer in the starred table
198+
assert not GroupSearchViewStarred.objects.filter(
199+
organization=self.organization,
200+
user_id=self.user.id,
201+
group_search_view_id=deleted_view_id,
202+
).exists()
203+
178204
@with_feature({"organizations:issue-stream-custom-views": True})
179205
@with_feature({"organizations:global-views": True})
180206
def test_adds_view_with_no_id(self) -> None:
@@ -194,6 +220,15 @@ def test_adds_view_with_no_id(self) -> None:
194220
assert response.data[3]["query"] == "is:unresolved"
195221
assert response.data[3]["querySort"] == "date"
196222

223+
starred_views = GroupSearchViewStarred.objects.filter(
224+
organization=self.organization, user_id=self.user.id
225+
)
226+
assert len(starred_views) == len(response.data)
227+
for idx, view in enumerate(response.data):
228+
assert starred_views[idx].position == idx
229+
assert starred_views[idx].position == view["position"]
230+
assert str(starred_views[idx].group_search_view.id) == view["id"]
231+
197232
@with_feature({"organizations:issue-stream-custom-views": True})
198233
@with_feature({"organizations:global-views": True})
199234
def test_reorder_views(self) -> None:
@@ -214,6 +249,15 @@ def test_reorder_views(self) -> None:
214249
assert are_views_equal(response.data[1], view_one)
215250
assert are_views_equal(response.data[2], views[2])
216251

252+
starred_views = GroupSearchViewStarred.objects.filter(
253+
organization=self.organization, user_id=self.user.id
254+
)
255+
assert len(starred_views) == len(response.data)
256+
for idx, view in enumerate(response.data):
257+
assert starred_views[idx].position == idx
258+
assert starred_views[idx].position == view["position"]
259+
assert str(starred_views[idx].group_search_view.id) == view["id"]
260+
217261
@with_feature({"organizations:issue-stream-custom-views": True})
218262
@with_feature({"organizations:global-views": True})
219263
def test_rename_views(self) -> None:
@@ -264,6 +308,15 @@ def test_change_everything(self) -> None:
264308
assert response.data[0]["query"] == "is:resolved"
265309
assert response.data[0]["querySort"] == "freq"
266310

311+
starred_views = GroupSearchViewStarred.objects.filter(
312+
organization=self.organization, user_id=self.user.id
313+
)
314+
assert len(starred_views) == len(response.data)
315+
for idx, view in enumerate(response.data):
316+
assert starred_views[idx].position == idx
317+
assert starred_views[idx].position == view["position"]
318+
assert str(starred_views[idx].group_search_view.id) == view["id"]
319+
267320
@with_feature({"organizations:issue-stream-custom-views": True})
268321
@with_feature({"organizations:global-views": True})
269322
def test_invalid_no_views(self) -> None:
@@ -343,6 +396,15 @@ def test_updated_deleted_view(self) -> None:
343396
assert response.data[1]["querySort"] == view_one["querySort"]
344397
assert are_views_equal(response.data[2], views[2])
345398

399+
starred_views = GroupSearchViewStarred.objects.filter(
400+
organization=self.organization, user_id=self.user.id
401+
)
402+
assert len(starred_views) == len(response.data)
403+
for idx, view in enumerate(response.data):
404+
assert starred_views[idx].position == idx
405+
assert starred_views[idx].position == view["position"]
406+
assert str(starred_views[idx].group_search_view.id) == view["id"]
407+
346408

347409
class OrganizationGroupSearchViewsWithPageFiltersPutTest(BaseGSVTestCase):
348410
endpoint = "sentry-api-0-organization-group-search-views"

0 commit comments

Comments
 (0)