Repository: ucfopen/canvasapi

Issue:
Add "list observers" endpoint coverage
**What resource needs additional coverage?**
User

**What endpoints need to be covered?**
GET /api/v1/users/:user_id/observers
https://canvas.instructure.com/doc/api/user_observees.html#method.user_observees.observers

The "list observees" already exists and it seems to be pretty easy to add support for "list observers" because it's almost identical to the existing function. I tested this and it works great, I just don't know how to write the tests for it to do a real contribution.

```
def get_observers(self, **kwargs):
        """
        List the users that are observing the given user.

        :calls:  `GET /api/v1/users/:user_id/observers \
        <https://canvas.instructure.com/doc/api/user_observees.html#method.user_observees.observers>`_

        :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
            :class:`canvasapi.user.User`
        """

        return PaginatedList(
            User,
            self._requester,
            "GET",
            "users/{}/observers".format(self.id),
            _kwargs=combine_kwargs(**kwargs),
        )
```


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

[![Impacted file tree graph](https://codecov.io/gh/ucfopen/canvasapi/pull/509/graphs/tree.svg?width=650&height=150&src=pr&token=CFNpp8f56M&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen)](https://codecov.io/gh/ucfopen/canvasapi/pull/509?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen)

```diff
@@            Coverage Diff            @@
##           develop      #509   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           67        67           
  Lines         3583      3585    +2     
=========================================
+ Hits          3583      3585    +2     
```


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

------

[Continue to review full report at Codecov](https://codecov.io/gh/ucfopen/canvasapi/pull/509?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/ucfopen/canvasapi/pull/509?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen). Last update [2ac9979...a938834](https://codecov.io/gh/ucfopen/canvasapi/pull/509?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3798213..7566354 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
 - Delete a Rubric (Thanks, [@ggarfink](https://github.com/ggarfink))
 - Grade Change Log for Assignments, Courses, and Users (Thanks, [@matthewf-ucsd](https://github.com/matthewf-ucsd))
 - Content Migrations: List items for selective import (Thanks, [@matthewf-ucsd](https://github.com/matthewf-ucsd))
+- List observers of a User (Thanks, [@bennettscience](https://github.com/bennettscience))
 
 ### General
 
diff --git a/canvasapi/user.py b/canvasapi/user.py
index 7f3f4f5..6804e65 100644
--- a/canvasapi/user.py
+++ b/canvasapi/user.py
@@ -752,6 +752,25 @@ class User(CanvasObject):
             _kwargs=combine_kwargs(**kwargs),
         )
 
+    def get_observers(self, **kwargs):
+        """
+        List the users that are observing the given user.
+
+        :calls:  `GET /api/v1/users/:user_id/observers \
+        <https://canvas.instructure.com/doc/api/user_observees.html#method.user_observees.observers>`_
+
+        :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
+            :class:`canvasapi.user.User`
+        """
+
+        return PaginatedList(
+            User,
+            self._requester,
+            "GET",
+            "users/{}/observers".format(self.id),
+            _kwargs=combine_kwargs(**kwargs),
+        )
+
     def get_open_poll_sessions(self, **kwargs):
         """
         Returns a paginated list of all opened poll sessions available to the current user.


Test patch:
diff --git a/tests/fixtures/user.json b/tests/fixtures/user.json
index 09e40e4..babaff5 100644
--- a/tests/fixtures/user.json
+++ b/tests/fixtures/user.json
@@ -735,6 +735,21 @@
 		],
 		"status_code": 200
 	},
+	"list_observers": {
+		"method": "GET",
+		"endpoint": "users/1/observers",
+		"data": [
+			{
+				"id": 3,
+				"name": "User 3"
+			},
+			{
+				"id": 4,
+				"name": "User 4"
+			}
+		],
+		"status_code": 200
+	},
 	"add_observee_with_credentials": {
 		"method": "POST",
 		"endpoint": "users/1/observees",
diff --git a/tests/test_user.py b/tests/test_user.py
index fce4896..f6574f5 100644
--- a/tests/test_user.py
+++ b/tests/test_user.py
@@ -362,6 +362,16 @@ class TestUser(unittest.TestCase):
         self.assertIsInstance(observees_list[0], User)
         self.assertEqual(len(observees_list), 4)
 
+    def test_get_observers(self, m):
+        requires = {"user": ["list_observers", "list_observers"]}
+        register_uris(requires, m)
+
+        response = self.user.get_observers()
+        observers_list = [observers for observers in response]
+
+        self.assertIsInstance(observers_list[0], User)
+        self.assertEqual(len(observers_list), 2)
+
     # add_observee_with_credentials()
     def test_add_observee_with_credentials(self, m):
         register_uris({"user": ["add_observee_with_credentials"]}, m)