Repository: ucfopen/canvasapi (language: python)

Issue:
Add missing methods to File
**What resource needs additional coverage?**
Files, first identified in #599 

**What endpoints need to be covered?**
- [Copy a file](https://canvas.instructure.com/doc/api/files.html#method.folders.copy_file)
- [Update file](https://canvas.instructure.com/doc/api/files.html#method.files.api_update)


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b6130967..29d9d67d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,8 @@
 - Enrollments (Thanks, [@svanderwulp](https://github.com/svanderwulp))
     - Accept Course Invitation
     - Reject Course Invitation
+- File (Thanks, [@bennettscience](https://github.com/bennettscience))
+    - Update File
 - JWTs (Thanks [@dmols](https://github.com/dmols))
     - Create JWTs
     - Refresh JWTs
diff --git a/canvasapi/file.py b/canvasapi/file.py
index 81439f6a..e4acbf36 100644
--- a/canvasapi/file.py
+++ b/canvasapi/file.py
@@ -44,3 +44,17 @@ def get_contents(self, binary=False):
             return response.content
         else:
             return response.text
+
+    def update(self, **kwargs):
+        """
+        Update some settings on the specified file.
+
+        :calls: `PUT /api/v1/files/:id \
+        <https://canvas.instructure.com/doc/api/files.html#method.files.api_update>`_
+
+        :rtype: :class:`canvasapi.file.File`
+        """
+        response = self._requester.request(
+            "PUT", "files/{}".format(self.id), _kwargs=combine_kwargs(**kwargs)
+        )
+        return File(self._requester, response.json())


Test patch:
diff --git a/tests/fixtures/file.json b/tests/fixtures/file.json
index f5aa344c..7d007135 100644
--- a/tests/fixtures/file.json
+++ b/tests/fixtures/file.json
@@ -32,5 +32,14 @@
         "endpoint": "ANY",
         "data": "file contents are here",
         "status_code": 200
+    },
+    "update_file": {
+        "method": "PUT",
+        "endpoint": "files/1",
+        "data": {
+            "id": 1,
+            "display_name": "New filename.docx"
+        },
+        "status_code": 200
     }
 }
diff --git a/tests/test_file.py b/tests/test_file.py
index ed7a5693..543ca8a5 100644
--- a/tests/test_file.py
+++ b/tests/test_file.py
@@ -55,3 +55,13 @@ def test_contents_file(self, m):
         self.assertEqual(contents, '"Hello there"')
         contents_binary = self.file.get_contents(binary=True)
         self.assertEqual(contents_binary, b'"Hello there"')
+
+    # update()
+    def test_update_file(self, m):
+        register_uris({"file": ["update_file"]}, m)
+
+        updated_file = self.file.update(name="New filename.docx")
+
+        self.assertIsInstance(updated_file, File)
+        self.assertTrue(hasattr(updated_file, "display_name"))
+        self.assertEqual(updated_file.display_name, "New filename.docx")