Repository: ucfopen/canvasapi
Pull request #485 (2021-04-15 18:40:06)

Issue/480 Add Support for Delete Rubric
# Proposed Changes
Addresses Issue #480 by adding a delete function to the Rubric class in rubric.py that calls the Rubric DELETE endpoint in the Canvas LMS REST API.

Sorry for the multiple pull requests - for some reason we failed a run on Github the first time.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d4fbdc2..9c4bd31 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
 
 ## [Unreleased]
 
+### New Endpoint Coverage
+
+- Delete a Rubric (Thanks, [@kailukaitisBrendan](https://github.com/kailukaitisBrendan))
+
 ### Breaking Changes
 
 - Update `QuizSubmission.get_submission_events` to return a `PaginatedList`.
diff --git a/canvasapi/course.py b/canvasapi/course.py
index fcb97f0..cca768d 100644
--- a/canvasapi/course.py
+++ b/canvasapi/course.py
@@ -528,6 +528,7 @@ class Course(CanvasObject):
 
         if "rubric" in dictionary:
             r_dict = dictionary["rubric"]
+            r_dict.update({"course_id": self.id})
             rubric = Rubric(self._requester, r_dict)
 
             rubric_dict = {"rubric": rubric}
@@ -1971,7 +1972,10 @@ class Course(CanvasObject):
             _kwargs=combine_kwargs(**kwargs),
         )
 
-        return Rubric(self._requester, response.json())
+        response_json = response.json()
+        response_json.update({"course_id": self.id})
+
+        return Rubric(self._requester, response_json)
 
     def get_rubrics(self, **kwargs):
         """
@@ -1988,6 +1992,7 @@ class Course(CanvasObject):
             self._requester,
             "GET",
             "courses/%s/rubrics" % (self.id),
+            {"course_id": self.id},
             _kwargs=combine_kwargs(**kwargs),
         )
 
diff --git a/canvasapi/rubric.py b/canvasapi/rubric.py
index a973e7e..5ee003f 100644
--- a/canvasapi/rubric.py
+++ b/canvasapi/rubric.py
@@ -6,6 +6,25 @@ class Rubric(CanvasObject):
     def __str__(self):
         return "{} ({})".format(self.title, self.id)
 
+    def delete(self, **kwargs):
+        """
+        Delete a Rubric.
+
+        :calls: `DELETE /api/v1/courses/:course_id/rubrics/:id \
+        <https://canvas.instructure.com/doc/api/rubrics.html#method.rubrics.destroy>`_
+
+        :rtype: :class:`canvasapi.rubric.Rubric`
+        """
+        from canvasapi.rubric import Rubric
+
+        response = self._requester.request(
+            "DELETE",
+            "courses/{}/rubrics/{}".format(self.course_id, self.id),
+            _kwargs=combine_kwargs(**kwargs),
+        )
+
+        return Rubric(self._requester, response.json())
+
 
 class RubricAssociation(CanvasObject):
     def __str__(self):


Test patch:
diff --git a/tests/fixtures/rubric.json b/tests/fixtures/rubric.json
index 78f8fcd..df4e058 100644
--- a/tests/fixtures/rubric.json
+++ b/tests/fixtures/rubric.json
@@ -16,5 +16,21 @@
 			"association_type": "Assignment"
 		},
 		"status_code": 200
+	},
+	"delete_rubric": {
+		"method": "DELETE",
+		"endpoint": "courses/1/rubrics/1",
+		"data": {
+			"id": 1,
+			"title": "Course Rubric 1",
+			"context_id": 1,
+			"context_type": "Course",
+			"points_possible": 10.0,
+			"reusable": false,
+			"read_only": true,
+			"free_form_critereon_comments": true,
+			"hide_score_total": true
+		},
+		"status_code": 200
 	}
 }
diff --git a/tests/test_course.py b/tests/test_course.py
index 8f95829..aeb58be 100644
--- a/tests/test_course.py
+++ b/tests/test_course.py
@@ -1202,6 +1202,7 @@ class TestCourse(unittest.TestCase):
         self.assertIsInstance(rubric, Rubric)
         self.assertEqual(rubric.id, rubric_id)
         self.assertEqual(rubric.title, "Course Rubric 1")
+        self.assertTrue(hasattr(rubric, "course_id"))
 
     # get_rubrics
     def test_get_rubrics(self, m):
@@ -1214,9 +1215,12 @@ class TestCourse(unittest.TestCase):
         self.assertIsInstance(rubrics[0], Rubric)
         self.assertEqual(rubrics[0].id, 1)
         self.assertEqual(rubrics[0].title, "Course Rubric 1")
+        self.assertTrue(hasattr(rubrics[0], "course_id"))
+
         self.assertIsInstance(rubrics[1], Rubric)
         self.assertEqual(rubrics[1].id, 2)
         self.assertEqual(rubrics[1].title, "Course Rubric 2")
+        self.assertTrue(hasattr(rubrics[1], "course_id"))
 
     # get_root_outcome_group()
     def test_get_root_outcome_group(self, m):
diff --git a/tests/test_rubric.py b/tests/test_rubric.py
index 626adb5..6735225 100644
--- a/tests/test_rubric.py
+++ b/tests/test_rubric.py
@@ -3,11 +3,45 @@ import unittest
 import requests_mock
 
 from canvasapi import Canvas
-from canvasapi.rubric import RubricAssociation
+from canvasapi.rubric import Rubric, RubricAssociation
 from tests import settings
 from tests.util import register_uris
 
 
+@requests_mock.Mocker()
+class TestRubric(unittest.TestCase):
+    def setUp(self):
+        self.canvas = Canvas(settings.BASE_URL, settings.API_KEY)
+
+        with requests_mock.Mocker() as m:
+            register_uris({"course": ["get_by_id", "create_rubric"]}, m)
+
+            self.course = self.canvas.get_course(1)
+            self.rubric = self.course.create_rubric()["rubric"]
+
+    # delete
+    def test_delete(self, m):
+        register_uris({"rubric": ["delete_rubric"]}, m)
+
+        rubric = self.rubric.delete()
+
+        self.assertIsInstance(rubric, Rubric)
+        self.assertEqual(rubric.id, 1)
+        self.assertEqual(rubric.title, "Course Rubric 1")
+        self.assertEqual(rubric.context_id, 1)
+        self.assertEqual(rubric.context_type, "Course")
+        self.assertEqual(rubric.points_possible, 10.0)
+        self.assertFalse(rubric.reusable)
+        self.assertTrue(rubric.read_only)
+        self.assertTrue(rubric.free_form_critereon_comments)
+        self.assertTrue(rubric.hide_score_total)
+
+    # __str__()
+    def test__str__(self, m):
+        string = str(self.rubric)
+        self.assertIsInstance(string, str)
+
+
 @requests_mock.Mocker()
 class TestGradingStandard(unittest.TestCase):
     def setUp(self):