123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- from datetime import datetime
- from unittest.mock import patch
- import pytz
- from django.utils import timezone
- from fixtures.page_objects.issue_list import IssueListPage
- from sentry.models import AssistantActivity, GroupInboxReason, GroupStatus
- from sentry.models.groupinbox import add_group_to_inbox
- from sentry.testutils import AcceptanceTestCase, SnubaTestCase
- from sentry.testutils.helpers.datetime import before_now, iso_format
- from sentry.testutils.silo import region_silo_test
- event_time = before_now(days=3).replace(tzinfo=pytz.utc)
- @region_silo_test
- class OrganizationGroupIndexTest(AcceptanceTestCase, SnubaTestCase):
- def setUp(self):
- super().setUp()
- self.user = self.create_user("foo@example.com")
- self.org = self.create_organization(owner=self.user, name="Rowdy Tiger")
- self.team = self.create_team(
- organization=self.org, name="Mariachi Band", members=[self.user]
- )
- self.project = self.create_project(organization=self.org, teams=[self.team], name="Bengal")
- self.other_project = self.create_project(
- organization=self.org, teams=[self.team], name="Sumatra"
- )
- self.login_as(self.user)
- self.page = IssueListPage(self.browser, self.client)
- self.dismiss_assistant()
- def create_issues(self):
- self.event_a = self.store_event(
- data={
- "event_id": "a" * 32,
- "message": "oh no",
- "timestamp": iso_format(event_time),
- "fingerprint": ["group-1"],
- },
- project_id=self.project.id,
- )
- add_group_to_inbox(self.event_a.group, GroupInboxReason.NEW)
- self.event_b = self.store_event(
- data={
- "event_id": "b" * 32,
- "message": "oh snap",
- "timestamp": iso_format(event_time),
- "fingerprint": ["group-2"],
- },
- project_id=self.project.id,
- )
- add_group_to_inbox(self.event_b.group, GroupInboxReason.NEW)
- def test_with_onboarding(self):
- self.project.update(first_event=None)
- self.page.visit_issue_list(self.org.slug)
- self.browser.wait_until_test_id("awaiting-events")
- self.browser.snapshot("organization issues onboarding")
- def test_with_no_results(self):
- self.project.update(first_event=timezone.now())
- self.page.visit_issue_list(self.org.slug, query="?query=assigned%3Ame")
- self.browser.wait_until_test_id("empty-state")
- self.browser.snapshot("organization issues no results")
- @patch("django.utils.timezone.now")
- def test_with_results(self, mock_now):
- mock_now.return_value = datetime.utcnow().replace(tzinfo=pytz.utc)
- self.create_issues()
- self.page.visit_issue_list(self.org.slug)
- self.page.wait_for_stream()
- self.browser.snapshot("organization issues with issues")
- groups = self.browser.elements('[data-test-id="event-issue-header"]')
- assert len(groups) == 2
- assert "oh snap" in groups[0].text
- assert "oh no" in groups[1].text
- @patch("django.utils.timezone.now")
- def test_resolve_issues(self, mock_now):
- mock_now.return_value = datetime.utcnow().replace(tzinfo=pytz.utc)
- self.create_issues()
- self.page.visit_issue_list(self.org.slug)
- self.page.wait_for_stream()
- self.page.select_issue(1)
- self.page.select_issue(2)
- self.page.resolve_issues()
- self.page.wait_for_resolved_issue()
- resolved_groups = self.page.find_resolved_issues()
- assert len(resolved_groups) == 2
- @patch("django.utils.timezone.now")
- def test_resolve_issues_removal(self, mock_now):
- mock_now.return_value = datetime.utcnow().replace(tzinfo=pytz.utc)
- self.create_issues()
- # TODO(Kelly): update once issue-list-removal-action feature is stable
- with self.feature("organizations:issue-list-removal-action"):
- group1 = self.event_a.group
- self.page.visit_issue_list(self.org.slug)
- self.page.wait_for_stream()
- self.page.select_issue(1)
- self.page.resolve_issues_removal()
- group1.update(status=GroupStatus.RESOLVED, substatus=None)
- self.page.wait_for_issue_removal()
- groups = self.browser.elements('[data-test-id="event-issue-header"]')
- assert len(groups) == 1
- @patch("django.utils.timezone.now")
- def test_resolve_issues_multi_projects(self, mock_now):
- mock_now.return_value = datetime.utcnow().replace(tzinfo=pytz.utc)
- self.create_issues()
- with self.feature("organizations:global-views"):
- self.page.visit_issue_list(self.org.slug)
- self.page.wait_for_stream()
- self.page.select_issue(1)
- self.page.select_issue(2)
- self.page.resolve_issues()
- self.page.wait_for_resolved_issue()
- resolved_groups = self.page.find_resolved_issues()
- assert len(resolved_groups) == 2
- @patch("django.utils.timezone.now")
- def test_resolve_issues_removal_multi_projects(self, mock_now):
- mock_now.return_value = datetime.utcnow().replace(tzinfo=pytz.utc)
- self.create_issues()
- # TODO(Kelly): update once issue-list-removal-action feature is stable
- with self.feature(
- ["organizations:global-views", "organizations:issue-list-removal-action"]
- ):
- group1 = self.event_a.group
- self.page.visit_issue_list(self.org.slug)
- self.page.wait_for_stream()
- self.page.select_issue(1)
- self.page.resolve_issues_removal()
- group1.update(status=GroupStatus.RESOLVED, substatus=None)
- self.page.wait_for_issue_removal()
- groups = self.browser.elements('[data-test-id="event-issue-header"]')
- assert len(groups) == 1
- @patch("django.utils.timezone.now")
- def test_ignore_issues(self, mock_now):
- # TODO(Kelly): update once issue-list-removal-action feature is stable
- with self.feature("organizations:issue-list-removal-action"):
- mock_now.return_value = datetime.utcnow().replace(tzinfo=pytz.utc)
- self.create_issues()
- group1 = self.event_a.group
- self.page.visit_issue_list(self.org.slug)
- self.page.wait_for_stream()
- self.page.select_issue(1)
- self.page.ignore_issues()
- group1.update(status=GroupStatus.IGNORED, substatus=None)
- self.page.wait_for_issue_removal()
- groups = self.browser.elements('[data-test-id="event-issue-header"]')
- assert len(groups) == 1
- @patch("django.utils.timezone.now")
- def test_ignore_issues_multi_projects(self, mock_now):
- # TODO(Kelly): update once issue-list-removal-action feature is stable
- with self.feature("organizations:issue-list-removal-action"):
- mock_now.return_value = datetime.utcnow().replace(tzinfo=pytz.utc)
- self.create_issues()
- group1 = self.event_a.group
- with self.feature("organizations:global-views"):
- self.page.visit_issue_list(self.org.slug)
- self.page.wait_for_stream()
- self.page.select_issue(1)
- self.page.ignore_issues()
- group1.update(status=GroupStatus.IGNORED, substatus=None)
- self.page.wait_for_issue_removal()
- groups = self.browser.elements('[data-test-id="event-issue-header"]')
- assert len(groups) == 1
- @patch("django.utils.timezone.now")
- def test_delete_issues(self, mock_now):
- # TODO(Kelly): update once issue-list-removal-action feature is stable
- with self.feature("organizations:issue-list-removal-action"):
- mock_now.return_value = datetime.utcnow().replace(tzinfo=pytz.utc)
- self.create_issues()
- group1 = self.event_a.group
- self.page.visit_issue_list(self.org.slug)
- self.page.wait_for_stream()
- self.page.select_issue(1)
- self.page.delete_issues()
- group1.update(status=GroupStatus.PENDING_DELETION, substatus=None)
- self.page.wait_for_issue_removal()
- groups = self.browser.elements('[data-test-id="event-issue-header"]')
- assert len(groups) == 1
- @patch("django.utils.timezone.now")
- def test_delete_issues_multi_projects(self, mock_now):
- # TODO(Kelly): update once issue-list-removal-action feature is stable
- with self.feature("organizations:issue-list-removal-action"):
- mock_now.return_value = datetime.utcnow().replace(tzinfo=pytz.utc)
- self.create_issues()
- group1 = self.event_a.group
- with self.feature("organizations:global-views"):
- self.page.visit_issue_list(self.org.slug)
- self.page.wait_for_stream()
- self.page.select_issue(1)
- self.page.delete_issues()
- group1.update(status=GroupStatus.PENDING_DELETION, substatus=None)
- self.page.wait_for_issue_removal()
- groups = self.browser.elements('[data-test-id="event-issue-header"]')
- assert len(groups) == 1
- @patch("django.utils.timezone.now")
- def test_merge_issues(self, mock_now):
- # TODO(Kelly): update once issue-list-removal-action feature is stable
- with self.feature("organizations:issue-list-removal-action"):
- mock_now.return_value = datetime.utcnow().replace(tzinfo=pytz.utc)
- self.create_issues()
- group1 = self.event_a.group
- group2 = self.event_b.group
- self.page.visit_issue_list(self.org.slug)
- self.page.wait_for_stream()
- self.page.select_issue(1)
- self.page.select_issue(2)
- self.page.merge_issues()
- group1.update(status=GroupStatus.PENDING_MERGE, substatus=None)
- group2.update(status=GroupStatus.PENDING_MERGE, substatus=None)
- self.page.wait_for_issue_removal()
- groups = self.browser.elements('[data-test-id="event-issue-header"]')
- assert len(groups) == 1
- @patch("django.utils.timezone.now")
- def test_inbox_results(self, mock_now):
- mock_now.return_value = datetime.utcnow().replace(tzinfo=pytz.utc)
- self.create_issues()
- # Disable for_review_guide
- AssistantActivity.objects.create(user=self.user, guide_id=9, viewed_ts=timezone.now())
- self.page.visit_issue_list(
- self.org.slug,
- query="?query=is%3Aunresolved+is%3Afor_review+assigned_or_suggested%3A[me, none]",
- )
- self.page.wait_for_stream()
- self.browser.snapshot("organization issues inbox results")
- groups = self.browser.elements('[data-test-id="event-issue-header"]')
- assert len(groups) == 2
- self.page.select_issue(1)
- self.page.mark_reviewed_issues()
- self.page.visit_issue_list(
- self.org.slug,
- query="?query=is%3Aunresolved+is%3Afor_review+assigned_or_suggested%3A[me, none]",
- )
- self.page.wait_for_stream()
- groups = self.browser.elements('[data-test-id="event-issue-header"]')
- assert len(groups) == 1
|