Repository: ucfopen/canvasapi

Issue:
Add `remove_admin` or similar to `canvasapi.account.Account`
**What resource needs additional coverage?**

Account Admin

**What endpoints need to be covered?**

`DELETE /api/v1/accounts/:account_id/admins/:user_id`

The [Remove account admin](https://canvas.instructure.com/doc/api/admins.html#method.admins.destroy) endpoint is not currently covered.


Discussion:
nhadley12: This function would be extremely useful to your K-12 users, many of us use integrations like GradeGuardian which require "admin" level access in order to use its full functionality! 
codecov[bot]: # [Codecov](https://codecov.io/gh/ucfopen/canvasapi/pull/529?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen) Report
> Merging [#529](https://codecov.io/gh/ucfopen/canvasapi/pull/529?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen) (035e30a) into [develop](https://codecov.io/gh/ucfopen/canvasapi/commit/098a02c2378cacc47039e8606bfab682595bc503?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen) (098a02c) will **not change** coverage.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff            @@
##           develop      #529   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           69        69           
  Lines         3650      3656    +6     
=========================================
+ Hits          3650      3656    +6     
```


| [Impacted Files](https://codecov.io/gh/ucfopen/canvasapi/pull/529?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen) | Coverage Δ | |
|---|---|---|
| [canvasapi/account.py](https://codecov.io/gh/ucfopen/canvasapi/pull/529/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ucfopen#diff-Y2FudmFzYXBpL2FjY291bnQucHk=) | `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/AUTHORS.md b/AUTHORS.md
index e9d74df..0790d78 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -73,6 +73,7 @@ Patches and Suggestions
 - Philip Carter [@phillyc](https://github.com/phillyc)
 - Ralph Baird [@rmanbaird](https://github.com/rmanbaird)
 - [@Screeeech](https://github.com/Screeeech)
+- Shane Rosenkrantz [@shaneros](https://github.com/shaneros)
 - Sigurður Baldursson [@sigurdurb](https://github.com/sigurdurb)
 - Spencer Rogers [@spencer1248](https://github.com/spencer1248)
 - Stephen Woosley [@stephenwoosley](https://github.com/stephenwoosley)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dc2a484..374a1a6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@
 - 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))
 - ePortfolio endpoints (Thanks, [@Birdmaaan4](https://github.com/Birdmaaan4) and [@bennettscience](https://github.com/bennettscience))
+- Delete an Admin from an Account (Thanks, [@shaneros](https://github.com/shaneros))
 
 ### General
 
diff --git a/canvasapi/account.py b/canvasapi/account.py
index 3877d4e..2aa37ee 100644
--- a/canvasapi/account.py
+++ b/canvasapi/account.py
@@ -545,6 +545,31 @@ class Account(CanvasObject):
 
         return response.json().get("workflow_state") == "deleted"
 
+    def delete_admin(self, user, **kwargs):
+        """
+        Remove an admin role from an existing user in the current account.
+
+        :calls: `DELETE /api/v1/accounts/:account_id/admins/:user_id \
+        <https://canvas.instructure.com/doc/api/admins.html#method.admins.destroy>`_
+
+        :param user: The user object or ID to remove as admin.
+        :type user: :class:`canvasapi.user.User` or int
+
+        :rtype: :class:`canvasapi.account.Admin`
+        """
+        from canvasapi.user import User
+
+        user_id = obj_or_id(user, "user", (User,))
+        kwargs["user_id"] = user_id
+
+        response = self._requester.request(
+            "DELETE",
+            "accounts/{}/admins/{}".format(self.id, user_id),
+            _kwargs=combine_kwargs(**kwargs),
+        )
+
+        return Admin(self._requester, response.json())
+
     def delete_grading_period(self, grading_period, **kwargs):
         """
         Delete a grading period for an account.
diff --git a/docs/account-ref.rst b/docs/account-ref.rst
index 176473d..a0ed5b5 100644
--- a/docs/account-ref.rst
+++ b/docs/account-ref.rst
@@ -19,6 +19,13 @@ AccountReport
 .. autoclass:: canvasapi.account.AccountReport
     :members:
 
+=====
+Admin
+=====
+
+.. autoclass:: canvasapi.account.Admin
+    :members:
+
 ====
 Role
 ====


Test patch:
diff --git a/tests/fixtures/account.json b/tests/fixtures/account.json
index 819ac40..a9feaef 100644
--- a/tests/fixtures/account.json
+++ b/tests/fixtures/account.json
@@ -1687,6 +1687,26 @@
 			"workflow_state": "active"
 		}
 	},
+	"delete_admin": {
+		"method": "DELETE",
+		"endpoint": "accounts/1/admins/123",
+		"data": {
+			"id": 100,
+			"role": "AccountAdmin",
+			"role_id": 1,
+			"user": {
+				"id": 123,
+				"name": "John Doe",
+				"sortable_name": "John Doe",
+				"short_name": "J Doe",
+				"sis_user_id": null,
+				"integration_id": null,
+				"sis_import_id": null,
+				"login_id": "jdoe"
+			},
+			"workflow_state": "deleted"
+		}
+	},
 	"get_features": {
 		"method": "GET",
 		"endpoint": "accounts/1/features",
diff --git a/tests/test_account.py b/tests/test_account.py
index 9d3a0d7..ab23f0a 100644
--- a/tests/test_account.py
+++ b/tests/test_account.py
@@ -152,6 +152,23 @@ class TestAccount(unittest.TestCase):
         with self.assertRaises(CanvasException):
             self.account.delete()
 
+    # delete_admin()
+    def test_delete_admin(self, m):
+        register_uris({"account": ["delete_admin"]}, m)
+
+        user_id = 123
+        deleted_admin = self.account.delete_admin(user=user_id)
+
+        self.assertIsInstance(deleted_admin, Admin)
+        self.assertTrue(hasattr(deleted_admin, "id"))
+        self.assertTrue(hasattr(deleted_admin, "role"))
+        self.assertTrue(hasattr(deleted_admin, "role_id"))
+        self.assertTrue(hasattr(deleted_admin, "workflow_state"))
+        self.assertEqual(deleted_admin.user["login_id"], "jdoe")
+        self.assertEqual(deleted_admin.role, "AccountAdmin")
+        self.assertEqual(deleted_admin.role_id, 1)
+        self.assertEqual(deleted_admin.workflow_state, "deleted")
+
     # delete_user()
     def test_delete_user_id(self, m):
         register_uris({"account": ["delete_user"]}, m)