Skip to content

Commit 4de60ea

Browse files
authored
Tests, refactoring, and bugfixes (Netflix#67)
* Refactors participant service module * Refactors Participant factory * Refactors incident factory * Switches to scoped database session * Adds participants fixture * Refactors participant create * Adds tests for participant service module * Adds participant_roles fixture * Adds tests for participant role service module * Fixes some get_all tests * Fixes skipped tests * Refactoring * Fixes Black error * Updates postgres username in list_and_test.yml workflow
1 parent 812db6f commit 4de60ea

24 files changed

Lines changed: 475 additions & 189 deletions

File tree

‎.github/workflows/list_and_test.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
postgres:
1010
image: postgres
1111
env:
12-
POSTGRES_USER: dispatch
12+
POSTGRES_USER: postgres
1313
POSTGRES_PASSWORD: dispatch
1414
POSTGRES_DB: dispatch
1515
ports:

‎src/dispatch/database.py‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import re
22
from typing import Any, List
33

4-
from sqlalchemy_searchable import search as search_db
5-
from sqlalchemy_filters import apply_pagination, apply_sort, apply_filters
6-
74
from sqlalchemy import create_engine
85
from sqlalchemy.ext.declarative import declarative_base, declared_attr
9-
from sqlalchemy.orm import Query, sessionmaker
6+
from sqlalchemy.orm import Query, sessionmaker, scoped_session
7+
from sqlalchemy_filters import apply_pagination, apply_sort, apply_filters
108
from sqlalchemy_searchable import make_searchable
9+
from sqlalchemy_searchable import search as search_db
1110
from starlette.requests import Request
1211

1312
from dispatch.common.utils.composite_search import CompositeSearch
1413

1514
from .config import SQLALCHEMY_DATABASE_URI
1615

1716
engine = create_engine(str(SQLALCHEMY_DATABASE_URI))
18-
SessionLocal = sessionmaker(bind=engine)
17+
session_factory = sessionmaker(bind=engine)
18+
SessionLocal = scoped_session(session_factory)
1919

2020

2121
def resolve_table_name(name):

‎src/dispatch/group/models.py‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ class Group(Base, ResourceMixin):
1212

1313
# Pydantic models...
1414
class GroupBase(DispatchBase):
15-
pass
15+
name: str
16+
email: str
17+
resource_id: str
18+
resource_type: str
19+
weblink: str
1620

1721

1822
class GroupCreate(GroupBase):

‎src/dispatch/incident/flows.py‎

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
)
3333
from dispatch.conversation import service as conversation_service
3434
from dispatch.conversation.models import ConversationCreate
35+
from dispatch.database import SessionLocal
3536
from dispatch.decorators import background_task
3637
from dispatch.document import service as document_service
3738
from dispatch.document.models import DocumentCreate
@@ -284,10 +285,15 @@ def update_incident_status(db_session, incident: Incident, status: str):
284285
log.debug(f"The incident has been marked as {status}.")
285286

286287

287-
def add_participant_to_conversation(conversation_id: str, participant_email: str):
288+
def add_participant_to_conversation(
289+
participant_email: str, incident_id: int, db_session: SessionLocal
290+
):
288291
"""Adds a participant to the conversation."""
292+
# we load the incident instance
293+
incident = incident_service.get(db_session=db_session, incident_id=incident_id)
294+
289295
convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
290-
convo_plugin.add(conversation_id, [participant_email])
296+
convo_plugin.add(incident.conversation.channel_id, [participant_email])
291297

292298

293299
@background_task
@@ -326,7 +332,7 @@ def incident_create_flow(*, incident_id: int, checkpoint: str = None, db_session
326332
db_session=db_session, user_email=individual.email, incident_id=incident.id
327333
)
328334

329-
log.debug(f"Added {len(individual_participants)} to incident.")
335+
log.debug(f"Added {len(individual_participants)} participants to incident id {incident.id}.")
330336

