Repository: ucfopen/canvasapi
Pull request #436 (2020-11-01 02:20:19)

Added backwards-compatible support for canvas.get_announcements
This PR makes a few adjustments to the changes introduced in #421.

- Renamed `courses` parameter to `context_codes` for backwards compatibility
- Allowed `course_xxx` format for `context_codes` for backwards compatibility
- Removed unnecessary keyword argument `context_codes` in `PaginatedList` call (already handled by adding to `kwargs["context_codes"]`)
- Update changelog
- Minor formatting tweaks

Related issue: #420

coveralls: 
[![Coverage Status](https://coveralls.io/builds/34616135/badge)](https://coveralls.io/builds/34616135)

Coverage decreased (-0.03%) to 99.972% when pulling **de0a6278a5bb14efffaeca04fbf2857ed70fa376 on Thetwam:issue/announcements-course-id-adjustment** into **9175ff4b43d6bdfb0149fb63c320e41e72b69314 on ucfopen:develop**.


Patch:
diff --git a/.gitignore b/.gitignore
index c2f3444..109ce10 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,4 +21,4 @@ venv/
 .vscode/settings.json
 setup.sh
 .python-version
-.*.swp
\ No newline at end of file
+.*.swp
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ababb2..f9fc32d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,11 @@
 ### General
 
 - Added missing documentation for the get_current_user method and clarifications to the CurrentUser class. (Thanks, [@Xx-Ashutosh-xX](https://github.com/Xx-Ashutosh-xX))
+- `Canvas.get_announcement` now has a required parameter `context_codes`, which accepts a list of course IDs or `Course` objects.
+
+### Bugfixes
+
+- Fixed an issue where an `Announcement` object sometimes didn't have an associated course ID. (Thanks, [@bennettscience](https://github.com/bennettscience))
 
 ### New Endpoint Coverage
 
diff --git a/canvasapi/canvas.py b/canvasapi/canvas.py
index dc8fae6..962106e 100644
--- a/canvasapi/canvas.py
+++ b/canvasapi/canvas.py
@@ -437,39 +437,45 @@ class Canvas(object):
         )
         return response.json()
 
-    def get_announcements(self, courses, **kwargs):
+    def get_announcements(self, context_codes, **kwargs):
         """
         List announcements.
 
         :calls: `GET /api/v1/announcements \
         <https://canvas.instructure.com/doc/api/announcements.html#method.announcements_api.index>`_
 
-        :param courses: Course ID(s) or <Course> objects to request announcements from.
-        :type courses: list
+        :param context_codes: Course ID(s) or <Course> objects to request announcements from.
+        :type context_codes: list
 
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
                 :class:`canvasapi.discussion_topic.DiscussionTopic`
         """
         from canvasapi.discussion_topic import DiscussionTopic
 
-        if type(courses) is not list or len(courses) == 0:
-            raise RequiredFieldMissing("Course IDs need to be passed as a list")
+        if type(context_codes) is not list or len(context_codes) == 0:
+            raise RequiredFieldMissing("context_codes need to be passed as a list")
 
-        # The type of object in `courses` is taken care of by obj_or_id, extracting the couse
-        # ID from a <Course> object or by returning plain strings.
-        course_ids = [
-            obj_or_id(course_id, "course_id", (Course,)) for course_id in courses
-        ]
-
-        # Set the **kwargs object vaue so it can be combined with others passed by the user.
-        kwargs["context_codes"] = [f"course_{course_id}" for course_id in course_ids]
+        if isinstance(context_codes[0], str) and "course_" in context_codes[0]:
+            # Legacy support for context codes passed as list of `course_123`-style strings
+            kwargs["context_codes"] = context_codes
+        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 context_codes
+            ]
+
+            # Set the **kwargs object vaue so it can be combined with others passed by the user.
+            kwargs["context_codes"] = [
+                f"course_{course_id}" for course_id in course_ids
+            ]
 
         return PaginatedList(
             DiscussionTopic,
             self.__requester,
             "GET",
             "announcements",
-            context_codes=course_ids,
             _kwargs=combine_kwargs(**kwargs),
         )
 


Test patch:
diff --git a/tests/test_canvas.py b/tests/test_canvas.py
index d99bc47..87ec42a 100644
--- a/tests/test_canvas.py
+++ b/tests/test_canvas.py
@@ -749,6 +749,14 @@ class TestCanvas(unittest.TestCase):
         self.assertEqual(announcement_list[2]._parent_type, "group")
         self.assertEqual(announcement_list[2]._parent_id, "1")
 
+    def test_course_announcements_legacy(self, m):
+        register_uris({"announcements": ["list_announcements"]}, m)
+        announcements = self.canvas.get_announcements(context_codes=["course_1"])
+
+        self.assertEqual(announcements[0].context_code, "course_1")
+        self.assertEqual(announcements[0]._parent_type, "course")
+        self.assertEqual(announcements[0]._parent_id, "1")
+
     # get_epub_exports()
     def test_get_epub_exports(self, m):