Repository: ucfopen/canvasapi

Issue:
Cannot print ChangeRecord class
# Describe the bug

Instances of the ChangeRecord class cannot be printed because the `__str__` method references attributes that don't exist on that object.

# To Reproduce

Steps to reproduce the behavior:

1. Get a blueprint course
2. Get a blueprint template
3. Iterate through unsynced changes and try to print them
4. You will get this error: AttributeError: 'ChangeRecord' object has no attribute 'id'

# Environment information (please complete the following information)

- Python version: 3.7.3
- CanvasAPI version: 0.14.0

# Additional context

Here is the definition of the ChangeRecord class:
```
@python_2_unicode_compatible
class ChangeRecord(CanvasObject):
    def __str__(self):  # pragma: no cover
        return "{} {}".format(self.id, self.template_id)
```

Here is Canvas's documented object:
https://canvas.instructure.com/doc/api/blueprint_courses.html#ChangeRecord

Discussion:
coveralls: 
[![Coverage Status](https://coveralls.io/builds/29059259/badge)](https://coveralls.io/builds/29059259)

Coverage remained the same at 100.0% when pulling **fcbcc14c603bf18e37b18b61222d8914a86a0153 on Mike-Nahmias:issue/294-print-change-record-class** into **309210681e28c58256ce5999a513b8a70f8aba31 on ucfopen:develop**.


Patch:
diff --git a/canvasapi/blueprint.py b/canvasapi/blueprint.py
index ad40862..f8e7fae 100644
--- a/canvasapi/blueprint.py
+++ b/canvasapi/blueprint.py
@@ -236,8 +236,8 @@ class BlueprintMigration(CanvasObject):
 
 @python_2_unicode_compatible
 class ChangeRecord(CanvasObject):
-    def __str__(self):  # pragma: no cover
-        return "{} {}".format(self.id, self.template_id)
+    def __str__(self):
+        return "{} {}".format(self.asset_id, self.asset_name)
 
 
 @python_2_unicode_compatible


Test patch:
diff --git a/tests/test_blueprint.py b/tests/test_blueprint.py
index fd4b60a..6b3c3b7 100644
--- a/tests/test_blueprint.py
+++ b/tests/test_blueprint.py
@@ -196,3 +196,25 @@ class TestBlueprintMigration(unittest.TestCase):
         import_details = self.b_import.get_import_details()
         self.assertIsInstance(import_details, PaginatedList)
         self.assertIsInstance(import_details[0], ChangeRecord)
+
+
+@requests_mock.Mocker()
+class TestChangeRecord(unittest.TestCase):
+    def setUp(self):
+        self.canvas = Canvas(settings.BASE_URL, settings.API_KEY)
+
+        with requests_mock.Mocker() as m:
+            requires = {
+                "course": ["get_blueprint", "get_by_id"],
+                "blueprint": ["get_unsynced_changes"],
+            }
+            register_uris(requires, m)
+
+            self.course = self.canvas.get_course(1)
+            self.blueprint = self.course.get_blueprint(1)
+            self.change_record = self.blueprint.get_unsynced_changes()[0]
+
+    # __str__()
+    def test__str__(self, m):
+        string = str(self.change_record)
+        self.assertIsInstance(string, str)