|
@@ -1,8 +1,5 @@
|
|
|
-import functools
|
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
|
|
-from django.urls import reverse
|
|
|
-
|
|
|
from sentry.constants import DataCategory
|
|
|
from sentry.testutils.cases import APITestCase, OutcomesSnubaTest
|
|
|
from sentry.testutils.helpers.datetime import freeze_time
|
|
@@ -12,6 +9,8 @@ from sentry.utils.outcomes import Outcome
|
|
|
|
|
|
@region_silo_test
|
|
|
class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
+ endpoint = "sentry-api-0-organization-stats-v2"
|
|
|
+
|
|
|
def setUp(self):
|
|
|
super().setUp()
|
|
|
self.now = datetime(2021, 3, 14, 12, 27, 28, tzinfo=timezone.utc)
|
|
@@ -64,7 +63,6 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"quantity": 1,
|
|
|
}
|
|
|
)
|
|
|
-
|
|
|
self.store_outcomes(
|
|
|
{
|
|
|
"org_id": self.org.id,
|
|
@@ -88,23 +86,20 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
}
|
|
|
)
|
|
|
|
|
|
- def do_request(self, query, user=None, org=None):
|
|
|
+ def do_request(self, query, user=None, org=None, status_code=200):
|
|
|
self.login_as(user=user or self.user)
|
|
|
- url = reverse(
|
|
|
- "sentry-api-0-organization-stats-v2",
|
|
|
- kwargs={"organization_slug": (org or self.organization).slug},
|
|
|
- )
|
|
|
- return self.client.get(url, query, format="json")
|
|
|
+ org_slug = (org or self.organization).slug
|
|
|
+ if status_code >= 400:
|
|
|
+ return self.get_error_response(org_slug, **query, status_code=status_code)
|
|
|
+ return self.get_success_response(org_slug, **query, status_code=status_code)
|
|
|
|
|
|
def test_empty_request(self):
|
|
|
- response = self.do_request({})
|
|
|
- assert response.status_code == 400, response.content
|
|
|
+ response = self.do_request({}, status_code=400)
|
|
|
assert result_sorted(response.data) == {"detail": 'At least one "field" is required.'}
|
|
|
|
|
|
def test_inaccessible_project(self):
|
|
|
- response = self.do_request({"project": [self.project3.id]})
|
|
|
+ response = self.do_request({"project": [self.project3.id]}, status_code=403)
|
|
|
|
|
|
- assert response.status_code == 403, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"detail": "You do not have permission to perform this action."
|
|
|
}
|
|
@@ -120,9 +115,9 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
},
|
|
|
user=self.user2,
|
|
|
org=self.org3,
|
|
|
+ status_code=400,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 400, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"detail": "No projects available",
|
|
|
}
|
|
@@ -133,20 +128,20 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"field": ["summ(qarntenty)"],
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "1d",
|
|
|
- }
|
|
|
+ },
|
|
|
+ status_code=400,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 400, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"detail": 'Invalid field: "summ(qarntenty)"',
|
|
|
}
|
|
|
|
|
|
def test_no_end_param(self):
|
|
|
response = self.do_request(
|
|
|
- {"field": ["sum(quantity)"], "interval": "1d", "start": "2021-03-14T00:00:00Z"}
|
|
|
+ {"field": ["sum(quantity)"], "interval": "1d", "start": "2021-03-14T00:00:00Z"},
|
|
|
+ status_code=400,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 400, response.content
|
|
|
assert result_sorted(response.data) == {"detail": "start and end are both required"}
|
|
|
|
|
|
@freeze_time(datetime(2021, 3, 14, 12, 27, 28, tzinfo=timezone.utc))
|
|
@@ -158,9 +153,10 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"category": ["error"],
|
|
|
"start": "2021-03-14T15:30:00",
|
|
|
"end": "2021-03-14T16:30:00",
|
|
|
- }
|
|
|
+ },
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
- assert response.status_code == 200, response.content
|
|
|
+
|
|
|
assert result_sorted(response.data) == {
|
|
|
"intervals": [
|
|
|
"2021-03-14T12:00:00Z",
|
|
@@ -187,10 +183,10 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "1d",
|
|
|
"category": "scoobydoo",
|
|
|
- }
|
|
|
+ },
|
|
|
+ status_code=400,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 400, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"detail": 'Invalid category: "scoobydoo"',
|
|
|
}
|
|
@@ -203,10 +199,10 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"interval": "1d",
|
|
|
"category": "error",
|
|
|
"outcome": "scoobydoo",
|
|
|
- }
|
|
|
+ },
|
|
|
+ status_code=400,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 400, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"detail": 'Invalid outcome: "scoobydoo"',
|
|
|
}
|
|
@@ -218,27 +214,22 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"groupBy": ["category_"],
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "1d",
|
|
|
- }
|
|
|
+ },
|
|
|
+ status_code=400,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 400, response.content
|
|
|
assert result_sorted(response.data) == {"detail": 'Invalid groupBy: "category_"'}
|
|
|
|
|
|
def test_resolution_invalid(self):
|
|
|
- self.login_as(user=self.user)
|
|
|
- make_request = functools.partial(
|
|
|
- self.client.get,
|
|
|
- reverse("sentry-api-0-organization-stats-v2", args=[self.org.slug]),
|
|
|
- )
|
|
|
- response = make_request(
|
|
|
+ self.do_request(
|
|
|
{
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "bad_interval",
|
|
|
- }
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=400,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 400, response.content
|
|
|
-
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
def test_attachment_filter_only(self):
|
|
|
response = self.do_request(
|
|
@@ -248,10 +239,10 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"interval": "1d",
|
|
|
"field": ["sum(quantity)"],
|
|
|
"category": ["error", "attachment"],
|
|
|
- }
|
|
|
+ },
|
|
|
+ status_code=400,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 400, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"detail": "if filtering by attachment no other category may be present"
|
|
|
}
|
|
@@ -265,10 +256,10 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "1d",
|
|
|
"field": ["sum(quantity)"],
|
|
|
- }
|
|
|
+ },
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 200, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"intervals": ["2021-03-13T00:00:00Z", "2021-03-14T00:00:00Z"],
|
|
|
"groups": [
|
|
@@ -285,10 +276,10 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"interval": "6h",
|
|
|
"field": ["sum(quantity)"],
|
|
|
"category": ["error"],
|
|
|
- }
|
|
|
+ },
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 200, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"intervals": [
|
|
|
"2021-03-13T12:00:00Z",
|
|
@@ -319,9 +310,9 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"category": ["error", "transaction"],
|
|
|
},
|
|
|
user=self.user2,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 200, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"start": "2021-03-13T00:00:00Z",
|
|
|
"end": "2021-03-15T00:00:00Z",
|
|
@@ -342,9 +333,9 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"category": ["error", "transaction"],
|
|
|
},
|
|
|
user=self.user2,
|
|
|
+ status_code=403,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 403
|
|
|
response = self.do_request(
|
|
|
{
|
|
|
"project": [-1],
|
|
@@ -355,9 +346,9 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"groupBy": ["project"],
|
|
|
},
|
|
|
user=self.user2,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 200
|
|
|
assert result_sorted(response.data) == {
|
|
|
"start": "2021-03-13T00:00:00Z",
|
|
|
"end": "2021-03-15T00:00:00Z",
|
|
@@ -379,9 +370,9 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
},
|
|
|
org=self.organization,
|
|
|
user=user,
|
|
|
+ status_code=403,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 403, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"detail": "You do not have permission to perform this action."
|
|
|
}
|
|
@@ -397,9 +388,9 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
},
|
|
|
org=self.organization,
|
|
|
user=user,
|
|
|
+ status_code=403,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 403, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"detail": "You do not have permission to perform this action."
|
|
|
}
|
|
@@ -418,9 +409,9 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"groupBy": ["project"],
|
|
|
},
|
|
|
user=self.user2,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 200
|
|
|
assert result_sorted(response.data) == {
|
|
|
"start": "2021-03-13T00:00:00Z",
|
|
|
"end": "2021-03-15T00:00:00Z",
|
|
@@ -438,19 +429,17 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
def test_org_simple(self):
|
|
|
- make_request = functools.partial(
|
|
|
- self.client.get, reverse("sentry-api-0-organization-stats-v2", args=[self.org.slug])
|
|
|
- )
|
|
|
- response = make_request(
|
|
|
+ response = self.do_request(
|
|
|
{
|
|
|
"statsPeriod": "2d",
|
|
|
"interval": "1d",
|
|
|
"field": ["sum(quantity)"],
|
|
|
"groupBy": ["category", "outcome", "reason"],
|
|
|
- }
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 200, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"start": "2021-03-12T00:00:00Z",
|
|
|
"end": "2021-03-15T00:00:00Z",
|
|
@@ -482,21 +471,73 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
],
|
|
|
}
|
|
|
|
|
|
+ @freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
+ def test_staff_org_individual_category(self):
|
|
|
+ staff_user = self.create_user(is_staff=True, is_superuser=True)
|
|
|
+ self.login_as(user=staff_user, superuser=True)
|
|
|
+
|
|
|
+ category_group_mapping = {
|
|
|
+ "attachment": {
|
|
|
+ "by": {
|
|
|
+ "outcome": "rate_limited",
|
|
|
+ "reason": "spike_protection",
|
|
|
+ },
|
|
|
+ "totals": {"sum(quantity)": 1024},
|
|
|
+ "series": {"sum(quantity)": [0, 0, 1024]},
|
|
|
+ },
|
|
|
+ "error": {
|
|
|
+ "by": {"outcome": "accepted", "reason": "none"},
|
|
|
+ "totals": {"sum(quantity)": 6},
|
|
|
+ "series": {"sum(quantity)": [0, 0, 6]},
|
|
|
+ },
|
|
|
+ "transaction": {
|
|
|
+ "by": {
|
|
|
+ "reason": "spike_protection",
|
|
|
+ "outcome": "rate_limited",
|
|
|
+ },
|
|
|
+ "totals": {"sum(quantity)": 1},
|
|
|
+ "series": {"sum(quantity)": [0, 0, 1]},
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ # Test each category individually
|
|
|
+ for category in ["attachment", "error", "transaction"]:
|
|
|
+ response = self.do_request(
|
|
|
+ {
|
|
|
+ "category": category,
|
|
|
+ "statsPeriod": "2d",
|
|
|
+ "interval": "1d",
|
|
|
+ "field": ["sum(quantity)"],
|
|
|
+ "groupBy": ["outcome", "reason"],
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
+ )
|
|
|
+
|
|
|
+ assert result_sorted(response.data) == {
|
|
|
+ "start": "2021-03-12T00:00:00Z",
|
|
|
+ "end": "2021-03-15T00:00:00Z",
|
|
|
+ "intervals": [
|
|
|
+ "2021-03-12T00:00:00Z",
|
|
|
+ "2021-03-13T00:00:00Z",
|
|
|
+ "2021-03-14T00:00:00Z",
|
|
|
+ ],
|
|
|
+ "groups": [category_group_mapping[category]],
|
|
|
+ }
|
|
|
+
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
def test_org_multiple_fields(self):
|
|
|
- make_request = functools.partial(
|
|
|
- self.client.get, reverse("sentry-api-0-organization-stats-v2", args=[self.org.slug])
|
|
|
- )
|
|
|
- response = make_request(
|
|
|
+ response = self.do_request(
|
|
|
{
|
|
|
"statsPeriod": "2d",
|
|
|
"interval": "1d",
|
|
|
"field": ["sum(quantity)", "sum(times_seen)"],
|
|
|
"groupBy": ["category", "outcome", "reason"],
|
|
|
- }
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 200, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"start": "2021-03-12T00:00:00Z",
|
|
|
"end": "2021-03-15T00:00:00Z",
|
|
@@ -530,21 +571,18 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
def test_org_group_by_project(self):
|
|
|
- make_request = functools.partial(
|
|
|
- self.client.get,
|
|
|
- reverse("sentry-api-0-organization-stats-v2", args=[self.org.slug]),
|
|
|
- )
|
|
|
- response = make_request(
|
|
|
+ response = self.do_request(
|
|
|
{
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "1d",
|
|
|
"field": ["sum(times_seen)"],
|
|
|
"groupBy": ["project"],
|
|
|
"category": ["error", "transaction"],
|
|
|
- }
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 200, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"start": "2021-03-13T00:00:00Z",
|
|
|
"end": "2021-03-15T00:00:00Z",
|
|
@@ -562,27 +600,26 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
def test_org_project_totals_per_project(self):
|
|
|
- make_request = functools.partial(
|
|
|
- self.client.get,
|
|
|
- reverse("sentry-api-0-organization-stats-v2", args=[self.org.slug]),
|
|
|
- )
|
|
|
- response_per_group = make_request(
|
|
|
+ response_per_group = self.do_request(
|
|
|
{
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "1h",
|
|
|
"field": ["sum(times_seen)"],
|
|
|
"groupBy": ["project"],
|
|
|
"category": ["error", "transaction"],
|
|
|
- }
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
-
|
|
|
- response_total = make_request(
|
|
|
+ response_total = self.do_request(
|
|
|
{
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "1h",
|
|
|
"field": ["sum(times_seen)"],
|
|
|
"category": ["error", "transaction"],
|
|
|
- }
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
|
|
|
per_group_total = 0
|
|
@@ -595,21 +632,18 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
def test_project_filter(self):
|
|
|
- make_request = functools.partial(
|
|
|
- self.client.get,
|
|
|
- reverse("sentry-api-0-organization-stats-v2", args=[self.org.slug]),
|
|
|
- )
|
|
|
- response = make_request(
|
|
|
+ response = self.do_request(
|
|
|
{
|
|
|
"project": self.project.id,
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "1d",
|
|
|
"field": ["sum(quantity)"],
|
|
|
"category": ["error", "transaction"],
|
|
|
- }
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 200, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"start": "2021-03-13T00:00:00Z",
|
|
|
"end": "2021-03-15T00:00:00Z",
|
|
@@ -620,22 +654,80 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
}
|
|
|
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
- def test_reason_filter(self):
|
|
|
- make_request = functools.partial(
|
|
|
- self.client.get,
|
|
|
- reverse("sentry-api-0-organization-stats-v2", args=[self.org.slug]),
|
|
|
+ def test_staff_project_filter(self):
|
|
|
+ staff_user = self.create_user(is_staff=True, is_superuser=True)
|
|
|
+ self.login_as(user=staff_user, superuser=True)
|
|
|
+
|
|
|
+ shared_query_params = {
|
|
|
+ "field": "sum(quantity)",
|
|
|
+ "groupBy": ["outcome", "reason"],
|
|
|
+ "interval": "1d",
|
|
|
+ "statsPeriod": "1d",
|
|
|
+ }
|
|
|
+ shared_data = {
|
|
|
+ "start": "2021-03-13T00:00:00Z",
|
|
|
+ "end": "2021-03-15T00:00:00Z",
|
|
|
+ "intervals": ["2021-03-13T00:00:00Z", "2021-03-14T00:00:00Z"],
|
|
|
+ }
|
|
|
+
|
|
|
+ # Test error category
|
|
|
+ response = self.do_request(
|
|
|
+ {
|
|
|
+ **shared_query_params,
|
|
|
+ "category": "error",
|
|
|
+ "project": self.project.id,
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
- response = make_request(
|
|
|
+
|
|
|
+ assert result_sorted(response.data) == {
|
|
|
+ **shared_data,
|
|
|
+ "groups": [
|
|
|
+ {
|
|
|
+ "by": {"outcome": "accepted", "reason": "none"},
|
|
|
+ "totals": {"sum(quantity)": 6},
|
|
|
+ "series": {"sum(quantity)": [0, 6]},
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ }
|
|
|
+
|
|
|
+ # Test transaction category
|
|
|
+ response = self.do_request(
|
|
|
+ {
|
|
|
+ **shared_query_params,
|
|
|
+ "category": "transaction",
|
|
|
+ "project": self.project2.id,
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
+ )
|
|
|
+
|
|
|
+ assert result_sorted(response.data) == {
|
|
|
+ **shared_data,
|
|
|
+ "groups": [
|
|
|
+ {
|
|
|
+ "by": {"outcome": "rate_limited", "reason": "spike_protection"},
|
|
|
+ "totals": {"sum(quantity)": 1},
|
|
|
+ "series": {"sum(quantity)": [0, 1]},
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }
|
|
|
+
|
|
|
+ @freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
+ def test_reason_filter(self):
|
|
|
+ response = self.do_request(
|
|
|
{
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "1d",
|
|
|
"field": ["sum(times_seen)"],
|
|
|
"reason": ["spike_protection"],
|
|
|
"groupBy": ["category"],
|
|
|
- }
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
|
|
|
- assert response.status_code == 200, response.content
|
|
|
assert result_sorted(response.data) == {
|
|
|
"start": "2021-03-13T00:00:00Z",
|
|
|
"end": "2021-03-15T00:00:00Z",
|
|
@@ -656,20 +748,18 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
def test_outcome_filter(self):
|
|
|
- make_request = functools.partial(
|
|
|
- self.client.get,
|
|
|
- reverse("sentry-api-0-organization-stats-v2", args=[self.org.slug]),
|
|
|
- )
|
|
|
- response = make_request(
|
|
|
+ response = self.do_request(
|
|
|
{
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "1d",
|
|
|
"field": ["sum(quantity)"],
|
|
|
"outcome": "accepted",
|
|
|
"category": ["error", "transaction"],
|
|
|
- }
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
- assert response.status_code == 200, response.content
|
|
|
+
|
|
|
assert result_sorted(response.data) == {
|
|
|
"start": "2021-03-13T00:00:00Z",
|
|
|
"end": "2021-03-15T00:00:00Z",
|
|
@@ -681,19 +771,17 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
def test_category_filter(self):
|
|
|
- make_request = functools.partial(
|
|
|
- self.client.get,
|
|
|
- reverse("sentry-api-0-organization-stats-v2", args=[self.org.slug]),
|
|
|
- )
|
|
|
- response = make_request(
|
|
|
+ response = self.do_request(
|
|
|
{
|
|
|
"statsPeriod": "1d",
|
|
|
"interval": "1d",
|
|
|
"field": ["sum(quantity)"],
|
|
|
"category": "error",
|
|
|
- }
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
- assert response.status_code == 200, response.content
|
|
|
+
|
|
|
assert result_sorted(response.data) == {
|
|
|
"start": "2021-03-13T00:00:00Z",
|
|
|
"end": "2021-03-15T00:00:00Z",
|
|
@@ -705,19 +793,17 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
def test_minute_interval_sum_quantity(self):
|
|
|
- make_request = functools.partial(
|
|
|
- self.client.get,
|
|
|
- reverse("sentry-api-0-organization-stats-v2", args=[self.org.slug]),
|
|
|
- )
|
|
|
- response = make_request(
|
|
|
+ response = self.do_request(
|
|
|
{
|
|
|
"statsPeriod": "1h",
|
|
|
"interval": "15m",
|
|
|
"field": ["sum(quantity)"],
|
|
|
"category": "error",
|
|
|
- }
|
|
|
+ },
|
|
|
+ org=self.org,
|
|
|
+ status_code=200,
|
|
|
)
|
|
|
- assert response.status_code == 200, response.content
|
|
|
+
|
|
|
assert result_sorted(response.data) == {
|
|
|
"start": "2021-03-14T11:15:00Z",
|
|
|
"end": "2021-03-14T12:30:00Z",
|
|
@@ -739,11 +825,7 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
def test_minute_interval_sum_times_seen(self):
|
|
|
- make_request = functools.partial(
|
|
|
- self.client.get,
|
|
|
- reverse("sentry-api-0-organization-stats-v2", args=[self.org.slug]),
|
|
|
- )
|
|
|
- response = make_request(
|
|
|
+ response = self.do_request(
|
|
|
{
|
|
|
"statsPeriod": "1h",
|
|
|
"interval": "15m",
|