test_organization_events_has_measurements.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. from django.urls import reverse
  2. from rest_framework.exceptions import ErrorDetail
  3. from sentry.testutils import APITestCase, SnubaTestCase
  4. from sentry.testutils.helpers.datetime import before_now, iso_format
  5. from sentry.utils.samples import load_data
  6. class OrganizationEventsHasMeasurementsTest(APITestCase, SnubaTestCase):
  7. def setUp(self):
  8. super().setUp()
  9. self.min_ago = iso_format(before_now(minutes=1))
  10. self.two_min_ago = iso_format(before_now(minutes=2))
  11. self.transaction_data = load_data("transaction", timestamp=before_now(minutes=1))
  12. self.features = {}
  13. def do_request(self, query, features=None):
  14. if features is None:
  15. features = {
  16. "organizations:discover-basic": True,
  17. "organizations:global-views": True,
  18. }
  19. features.update(self.features)
  20. self.login_as(user=self.user)
  21. url = reverse(
  22. "sentry-api-0-organization-events-has-measurements",
  23. kwargs={"organization_slug": self.organization.slug},
  24. )
  25. with self.feature(features):
  26. return self.client.get(url, query, format="json")
  27. def test_without_feature(self):
  28. response = self.do_request({}, features={"organizations:discover-basic": False})
  29. assert response.status_code == 404, response.content
  30. def test_no_projects(self):
  31. response = self.do_request({})
  32. assert response.status_code == 200, response.content
  33. assert response.data == {"measurements": False}
  34. def test_more_than_one_project(self):
  35. project = self.create_project()
  36. response = self.do_request(
  37. {
  38. "project": [self.project.id, project.id],
  39. "transaction": self.transaction_data["transaction"],
  40. "type": "web",
  41. }
  42. )
  43. assert response.status_code == 400, response.content
  44. assert response.data == {
  45. "non_field_errors": [ErrorDetail("Only 1 project allowed.", code="invalid")],
  46. }
  47. def test_no_transaction(self):
  48. response = self.do_request(
  49. {
  50. "project": [self.project.id],
  51. "type": "web",
  52. }
  53. )
  54. assert response.status_code == 400, response.content
  55. assert response.data == {
  56. "transaction": [ErrorDetail("This field may not be null.", code="null")],
  57. }
  58. def test_no_type(self):
  59. response = self.do_request(
  60. {
  61. "project": [self.project.id],
  62. "transaction": self.transaction_data["transaction"],
  63. }
  64. )
  65. assert response.status_code == 400, response.content
  66. assert response.data == {
  67. "type": [ErrorDetail("This field may not be null.", code="null")],
  68. }
  69. def test_unknown_type(self):
  70. response = self.do_request(
  71. {
  72. "project": [self.project.id],
  73. "transaction": self.transaction_data["transaction"],
  74. "type": "foo",
  75. }
  76. )
  77. assert response.status_code == 400, response.content
  78. assert response.data == {
  79. "type": [ErrorDetail('"foo" is not a valid choice.', code="invalid_choice")],
  80. }
  81. def test_no_events(self):
  82. response = self.do_request(
  83. {
  84. "project": [self.project.id],
  85. "transaction": self.transaction_data["transaction"],
  86. "type": "web",
  87. }
  88. )
  89. assert response.status_code == 200, response.content
  90. assert response.data == {"measurements": False}
  91. def test_has_event_but_no_web_measurements(self):
  92. # make sure the transaction doesnt have measurements
  93. self.transaction_data["measurements"] = {}
  94. self.store_event(self.transaction_data, self.project.id)
  95. response = self.do_request(
  96. {
  97. "project": [self.project.id],
  98. "transaction": self.transaction_data["transaction"],
  99. "type": "web",
  100. }
  101. )
  102. assert response.status_code == 200, response.content
  103. assert response.data == {"measurements": False}
  104. def test_has_event_and_no_recent_web_measurements(self):
  105. # make sure the event is older than 7 days
  106. transaction_data = load_data("transaction", timestamp=before_now(days=8))
  107. # make sure the transaction has some web measurements
  108. transaction_data["measurements"] = {"lcp": {"value": 100}}
  109. self.store_event(transaction_data, self.project.id)
  110. response = self.do_request(
  111. {
  112. "project": [self.project.id],
  113. "transaction": self.transaction_data["transaction"],
  114. "type": "web",
  115. }
  116. )
  117. assert response.status_code == 200, response.content
  118. assert response.data == {"measurements": False}
  119. def test_has_event_and_web_measurements(self):
  120. # make sure the transaction has some web measurements
  121. self.transaction_data["measurements"] = {"lcp": {"value": 100}}
  122. self.store_event(self.transaction_data, self.project.id)
  123. response = self.do_request(
  124. {
  125. "project": [self.project.id],
  126. "transaction": self.transaction_data["transaction"],
  127. "type": "web",
  128. }
  129. )
  130. assert response.status_code == 200, response.content
  131. assert response.data == {"measurements": True}
  132. def test_has_event_and_no_recent_mobile_measurements(self):
  133. # make sure the event is older than 7 days
  134. transaction_data = load_data("transaction", timestamp=before_now(days=8))
  135. # make sure the transaction has some web measurements
  136. transaction_data["measurements"] = {"app_start_cold": {"value": 100}}
  137. self.store_event(transaction_data, self.project.id)
  138. response = self.do_request(
  139. {
  140. "project": [self.project.id],
  141. "transaction": self.transaction_data["transaction"],
  142. "type": "mobile",
  143. }
  144. )
  145. assert response.status_code == 200, response.content
  146. assert response.data == {"measurements": False}
  147. def test_has_event_and_mobile_measurements(self):
  148. # make sure the transaction has some mobile measurements
  149. self.transaction_data["measurements"] = {"app_start_cold": {"value": 100}}
  150. self.store_event(self.transaction_data, self.project.id)
  151. response = self.do_request(
  152. {
  153. "project": [self.project.id],
  154. "transaction": self.transaction_data["transaction"],
  155. "type": "mobile",
  156. }
  157. )
  158. assert response.status_code == 200, response.content
  159. assert response.data == {"measurements": True}