test_organization_group_index.py 8.7 KB

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