Skip to content

Commit 636e887

Browse files
authored
Add new query param "excludedTeams" to iCal API endpoint (#406)
* Add new query param "excludedTeams" to iCal API endpoint * stylecheck * assert number of events
1 parent cde5a22 commit 636e887

File tree

4 files changed

+63
-4
lines changed

4 files changed

+63
-4
lines changed

e2e/test_ical.py

+38
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,44 @@ def test_user_ical(event, team, user, role):
3636
assert start == calendar.timegm(component.get('dtstart').dt.timetuple())
3737
assert end == calendar.timegm(component.get('dtend').dt.timetuple())
3838

39+
@prefix('test_user_ical_exclude_team')
40+
def test_user_ical_exclude_team(event, team, user, role):
41+
team_name = team.create()
42+
team_name_2 = team.create()
43+
user_name = user.create()
44+
role_name = role.create()
45+
user.add_to_team(user_name, team_name)
46+
user.add_to_team(user_name, team_name_2)
47+
48+
start = int(time.time()) + 100
49+
end = start + 1000
50+
51+
ev1 = event.create({'start': start,
52+
'end': end,
53+
'user': user_name,
54+
'team': team_name,
55+
'role': role_name})
56+
ev2 = event.create({'start': start + 100,
57+
'end': end + 100,
58+
'user': user_name,
59+
'team': team_name_2,
60+
'role': role_name})
61+
62+
re = requests.get(api_v0('users/%s/ical?excludedTeams=%s' % (user_name, team_name_2)))
63+
cal = re.content
64+
# Parse icalendar, make sure event info is correct (excluded team's event should not be present)
65+
ical = icalendar.Calendar.from_ical(re.content)
66+
num_events = 0
67+
for component in ical.walk():
68+
if component.name == 'VEVENT':
69+
num_events += 1
70+
assert user_name in component.get('description')
71+
assert team_name_2 not in component.get('summary')
72+
assert start == calendar.timegm(component.get('dtstart').dt.timetuple())
73+
assert end == calendar.timegm(component.get('dtend').dt.timetuple())
74+
# Make sure that there is only 1 event parsed (excluded team event not included)
75+
assert num_events == 1
76+
3977

4078
@prefix('test_team_ical')
4179
def test_team_ical(event, team, user, role):

src/oncall/api/v0/public_ical.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def on_get(req, resp, key):
1717
1818
"""
1919
roles = req.get_param_as_list('roles')
20+
excluded_teams = req.get_param_as_list('excludedTeams')
2021

2122
name_and_type = get_name_and_type_from_key(key)
2223
if name_and_type is None:
@@ -26,7 +27,7 @@ def on_get(req, resp, key):
2627
start = int(time.time())
2728
events = []
2829
if type == 'user':
29-
events = get_user_events(name, start, roles=roles)
30+
events = get_user_events(name, start, roles=roles, excluded_teams=excluded_teams)
3031
elif type == 'team':
3132
events = get_team_events(name, start, roles=roles, include_subscribed=True)
3233

src/oncall/api/v0/teams.py

+11
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@
2727
}
2828

2929

30+
def get_team_ids(cursor, team_names):
31+
if not team_names:
32+
return []
33+
34+
team_query = 'SELECT DISTINCT `id` FROM `team` WHERE `name` IN ({0})'.format(
35+
','.join(['%s'] * len(team_names)))
36+
# we need prepared statements here because team_names come from user input
37+
cursor.execute(team_query, team_names)
38+
return [row['id'] for row in cursor]
39+
40+
3041
def on_get(req, resp):
3142
'''
3243
Search for team names. Allows filtering based on a number of parameters, detailed below.

src/oncall/api/v0/user_ical.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
import time
55
from . import ical
66
from .roles import get_role_ids
7+
from .teams import get_team_ids
78
from ... import db
89

910

10-
def get_user_events(user_name, start, roles=None):
11+
def get_user_events(user_name, start, roles=None, excluded_teams=None):
1112
connection = db.connect()
1213
cursor = connection.cursor(db.DictCursor)
1314

@@ -17,6 +18,13 @@ def get_user_events(user_name, start, roles=None):
1718
role_condition = ' AND `event`.`role_id` IN ({0})'.format(
1819
','.join(map(str, role_ids)))
1920

21+
excluded_teams_condition = ''
22+
excluded_team_ids = get_team_ids(cursor, excluded_teams)
23+
if excluded_team_ids:
24+
excluded_teams_condition = ' AND `event`.`team_id` NOT IN ({0})'.format(
25+
','.join(map(str, excluded_team_ids))
26+
)
27+
2028
query = '''
2129
SELECT
2230
`event`.`id`,
@@ -32,7 +40,7 @@ def get_user_events(user_name, start, roles=None):
3240
WHERE
3341
`event`.`end` > %s AND
3442
`user`.`name` = %s
35-
''' + role_condition
43+
''' + role_condition + excluded_teams_condition
3644

3745
cursor.execute(query, (start, user_name))
3846

@@ -66,7 +74,8 @@ def on_get(req, resp, user_name):
6674
if contact is None:
6775
contact = True
6876
roles = req.get_param_as_list('roles')
77+
excluded_teams = req.get_param_as_list('excludedTeams')
6978

70-
events = get_user_events(user_name, start, roles=roles)
79+
events = get_user_events(user_name, start, roles=roles, excluded_teams=excluded_teams)
7180
resp.body = ical.events_to_ical(events, user_name, contact)
7281
resp.set_header('Content-Type', 'text/calendar')

0 commit comments

Comments
 (0)