Skip to content

Commit

Permalink
Adding google hangout link to the meeting invite (#492)
Browse files Browse the repository at this point in the history
* Adding google hangout link to the meeting invite

* Removing comments that are not needed
  • Loading branch information
sylviamclaughlin authored May 7, 2024
1 parent d3363c7 commit 92f8309
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 4 deletions.
9 changes: 8 additions & 1 deletion app/integrations/google_workspace/google_calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
execute_google_api_call,
DEFAULT_DELEGATED_ADMIN_EMAIL,
)
from integrations.utils.api import convert_string_to_camel_case
from integrations.utils.api import convert_string_to_camel_case, generate_unique_id

# Get the email for the SRE bot
SRE_BOT_EMAIL = os.environ.get("SRE_BOT_EMAIL")
Expand Down Expand Up @@ -71,6 +71,12 @@ def insert_event(start, end, emails, title, incident_document, **kwargs):
"attendees": [{"email": email.strip()} for email in emails],
"summary": title,
"guestsCanModify": True,
"conferenceData": {
"createRequest": {
"requestId": generate_unique_id(),
"conferenceSolutionKey": {"type": "hangoutsMeet"},
}
},
}
if incident_document:
body["attachments"] = [
Expand Down Expand Up @@ -103,6 +109,7 @@ def insert_event(start, end, emails, title, incident_document, **kwargs):
body=body,
calendarId="primary",
supportsAttachments=True,
conferenceDataVersion=1,
)
return result.get("htmlLink")

