From e826fb47ed530f19d5cb48bc092d062bea008431 Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Wed, 4 Sep 2024 22:25:28 -0700 Subject: [PATCH 1/8] fix(search): hide feedback from issues search by default --- src/sentry/issues/search.py | 11 +++- .../feedback/usecases/test_create_feedback.py | 37 ++++++++++++ .../test_organization_group_index.py | 57 ++++++++++++++++++- 3 files changed, 101 insertions(+), 4 deletions(-) diff --git a/src/sentry/issues/search.py b/src/sentry/issues/search.py index b060999729eac4..f1d99e3a263acf 100644 --- a/src/sentry/issues/search.py +++ b/src/sentry/issues/search.py @@ -8,7 +8,12 @@ from sentry.api.event_search import SearchFilter, SearchKey, SearchValue from sentry.issues import grouptype -from sentry.issues.grouptype import GroupCategory, get_all_group_type_ids, get_group_type_by_type_id +from sentry.issues.grouptype import ( + FeedbackGroup, + GroupCategory, + get_all_group_type_ids, + get_group_type_by_type_id, +) from sentry.models.environment import Environment from sentry.models.organization import Organization from sentry.search.events.filter import convert_search_filter_to_snuba_query @@ -103,9 +108,9 @@ def group_types_from( Return the set of group type ids to include in the query, or None if all group types should be included. """ - # if no relevant filters, return none to signify we should query all group types + # if no relevant filters, return all group types except feedback, which we hide by default if not any(sf.key.name in ("issue.category", "issue.type") for sf in search_filters or ()): - return None + return set(get_all_group_type_ids()) - {FeedbackGroup.type_id} # start by including all group types include_group_types = set(get_all_group_type_ids()) diff --git a/tests/sentry/feedback/usecases/test_create_feedback.py b/tests/sentry/feedback/usecases/test_create_feedback.py index 986a4141e025df..80bfb2ea02b1a4 100644 --- a/tests/sentry/feedback/usecases/test_create_feedback.py +++ b/tests/sentry/feedback/usecases/test_create_feedback.py @@ -1,6 +1,7 @@ from __future__ import annotations import time +from datetime import datetime from typing import Any from unittest.mock import Mock @@ -16,6 +17,7 @@ ) from sentry.models.group import Group, GroupStatus from sentry.testutils.helpers import Feature +from sentry.testutils.helpers.datetime import iso_format from sentry.testutils.pytest.fixtures import django_db_all from sentry.types.group import GroupSubStatus @@ -70,6 +72,41 @@ def create_dummy_response(*args, **kwargs): ) +def mock_feedback_event(project_id: int, dt: datetime): + return { + "project_id": project_id, + "request": { + "url": "https://sentry.sentry.io/feedback/?statsPeriod=14d", + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" + }, + }, + "event_id": "56b08cf7852c42cbb95e4a6998c66ad6", + "timestamp": dt.timestamp(), + "received": iso_format(dt), + "environment": "prod", + "release": "frontend@daf1316f209d961443664cd6eb4231ca154db502", + "user": { + "ip_address": "72.164.175.154", + "email": "josh.ferge@sentry.io", + "id": 880461, + "isStaff": False, + "name": "Josh Ferge", + }, + "contexts": { + "feedback": { + "contact_email": "josh.ferge@sentry.io", + "name": "Josh Ferge", + "message": "Testing!!", + "replay_id": "3d621c61593c4ff9b43f8490a78ae18e", + "url": "https://sentry.sentry.io/feedback/?statsPeriod=14d", + }, + }, + "breadcrumbs": [], + "platform": "javascript", + } + + def test_fix_for_issue_platform(): event: dict[str, Any] = { "project_id": 1, diff --git a/tests/sentry/issues/endpoints/test_organization_group_index.py b/tests/sentry/issues/endpoints/test_organization_group_index.py index 97a98462f01fbd..3d879ba79c743a 100644 --- a/tests/sentry/issues/endpoints/test_organization_group_index.py +++ b/tests/sentry/issues/endpoints/test_organization_group_index.py @@ -9,9 +9,11 @@ from django.utils import timezone from sentry import options +from sentry.feedback.usecases.create_feedback import FeedbackCreationSource, create_feedback_issue from sentry.integrations.models.external_issue import ExternalIssue from sentry.integrations.models.organization_integration import OrganizationIntegration from sentry.issues.grouptype import ( + FeedbackGroup, PerformanceNPlusOneGroupType, PerformanceRenderBlockingAssetSpanGroupType, PerformanceSlowDBQueryGroupType, @@ -57,13 +59,14 @@ from sentry.testutils.cases import APITestCase, SnubaTestCase from sentry.testutils.helpers import parse_link_header from sentry.testutils.helpers.datetime import before_now, iso_format -from sentry.testutils.helpers.features import apply_feature_flag_on_cls, with_feature +from sentry.testutils.helpers.features import Feature, apply_feature_flag_on_cls, with_feature from sentry.testutils.helpers.options import override_options from sentry.testutils.silo import assume_test_silo_mode from sentry.types.activity import ActivityType from sentry.types.group import GroupSubStatus, PriorityLevel from sentry.users.models.user_option import UserOption from sentry.utils import json +from tests.sentry.feedback.usecases.test_create_feedback import mock_feedback_event from tests.sentry.issues.test_utils import SearchIssueTestMixin @@ -3917,6 +3920,58 @@ def test_snuba_heavy_error_handled_boolean(self, _: MagicMock) -> None: assert len(response_handled_0.data) == 1 assert int(response_handled_0.data[0]["id"]) == handled_event.group.id + def test_feedback_filtered_by_default(self, _): + with Feature( + { + "organizations:feedback-ingest": True, + "organizations:feedback-visible": True, + } + ): + event = self.store_event( + data={"event_id": uuid4().hex, "timestamp": iso_format(before_now(seconds=1))}, + project_id=self.project.id, + ) + assert event.group is not None + + feedback_event = mock_feedback_event(self.project.id, before_now(seconds=1)) + create_feedback_issue( + feedback_event, self.project.id, FeedbackCreationSource.NEW_FEEDBACK_ENVELOPE + ) + self.login_as(user=self.user) + res = self.get_success_response() + + assert len(res.data) == 1 + issue = res.data[0] + feedback_group = Group.objects.get(type=FeedbackGroup.type_id) + assert int(issue["id"]) != feedback_group.id + assert issue["issueCategory"] != "feedback" + + def test_feedback_filter(self, _): + with Feature( + { + "organizations:feedback-ingest": True, + "organizations:feedback-visible": True, + } + ): + event = self.store_event( + data={"event_id": uuid4().hex, "timestamp": iso_format(before_now(seconds=1))}, + project_id=self.project.id, + ) + assert event.group is not None + + feedback_event = mock_feedback_event(self.project.id, before_now(seconds=1)) + create_feedback_issue( + feedback_event, self.project.id, FeedbackCreationSource.NEW_FEEDBACK_ENVELOPE + ) + self.login_as(user=self.user) + res = self.get_success_response(query="issue.category:feedback") + + assert len(res.data) == 1 + issue = res.data[0] + feedback_group = Group.objects.get(type=FeedbackGroup.type_id) + assert int(issue["id"]) == feedback_group.id + assert issue["issueCategory"] == "feedback" + class GroupUpdateTest(APITestCase, SnubaTestCase): endpoint = "sentry-api-0-organization-group-index" From 4fa57dbe67d86c2abd8de8e54ee2b0602767e583 Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Thu, 5 Sep 2024 10:46:09 -0700 Subject: [PATCH 2/8] Refactor to a separate where condition --- src/sentry/issues/search.py | 6 ++++-- src/sentry/search/snuba/executors.py | 12 ++++++++++++ .../endpoints/test_organization_group_index.py | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/sentry/issues/search.py b/src/sentry/issues/search.py index f1d99e3a263acf..642e3b8cb81c5a 100644 --- a/src/sentry/issues/search.py +++ b/src/sentry/issues/search.py @@ -21,6 +21,8 @@ from sentry.utils import snuba from sentry.utils.snuba import SnubaQueryParams +HIDDEN_FROM_DEFAULT_SEARCH_GROUP_TYPES = (FeedbackGroup,) + class UnsupportedSearchQuery(Exception): pass @@ -108,9 +110,9 @@ def group_types_from( Return the set of group type ids to include in the query, or None if all group types should be included. """ - # if no relevant filters, return all group types except feedback, which we hide by default + # if no relevant filters, return none to signify we should query all group types if not any(sf.key.name in ("issue.category", "issue.type") for sf in search_filters or ()): - return set(get_all_group_type_ids()) - {FeedbackGroup.type_id} + return None # start by including all group types include_group_types = set(get_all_group_type_ids()) diff --git a/src/sentry/search/snuba/executors.py b/src/sentry/search/snuba/executors.py index a0f38d55238395..8dd127553a1eed 100644 --- a/src/sentry/search/snuba/executors.py +++ b/src/sentry/search/snuba/executors.py @@ -44,6 +44,7 @@ from sentry.issues import grouptype from sentry.issues.grouptype import ErrorGroupType, GroupCategory, get_group_types_by_category from sentry.issues.search import ( + HIDDEN_FROM_DEFAULT_SEARCH_GROUP_TYPES, SEARCH_FILTER_UPDATERS, IntermediateSearchQueryPartial, MergeableRow, @@ -1837,6 +1838,17 @@ def query( where_conditions.append( Condition(Column("occurrence_type_id", joined_entity), Op.IN, group_types) ) + else: + hidden_group_type_ids = list( + map(lambda gt: gt.type_id, HIDDEN_FROM_DEFAULT_SEARCH_GROUP_TYPES) + ) + where_conditions.append( + Condition( + Column("occurrence_type_id", joined_entity), + Op.NOT_IN, + hidden_group_type_ids, + ) + ) sort_func = self.get_sort_defs(joined_entity)[sort_by] diff --git a/tests/sentry/issues/endpoints/test_organization_group_index.py b/tests/sentry/issues/endpoints/test_organization_group_index.py index 3d879ba79c743a..544cab7afd6326 100644 --- a/tests/sentry/issues/endpoints/test_organization_group_index.py +++ b/tests/sentry/issues/endpoints/test_organization_group_index.py @@ -3152,7 +3152,7 @@ def test_snuba_perf_issue(self, mock_query: MagicMock) -> None: sort="new", query="user.email:myemail@example.com", ) - assert len(response.data) == 2 + # assert len(response.data) == 2 assert {r["id"] for r in response.data} == { str(perf_group_id), str(error_event.group.id), From a4a77c2f91b24cab5be10184611aff9c0aae529e Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Thu, 5 Sep 2024 10:48:45 -0700 Subject: [PATCH 3/8] Uncomment line in test_snuba_perf_issue --- tests/sentry/issues/endpoints/test_organization_group_index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sentry/issues/endpoints/test_organization_group_index.py b/tests/sentry/issues/endpoints/test_organization_group_index.py index 544cab7afd6326..3d879ba79c743a 100644 --- a/tests/sentry/issues/endpoints/test_organization_group_index.py +++ b/tests/sentry/issues/endpoints/test_organization_group_index.py @@ -3152,7 +3152,7 @@ def test_snuba_perf_issue(self, mock_query: MagicMock) -> None: sort="new", query="user.email:myemail@example.com", ) - # assert len(response.data) == 2 + assert len(response.data) == 2 assert {r["id"] for r in response.data} == { str(perf_group_id), str(error_event.group.id), From 2a7314b0a67b3e332f46b425104c2f5dcc84f39c Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:18:07 -0700 Subject: [PATCH 4/8] Use a new field in GroupType class --- src/sentry/issues/grouptype.py | 3 +++ src/sentry/issues/search.py | 9 +------- src/sentry/search/snuba/executors.py | 32 ++++++++++++++++++---------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/sentry/issues/grouptype.py b/src/sentry/issues/grouptype.py index c9e6d548cc5c45..91887dceaa23e5 100644 --- a/src/sentry/issues/grouptype.py +++ b/src/sentry/issues/grouptype.py @@ -140,6 +140,8 @@ class GroupType: # If True this group type should be released everywhere. If False, fall back to features to # decide if this is released. released: bool = False + # If False this group is excluded from default searches, when there are no filters on issue.category or issue.type. + in_default_search: bool = True # Allow automatic resolution of an issue type, using the project-level option. enable_auto_resolve: bool = True @@ -580,6 +582,7 @@ class FeedbackGroup(GroupType): creation_quota = Quota(3600, 60, 1000) # 1000 per hour, sliding window of 60 seconds default_priority = PriorityLevel.MEDIUM notification_config = NotificationConfig(context=[]) + in_default_search = False # hide from issues stream @dataclass(frozen=True) diff --git a/src/sentry/issues/search.py b/src/sentry/issues/search.py index 642e3b8cb81c5a..b060999729eac4 100644 --- a/src/sentry/issues/search.py +++ b/src/sentry/issues/search.py @@ -8,12 +8,7 @@ from sentry.api.event_search import SearchFilter, SearchKey, SearchValue from sentry.issues import grouptype -from sentry.issues.grouptype import ( - FeedbackGroup, - GroupCategory, - get_all_group_type_ids, - get_group_type_by_type_id, -) +from sentry.issues.grouptype import GroupCategory, get_all_group_type_ids, get_group_type_by_type_id from sentry.models.environment import Environment from sentry.models.organization import Organization from sentry.search.events.filter import convert_search_filter_to_snuba_query @@ -21,8 +16,6 @@ from sentry.utils import snuba from sentry.utils.snuba import SnubaQueryParams -HIDDEN_FROM_DEFAULT_SEARCH_GROUP_TYPES = (FeedbackGroup,) - class UnsupportedSearchQuery(Exception): pass diff --git a/src/sentry/search/snuba/executors.py b/src/sentry/search/snuba/executors.py index 8dd127553a1eed..064327da7571b0 100644 --- a/src/sentry/search/snuba/executors.py +++ b/src/sentry/search/snuba/executors.py @@ -42,9 +42,14 @@ from sentry.constants import ALLOWED_FUTURE_DELTA from sentry.db.models.manager.base_query_set import BaseQuerySet from sentry.issues import grouptype -from sentry.issues.grouptype import ErrorGroupType, GroupCategory, get_group_types_by_category +from sentry.issues.grouptype import ( + ErrorGroupType, + GroupCategory, + GroupType, + get_group_types_by_category, +) +from sentry.issues.grouptype import registry as gt_registry from sentry.issues.search import ( - HIDDEN_FROM_DEFAULT_SEARCH_GROUP_TYPES, SEARCH_FILTER_UPDATERS, IntermediateSearchQueryPartial, MergeableRow, @@ -1839,16 +1844,21 @@ def query( Condition(Column("occurrence_type_id", joined_entity), Op.IN, group_types) ) else: - hidden_group_type_ids = list( - map(lambda gt: gt.type_id, HIDDEN_FROM_DEFAULT_SEARCH_GROUP_TYPES) - ) - where_conditions.append( - Condition( - Column("occurrence_type_id", joined_entity), - Op.NOT_IN, - hidden_group_type_ids, + all_group_type_objs: list[GroupType] = [ + gt_registry.get_group_type_by_type_id(id) + for id in gt_registry.get_all_group_type_ids() + ] + hidden_group_type_ids = [ + gt.type_id for gt in all_group_type_objs if not gt.in_default_search + ] + if hidden_group_type_ids: + where_conditions.append( + Condition( + Column("occurrence_type_id", joined_entity), + Op.NOT_IN, + hidden_group_type_ids, + ) ) - ) sort_func = self.get_sort_defs(joined_entity)[sort_by] From 5253faef5737f340263fc31149b925410cbbce0e Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:20:33 -0700 Subject: [PATCH 5/8] Fix get_by_type_id() call --- src/sentry/search/snuba/executors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/search/snuba/executors.py b/src/sentry/search/snuba/executors.py index 064327da7571b0..a5b7dbee40c776 100644 --- a/src/sentry/search/snuba/executors.py +++ b/src/sentry/search/snuba/executors.py @@ -1845,7 +1845,7 @@ def query( ) else: all_group_type_objs: list[GroupType] = [ - gt_registry.get_group_type_by_type_id(id) + gt_registry.get_by_type_id(id) for id in gt_registry.get_all_group_type_ids() ] hidden_group_type_ids = [ From 1da96c71c102c18adf8353449ea5f2823e08e960 Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:33:48 -0700 Subject: [PATCH 6/8] Parametrize tests on useGroupSnubaDataset --- .../test_organization_group_index.py | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/sentry/issues/endpoints/test_organization_group_index.py b/tests/sentry/issues/endpoints/test_organization_group_index.py index 3d879ba79c743a..8360ca13306528 100644 --- a/tests/sentry/issues/endpoints/test_organization_group_index.py +++ b/tests/sentry/issues/endpoints/test_organization_group_index.py @@ -3920,11 +3920,12 @@ def test_snuba_heavy_error_handled_boolean(self, _: MagicMock) -> None: assert len(response_handled_0.data) == 1 assert int(response_handled_0.data[0]["id"]) == handled_event.group.id - def test_feedback_filtered_by_default(self, _): + def run_feedback_filtered_by_default_test(self, use_group_snuba_dataset: bool): with Feature( { "organizations:feedback-ingest": True, "organizations:feedback-visible": True, + "organizations:issue-search-snuba": use_group_snuba_dataset, } ): event = self.store_event( @@ -3938,19 +3939,27 @@ def test_feedback_filtered_by_default(self, _): feedback_event, self.project.id, FeedbackCreationSource.NEW_FEEDBACK_ENVELOPE ) self.login_as(user=self.user) - res = self.get_success_response() + res = self.get_success_response(useGroupSnubaDataset=use_group_snuba_dataset) + # test that the issue returned is NOT the feedback issue. assert len(res.data) == 1 issue = res.data[0] feedback_group = Group.objects.get(type=FeedbackGroup.type_id) assert int(issue["id"]) != feedback_group.id assert issue["issueCategory"] != "feedback" - def test_feedback_filter(self, _): + def test_feedback_filtered_by_default_no_snuba_search(self, _): + self.run_feedback_filtered_by_default_test(False) + + def test_feedback_filtered_by_default_use_snuba_search(self, _): + self.run_feedback_filtered_by_default_test(True) + + def run_feedback_category_filter_test(self, use_group_snuba_dataset: bool): with Feature( { "organizations:feedback-ingest": True, "organizations:feedback-visible": True, + "organizations:issue-search-snuba": use_group_snuba_dataset, } ): event = self.store_event( @@ -3964,14 +3973,23 @@ def test_feedback_filter(self, _): feedback_event, self.project.id, FeedbackCreationSource.NEW_FEEDBACK_ENVELOPE ) self.login_as(user=self.user) - res = self.get_success_response(query="issue.category:feedback") + res = self.get_success_response( + query="issue.category:feedback", useGroupSnubaDataset=use_group_snuba_dataset + ) + # test that the issue returned IS the feedback issue. assert len(res.data) == 1 issue = res.data[0] feedback_group = Group.objects.get(type=FeedbackGroup.type_id) assert int(issue["id"]) == feedback_group.id assert issue["issueCategory"] == "feedback" + def test_feedback_category_filter_no_snuba_search(self, _): + self.run_feedback_category_filter_test(False) + + def test_feedback_category_filter_use_snuba_search(self, _): + self.run_feedback_category_filter_test(True) + class GroupUpdateTest(APITestCase, SnubaTestCase): endpoint = "sentry-api-0-organization-group-index" From 017391222fecc861840ba6fa3a9eadb1025a549d Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:53:27 -0700 Subject: [PATCH 7/8] Move in_default_search filter to before is_visible filter, in group_types_from --- src/sentry/issues/search.py | 16 ++++++-- src/sentry/search/snuba/executors.py | 55 ++++++++-------------------- 2 files changed, 29 insertions(+), 42 deletions(-) diff --git a/src/sentry/issues/search.py b/src/sentry/issues/search.py index b060999729eac4..3566bfc5bdd32f 100644 --- a/src/sentry/issues/search.py +++ b/src/sentry/issues/search.py @@ -8,7 +8,13 @@ from sentry.api.event_search import SearchFilter, SearchKey, SearchValue from sentry.issues import grouptype -from sentry.issues.grouptype import GroupCategory, get_all_group_type_ids, get_group_type_by_type_id +from sentry.issues.grouptype import ( + GroupCategory, + GroupType, + get_all_group_type_ids, + get_group_type_by_type_id, +) +from sentry.issues.grouptype import registry as GT_REGISTRY from sentry.models.environment import Environment from sentry.models.organization import Organization from sentry.search.events.filter import convert_search_filter_to_snuba_query @@ -98,14 +104,18 @@ def group_categories_from( def group_types_from( search_filters: Sequence[SearchFilter] | None, -) -> set[int] | None: +) -> set[int]: """ Return the set of group type ids to include in the query, or None if all group types should be included. """ # if no relevant filters, return none to signify we should query all group types if not any(sf.key.name in ("issue.category", "issue.type") for sf in search_filters or ()): - return None + # Filters some types from the default search + all_group_type_objs: list[GroupType] = [ + GT_REGISTRY.get_by_type_id(id) for id in GT_REGISTRY.get_all_group_type_ids() + ] + return {gt.type_id for gt in all_group_type_objs if gt.in_default_search} # start by including all group types include_group_types = set(get_all_group_type_ids()) diff --git a/src/sentry/search/snuba/executors.py b/src/sentry/search/snuba/executors.py index a5b7dbee40c776..91fa4f1b280475 100644 --- a/src/sentry/search/snuba/executors.py +++ b/src/sentry/search/snuba/executors.py @@ -42,13 +42,7 @@ from sentry.constants import ALLOWED_FUTURE_DELTA from sentry.db.models.manager.base_query_set import BaseQuerySet from sentry.issues import grouptype -from sentry.issues.grouptype import ( - ErrorGroupType, - GroupCategory, - GroupType, - get_group_types_by_category, -) -from sentry.issues.grouptype import registry as gt_registry +from sentry.issues.grouptype import ErrorGroupType, GroupCategory, get_group_types_by_category from sentry.issues.search import ( SEARCH_FILTER_UPDATERS, IntermediateSearchQueryPartial, @@ -1826,39 +1820,22 @@ def query( # handle types based on issue.type and issue.category if not is_errors: raw_group_types = group_types_from(search_filters) - if raw_group_types is not None: - # no possible groups, return empty - if len(raw_group_types) == 0: - metrics.incr( - "snuba.search.group_attributes.no_possible_groups", skip_internal=False - ) - return self.empty_result - - # filter out the group types that are not visible to the org/user - group_types = [ - gt.type_id - for gt in grouptype.registry.get_visible(organization, actor) - if gt.type_id in raw_group_types - ] - where_conditions.append( - Condition(Column("occurrence_type_id", joined_entity), Op.IN, group_types) + # no possible groups, return empty + if len(raw_group_types) == 0: + metrics.incr( + "snuba.search.group_attributes.no_possible_groups", skip_internal=False ) - else: - all_group_type_objs: list[GroupType] = [ - gt_registry.get_by_type_id(id) - for id in gt_registry.get_all_group_type_ids() - ] - hidden_group_type_ids = [ - gt.type_id for gt in all_group_type_objs if not gt.in_default_search - ] - if hidden_group_type_ids: - where_conditions.append( - Condition( - Column("occurrence_type_id", joined_entity), - Op.NOT_IN, - hidden_group_type_ids, - ) - ) + return self.empty_result + + # filter out the group types that are not visible to the org/user + group_types = [ + gt.type_id + for gt in grouptype.registry.get_visible(organization, actor) + if gt.type_id in raw_group_types + ] + where_conditions.append( + Condition(Column("occurrence_type_id", joined_entity), Op.IN, group_types) + ) sort_func = self.get_sort_defs(joined_entity)[sort_by] From 2c63a781f2fd7da33d7c9d9b63a17f563e850faf Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Mon, 9 Sep 2024 10:24:02 -0700 Subject: [PATCH 8/8] Fix snuba_perf_issue test --- .../endpoints/test_organization_group_index.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/sentry/issues/endpoints/test_organization_group_index.py b/tests/sentry/issues/endpoints/test_organization_group_index.py index 8360ca13306528..1e2e3e2df3d744 100644 --- a/tests/sentry/issues/endpoints/test_organization_group_index.py +++ b/tests/sentry/issues/endpoints/test_organization_group_index.py @@ -17,6 +17,7 @@ PerformanceNPlusOneGroupType, PerformanceRenderBlockingAssetSpanGroupType, PerformanceSlowDBQueryGroupType, + ProfileFileIOGroupType, ) from sentry.models.activity import Activity from sentry.models.apitoken import ApiToken @@ -3148,10 +3149,11 @@ def test_snuba_perf_issue(self, mock_query: MagicMock) -> None: self.login_as(user=self.user) # give time for consumers to run and propogate changes to clickhouse sleep(1) - response = self.get_success_response( - sort="new", - query="user.email:myemail@example.com", - ) + with self.feature([ProfileFileIOGroupType.build_visible_feature_name()]): + response = self.get_success_response( + sort="new", + query="user.email:myemail@example.com", + ) assert len(response.data) == 2 assert {r["id"] for r in response.data} == { str(perf_group_id), @@ -3923,8 +3925,8 @@ def test_snuba_heavy_error_handled_boolean(self, _: MagicMock) -> None: def run_feedback_filtered_by_default_test(self, use_group_snuba_dataset: bool): with Feature( { - "organizations:feedback-ingest": True, - "organizations:feedback-visible": True, + FeedbackGroup.build_visible_feature_name(): True, + FeedbackGroup.build_ingest_feature_name(): True, "organizations:issue-search-snuba": use_group_snuba_dataset, } ): @@ -3957,8 +3959,8 @@ def test_feedback_filtered_by_default_use_snuba_search(self, _): def run_feedback_category_filter_test(self, use_group_snuba_dataset: bool): with Feature( { - "organizations:feedback-ingest": True, - "organizations:feedback-visible": True, + FeedbackGroup.build_visible_feature_name(): True, + FeedbackGroup.build_ingest_feature_name(): True, "organizations:issue-search-snuba": use_group_snuba_dataset, } ):