Skip to content

Commit

Permalink
Param for get_appointment_groups, checks for creating new appointment…
Browse files Browse the repository at this point in the history
… groups

Fixes ucfopen#678

Two issues in one:

1. `canvas.get_appointment_groups()` returns an empty list for teachers
because it defaults to "reservable", but instructors can't reserve, so
the list is empty. Create a new param on the method that defaults to
`reservable` but can be overridden. Update the docstring to note the
change.

2. Update `create_appointment_group()` to take either a course ID or a
`Course` object. Check that the `context_codes` key is present on the
`appointment_group` dict before checking formatting.

All tests passing.
  • Loading branch information
bennettscience committed Dec 28, 2024
1 parent 45ba5ac commit 4e0ae56
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 1 deletion.
30 changes: 29 additions & 1 deletion canvasapi/canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,13 +211,33 @@ def create_appointment_group(self, appointment_group, **kwargs):
:type appointment_group: `dict`
:param title: The title of the appointment group.
:type title: `str`
:param context_codes: Course IDs for the appointment group.
:type context_codes: `list`
:rtype: :class:`canvasapi.appointment_group.AppointmentGroup`
"""
if (
isinstance(appointment_group, dict)
and "context_codes" in appointment_group
and "title" in appointment_group
):
# Both properties exist, check the context codes list
if (
isinstance(appointment_group["context_codes"][0], str)
and "course_" in appointment_group["context_codes"][0]
):
# Legacy support for context codes passed as list of `course_123`-style strings
# Everything is formatted correctly, so go ahead and move on
pass
else:
# The type of object in `context_codes` is taken care of by obj_or_id, extracting
# the course ID from a <Course> object or by returning plain strings.
course_ids = [
obj_or_id(course_id, "context_codes", (Course,))
for course_id in appointment_group["context_codes"]
]
appointment_group["context_codes"] = course_ids

# Everything is formatted properly to send.
kwargs["appointment_group"] = appointment_group

elif (
Expand Down Expand Up @@ -530,16 +550,24 @@ def get_appointment_group(self, appointment_group, **kwargs):
)
return AppointmentGroup(self.__requester, response.json())

def get_appointment_groups(self, **kwargs):
def get_appointment_groups(self, group_type="reservable", **kwargs):
"""
List appointment groups.
This returns "reservable" appointment groups by default,
but will result in an empty list for teachers.
Set the `group_type` parameter to "manageable" to override.
:calls: `GET /api/v1/appointment_groups \
<https://canvas.instructure.com/doc/api/appointment_groups.html#method.appointment_groups.index>`_
:param group_type: Type of `AppointmentGroup` objects to return. Defaults to "reservable".
:type group_type: `str`
:rtype: :class:`canvasapi.paginated_list.PaginatedList` of
:class:`canvasapi.appointment_group.AppointmentGroup`
"""
kwargs["scope"] = group_type

return PaginatedList(
AppointmentGroup,
self.__requester,
Expand Down
17 changes: 17 additions & 0 deletions tests/fixtures/appointment_group.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,23 @@
],
"status_code": 200
},
"list_manageable_appointment_groups": {
"method": "GET",
"endpoint": "appointment_groups",
"data": [
{
"id": 999,
"context_codes": ["course_123"],
"title": "Test Group 1"
},
{
"id": 888,
"context_codes": ["course_456"],
"title": "Test Group 2"
}
],
"status_code": 200
},
"list_user_participants": {
"method": "GET",
"endpoint": "appointment_groups/222/users",
Expand Down
19 changes: 19 additions & 0 deletions tests/test_canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,14 @@ def test_get_appointment_groups(self, m):
appt_groups_list = [appt_group for appt_group in appt_groups]
self.assertEqual(len(appt_groups_list), 2)

# get_appointment_group(), not reservable
def test_get_manageable_appointment_groups(self, m):
register_uris({"appointment_group": ["list_manageable_appointment_groups"]}, m)

appt_groups = self.canvas.get_appointment_groups(group_type="manageable")
appt_groups_list = [appt_group for appt_group in appt_groups]
self.assertEqual(len(appt_groups_list), 2)

# get_appointment_group()
def test_get_appointment_group(self, m):
register_uris({"appointment_group": ["get_appointment_group"]}, m)
Expand All @@ -661,6 +669,17 @@ def test_create_appointment_group(self, m):
self.assertEqual(evnt.context_codes[0], "course_123")
self.assertEqual(evnt.id, 234)

def test_create_appointment_group_with_course_ids(self, m):
register_uris({"appointment_group": ["create_appointment_group"]}, m)

evnt = self.canvas.create_appointment_group(
{"context_codes": [123], "title": "Test Group"}
)

self.assertIsInstance(evnt, AppointmentGroup)
self.assertEqual(evnt.context_codes[0], "course_123")
self.assertEqual(evnt.id, 234)

def test_create_appointment_group_fail_on_context_codes(self, m):
with self.assertRaises(RequiredFieldMissing):
self.canvas.create_appointment_group({"title": "Test Group"})
Expand Down

0 comments on commit 4e0ae56

Please sign in to comment.