Expand Down
17 changes: 17 additions & 0 deletions app/integrations/utils/api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Utilities for API integrations."""
import re
import string
import random


def convert_string_to_camel_case(snake_str):
Expand Down Expand Up @@ -67,3 +69,18 @@ def convert_kwargs_to_pascal_case(kwargs):
return [convert_kwargs_to_pascal_case(i) for i in kwargs]
else:
return kwargs


def generate_unique_id():
# Define the characters to use in the ID
chars = string.ascii_lowercase + string.digits

# Function to generate a segment of three characters
def generate_segment():
return "".join(random.choices(chars, k=3))

# Generate the three segments and join them with hyphens
segments = [generate_segment() for _ in range(3)]
unique_id = "-".join(segments)

return unique_id
97 changes: 94 additions & 3 deletions app/tests/integrations/google_workspace/test_google_calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,15 @@ def test_get_freebusy_returns_object(mock_execute):
@patch("os.environ.get", return_value="test_email")
@patch("integrations.google_workspace.google_calendar.execute_google_api_call")
@patch("integrations.google_workspace.google_calendar.convert_string_to_camel_case")
@patch("integrations.google_workspace.google_calendar.generate_unique_id")
def test_insert_event_no_kwargs_no_delegated_email(
mock_convert_string_to_camel_case, mock_execute_google_api_call, mock_os_environ_get
mock_unique_id,
mock_convert_string_to_camel_case,
mock_execute_google_api_call,
mock_os_environ_get,
):
mock_execute_google_api_call.return_value = {"htmlLink": "test_link"}
mock_unique_id.return_value = "abc-123-de4"
start = datetime.now()
end = start
emails = ["[email protected]", "[email protected]"]
Expand Down Expand Up @@ -189,9 +194,16 @@ def test_insert_event_no_kwargs_no_delegated_email(
"title": "Incident Document",
}
],
"conferenceData": {
"createRequest": {
"requestId": "abc-123-de4",
"conferenceSolutionKey": {"type": "hangoutsMeet"},
}
},
},
calendarId="primary",
supportsAttachments=True,
conferenceDataVersion=1,
)
assert not mock_convert_string_to_camel_case.called
assert mock_os_environ_get.called_once_with("SRE_BOT_EMAIL")
Expand All @@ -200,10 +212,15 @@ def test_insert_event_no_kwargs_no_delegated_email(
@patch("os.environ.get", return_value="test_email")
@patch("integrations.google_workspace.google_calendar.execute_google_api_call")
@patch("integrations.google_workspace.google_calendar.convert_string_to_camel_case")
@patch("integrations.google_workspace.google_calendar.generate_unique_id")
def test_insert_event_with_kwargs(
mock_convert_string_to_camel_case, mock_execute_google_api_call, mock_os_environ_get
mock_unique_id,
mock_convert_string_to_camel_case,
mock_execute_google_api_call,
mock_os_environ_get,
):
mock_execute_google_api_call.return_value = {"htmlLink": "test_link"}
mock_unique_id.return_value = "abc-123-de4"
mock_convert_string_to_camel_case.side_effect = (
lambda x: x
) # just return the same value
Expand All @@ -224,6 +241,12 @@ def test_insert_event_with_kwargs(
"title": "Incident Document",
}
],
"conferenceData": {
"createRequest": {
"requestId": "abc-123-de4",
"conferenceSolutionKey": {"type": "hangoutsMeet"},
}
},
}
result = google_calendar.insert_event(
start, end, emails, title, document_id, **kwargs
Expand All @@ -246,6 +269,7 @@ def test_insert_event_with_kwargs(
},
calendarId="primary",
supportsAttachments=True,
conferenceDataVersion=1,
)
for key in kwargs:
mock_convert_string_to_camel_case.assert_any_call(key)
Expand All @@ -256,10 +280,15 @@ def test_insert_event_with_kwargs(
@patch("os.environ.get", return_value="test_email")
@patch("integrations.google_workspace.google_calendar.execute_google_api_call")
@patch("integrations.google_workspace.google_calendar.convert_string_to_camel_case")
@patch("integrations.google_workspace.google_calendar.generate_unique_id")
def test_insert_event_with_no_document(
mock_convert_string_to_camel_case, mock_execute_google_api_call, mock_os_environ_get
mock_unique_id,
mock_convert_string_to_camel_case,
mock_execute_google_api_call,
mock_os_environ_get,
):
mock_execute_google_api_call.return_value = {"htmlLink": "test_link"}
mock_unique_id.return_value = "abc-123-de4"
mock_convert_string_to_camel_case.side_effect = (
lambda x: x
) # just return the same value
Expand All @@ -273,6 +302,12 @@ def test_insert_event_with_no_document(
"description": "Test Description",
"delegated_user_email": "test_custom_email",
"time_zone": "Magic/Time_Zone",
"conferenceData": {
"createRequest": {
"requestId": "abc-123-de4",
"conferenceSolutionKey": {"type": "hangoutsMeet"},
}
},
}
result = google_calendar.insert_event(
start, end, emails, title, document_id, **kwargs
Expand All @@ -295,13 +330,69 @@ def test_insert_event_with_no_document(
},
calendarId="primary",
supportsAttachments=True,
conferenceDataVersion=1,
)
for key in kwargs:
mock_convert_string_to_camel_case.assert_any_call(key)

assert not mock_os_environ_get.called


@patch("os.environ.get", return_value="test_email")
@patch("integrations.google_workspace.google_calendar.execute_google_api_call")
@patch("integrations.google_workspace.google_calendar.convert_string_to_camel_case")
@patch("integrations.google_workspace.google_calendar.generate_unique_id")
def test_insert_event_google_hangout_link_created(
mock_unique_id,
mock_convert_string_to_camel_case,
mock_execute_google_api_call,
mock_os_environ_get,
):
mock_execute_google_api_call.return_value = {"htmlLink": "test_link"}
mock_unique_id.return_value = "abc-123-de4"
start = datetime.now()
end = start
emails = ["[email protected]", "[email protected]"]
title = "Test Event"
document_id = "test_document_id"
result = google_calendar.insert_event(start, end, emails, title, document_id)
assert result == "test_link"
mock_execute_google_api_call.assert_called_once_with(
"calendar",
"v3",
"events",
"insert",
scopes=["https://www.googleapis.com/auth/calendar.events"],
delegated_user_email="test_email",
body={
"start": {"dateTime": start, "timeZone": "America/New_York"},
"end": {"dateTime": end, "timeZone": "America/New_York"},
"attendees": [{"email": email.strip()} for email in emails],
"summary": title,
"guestsCanModify": True,
"attachments": [
{
"fileUrl": f"https://docs.google.com/document/d/{document_id}",
"mimeType": "application/vnd.google-apps.document",
"title": "Incident Document",
}
],
"conferenceData": {
"createRequest": {
"requestId": "abc-123-de4",
"conferenceSolutionKey": {"type": "hangoutsMeet"},
}
},
},
calendarId="primary",
supportsAttachments=True,
conferenceDataVersion=1,
)
assert mock_unique_id.called
assert mock_execute_google_api_call.contains("conferenceData")
assert mock_execute_google_api_call.contains(mock_unique_id.return_value)


@patch("integrations.google_workspace.google_service.handle_google_api_errors")
@patch("os.environ.get", return_value="test_email")
@patch("integrations.google_workspace.google_calendar.execute_google_api_call")
Expand Down
38 changes: 38 additions & 0 deletions app/tests/integrations/utils/test_api.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import pytest
import string
from integrations.utils.api import (
convert_string_to_camel_case,
convert_dict_to_camel_case,
convert_kwargs_to_camel_case,
convert_string_to_pascal_case,
convert_dict_to_pascale_case,
convert_kwargs_to_pascal_case,
generate_unique_id,
)


Expand Down Expand Up @@ -211,3 +213,39 @@ def test_convert_kwargs_to_pascal_case_with_non_dict_non_list_kwargs():
def test_convert_kwargs_to_pascal_case_with_nested_list():
kwargs = [{"key": ["value1", "value2"]}]
assert convert_kwargs_to_pascal_case(kwargs) == [{"Key": ["value1", "value2"]}]


def test_unique_id_format():
"""Test that the unique ID is in the correct format."""
unique_id = generate_unique_id()
assert isinstance(unique_id, str), "Unique ID should be a string"
parts = unique_id.split("-")
assert len(parts) == 3, "Unique ID should have three parts separated by hyphens"
assert all(
len(part) == 3 for part in parts
), "Each segment should be exactly 3 characters long"


def test_unique_id_characters():
"""Test that the unique ID contains only uppercase letters and digits."""
unique_id = generate_unique_id()
allowed_chars = set(string.ascii_lowercase + string.digits)
assert all(
char in allowed_chars for char in unique_id.replace("-", "")
), "All characters should be alphanumeric"


def test_unique_id_uniqueness():
"""Test that multiple IDs are unique from each other."""
ids = {generate_unique_id() for _ in range(100)}
assert len(ids) == 100, "All generated IDs should be unique"


# Additional test to ensure no illegal characters or formats appear
def test_no_illegal_characters():
"""Ensure no lowecase or special characters are in the ID"""
unique_id = generate_unique_id()
illegal_chars = set(string.ascii_uppercase + string.punctuation)
assert not any(
char in illegal_chars for char in unique_id.replace("-", "")
), "ID should not have uppercase or special characters"

0 comments on commit 92f8309

Please sign in to comment.