Repository: ucfopen/canvasapi

Issue:
Endpoint for accepting and rejecting course invites
**What resource needs additional coverage?**
Enrollments.

**What endpoints need to be covered?**
- [ ] [accept course invite](https://canvas.instructure.com/doc/api/enrollments.html#method.enrollments_api.accept)
- [ ] [reject course invite](https://canvas.instructure.com/doc/api/enrollments.html#method.enrollments_api.reject)


Discussion:
codecov[bot]: ## [Codecov](https://codecov.io/gh/ucfopen/canvasapi/pull/597?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen) Report
> Merging [#597](https://codecov.io/gh/ucfopen/canvasapi/pull/597?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen) (94b4d36) into [develop](https://codecov.io/gh/ucfopen/canvasapi/commit/afe91b5e091901dd98219ed7bf4fcec0015a9942?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen) (afe91b5) will **not change** coverage.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff            @@
##           develop      #597   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           72        72           
  Lines         3672      3681    +9     
=========================================
+ Hits          3672      3681    +9     
```


| [Impacted Files](https://codecov.io/gh/ucfopen/canvasapi/pull/597?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen) | Coverage Δ | |
|---|---|---|
| [canvasapi/enrollment.py](https://codecov.io/gh/ucfopen/canvasapi/pull/597?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen#diff-Y2FudmFzYXBpL2Vucm9sbG1lbnQucHk=) | `100.00% <100.00%> (ø)` | |
| [canvasapi/user.py](https://codecov.io/gh/ucfopen/canvasapi/pull/597?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen#diff-Y2FudmFzYXBpL3VzZXIucHk=) | `100.00% <100.00%> (ø)` | |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen)


Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 18564f7..994832d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
-  - repo: https://github.com/ambv/black
-    rev: stable
+  - repo: https://github.com/psf/black
+    rev: 23.3.0
     hooks:
     - id: black
-      language_version: python3.9
+      language_version: python3
diff --git a/AUTHORS.md b/AUTHORS.md
index adb06d8..3b38cd8 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -83,6 +83,7 @@ Patches and Suggestions
 - Stephen Woosley [@stephenwoosley](https://github.com/stephenwoosley)
 - Steven Bell [@stevenbell](https://github.com/stevenbell)
 - Steven Williams [@onomou](https://github.com/onomou)
+- [@svanderwulp](https://github.com/svanderwulp)
 - Tinson Lai [@laitingsheng](https://github.com/laitingsheng)
 - Toan Vu [@vutoan1245](https://github.com/vutoan1245)
 - [@Tobiaqs](https://github.com/Tobiaqs)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9cf073f..b613096 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,9 @@
     - Update a calendar's visibility
     - Update many calendars' visibility
     - List all account calendars
+- Enrollments (Thanks, [@svanderwulp](https://github.com/svanderwulp))
+    - Accept Course Invitation
+    - Reject Course Invitation
 - JWTs (Thanks [@dmols](https://github.com/dmols))
     - Create JWTs
     - Refresh JWTs
diff --git a/canvasapi/enrollment.py b/canvasapi/enrollment.py
index 476c8f7..bd4ab84 100644
--- a/canvasapi/enrollment.py
+++ b/canvasapi/enrollment.py
@@ -6,6 +6,23 @@ class Enrollment(CanvasObject):
     def __str__(self):
         return "{} ({})".format(self.type, self.id)
 
+    def accept(self, **kwargs):
+        """
+        Accept a pending course invitation.
+
+        :calls: `POST /api/v1/courses/:course_id/enrollments/:id/accept \
+        <https://canvas.instructure.com/doc/api/enrollments.html#method.enrollments_api.accept>`_
+
+        :returns: True if the course invitation was accepted.
+        :rtype: bool
+        """
+        response = self._requester.request(
+            "POST",
+            "courses/{}/enrollments/{}/accept".format(self.course_id, self.id),
+            _kwargs=combine_kwargs(**kwargs),
+        )
+        return response.json().get("success", False)
+
     def deactivate(self, task, **kwargs):
         """
         Delete, conclude, or deactivate an enrollment.
@@ -53,3 +70,20 @@ class Enrollment(CanvasObject):
             _kwargs=combine_kwargs(**kwargs),
         )
         return Enrollment(self._requester, response.json())
+
+    def reject(self, **kwargs):
+        """
+        Reject a pending course invitation.
+
+        :calls: `POST /api/v1/courses/:course_id/enrollments/:id/reject \
+        <https://canvas.instructure.com/doc/api/enrollments.html#method.enrollments_api.reject>`_
+
+        :returns: True if the course invitation was rejected.
+        :rtype: bool
+        """
+        response = self._requester.request(
+            "POST",
+            "courses/{}/enrollments/{}/reject".format(self.course_id, self.id),
+            _kwargs=combine_kwargs(**kwargs),
+        )
+        return response.json().get("success", False)


Test patch:
diff --git a/tests/fixtures/enrollment.json b/tests/fixtures/enrollment.json
index d665daf..c8b7527 100644
--- a/tests/fixtures/enrollment.json
+++ b/tests/fixtures/enrollment.json
@@ -33,5 +33,21 @@
 			"state": "active"
 		},
 		"status_code": 200
+	},
+	"accept": {
+		"method": "POST",
+		"endpoint": "courses/1/enrollments/1/accept",
+		"data": {
+			"success": true
+		},
+		"status_code": 200
+	},
+	"reject": {
+		"method": "POST",
+		"endpoint": "courses/1/enrollments/1/reject",
+		"data": {
+			"success": true
+		},
+		"status_code": 200
 	}
-}
\ No newline at end of file
+}
diff --git a/tests/test_enrollment.py b/tests/test_enrollment.py
index 111cf5d..17b7616 100644
--- a/tests/test_enrollment.py
+++ b/tests/test_enrollment.py
@@ -44,3 +44,21 @@ class TestEnrollment(unittest.TestCase):
         target_enrollment = self.enrollment.reactivate()
 
         self.assertIsInstance(target_enrollment, Enrollment)
+
+    # accept()
+    def test_accept(self, m):
+        register_uris({"enrollment": ["accept"]}, m)
+
+        enrollment_accepted = self.enrollment.accept()
+
+        self.assertIsInstance(enrollment_accepted, bool)
+        self.assertTrue(enrollment_accepted)
+
+    # reject()
+    def test_reject(self, m):
+        register_uris({"enrollment": ["reject"]}, m)
+
+        enrollment_rejected = self.enrollment.reject()
+
+        self.assertIsInstance(enrollment_rejected, bool)
+        self.assertTrue(enrollment_rejected)