test_organization_events_geo.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. from django.urls import reverse
  2. from sentry.testutils import APITestCase, SnubaTestCase
  3. from sentry.testutils.helpers.datetime import before_now, iso_format
  4. from sentry.testutils.silo import region_silo_test
  5. @region_silo_test
  6. class OrganizationEventsGeoEndpointTest(APITestCase, SnubaTestCase):
  7. def setUp(self):
  8. super().setUp()
  9. self.ten_mins_ago = iso_format(before_now(minutes=10))
  10. self.features = {}
  11. def do_request(self, query, features=None):
  12. if features is None:
  13. features = {"organizations:dashboards-basic": True}
  14. features.update(self.features)
  15. self.login_as(user=self.user)
  16. url = reverse(
  17. "sentry-api-0-organization-events-geo",
  18. kwargs={"organization_slug": self.organization.slug},
  19. )
  20. with self.feature(features):
  21. return self.client.get(url, query, format="json")
  22. def test_no_projects(self):
  23. response = self.do_request({})
  24. assert response.status_code == 200, response.data
  25. assert len(response.data) == 0
  26. def test_no_field(self):
  27. query = {
  28. "field": [],
  29. "project": [self.project.id],
  30. }
  31. response = self.do_request(query)
  32. assert response.status_code == 400
  33. assert response.data["detail"] == "No column selected"
  34. def test_require_aggregate_field(self):
  35. query = {
  36. "field": ["i_am_a_tag"],
  37. "project": [self.project.id],
  38. }
  39. response = self.do_request(query)
  40. assert response.status_code == 400
  41. assert response.data["detail"] == "Functions may only be given"
  42. def test_happy_path(self):
  43. other_project = self.create_project()
  44. self.store_event(
  45. data={"event_id": "a" * 32, "environment": "staging", "timestamp": self.ten_mins_ago},
  46. project_id=self.project.id,
  47. )
  48. self.store_event(
  49. data={"event_id": "b" * 32, "environment": "staging", "timestamp": self.ten_mins_ago},
  50. project_id=other_project.id,
  51. )
  52. self.store_event(
  53. data={
  54. "event_id": "c" * 32,
  55. "environment": "production",
  56. "timestamp": self.ten_mins_ago,
  57. "user": {
  58. "email": "foo@example.com",
  59. "id": "123",
  60. "ip_address": "127.0.0.1",
  61. "username": "foo",
  62. "geo": {"country_code": "CA", "region": "Canada"},
  63. },
  64. },
  65. project_id=self.project.id,
  66. )
  67. query = {
  68. "project": [self.project.id],
  69. "field": ["count()"],
  70. "statsPeriod": "24h",
  71. }
  72. response = self.do_request(query)
  73. assert response.status_code == 200, response.data
  74. assert len(response.data["data"]) == 1
  75. assert response.data["data"] == [{"count": 1, "geo.country_code": "CA"}]
  76. # Expect no pagination
  77. assert "Link" not in response
  78. def test_only_use_last_field(self):
  79. self.store_event(
  80. data={
  81. "event_id": "a" * 32,
  82. "environment": "staging",
  83. "timestamp": self.ten_mins_ago,
  84. "user": {
  85. "email": "foo@example.com",
  86. "id": "123",
  87. "ip_address": "127.0.0.1",
  88. "username": "foo",
  89. "geo": {"country_code": "CA", "region": "Canada"},
  90. },
  91. },
  92. project_id=self.project.id,
  93. )
  94. query = {
  95. "project": [self.project.id],
  96. "field": ["p75()", "count()"],
  97. "statsPeriod": "24h",
  98. }
  99. response = self.do_request(query)
  100. assert response.status_code == 200, response.data
  101. assert len(response.data["data"]) == 1
  102. assert response.data["data"] == [{"count": 1, "geo.country_code": "CA"}]
  103. def test_orderby(self):
  104. def get_mock_data(index, geo):
  105. return {
  106. "event_id": str(index) * 32,
  107. "environment": "staging",
  108. "timestamp": self.ten_mins_ago,
  109. "user": {
  110. "email": "foo@example.com",
  111. "id": "123",
  112. "ip_address": "127.0.0.1",
  113. "username": "foo",
  114. "geo": geo,
  115. },
  116. }
  117. self.store_event(
  118. data=get_mock_data(0, {"country_code": "CA", "region": "Canada"}),
  119. project_id=self.project.id,
  120. )
  121. self.store_event(
  122. data=get_mock_data(1, {"country_code": "BR", "region": "Brazil"}),
  123. project_id=self.project.id,
  124. )
  125. self.store_event(
  126. data=get_mock_data(2, {"country_code": "BR", "region": "Brazil"}),
  127. project_id=self.project.id,
  128. )
  129. self.store_event(
  130. data=get_mock_data(3, {"country_code": "BR", "region": "Brazil"}),
  131. project_id=self.project.id,
  132. )
  133. self.store_event(
  134. data=get_mock_data(4, {"country_code": "JP", "region": "Japan"}),
  135. project_id=self.project.id,
  136. )
  137. self.store_event(
  138. data=get_mock_data(5, {"country_code": "JP", "region": "Japan"}),
  139. project_id=self.project.id,
  140. )
  141. query = {
  142. "project": [self.project.id],
  143. "field": ["count()"],
  144. "statsPeriod": "24h",
  145. "sort": "-count",
  146. }
  147. response = self.do_request(query)
  148. assert response.status_code == 200, response.data
  149. assert len(response.data["data"]) == 3
  150. assert response.data["data"] == [
  151. {"count": 3, "geo.country_code": "BR"},
  152. {"count": 2, "geo.country_code": "JP"},
  153. {"count": 1, "geo.country_code": "CA"},
  154. ]
  155. query = {
  156. "project": [self.project.id],
  157. "field": ["count()"],
  158. "statsPeriod": "24h",
  159. }
  160. response = self.do_request(query)
  161. assert response.status_code == 200, response.data
  162. assert len(response.data["data"]) == 3
  163. assert response.data["data"] == [
  164. {"count": 1, "geo.country_code": "CA"},
  165. {"count": 2, "geo.country_code": "JP"},
  166. {"count": 3, "geo.country_code": "BR"},
  167. ]