Skip to content

Commit

Permalink
feat(view-sharing): Double write position to new table in PUT endpoint (
Browse files Browse the repository at this point in the history
#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.
  • Loading branch information
MichaelSun48 authored Mar 1, 2025
1 parent 24c89af commit e361d89
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/sentry/issues/endpoints/organization_group_search_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
GroupSearchViewValidatorResponse,
)
from sentry.models.groupsearchview import DEFAULT_TIME_FILTER, GroupSearchView
from sentry.models.groupsearchviewstarred import GroupSearchViewStarred
from sentry.models.organization import Organization
from sentry.models.project import Project
from sentry.models.savedsearch import SortOptions
Expand Down Expand Up @@ -239,6 +240,12 @@ def _update_existing_view(
gsv.time_filters = view["timeFilters"]

gsv.save()
GroupSearchViewStarred.objects.update_or_create(
organization=org,
user_id=user_id,
group_search_view=gsv,
defaults={"position": position},
)
except GroupSearchView.DoesNotExist:
# It is possible – though unlikely under normal circumstances – for a view to come in that
# doesn't exist anymore. If, for example, the user has the issue stream open in separate
Expand All @@ -263,3 +270,10 @@ def _create_view(
)
if "projects" in view:
gsv.projects.set(view["projects"] or [])

GroupSearchViewStarred.objects.create(
organization=org,
user_id=user_id,
group_search_view=gsv,
position=position,
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from sentry.api.serializers.rest_framework.groupsearchview import GroupSearchViewValidatorResponse
from sentry.issues.endpoints.organization_group_search_views import DEFAULT_VIEWS
from sentry.models.groupsearchview import GroupSearchView
from sentry.models.groupsearchviewstarred import GroupSearchViewStarred
from sentry.testutils.cases import APITestCase, TransactionTestCase
from sentry.testutils.helpers.features import with_feature

Expand Down Expand Up @@ -159,9 +160,18 @@ def setUp(self) -> None:
@with_feature({"organizations:issue-stream-custom-views": True})
@with_feature({"organizations:global-views": True})
def test_deletes_missing_views(self) -> None:
starred_views = GroupSearchViewStarred.objects.filter(
organization=self.organization, user_id=self.user.id
)

# Verify that no starred views exist initially
assert len(starred_views) == 0

views = self.client.get(self.url).data

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

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

starred_views = GroupSearchViewStarred.objects.filter(
organization=self.organization, user_id=self.user.id
)
assert len(starred_views) == len(response.data)
for idx, view in enumerate(response.data):
assert starred_views[idx].position == idx
assert starred_views[idx].position == view["position"]
assert str(starred_views[idx].group_search_view.id) == view["id"]

# Verify that the deleted view is no longer in the starred table
assert not GroupSearchViewStarred.objects.filter(
organization=self.organization,
user_id=self.user.id,
group_search_view_id=deleted_view_id,
).exists()

@with_feature({"organizations:issue-stream-custom-views": True})
@with_feature({"organizations:global-views": True})
def test_adds_view_with_no_id(self) -> None:
Expand All @@ -194,6 +220,15 @@ def test_adds_view_with_no_id(self) -> None:
assert response.data[3]["query"] == "is:unresolved"
assert response.data[3]["querySort"] == "date"

starred_views = GroupSearchViewStarred.objects.filter(
organization=self.organization, user_id=self.user.id
)
assert len(starred_views) == len(response.data)
for idx, view in enumerate(response.data):
assert starred_views[idx].position == idx
assert starred_views[idx].position == view["position"]
assert str(starred_views[idx].group_search_view.id) == view["id"]

@with_feature({"organizations:issue-stream-custom-views": True})
@with_feature({"organizations:global-views": True})
def test_reorder_views(self) -> None:
Expand All @@ -214,6 +249,15 @@ def test_reorder_views(self) -> None:
assert are_views_equal(response.data[1], view_one)
assert are_views_equal(response.data[2], views[2])

starred_views = GroupSearchViewStarred.objects.filter(
organization=self.organization, user_id=self.user.id
)
assert len(starred_views) == len(response.data)
for idx, view in enumerate(response.data):
assert starred_views[idx].position == idx
assert starred_views[idx].position == view["position"]
assert str(starred_views[idx].group_search_view.id) == view["id"]

@with_feature({"organizations:issue-stream-custom-views": True})
@with_feature({"organizations:global-views": True})
def test_rename_views(self) -> None:
Expand Down Expand Up @@ -264,6 +308,15 @@ def test_change_everything(self) -> None:
assert response.data[0]["query"] == "is:resolved"
assert response.data[0]["querySort"] == "freq"

starred_views = GroupSearchViewStarred.objects.filter(
organization=self.organization, user_id=self.user.id
)
assert len(starred_views) == len(response.data)
for idx, view in enumerate(response.data):
assert starred_views[idx].position == idx
assert starred_views[idx].position == view["position"]
assert str(starred_views[idx].group_search_view.id) == view["id"]

@with_feature({"organizations:issue-stream-custom-views": True})
@with_feature({"organizations:global-views": True})
def test_invalid_no_views(self) -> None:
Expand Down Expand Up @@ -343,6 +396,15 @@ def test_updated_deleted_view(self) -> None:
assert response.data[1]["querySort"] == view_one["querySort"]
assert are_views_equal(response.data[2], views[2])

starred_views = GroupSearchViewStarred.objects.filter(
organization=self.organization, user_id=self.user.id
)
assert len(starred_views) == len(response.data)
for idx, view in enumerate(response.data):
assert starred_views[idx].position == idx
assert starred_views[idx].position == view["position"]
assert str(starred_views[idx].group_search_view.id) == view["id"]


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

0 comments on commit e361d89

Please sign in to comment.