test_discover_saved_query_detail.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. from django.urls import NoReverseMatch, reverse
  2. from sentry.discover.models import DiscoverSavedQuery, DiscoverSavedQueryProject
  3. from sentry.testutils import APITestCase, SnubaTestCase
  4. class DiscoverSavedQueryDetailTest(APITestCase, SnubaTestCase):
  5. feature_name = "organizations:discover"
  6. def setUp(self):
  7. super().setUp()
  8. self.login_as(user=self.user)
  9. self.org = self.create_organization(owner=self.user)
  10. self.org_without_access = self.create_organization()
  11. self.project_ids = [
  12. self.create_project(organization=self.org).id,
  13. self.create_project(organization=self.org).id,
  14. ]
  15. query = {"fields": ["test"], "conditions": [], "limit": 10}
  16. model = DiscoverSavedQuery.objects.create(
  17. organization=self.org, created_by=self.user, name="Test query", query=query
  18. )
  19. model.set_projects(self.project_ids)
  20. self.query_id = model.id
  21. invalid = DiscoverSavedQuery.objects.create(
  22. organization=self.org_without_access, name="Query without access", query=query
  23. )
  24. invalid.set_projects(self.project_ids)
  25. self.query_id_without_access = invalid.id
  26. def test_invalid_id(self):
  27. with self.assertRaises(NoReverseMatch):
  28. reverse("sentry-api-0-discover-saved-query-detail", args=[self.org.slug, "not-an-id"])
  29. def test_get(self):
  30. with self.feature(self.feature_name):
  31. url = reverse(
  32. "sentry-api-0-discover-saved-query-detail", args=[self.org.slug, self.query_id]
  33. )
  34. response = self.client.get(url)
  35. assert response.status_code == 200, response.content
  36. assert response.data["id"] == str(self.query_id)
  37. assert set(response.data["projects"]) == set(self.project_ids)
  38. assert response.data["fields"] == ["test"]
  39. assert response.data["conditions"] == []
  40. assert response.data["limit"] == 10
  41. def test_get_discover_query_flag(self):
  42. with self.feature("organizations:discover-query"):
  43. url = reverse(
  44. "sentry-api-0-discover-saved-query-detail", args=[self.org.slug, self.query_id]
  45. )
  46. response = self.client.get(url)
  47. assert response.status_code == 200, response.content
  48. assert response.data["id"] == str(self.query_id)
  49. assert set(response.data["projects"]) == set(self.project_ids)
  50. assert response.data["fields"] == ["test"]
  51. assert response.data["conditions"] == []
  52. assert response.data["limit"] == 10
  53. def test_get_version(self):
  54. query = {"fields": ["event_id"], "query": "event.type:error", "limit": 10, "version": 2}
  55. model = DiscoverSavedQuery.objects.create(
  56. organization=self.org, created_by=self.user, name="v2 query", query=query
  57. )
  58. model.set_projects(self.project_ids)
  59. with self.feature(self.feature_name):
  60. url = reverse(
  61. "sentry-api-0-discover-saved-query-detail", args=[self.org.slug, model.id]
  62. )
  63. response = self.client.get(url)
  64. assert response.status_code == 200, response.content
  65. assert response.data["id"] == str(model.id)
  66. assert set(response.data["projects"]) == set(self.project_ids)
  67. assert response.data["fields"] == ["event_id"]
  68. assert response.data["query"] == "event.type:error"
  69. assert response.data["limit"] == 10
  70. assert response.data["version"] == 2
  71. def test_get_org_without_access(self):
  72. with self.feature(self.feature_name):
  73. url = reverse(
  74. "sentry-api-0-discover-saved-query-detail",
  75. args=[self.org_without_access.slug, self.query_id],
  76. )
  77. response = self.client.get(url)
  78. assert response.status_code == 403, response.content
  79. def test_put(self):
  80. with self.feature(self.feature_name):
  81. url = reverse(
  82. "sentry-api-0-discover-saved-query-detail", args=[self.org.slug, self.query_id]
  83. )
  84. response = self.client.put(
  85. url,
  86. {
  87. "name": "New query",
  88. "projects": self.project_ids,
  89. "fields": [],
  90. "range": "24h",
  91. "limit": 20,
  92. "conditions": [],
  93. "aggregations": [],
  94. "orderby": "-time",
  95. },
  96. )
  97. assert response.status_code == 200, response.content
  98. assert response.data["id"] == str(self.query_id)
  99. assert set(response.data["projects"]) == set(self.project_ids)
  100. assert response.data["fields"] == []
  101. assert response.data["conditions"] == []
  102. assert response.data["limit"] == 20
  103. def test_put_query_without_access(self):
  104. with self.feature(self.feature_name):
  105. url = reverse(
  106. "sentry-api-0-discover-saved-query-detail",
  107. args=[self.org.slug, self.query_id_without_access],
  108. )
  109. response = self.client.put(
  110. url, {"name": "New query", "projects": self.project_ids, "range": "24h"}
  111. )
  112. assert response.status_code == 404
  113. def test_put_query_with_team(self):
  114. team = self.create_team(organization=self.org, members=[self.user])
  115. project = self.create_project(organization=self.org, teams=[team])
  116. query = DiscoverSavedQuery.objects.create(
  117. organization=self.org,
  118. created_by=self.user,
  119. name="Test query",
  120. query={"fields": ["test"], "conditions": [], "limit": 10},
  121. )
  122. query.set_projects([project.id])
  123. with self.feature(self.feature_name):
  124. url = reverse(
  125. "sentry-api-0-discover-saved-query-detail",
  126. args=[self.org.slug, query.id],
  127. )
  128. response = self.client.put(url, {"name": "New query", "projects": [], "range": "24h"})
  129. assert response.status_code == 200
  130. def test_put_query_without_team(self):
  131. team = self.create_team(organization=self.org, members=[])
  132. project = self.create_project(organization=self.org, teams=[team])
  133. query = DiscoverSavedQuery.objects.create(
  134. organization=self.org,
  135. created_by=self.user,
  136. name="Test query",
  137. query={"fields": ["test"], "conditions": [], "limit": 10},
  138. )
  139. query.set_projects([project.id])
  140. with self.feature(self.feature_name):
  141. url = reverse(
  142. "sentry-api-0-discover-saved-query-detail",
  143. args=[self.org.slug, query.id],
  144. )
  145. response = self.client.put(url, {"name": "New query", "projects": [], "range": "24h"})
  146. assert response.status_code == 400
  147. assert "No Projects found, join a Team" == response.data["detail"]
  148. def test_put_org_without_access(self):
  149. with self.feature(self.feature_name):
  150. url = reverse(
  151. "sentry-api-0-discover-saved-query-detail",
  152. args=[self.org_without_access.slug, self.query_id],
  153. )
  154. response = self.client.put(
  155. url, {"name": "New query", "projects": self.project_ids, "range": "24h"}
  156. )
  157. assert response.status_code == 403, response.content
  158. def test_delete(self):
  159. with self.feature(self.feature_name):
  160. url = reverse(
  161. "sentry-api-0-discover-saved-query-detail", args=[self.org.slug, self.query_id]
  162. )
  163. response = self.client.delete(url)
  164. assert response.status_code == 204
  165. assert self.client.get(url).status_code == 404
  166. def test_delete_removes_projects(self):
  167. with self.feature(self.feature_name):
  168. url = reverse(
  169. "sentry-api-0-discover-saved-query-detail", args=[self.org.slug, self.query_id]
  170. )
  171. self.client.delete(url)
  172. projects = list(
  173. DiscoverSavedQueryProject.objects.filter(discover_saved_query=self.query_id)
  174. )
  175. assert projects == []
  176. def test_delete_query_without_access(self):
  177. with self.feature(self.feature_name):
  178. url = reverse(
  179. "sentry-api-0-discover-saved-query-detail",
  180. args=[self.org.slug, self.query_id_without_access],
  181. )
  182. response = self.client.delete(url)
  183. assert response.status_code == 404
  184. def test_delete_org_without_access(self):
  185. with self.feature(self.feature_name):
  186. url = reverse(
  187. "sentry-api-0-discover-saved-query-detail",
  188. args=[self.org_without_access.slug, self.query_id],
  189. )
  190. response = self.client.delete(url)
  191. assert response.status_code == 403, response.content
  192. class OrganizationDiscoverQueryVisitTest(APITestCase, SnubaTestCase):
  193. def setUp(self):
  194. super().setUp()
  195. self.login_as(user=self.user)
  196. self.org = self.create_organization(owner=self.user)
  197. self.org_without_access = self.create_organization()
  198. self.project_ids = [
  199. self.create_project(organization=self.org).id,
  200. self.create_project(organization=self.org).id,
  201. ]
  202. q = {"fields": ["test"], "conditions": [], "limit": 10}
  203. self.query = DiscoverSavedQuery.objects.create(
  204. organization=self.org, created_by=self.user, name="Test query", query=q
  205. )
  206. self.query.set_projects(self.project_ids)
  207. def url(self, query_id):
  208. return reverse(
  209. "sentry-api-0-discover-saved-query-visit",
  210. kwargs={"organization_slug": self.org.slug, "query_id": query_id},
  211. )
  212. def test_visit_query(self):
  213. last_visited = self.query.last_visited
  214. assert self.query.visits == 1
  215. with self.feature("organizations:discover-query"):
  216. response = self.client.post(self.url(self.query.id))
  217. assert response.status_code == 204
  218. query = DiscoverSavedQuery.objects.get(id=self.query.id)
  219. assert query.visits == 2
  220. assert query.last_visited > last_visited
  221. def test_visit_query_no_access(self):
  222. last_visited = self.query.last_visited
  223. assert self.query.visits == 1
  224. with self.feature({"organizations:discover-query": False}):
  225. response = self.client.post(self.url(self.query.id))
  226. assert response.status_code == 404
  227. query = DiscoverSavedQuery.objects.get(id=self.query.id)
  228. assert query.visits == 1
  229. assert query.last_visited == last_visited