test_issue_details.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. from __future__ import absolute_import
  2. import json
  3. import pytz
  4. from mock import patch
  5. from datetime import datetime, timedelta
  6. from django.conf import settings
  7. from django.utils import timezone
  8. from sentry.testutils import AcceptanceTestCase, SnubaTestCase
  9. from sentry.utils.samples import load_data
  10. event_time = (datetime.utcnow() - timedelta(days=3)).replace(tzinfo=pytz.utc)
  11. now = datetime.utcnow().replace(tzinfo=pytz.utc)
  12. class IssueDetailsTest(AcceptanceTestCase, SnubaTestCase):
  13. def setUp(self):
  14. super(IssueDetailsTest, self).setUp()
  15. patcher = patch("django.utils.timezone.now", return_value=now)
  16. patcher.start()
  17. self.addCleanup(patcher.stop)
  18. self.user = self.create_user("foo@example.com")
  19. self.org = self.create_organization(owner=self.user, name="Rowdy Tiger")
  20. self.team = self.create_team(organization=self.org, name="Mariachi Band")
  21. self.project = self.create_project(organization=self.org, teams=[self.team], name="Bengal")
  22. self.login_as(self.user)
  23. self.dismiss_assistant()
  24. def create_sample_event(self, platform, default=None, sample_name=None, time=None):
  25. event_data = load_data(platform, default=default, sample_name=sample_name)
  26. event_data["event_id"] = "d964fdbd649a4cf8bfc35d18082b6b0e"
  27. # Only set these properties if we were given a time.
  28. # event processing will mark old time values as processing errors.
  29. if time:
  30. event_data["received"] = time.isoformat()
  31. # We need a fallback datetime for the event
  32. if time is None:
  33. time = now - timedelta(days=1)
  34. time = time.replace(hour=0, minute=0, second=0, microsecond=0)
  35. event_data["timestamp"] = time.isoformat()
  36. event = self.store_event(
  37. data=event_data, project_id=self.project.id, assert_no_errors=False
  38. )
  39. event.group.update(
  40. first_seen=datetime(2015, 8, 13, 3, 8, 25, tzinfo=timezone.utc), last_seen=time
  41. )
  42. return event
  43. def visit_issue(self, groupid):
  44. self.dismiss_assistant()
  45. self.browser.get(u"/organizations/{}/issues/{}/".format(self.org.slug, groupid))
  46. self.wait_until_loaded()
  47. def test_python_event(self):
  48. event = self.create_sample_event(platform="python", time=event_time)
  49. self.visit_issue(event.group.id)
  50. # Wait for tag bars to load
  51. self.browser.wait_until('[data-test-id="loaded-device-name"]')
  52. self.browser.snapshot("issue details python")
  53. def test_python_rawbody_event(self):
  54. event = self.create_sample_event(platform="python-rawbody")
  55. self.visit_issue(event.group.id)
  56. self.browser.move_to(".request pre span")
  57. self.browser.snapshot("issue details python raw body")
  58. def test_python_formdata_event(self):
  59. event = self.create_sample_event(platform="python-formdata")
  60. self.visit_issue(event.group.id)
  61. self.browser.snapshot("issue details python formdata")
  62. def test_cocoa_event(self):
  63. event = self.create_sample_event(platform="cocoa")
  64. self.visit_issue(event.group.id)
  65. self.browser.snapshot("issue details cocoa")
  66. def test_unity_event(self):
  67. event = self.create_sample_event(default="unity", platform="csharp")
  68. self.visit_issue(event.group.id)
  69. self.browser.snapshot("issue details unity")
  70. def test_android_event(self):
  71. event = self.create_sample_event(platform="android")
  72. self.visit_issue(event.group.id)
  73. self.browser.snapshot("issue details android")
  74. def test_aspnetcore_event(self):
  75. event = self.create_sample_event(default="aspnetcore", platform="csharp")
  76. self.visit_issue(event.group.id)
  77. self.browser.snapshot("issue details aspnetcore")
  78. def test_javascript_specific_event(self):
  79. event = self.create_sample_event(platform="javascript")
  80. self.dismiss_assistant()
  81. self.visit_issue(event.group.id)
  82. self.browser.snapshot("issue details javascript - event details")
  83. self.browser.find_element_by_xpath("//a//code[contains(text(), 'curl')]").click()
  84. self.browser.snapshot("issue details javascript - event details - curl command")
  85. def test_rust_event(self):
  86. # TODO: This should become its own "rust" platform type
  87. event = self.create_sample_event(platform="native", sample_name="Rust")
  88. self.visit_issue(event.group.id)
  89. self.wait_until_loaded()
  90. self.browser.snapshot("issue details rust")
  91. def test_cordova_event(self):
  92. event = self.create_sample_event(platform="cordova")
  93. self.visit_issue(event.group.id)
  94. self.browser.snapshot("issue details cordova")
  95. def test_stripped_event(self):
  96. event = self.create_sample_event(platform="pii")
  97. self.visit_issue(event.group.id)
  98. self.browser.snapshot("issue details pii stripped")
  99. def test_empty_exception(self):
  100. event = self.create_sample_event(platform="empty-exception")
  101. self.visit_issue(event.group.id)
  102. self.browser.snapshot("issue details empty exception")
  103. def test_empty_stacktrace(self):
  104. event = self.create_sample_event(platform="empty-stacktrace")
  105. self.visit_issue(event.group.id)
  106. self.browser.snapshot("issue details empty stacktrace")
  107. def test_invalid_interfaces(self):
  108. event = self.create_sample_event(platform="invalid-interfaces")
  109. self.visit_issue(event.group.id)
  110. self.browser.click(".errors-toggle")
  111. self.browser.wait_until(".entries > .errors ul")
  112. self.browser.snapshot("issue details invalid interfaces")
  113. def test_activity_page(self):
  114. event = self.create_sample_event(platform="python")
  115. self.browser.get(
  116. u"/organizations/{}/issues/{}/activity/".format(self.org.slug, event.group.id)
  117. )
  118. self.browser.wait_until_test_id("activity-item")
  119. self.browser.snapshot("issue activity python")
  120. def wait_until_loaded(self):
  121. self.browser.wait_until_not(".loading-indicator")
  122. self.browser.wait_until(".entries")
  123. self.browser.wait_until_test_id("linked-issues")
  124. self.browser.wait_until_test_id("loaded-device-name")
  125. self.browser.wait_until_test_id("loaded-event-cause-empty")
  126. def dismiss_assistant(self):
  127. # Forward session cookie to django client.
  128. self.client.cookies[settings.SESSION_COOKIE_NAME] = self.session.session_key
  129. res = self.client.put(
  130. "/api/0/assistant/",
  131. content_type="application/json",
  132. data=json.dumps({"guide_id": 1, "status": "viewed", "useful": True}),
  133. )
  134. assert res.status_code == 201
  135. res = self.client.put(
  136. "/api/0/assistant/",
  137. content_type="application/json",
  138. data=json.dumps({"guide_id": 3, "status": "viewed", "useful": True}),
  139. )
  140. assert res.status_code == 201