-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Update incidents-list (/api/incidents) * Update incidents with PUT /incidents/<pk> * Tidy up tests * Update incident lead via API * /incidents list should be sorted by report date * Return primary key in incident response * Change deprecated parameter * Add docs for incidents endpoint
- Loading branch information
Showing
11 changed files
with
285 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import pytest | ||
from rest_framework.test import APIRequestFactory | ||
|
||
from tests.factories import UserFactory, ExternalUserFactory | ||
|
||
@pytest.fixture | ||
def arf(): | ||
return APIRequestFactory() | ||
|
||
|
||
@pytest.fixture() | ||
def api_user(transactional_db): | ||
e = ExternalUserFactory() | ||
return e.owner |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
from django.urls import reverse | ||
from faker import Faker | ||
from rest_framework.test import force_authenticate | ||
import json | ||
import pytest | ||
import random | ||
|
||
from response.models import Incident, ExternalUser | ||
from response import serializers | ||
from response.core.views import IncidentViewSet | ||
from tests.factories import IncidentFactory | ||
|
||
faker = Faker() | ||
|
||
|
||
def test_list_incidents(arf, api_user): | ||
persisted_incidents = IncidentFactory.create_batch(5) | ||
|
||
req = arf.get(reverse("incident-list")) | ||
force_authenticate(req, user=api_user) | ||
response = IncidentViewSet.as_view({"get": "list"})(req) | ||
|
||
assert response.status_code == 200, "Got non-200 response from API" | ||
content = json.loads(response.rendered_content) | ||
|
||
assert "results" in content, "Response didn't have results key" | ||
incidents = content["results"] | ||
assert len(incidents) == len( | ||
persisted_incidents | ||
), "Didn't get expected number of incidents back" | ||
|
||
for idx, incident in enumerate(incidents): | ||
assert incident["report_time"] | ||
|
||
# incidents should be in order of newest to oldest | ||
if idx != len(incidents) - 1: | ||
assert ( | ||
incident["report_time"] >= incidents[idx + 1]["report_time"] | ||
), "Incidents are not in order of newest to oldest by report time" | ||
|
||
assert "end_time" in incident # end_time can be null for open incidents | ||
assert incident["impact"] | ||
assert incident["report"] | ||
assert incident["start_time"] | ||
assert incident["summary"] | ||
assert incident["severity"] | ||
|
||
reporter = incident["reporter"] | ||
assert reporter["display_name"] | ||
assert reporter["external_id"] | ||
|
||
lead = incident["lead"] | ||
assert lead["display_name"] | ||
assert lead["external_id"] | ||
|
||
# TODO: verify actions are serialised inline | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"update_key,update_value", | ||
( | ||
("", ""), # no update | ||
("impact", faker.paragraph(nb_sentences=2, variable_nb_sentences=True)), | ||
("report", faker.paragraph(nb_sentences=1, variable_nb_sentences=True)), | ||
("summary", faker.paragraph(nb_sentences=3, variable_nb_sentences=True)), | ||
( | ||
"start_time", | ||
faker.date_time_between(start_date="-3d", end_date="now", tzinfo=None), | ||
), | ||
( | ||
"end_time", | ||
faker.date_time_between(start_date="-3d", end_date="now", tzinfo=None), | ||
), | ||
("severity", str(random.randint(1, 4))), | ||
), | ||
) | ||
def test_update_incident(arf, api_user, update_key, update_value): | ||
""" | ||
Tests that we can PUT /incidents/<pk> and mutate fields that get saved to | ||
the DB. | ||
""" | ||
persisted_incidents = IncidentFactory.create_batch(5) | ||
|
||
incident = persisted_incidents[0] | ||
serializer = serializers.IncidentSerializer(incident) | ||
serialized = serializer.data | ||
|
||
updated = serialized | ||
del updated["reporter"] # can't update reporter | ||
if update_key: | ||
updated[update_key] = update_value | ||
|
||
req = arf.put( | ||
reverse("incident-detail", kwargs={"pk": incident.pk}), updated, format="json" | ||
) | ||
force_authenticate(req, user=api_user) | ||
|
||
response = IncidentViewSet.as_view({"put": "update"})(req, pk=incident.pk) | ||
print(response.rendered_content) | ||
assert response.status_code == 200, "Got non-200 response from API" | ||
|
||
if update_key: | ||
new_incident = Incident.objects.get(pk=incident.pk) | ||
assert ( | ||
getattr(new_incident, update_key) == update_value | ||
), "Updated value wasn't persisted to the DB" | ||
|
||
|
||
def test_update_incident_lead(arf, api_user): | ||
""" | ||
Tests that we can update the incident lead by name | ||
""" | ||
persisted_incidents = IncidentFactory.create_batch(5) | ||
|
||
incident = persisted_incidents[0] | ||
serializer = serializers.IncidentSerializer(incident) | ||
updated = serializer.data | ||
|
||
users = ExternalUser.objects.all() | ||
|
||
new_lead = users[0] | ||
while new_lead == incident.lead: | ||
new_lead = random.choices(users) | ||
|
||
updated["lead"] = serializers.ExternalUserSerializer(new_lead).data | ||
del updated["reporter"] # can't update reporter | ||
|
||
req = arf.put( | ||
reverse("incident-detail", kwargs={"pk": incident.pk}), updated, format="json" | ||
) | ||
force_authenticate(req, user=api_user) | ||
|
||
response = IncidentViewSet.as_view({"put": "update"})(req, pk=incident.pk) | ||
print(response.rendered_content) | ||
assert response.status_code == 200, "Got non-200 response from API" | ||
|
||
new_incident = Incident.objects.get(pk=incident.pk) | ||
assert new_incident.lead == new_lead |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from .incident import * | ||
from .user import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import random | ||
|
||
from django.db.models.signals import post_save | ||
import factory | ||
from faker import Factory | ||
|
||
from response.core.models import Incident, ExternalUser | ||
|
||
faker = Factory.create() | ||
|
||
|
||
@factory.django.mute_signals(post_save) | ||
class IncidentFactory(factory.DjangoModelFactory): | ||
class Meta: | ||
model = Incident | ||
|
||
impact = factory.LazyFunction( | ||
lambda: faker.paragraph(nb_sentences=1, variable_nb_sentences=True) | ||
) | ||
report = factory.LazyFunction( | ||
lambda: faker.paragraph(nb_sentences=3, variable_nb_sentences=True) | ||
) | ||
report_time = factory.LazyFunction( | ||
lambda: faker.date_time_between(start_date="-3d", end_date="now", tzinfo=None) | ||
) | ||
|
||
reporter = factory.SubFactory("tests.factories.ExternalUserFactory") | ||
lead = factory.SubFactory("tests.factories.ExternalUserFactory") | ||
|
||
start_time = factory.LazyFunction( | ||
lambda: faker.date_time_between(start_date="-3d", end_date="now", tzinfo=None) | ||
) | ||
|
||
if random.random() > 0.5: | ||
end_time = factory.LazyAttribute( | ||
lambda a: faker.date_time_between(start_date=a.start_time, end_date="now") | ||
) | ||
|
||
severity = factory.LazyFunction(lambda: str(random.randint(1, 4))) | ||
summary = factory.LazyFunction( | ||
lambda: faker.paragraph(nb_sentences=3, variable_nb_sentences=True) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
from django.contrib.auth.models import User | ||
import factory | ||
from faker import Factory | ||
|
||
|
||
from response.core.models import ExternalUser | ||
|
||
faker = Factory.create() | ||
|
||
|
||
class UserFactory(factory.DjangoModelFactory): | ||
class Meta: | ||
model = User | ||
|
||
username = factory.LazyFunction(faker.user_name) | ||
password = factory.LazyFunction(faker.password) | ||
|
||
|
||
class ExternalUserFactory(factory.DjangoModelFactory): | ||
class Meta: | ||
model = ExternalUser | ||
|
||
app_id = "slack" | ||
display_name = factory.LazyFunction(faker.name) | ||
external_id = factory.LazyFunction(lambda: "U" + faker.word()) | ||
owner = factory.SubFactory("tests.factories.UserFactory") |