331337
# create the incident ticket
332338
ticket = create_incident_ticket(
@@ -343,7 +349,6 @@ def incident_create_flow(*, incident_id: int, checkpoint: str = None, db_session
343349

344350
# we set the incident name
345351
name = ticket["resource_id"]
346-
347352
incident.name = name
348353

349354
log.debug("Added name to incident.")
@@ -423,12 +428,11 @@ def incident_create_flow(*, incident_id: int, checkpoint: str = None, db_session
423428
weblink=conversation["weblink"],
424429
channel_id=conversation["id"],
425430
)
431+
426432
incident.conversation = conversation_service.create(
427433
db_session=db_session, conversation_in=conversation_in
428434
)
429435

430-
log.debug("Added conversation to incident.")
431-
432436
db_session.add(incident)
433437
db_session.commit()
434438

@@ -472,12 +476,12 @@ def incident_create_flow(*, incident_id: int, checkpoint: str = None, db_session
472476
for participant in incident.participants:
473477
# we announce the participant in the conversation
474478
send_incident_participant_announcement_message(
475-
participant.individual.email, incident, db_session
479+
participant.individual.email, incident.id, db_session
476480
)
477481

478482
# we send the welcome messages to the participant
479483
send_incident_welcome_participant_messages(
480-
participant.individual.email, incident, db_session
484+
participant.individual.email, incident.id, db_session
481485
)
482486

483487
log.debug("Sent incident welcome and announcement notifications.")
@@ -967,9 +971,6 @@ def incident_add_or_reactivate_participant_flow(
967971
user_email: str, incident_id: int, role: ParticipantRoleType = None, db_session=None
968972
):
969973
"""Runs the add or reactivate incident participant flow."""
970-
# we load the incident instance
971-
incident = incident_service.get(db_session=db_session, incident_id=incident_id)
972-
973974
# We get information about the individual
974975
contact_plugin = plugins.get(INCIDENT_PLUGIN_CONTACT_SLUG)
975976
individual_info = contact_plugin.get(user_email)
@@ -981,7 +982,6 @@ def incident_add_or_reactivate_participant_flow(
981982
if participant:
982983
if participant.is_active:
983984
log.debug(f"{individual_info['fullname']} is already an active participant.")
984-
return
985985
else:
986986
# we reactivate the participant
987987
reactivated = participant_flows.reactivate_participant(
@@ -990,31 +990,31 @@ def incident_add_or_reactivate_participant_flow(
990990

991991
if reactivated:
992992
# we add the participant to the conversation
993-
add_participant_to_conversation(incident.conversation.channel_id, user_email)
993+
add_participant_to_conversation(user_email, incident_id, db_session)
994994

995995
# we announce the participant in the conversation
996-
send_incident_participant_announcement_message(user_email, incident, db_session)
996+
send_incident_participant_announcement_message(user_email, incident_id, db_session)
997997

998998
# we send the welcome messages to the participant
999-
send_incident_welcome_participant_messages(user_email, incident, db_session)
1000-
1001-
return
999+
send_incident_welcome_participant_messages(user_email, incident_id, db_session)
10021000
else:
10031001
# we add the participant to the incident
1004-
added = participant_flows.add_participant(user_email, incident_id, db_session, role=role)
1002+
participant = participant_flows.add_participant(
1003+
user_email, incident_id, db_session, role=role
1004+
)
10051005

1006-
if added:
1006+
if participant:
10071007
# we add the participant to the tactical group
10081008
add_participant_to_tactical_group(user_email, incident_id)
10091009

10101010
# we add the participant to the conversation
1011-
add_participant_to_conversation(incident.conversation.channel_id, user_email)
1011+
add_participant_to_conversation(user_email, incident_id, db_session)
10121012

10131013
# we announce the participant in the conversation
1014-
send_incident_participant_announcement_message(user_email, incident, db_session)
1014+
send_incident_participant_announcement_message(user_email, incident_id, db_session)
10151015

10161016
# we send the welcome messages to the participant
1017-
send_incident_welcome_participant_messages(user_email, incident, db_session)
1017+
send_incident_welcome_participant_messages(user_email, incident_id, db_session)
10181018

10191019

10201020
@background_task
@@ -1025,13 +1025,13 @@ def incident_remove_participant_flow(user_email: str, incident_id: int, db_sessi
10251025

10261026
if user_email == incident.commander.email:
10271027
# we add the incident commander to the conversation again
1028-
add_participant_to_conversation(incident.conversation.channel_id, user_email)
1028+
add_participant_to_conversation(user_email, incident_id, db_session)
10291029

10301030
# we send a notification to the channel
1031-
send_incident_commander_readded_notification(incident)
1031+
send_incident_commander_readded_notification(incident_id, db_session)
10321032

10331033
log.debug(
1034-
f"Incident Commander {incident.commander.name} has been re-added to conversation {incident.conversation.channel_id}."
1034+
f"Incident Commander with email {user_email} has been re-added to the incident conversation."
10351035
)
10361036
else:
10371037
# we remove the participant from the incident

‎src/dispatch/incident/messaging.py‎

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
MessageType,
3030
)
3131
from dispatch.document.service import get_by_incident_id_and_resource_type as get_document
32+
from dispatch.incident import service as incident_service
3233
from dispatch.incident.models import Incident
3334
from dispatch.participant import service as participant_service
3435
from dispatch.participant_role import service as participant_role_service
@@ -39,20 +40,21 @@
3940

4041

4142
def send_welcome_ephemeral_message_to_participant(
42-
participant_email: str, incident: Incident, db_session: SessionLocal
43+
participant_email: str, incident_id: int, db_session: SessionLocal
4344
):
4445
"""Sends an ephemeral message to the participant."""
46+
# we load the incident instance
47+
incident = incident_service.get(db_session=db_session, incident_id=incident_id)
48+
4549
# we get the incident documents
4650
incident_document = get_document(
4751
db_session=db_session,
48-
incident_id=incident.id,
52+
incident_id=incident_id,
4953
resource_type=INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
5054
)
5155

5256
incident_faq = get_document(
53-
db_session=db_session,
54-
incident_id=incident.id,
55-
resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT,
57+
db_session=db_session, incident_id=incident_id, resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT
5658
)
5759

5860
# we send the ephemeral message
@@ -79,20 +81,21 @@ def send_welcome_ephemeral_message_to_participant(
7981

8082

8183
def send_welcome_email_to_participant(
82-
participant_email: str, incident: Incident, db_session: SessionLocal
84+
participant_email: str, incident_id: int, db_session: SessionLocal
8385
):
8486
"""Sends a welcome email to the participant."""
87+
# we load the incident instance
88+
incident = incident_service.get(db_session=db_session, incident_id=incident_id)
89+
8590
# we get the incident documents
8691
incident_document = get_document(
8792
db_session=db_session,
88-
incident_id=incident.id,
93+
incident_id=incident_id,
8994
resource_type=INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT,
9095
)
9196

9297
incident_faq = get_document(
93-
db_session=db_session,
94-
incident_id=incident.id,
95-
resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT,
98+
db_session=db_session, incident_id=incident_id, resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT
9699
)
97100

98101
email_plugin = plugins.get(INCIDENT_PLUGIN_EMAIL_SLUG)
@@ -116,14 +119,14 @@ def send_welcome_email_to_participant(
116119

117120

118121
def send_incident_welcome_participant_messages(
119-
participant_email: str, incident: Incident, db_session: SessionLocal
122+
participant_email: str, incident_id: int, db_session: SessionLocal
120123
):
121124
"""Sends welcome messages to the participant."""
122125
# we send the welcome ephemeral message
123-
send_welcome_ephemeral_message_to_participant(participant_email, incident, db_session)
126+
send_welcome_ephemeral_message_to_participant(participant_email, incident_id, db_session)
124127

125128
# we send the welcome email
126-
send_welcome_email_to_participant(participant_email, incident, db_session)
129+
send_welcome_email_to_participant(participant_email, incident_id, db_session)
127130

128131
log.debug(f"Welcome participant messages sent {participant_email}.")
129132

@@ -142,9 +145,7 @@ def send_incident_status_notifications(incident: Incident, db_session: SessionLo
142145
)
143146

144147
incident_faq = get_document(
145-
db_session=db_session,
146-
incident_id=incident.id,
147-
resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT,
148+
db_session=db_session, incident_id=incident.id, resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT
148149
)
149150

150151
# we send status notifications to conversations
@@ -268,15 +269,18 @@ def send_incident_change_notifications(
268269

269270

270271
def send_incident_participant_announcement_message(
271-
participant_email: str, incident: Incident, db_session=SessionLocal
272+
participant_email: str, incident_id: int, db_session=SessionLocal
272273
):
273274
"""Announces a participant in the conversation."""
274275
notification_text = "New Incident Participant"
275276
notification_type = MessageType.incident_notification
276277
notification_template = []
277278

279+
# we load the incident instance
280+
incident = incident_service.get(db_session=db_session, incident_id=incident_id)
281+
278282
participant = participant_service.get_by_incident_id_and_email(
279-
db_session=db_session, incident_id=incident.id, email=participant_email
283+
db_session=db_session, incident_id=incident_id, email=participant_email
280284
)
281285

282286
contact_plugin = plugins.get(INCIDENT_PLUGIN_CONTACT_SLUG)
@@ -291,7 +295,7 @@ def send_incident_participant_announcement_message(
291295
convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
292296
participant_avatar_url = convo_plugin.get_participant_avatar_url(participant_email)
293297

294-
participant_active_roles = participant_role_service.get_active_roles(
298+
participant_active_roles = participant_role_service.get_all_active_roles(
295299
db_session=db_session, participant_id=participant.id
296300
)
297301
participant_roles = []
@@ -330,11 +334,14 @@ def send_incident_participant_announcement_message(
330334
log.debug(f"Incident participant announcement message sent.")
331335

332336

333-
def send_incident_commander_readded_notification(incident: Incident):
337+
def send_incident_commander_readded_notification(incident_id: int, db_session: SessionLocal):
334338
"""Sends a notification about re-adding the incident commander to the conversation."""
335339
notification_text = "Incident Notification"
336340
notification_type = MessageType.incident_notification
337341

342+
# we load the incident instance
343+
incident = incident_service.get(db_session=db_session, incident_id=incident_id)
344+
338345
convo_plugin = plugins.get(INCIDENT_PLUGIN_CONVERSATION_SLUG)
339346
convo_plugin.send(
340347
incident.conversation.channel_id,
@@ -451,9 +458,7 @@ def send_incident_resources_ephemeral_message_to_participant(
451458
)
452459

453460
incident_faq = get_document(
454-
db_session=db_session,
455-
incident_id=incident.id,
456-
resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT,
461+
db_session=db_session, incident_id=incident.id, resource_type=INCIDENT_RESOURCE_FAQ_DOCUMENT
457462
)
458463

459464
# we send the ephemeral message

0 commit comments

Comments
 (0)