Repository: box/box-python-sdk
Pull request #167 (2016-09-07 16:10:02)

Support folder metadata


Patch:
diff --git a/AUTHORS.rst b/AUTHORS.rst
index 57dfea7..d9a0e18 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -8,3 +8,4 @@ used to interact with the Box API. This is a list of contributors.
 - `@potrebic <https://github.com/potrebic>`_
 - `@nsundareswaran <https://github.com/nsundareswaran>`_
 - `@kelseymorris95 <https://github.com/kelseymorris95>`_
+- `@sp4x <https://github.com/sp4x>`_
diff --git a/HISTORY.rst b/HISTORY.rst
index 37e4a67..0388bfd 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -36,6 +36,7 @@ Release History
     default ``Translator``.
 
 - Added an ``Event`` class.
+- Moved `metadata` method to `Item` so it's now available for `Folder` as well as `File`.
 
 **Other**
 
diff --git a/boxsdk/object/file.py b/boxsdk/object/file.py
index fb9afc1..6affa65 100644
--- a/boxsdk/object/file.py
+++ b/boxsdk/object/file.py
@@ -4,7 +4,6 @@
 
 from boxsdk.config import API
 from .item import Item
-from .metadata import Metadata
 from ..util.api_call_decorator import api_call
 
 
@@ -226,26 +225,6 @@ def unlock(self):
         data = {'lock': None}
         return self.update_info(data)
 
-    def metadata(self, scope='global', template='properties'):
-        """
-        Instantiate a :class:`Metadata` object associated with this file.
-
-        :param scope:
-            Scope of the metadata. Must be either 'global' or 'enterprise'.
-        :type scope:
-            `unicode`
-        :param template:
-            The name of the metadata template.
-            See https://box-content.readme.io/reference#metadata-object for more details.
-        :type template:
-            `unicode`
-        :return:
-            A new metadata instance associated with this file.
-        :rtype:
-            :class:`Metadata`
-        """
-        return Metadata(self._session, self, scope, template)
-
     @api_call
     def get_shared_link_download_url(
             self,
diff --git a/boxsdk/object/item.py b/boxsdk/object/item.py
index 3b5363e..bb124bd 100644
--- a/boxsdk/object/item.py
+++ b/boxsdk/object/item.py
@@ -6,6 +6,7 @@
 from .base_object import BaseObject
 from ..config import API
 from ..exception import BoxAPIException
+from .metadata import Metadata
 from ..util.api_call_decorator import api_call
 
 
@@ -335,3 +336,23 @@ def delete(self, params=None, etag=None):
         """
         headers = {'If-Match': etag} if etag is not None else None
         return super(Item, self).delete(params, headers)
+
+    def metadata(self, scope='global', template='properties'):
+        """
+        Instantiate a :class:`Metadata` object associated with this item.
+
+        :param scope:
+            Scope of the metadata. Must be either 'global' or 'enterprise'.
+        :type scope:
+            `unicode`
+        :param template:
+            The name of the metadata template.
+            See https://docs.box.com/reference#metadata-object for more details.
+        :type template:
+            `unicode`
+        :return:
+            A new metadata instance associated with this item.
+        :rtype:
+            :class:`Metadata`
+        """
+        return Metadata(self._session, self, scope, template)


Test patch:
diff --git a/test/unit/object/test_metadata.py b/test/unit/object/test_metadata.py
index 409914b..102b4dd 100644
--- a/test/unit/object/test_metadata.py
+++ b/test/unit/object/test_metadata.py
@@ -26,16 +26,24 @@ def metadata_scope(request):
     return request.param
 
 
-@pytest.fixture
-def metadata_template():
-    return 'properties'
+@pytest.fixture(params=['properties', 'custom'])
+def metadata_template(request):
+    return request.param
+
+
+@pytest.fixture(params=['file', 'folder'])
+def test_object(test_file, test_folder, request):
+    if request.param == 'file':
+        return test_file
+    else:
+        return test_folder
 
 
 @pytest.mark.parametrize('success', [True, False])
-def test_delete(mock_box_session, make_mock_box_request, test_file, metadata_scope, metadata_template, success):
+def test_delete(mock_box_session, make_mock_box_request, test_object, metadata_scope, metadata_template, success):
     # pylint:disable=redefined-outer-name
     mock_box_session.delete.return_value, _ = make_mock_box_request(response_ok=success)
-    metadata = test_file.metadata(metadata_scope, metadata_template)
+    metadata = test_object.metadata(metadata_scope, metadata_template)
     assert metadata.delete() is success
     mock_box_session.delete.assert_called_once_with(metadata.get_url())
 
@@ -43,14 +51,14 @@ def test_delete(mock_box_session, make_mock_box_request, test_file, metadata_sco
 def test_create(
         mock_box_session,
         make_mock_box_request,
-        test_file,
+        test_object,
         metadata_scope,
         metadata_template,
         metadata_response,
 ):
     # pylint:disable=redefined-outer-name
     mock_box_session.post.return_value, _ = make_mock_box_request(response=metadata_response)
-    metadata = test_file.metadata(metadata_scope, metadata_template)
+    metadata = test_object.metadata(metadata_scope, metadata_template)
     response = metadata.create(metadata_response)
     assert response is metadata_response
     mock_box_session.post.assert_called_once_with(
@@ -63,14 +71,14 @@ def test_create(
 def test_get(
         mock_box_session,
         make_mock_box_request,
-        test_file,
+        test_object,
         metadata_scope,
         metadata_template,
         metadata_response,
 ):
     # pylint:disable=redefined-outer-name
     mock_box_session.get.return_value, _ = make_mock_box_request(response=metadata_response)
-    metadata = test_file.metadata(metadata_scope, metadata_template)
+    metadata = test_object.metadata(metadata_scope, metadata_template)
     response = metadata.get()
     assert response is metadata_response
     mock_box_session.get.assert_called_once_with(metadata.get_url())
@@ -89,7 +97,7 @@ def metadata_update():
 def test_update(
         mock_box_session,
         make_mock_box_request,
-        test_file,
+        test_object,
         metadata_scope,
         metadata_template,
         metadata_response,
@@ -97,7 +105,7 @@ def test_update(
 ):
     # pylint:disable=redefined-outer-name
     mock_box_session.put.return_value, _ = make_mock_box_request(response=metadata_response)
-    metadata = test_file.metadata(metadata_scope, metadata_template)
+    metadata = test_object.metadata(metadata_scope, metadata_template)
     response = metadata.update(metadata_update)
     assert response is metadata_response
     mock_box_session.put.assert_called_once_with(
@@ -107,6 +115,6 @@ def test_update(
     )
 
 
-def test_start_update(test_file):
-    update = test_file.metadata().start_update()
+def test_start_update(test_object):
+    update = test_object.metadata().start_update()
     assert isinstance(update, MetadataUpdate)