test_organization_group_index.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. from datetime import datetime, timedelta, timezone
  2. from unittest.mock import patch
  3. from django.utils import timezone as django_timezone
  4. from fixtures.page_objects.issue_list import IssueListPage
  5. from sentry.models import AssistantActivity, GroupInboxReason, GroupStatus
  6. from sentry.models.groupinbox import add_group_to_inbox
  7. from sentry.testutils.cases import AcceptanceTestCase, SnubaTestCase
  8. from sentry.testutils.helpers.datetime import before_now, iso_format
  9. from sentry.testutils.silo import no_silo_test
  10. event_time = before_now(days=3).replace(tzinfo=timezone.utc)
  11. @no_silo_test(stable=True)
  12. class OrganizationGroupIndexTest(AcceptanceTestCase, SnubaTestCase):
  13. def setUp(self):
  14. super().setUp()
  15. self.user = self.create_user("foo@example.com")
  16. self.org = self.create_organization(owner=self.user, name="Rowdy Tiger")
  17. self.team = self.create_team(
  18. organization=self.org, name="Mariachi Band", members=[self.user]
  19. )
  20. self.project = self.create_project(organization=self.org, teams=[self.team], name="Bengal")
  21. self.other_project = self.create_project(
  22. organization=self.org, teams=[self.team], name="Sumatra"
  23. )
  24. self.login_as(self.user)
  25. self.page = IssueListPage(self.browser, self.client)
  26. self.dismiss_assistant()
  27. def create_issues(self):
  28. self.event_a = self.store_event(
  29. data={
  30. "event_id": "a" * 32,
  31. "message": "oh no",
  32. "timestamp": iso_format(event_time - timedelta(hours=1)),
  33. "fingerprint": ["group-1"],
  34. },
  35. project_id=self.project.id,
  36. )
  37. add_group_to_inbox(self.event_a.group, GroupInboxReason.NEW)
  38. self.event_b = self.store_event(
  39. data={
  40. "event_id": "b" * 32,
  41. "message": "oh snap",
  42. "timestamp": iso_format(event_time),
  43. "fingerprint": ["group-2"],
  44. },
  45. project_id=self.project.id,
  46. )
  47. add_group_to_inbox(self.event_b.group, GroupInboxReason.NEW)
  48. def test_with_onboarding(self):
  49. self.project.update(first_event=None)
  50. self.page.visit_issue_list(self.org.slug)
  51. self.browser.wait_until_test_id("awaiting-events")
  52. def test_with_no_results(self):
  53. self.project.update(first_event=django_timezone.now())
  54. self.page.visit_issue_list(self.org.slug, query="?query=assigned%3Ame")
  55. self.browser.wait_until_test_id("empty-state")
  56. @patch("django.utils.timezone.now")
  57. def test_with_results(self, mock_now):
  58. mock_now.return_value = datetime.utcnow().replace(tzinfo=timezone.utc)
  59. self.create_issues()
  60. self.page.visit_issue_list(self.org.slug)
  61. self.page.wait_for_stream()
  62. groups = self.browser.elements('[data-test-id="event-issue-header"]')
  63. assert len(groups) == 2
  64. assert "oh snap" in groups[0].text
  65. assert "oh no" in groups[1].text
  66. @patch("django.utils.timezone.now")
  67. def test_resolve_issues_removal(self, mock_now):
  68. mock_now.return_value = datetime.utcnow().replace(tzinfo=timezone.utc)
  69. self.create_issues()
  70. group1 = self.event_a.group
  71. self.page.visit_issue_list(self.org.slug)
  72. self.page.wait_for_stream()
  73. self.page.select_issue(1)
  74. self.page.resolve_issues()
  75. group1.update(status=GroupStatus.RESOLVED, substatus=None)
  76. self.page.wait_for_issue_removal()
  77. groups = self.browser.elements('[data-test-id="event-issue-header"]')
  78. assert len(groups) == 1
  79. @patch("django.utils.timezone.now")
  80. def test_resolve_issues_removal_multi_projects(self, mock_now):
  81. mock_now.return_value = datetime.utcnow().replace(tzinfo=timezone.utc)
  82. self.create_issues()
  83. with self.feature(["organizations:global-views"]):
  84. group1 = self.event_a.group
  85. self.page.visit_issue_list(self.org.slug)
  86. self.page.wait_for_stream()
  87. self.page.select_issue(1)
  88. self.page.resolve_issues()
  89. group1.update(status=GroupStatus.RESOLVED, substatus=None)
  90. self.page.wait_for_issue_removal()
  91. groups = self.browser.elements('[data-test-id="event-issue-header"]')
  92. assert len(groups) == 1
  93. @patch("django.utils.timezone.now")
  94. def test_ignore_issues(self, mock_now):
  95. mock_now.return_value = datetime.utcnow().replace(tzinfo=timezone.utc)
  96. self.create_issues()
  97. group1 = self.event_a.group
  98. self.page.visit_issue_list(self.org.slug)
  99. self.page.wait_for_stream()
  100. self.page.select_issue(1)
  101. self.page.ignore_issues()
  102. group1.update(status=GroupStatus.IGNORED, substatus=None)
  103. self.page.wait_for_issue_removal()
  104. groups = self.browser.elements('[data-test-id="event-issue-header"]')
  105. assert len(groups) == 1
  106. @patch("django.utils.timezone.now")
  107. def test_ignore_issues_multi_projects(self, mock_now):
  108. mock_now.return_value = datetime.utcnow().replace(tzinfo=timezone.utc)
  109. self.create_issues()
  110. group1 = self.event_a.group
  111. with self.feature("organizations:global-views"):
  112. self.page.visit_issue_list(self.org.slug)
  113. self.page.wait_for_stream()
  114. self.page.select_issue(1)
  115. self.page.ignore_issues()
  116. group1.update(status=GroupStatus.IGNORED, substatus=None)
  117. self.page.wait_for_issue_removal()
  118. groups = self.browser.elements('[data-test-id="event-issue-header"]')
  119. assert len(groups) == 1
  120. @patch("django.utils.timezone.now")
  121. def test_delete_issues(self, mock_now):
  122. mock_now.return_value = datetime.utcnow().replace(tzinfo=timezone.utc)
  123. self.create_issues()
  124. group1 = self.event_a.group
  125. self.page.visit_issue_list(self.org.slug)
  126. self.page.wait_for_stream()
  127. self.page.select_issue(1)
  128. self.page.delete_issues()
  129. group1.update(status=GroupStatus.PENDING_DELETION, substatus=None)
  130. self.page.wait_for_issue_removal()
  131. groups = self.browser.elements('[data-test-id="event-issue-header"]')
  132. assert len(groups) == 1
  133. @patch("django.utils.timezone.now")
  134. def test_delete_issues_multi_projects(self, mock_now):
  135. mock_now.return_value = datetime.utcnow().replace(tzinfo=timezone.utc)
  136. self.create_issues()
  137. group1 = self.event_a.group
  138. with self.feature("organizations:global-views"):
  139. self.page.visit_issue_list(self.org.slug)
  140. self.page.wait_for_stream()
  141. self.page.select_issue(1)
  142. self.page.delete_issues()
  143. group1.update(status=GroupStatus.PENDING_DELETION, substatus=None)
  144. self.page.wait_for_issue_removal()
  145. groups = self.browser.elements('[data-test-id="event-issue-header"]')
  146. assert len(groups) == 1
  147. @patch("django.utils.timezone.now")
  148. def test_merge_issues(self, mock_now):
  149. mock_now.return_value = datetime.utcnow().replace(tzinfo=timezone.utc)
  150. self.create_issues()
  151. group1 = self.event_a.group
  152. group2 = self.event_b.group
  153. self.page.visit_issue_list(self.org.slug)
  154. self.page.wait_for_stream()
  155. self.page.select_issue(1)
  156. self.page.select_issue(2)
  157. self.page.merge_issues()
  158. group1.update(status=GroupStatus.PENDING_MERGE, substatus=None)
  159. group2.update(status=GroupStatus.PENDING_MERGE, substatus=None)
  160. self.page.wait_for_issue_removal()
  161. groups = self.browser.elements('[data-test-id="event-issue-header"]')
  162. assert len(groups) == 1
  163. @patch("django.utils.timezone.now")
  164. def test_inbox_results(self, mock_now):
  165. mock_now.return_value = datetime.utcnow().replace(tzinfo=timezone.utc)
  166. self.create_issues()
  167. # Disable for_review_guide
  168. AssistantActivity.objects.create(
  169. user=self.user, guide_id=9, viewed_ts=django_timezone.now()
  170. )
  171. self.page.visit_issue_list(
  172. self.org.slug,
  173. query="?query=is%3Aunresolved+is%3Afor_review+assigned_or_suggested%3A[me, none]",
  174. )
  175. self.page.wait_for_stream()
  176. groups = self.browser.elements('[data-test-id="event-issue-header"]')
  177. assert len(groups) == 2
  178. self.page.select_issue(1)
  179. self.page.mark_reviewed_issues()
  180. self.page.visit_issue_list(
  181. self.org.slug,
  182. query="?query=is%3Aunresolved+is%3Afor_review+assigned_or_suggested%3A[me, none]",
  183. )
  184. self.page.wait_for_stream()
  185. groups = self.browser.elements('[data-test-id="event-issue-header"]')
  186. assert len(groups) == 1