chemistry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lmig...@apache.org
Subject svn commit: r1836987 - in /chemistry/cmislib/branches/py3_compat: ./ src/tests/
Date Sun, 29 Jul 2018 16:51:06 GMT
Author: lmignon
Date: Sun Jul 29 16:51:06 2018
New Revision: 1836987

URL: http://svn.apache.org/viewvc?rev=1836987&view=rev
Log:
[IMP] Move tests to py.test
Py.test allow us to run the same tests for a list of configurations. In one run we are therefore able to run the same tests for the browser binding and the atompub binding on alfresco. At this stage, the configurations is only defined for Alfresco, but it's easy to add configurations for others CMIS server.

Added:
    chemistry/cmislib/branches/py3_compat/.gitignore
    chemistry/cmislib/branches/py3_compat/src/tests/conftest.py
    chemistry/cmislib/branches/py3_compat/src/tests/test_acl.py
    chemistry/cmislib/branches/py3_compat/src/tests/test_changeentry.py
    chemistry/cmislib/branches/py3_compat/src/tests/test_cmisclient.py
    chemistry/cmislib/branches/py3_compat/src/tests/test_document.py
    chemistry/cmislib/branches/py3_compat/src/tests/test_folder.py
    chemistry/cmislib/branches/py3_compat/src/tests/test_query.py
    chemistry/cmislib/branches/py3_compat/src/tests/test_repository.py
    chemistry/cmislib/branches/py3_compat/src/tests/test_type.py
    chemistry/cmislib/branches/py3_compat/src/tests/tools.py
Removed:
    chemistry/cmislib/branches/py3_compat/src/tests/settings.py
    chemistry/cmislib/branches/py3_compat/src/tests/settings.py.sample
    chemistry/cmislib/branches/py3_compat/src/tests/test_cmislib.py
Modified:
    chemistry/cmislib/branches/py3_compat/src/tests/test_browser.py

Added: chemistry/cmislib/branches/py3_compat/.gitignore
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/.gitignore?rev=1836987&view=auto
==============================================================================
--- chemistry/cmislib/branches/py3_compat/.gitignore (added)
+++ chemistry/cmislib/branches/py3_compat/.gitignore Sun Jul 29 16:51:06 2018
@@ -0,0 +1,83 @@
+.project
+.pydevproject
+.settings/
+
+# pycharm dev env
+.idea/
+.ropeproject/
+
+release
+*.swp
+
+gcom_gateway/java_gateway/*.class
+gcom_gateway/java_gateway/dump
+gcom_gateway/java_gateway/trace
+gcom_gateway/java_gateway/sbi*
+
+# machine dependent config parameters
+odoo_addons/server_environment_files/local/
+odoo.cfg
+
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+*~
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*,cover
+.hypothesis/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+#Ipython Notebook
+.ipynb_checkpoints

Added: chemistry/cmislib/branches/py3_compat/src/tests/conftest.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/src/tests/conftest.py?rev=1836987&view=auto
==============================================================================
--- chemistry/cmislib/branches/py3_compat/src/tests/conftest.py (added)
+++ chemistry/cmislib/branches/py3_compat/src/tests/conftest.py Sun Jul 29 16:51:06 2018
@@ -0,0 +1,167 @@
+# -*- coding: utf-8 -*-
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you under the Apache License, Version 2.0 (the
+#      "License"); you may not use this file except in compliance
+#      with the License.  You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#      Unless required by applicable law or agreed to in writing,
+#      software distributed under the License is distributed on an
+#      "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#      KIND, either express or implied.  See the License for the
+#      specific language governing permissions and limitations
+#      under the License.
+#
+
+import os
+import tempfile
+from collections import namedtuple
+from time import time
+from time import sleep
+
+import pytest
+
+from cmislib.atompub import AtomPubBinding
+from cmislib.browser import BrowserBinding
+from cmislib.exceptions import \
+    NotSupportedException, RuntimeException
+from cmislib.model import CmisClient
+
+CmisEnv = namedtuple(
+    'CmisEnv',
+    ['env_name',
+     'binding',
+     'url',
+     'user',
+     'pwd',
+     'versionable_type_id',
+     'acl_principal_id',
+     'ext_args',
+     ]
+)
+
+
+CMIS_ENV_PARAMS = [
+    CmisEnv(
+        'alfresco',
+        BrowserBinding(),
+        'http://localhost:80/alfresco/api/-default-/cmis/versions/1.1/browser',
+        'admin',
+        'admin',
+        'cmis:document',
+        'anyone',
+        {}
+    ),
+    CmisEnv(
+        'alfresco',
+        AtomPubBinding(),
+        'http://localhost:80/alfresco/api/-default-/cmis/versions/1.1/atom',
+        'admin',
+        'admin',
+        'cmis:document',
+        'anyone',
+        {}
+
+    )
+]
+
+
+def _make_cmis_env_ids():
+    env_ids = []
+    for env in CMIS_ENV_PARAMS:
+        env_ids.append(
+            '{name}-{binding}'.format(
+                name=env.env_name,
+                binding=env.binding.__class__.__name__
+            )
+        )
+    return env_ids
+
+
+CMIS_ENV_IDS = _make_cmis_env_ids()
+MAX_FULL_TEXT_TRIES = 10
+
+
+@pytest.fixture(params=CMIS_ENV_PARAMS, ids=CMIS_ENV_IDS)
+def cmis_conf(request):
+    """Apply config params as attribute on the class"""
+    param = request.param
+    request.cls.max_full_text_tries = MAX_FULL_TEXT_TRIES
+    for field in param._fields:
+        setattr(request.cls, field, getattr(param, field))
+    request.cls.fixture_id =  '{name}-{binding}'.format(
+        name=param.env_name,
+        binding=param.binding.__class__.__name__
+    )
+
+
+@pytest.fixture(params=CMIS_ENV_PARAMS, ids=CMIS_ENV_IDS)
+def cmis_env(request):
+    """Initialize a cmis environement with
+    * CmisClient
+    * repo
+    * rootFolder
+    * test folder name
+    * test folder
+    All these attributes are reset after each test method
+    """
+    cmis_conf(request)
+    param = request.param
+    request.cls._cmisClient = CmisClient(
+        param.url, param.user, param.pwd, binding=param.binding,
+        **param.ext_args)
+    request.cls._repo = request.cls._cmisClient.getDefaultRepository()
+    request.cls._rootFolder = request.cls._repo.getRootFolder()
+    request.cls._folderName = " ".join([
+        'cmislib', request.cls.__name__, str(time())])
+    request.cls._testFolder = request.cls._rootFolder.createFolder(
+        request.cls._folderName)
+    yield request
+    try:
+        request.cls._testFolder.deleteTree()
+    except NotSupportedException:
+        print("Couldn't delete test folder because deleteTree is not "
+              "supported")
+    except RuntimeException:
+        # deleting a folder could fail if the indexation of a new document
+        # is in progress
+        sleep(5)
+        try:
+            request.cls._testFolder.deleteTree()
+        except RuntimeException:
+            print("Couldn't delete test folder")
+
+
+TEST_BINARY_1 = '250px-Cmis_logo.png'
+TEST_BINARY_2 = 'sample-a.pdf'
+
+
+@pytest.fixture(scope="class")
+def binary_files(request):
+    global TEST_BINARY_1
+    global TEST_BINARY_2
+    my_dir = os.path.dirname(os.path.abspath(__file__))
+    try:
+        os.stat(TEST_BINARY_1)
+    except OSError:
+        TEST_BINARY_1 = os.path.join(my_dir, TEST_BINARY_1)
+    try:
+        os.stat(TEST_BINARY_2)
+    except OSError:
+        TEST_BINARY_2 = os.path.join(my_dir, TEST_BINARY_2)
+    request.cls.binary_file_1 = TEST_BINARY_1
+    request.cls.binary_filename_1 = os.path.basename(TEST_BINARY_1)
+    request.cls.binary_file_2 = TEST_BINARY_2
+    request.cls.binary_filename_2 = os.path.basename(TEST_BINARY_2)
+
+
+@pytest.fixture()
+def cleandir():
+    """ Use temp directory as working directory"""
+    newpath = tempfile.mkdtemp()
+    os.chdir(newpath)

Added: chemistry/cmislib/branches/py3_compat/src/tests/test_acl.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/src/tests/test_acl.py?rev=1836987&view=auto
==============================================================================
--- chemistry/cmislib/branches/py3_compat/src/tests/test_acl.py (added)
+++ chemistry/cmislib/branches/py3_compat/src/tests/test_acl.py Sun Jul 29 16:51:06 2018
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you under the Apache License, Version 2.0 (the
+#      "License"); you may not use this file except in compliance
+#      with the License.  You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#      Unless required by applicable law or agreed to in writing,
+#      software distributed under the License is distributed on an
+#      "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#      KIND, either express or implied.  See the License for the
+#      specific language governing permissions and limitations
+#      under the License.
+#
+import pytest
+
+from cmislib import messages
+
+
+@pytest.mark.usefixtures('cmis_env')
+class TestACL:
+
+    """
+    Tests related to :class:`ACL` and :class:`ACE`
+    """
+
+    def testSupportedPermissions(self):
+        """Test the value of supported permissions enum"""
+        if not self._repo.getCapabilities()['ACL']:
+            print messages.NO_ACL_SUPPORT
+            return
+        assert self._repo.getSupportedPermissions() in ['basic', 'repository', 'both']
+
+    def testPermissionDefinitions(self):
+        """Test the list of permission definitions"""
+        if not self._repo.getCapabilities()['ACL']:
+            print messages.NO_ACL_SUPPORT
+            return
+        supportedPerms = self._repo.getPermissionDefinitions()
+        assert supportedPerms.has_key('cmis:write')
+
+    def testPermissionMap(self):
+        """Test the permission mapping"""
+        if not self._repo.getCapabilities()['ACL']:
+            print messages.NO_ACL_SUPPORT
+            return
+        permMap = self._repo.getPermissionMap()
+        assert permMap.has_key('canGetProperties.Object')
+        assert len(permMap['canGetProperties.Object']) > 0
+
+    def testPropagation(self):
+        """Test the propagation setting"""
+        if not self._repo.getCapabilities()['ACL']:
+            print messages.NO_ACL_SUPPORT
+            return
+        assert self._repo.getPropagation() in ['objectonly', 'propagate', 'repositorydetermined']
+
+    def testGetObjectACL(self):
+        """Test getting an object's ACL"""
+        if not self._repo.getCapabilities()['ACL']:
+            print messages.NO_ACL_SUPPORT
+            return
+        acl = self._testFolder.getACL()
+        for entry in acl.getEntries().values():
+            assert entry.principalId
+            assert entry.permissions
+
+    def testApplyACL(self):
+        """Test updating an object's ACL"""
+        if not self._repo.getCapabilities()['ACL']:
+            print messages.NO_ACL_SUPPORT
+            return
+        if not self._repo.getCapabilities()['ACL'] == 'manage':
+            print 'Repository does not support manage ACL'
+            return
+        if not self._repo.getSupportedPermissions() in ['both', 'basic']:
+            print 'Repository needs to support either both or basic permissions for this test'
+            return
+        acl = self._testFolder.getACL()
+        acl.removeEntry(self.acl_principal_id)
+        acl.addEntry(self.acl_principal_id, 'cmis:write')
+        acl = self._testFolder.applyACL(acl)
+        # would be good to check that the permission we get back is what we set
+        # but at least one server (Alf) appears to map the basic perm to a
+        # repository-specific perm
+        assert acl.getEntries().has_key(self.acl_principal_id)

Modified: chemistry/cmislib/branches/py3_compat/src/tests/test_browser.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/src/tests/test_browser.py?rev=1836987&r1=1836986&r2=1836987&view=diff
==============================================================================
--- chemistry/cmislib/branches/py3_compat/src/tests/test_browser.py (original)
+++ chemistry/cmislib/branches/py3_compat/src/tests/test_browser.py Sun Jul 29 16:51:06 2018
@@ -28,7 +28,7 @@ from cmislib.browser.binding import Brow
 from cmislib.browser.binding import BrowserACL
 
 
-class BrowserACLTest(unittest.TestCase):
+class TestBrowserACL(unittest.TestCase):
 
     def setUp(self):
         self.aceUser1 = BrowserACE(
@@ -42,56 +42,54 @@ class BrowserACLTest(unittest.TestCase):
         originalEntries = self.acl.originalEntries
         for entry in [self.aceUser1, self.aceUser2]:
             copy = originalEntries.get(entry.principalId)
-            self.assertTrue(copy)
+            assert copy
             # check we have 2 different instances of the same object
-            self.assertNotEquals(id(entry), id(copy))
-            self.assertEqual(entry, copy)
+            assert id(entry) != id(copy)
+            assert entry == copy
 
     def test_get_removed_aces(self):
         # test the complete removal of an alc entry
         self.acl.removeEntry(self.aceUser1.principalId)
         removedAces = self.acl.getRemovedAces()
-        self.assertEqual(len(removedAces), 1)
-        self.assertEqual(removedAces[0], self.aceUser1)
+        assert len(removedAces) == 1
+        assert removedAces[0] == self.aceUser1
         # test partial removal of an entry (delete all + add an existing one
         #  with same direct)
         self.acl.removeEntry(self.aceUser2.principalId)
         self.acl.addEntry(self.aceUser2.principalId, 'cmis:write',
                           direct=False)
         removedAces = self.acl.getRemovedAces()
-        self.assertEqual(len(removedAces), 2)
+        assert len(removedAces) == 2
         toCheck = None
         for removedAce in removedAces:
             if removedAce.principalId == self.aceUser2.principalId:
                 toCheck = removedAce
-        self.assertTrue(toCheck)
-        self.assertEqual(toCheck.principalId, self.aceUser2.principalId)
-        self.assertListEqual(toCheck.permissions, ['cmis:read'])
+        assert toCheck
+        assert toCheck.principalId == self.aceUser2.principalId
+        assert toCheck.permissions == ['cmis:read']
 
     def test_get_added_aces(self):
         # add new entry for a new princpal
         self.acl.addEntry('user3', 'cmis:all')
         addedAces = self.acl.getAddedAces()
-        self.assertEqual(len(addedAces), 1)
-        self.assertEqual(addedAces[0], BrowserACE('user3', 'cmis:all', True))
+        assert len(addedAces) == 1
+        assert addedAces[0] == BrowserACE('user3', 'cmis:all', True)
         # add a new entry for the same principal
         self.acl.addEntry(
             'user3', ['cmis:all', 'cmis:write'])
         addedAces = self.acl.getAddedAces()
-        self.assertEqual(len(addedAces), 1)
-        self.assertEqual(
-            addedAces[0],
-            BrowserACE('user3', ['cmis:all', 'cmis:write'], True))
+        assert len(addedAces) == 1
+        assert addedAces[0] == \
+            BrowserACE('user3', ['cmis:all', 'cmis:write'], True)
         # add a new entry for an exising principal
         self.acl.addEntry(
             self.aceUser1.principalId, ['cmis:read','cmis:write'])
         addedAces = self.acl.getAddedAces()
-        self.assertEqual(len(addedAces), 2)
+        assert len(addedAces) == 2
         toCheck = None
         for addedAce in addedAces:
             if addedAce.principalId == self.aceUser1.principalId:
                 toCheck = addedAce
-        self.assertTrue(toCheck)
-        self.assertEqual(
-            toCheck,
-            BrowserACE(self.aceUser1.principalId, ['cmis:write'], True))
+        assert toCheck
+        assert toCheck == \
+            BrowserACE(self.aceUser1.principalId, ['cmis:write'], True)

Added: chemistry/cmislib/branches/py3_compat/src/tests/test_changeentry.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/src/tests/test_changeentry.py?rev=1836987&view=auto
==============================================================================
--- chemistry/cmislib/branches/py3_compat/src/tests/test_changeentry.py (added)
+++ chemistry/cmislib/branches/py3_compat/src/tests/test_changeentry.py Sun Jul 29 16:51:06 2018
@@ -0,0 +1,115 @@
+
+# -*- coding: utf-8 -*-
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you under the Apache License, Version 2.0 (the
+#      "License"); you may not use this file except in compliance
+#      with the License.  You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#      Unless required by applicable law or agreed to in writing,
+#      software distributed under the License is distributed on an
+#      "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#      KIND, either express or implied.  See the License for the
+#      specific language governing permissions and limitations
+#      under the License.
+#
+import pytest
+
+from cmislib import messages
+
+
+@pytest.mark.usefixtures('cmis_env')
+class TestChangeEntry:
+
+    """ Tests for the :class:`ChangeEntry` class """
+
+    def testGetContentChanges(self):
+
+        """Get the content changes and inspect Change Entry props"""
+
+        # need to check changes capability
+        changeCap = self._repo.capabilities['Changes']
+        if changeCap == None or changeCap == 'none':
+            print messages.NO_CHANGE_LOG_SUPPORT
+            return
+
+        # at least one change should have been made due to the creation of the
+        # test documents
+        rs = self._repo.getContentChanges()
+        assert len(rs) > 0
+        changeEntry = rs[0]
+        assert changeEntry.objectId
+        assert changeEntry.changeType in ['created', 'updated', 'deleted', 'security']
+        assert changeEntry.changeTime
+
+    def testGetACL(self):
+
+        """Gets the ACL that is included with a Change Entry."""
+
+        # need to check changes capability
+        changeCap = self._repo.capabilities['Changes']
+        if changeCap == None or changeCap == 'none':
+            print messages.NO_CHANGE_LOG_SUPPORT
+            return
+
+        if changeCap == 'objectidsonly':
+            print messages.NO_CHANGE_OBJECT_SUPPORT
+            return
+
+        # need to check ACL capability
+        if not self._repo.capabilities['ACL']:
+            print messages.NO_ACL_SUPPORT
+            return
+
+        # need to test once with includeACL set to true
+        rs = self._repo.getContentChanges(includeACL='true')
+        assert len(rs) > 0
+        changeEntry = rs[0]
+        acl = changeEntry.getACL()
+        assert acl
+        for entry in acl.getEntries().values():
+            assert entry.principalId
+            assert entry.permissions
+
+        # need to test once without includeACL set
+        rs = self._repo.getContentChanges()
+        assert len(rs) > 0
+        changeEntry = rs[0]
+        acl = changeEntry.getACL()
+        assert acl
+        for entry in acl.getEntries().values():
+            assert entry.principalId
+            assert entry.permissions
+
+    def testGetProperties(self):
+
+        """Gets the properties of an object included with a Change Entry."""
+
+        # need to check changes capability
+        changeCap = self._repo.capabilities['Changes']
+        if changeCap == None or changeCap == 'none':
+            print messages.NO_CHANGE_LOG_SUPPORT
+            return
+
+        if changeCap == 'objectidsonly':
+            print messages.NO_CHANGE_OBJECT_SUPPORT
+            return
+
+        # need to test once without includeProperties set. the objectID should be there
+        rs = self._repo.getContentChanges()
+        assert len(rs) > 0
+        changeEntry = rs[0]
+        assert changeEntry.properties['cmis:objectId']
+
+        # need to test once with includeProperties set. the objectID should be there plus object props
+        if changeCap in ['properties', 'all']:
+            rs = self._repo.getContentChanges(includeProperties='true')
+            assert len(rs) > 0
+            changeEntry = rs[0]
+            assert changeEntry.properties['cmis:objectId']
+            assert changeEntry.properties['cmis:name']

Added: chemistry/cmislib/branches/py3_compat/src/tests/test_cmisclient.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/src/tests/test_cmisclient.py?rev=1836987&view=auto
==============================================================================
--- chemistry/cmislib/branches/py3_compat/src/tests/test_cmisclient.py (added)
+++ chemistry/cmislib/branches/py3_compat/src/tests/test_cmisclient.py Sun Jul 29 16:51:06 2018
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you under the Apache License, Version 2.0 (the
+#      "License"); you may not use this file except in compliance
+#      with the License.  You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#      Unless required by applicable law or agreed to in writing,
+#      software distributed under the License is distributed on an
+#      "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#      KIND, either express or implied.  See the License for the
+#      specific language governing permissions and limitations
+#      under the License.
+#
+import pytest
+
+from cmislib.exceptions import \
+    ObjectNotFoundException, \
+    CmisException
+from cmislib.model import CmisClient
+
+
+@pytest.mark.usefixtures('cmis_conf')
+class TestCmisClient:
+
+    """ Tests for the :class:`CmisClient` class. """
+
+    def testCmisClient(self):
+        """Instantiate a CmisClient object"""
+        cmisClient = CmisClient(self.url, self.user, self.pwd,
+                                binding=self.binding,
+                                **self.ext_args)
+        assert cmisClient is not None
+
+    def testGetRepositories(self):
+        """Call getRepositories and make sure at least one comes back with
+        an ID and a name
+        """
+        cmisClient = CmisClient(self.url, self.user, self.pwd,
+                                binding=self.binding,
+                                **self.ext_args)
+        repoInfo = cmisClient.getRepositories()
+        assert len(repoInfo) >= 1
+        assert 'repositoryId' in repoInfo[0]
+        assert 'repositoryName' in repoInfo[0]
+
+    def testDefaultRepository(self):
+        """Get the default repository by calling the repo's service URL"""
+        cmisClient = CmisClient(self.url, self.user, self.pwd,
+                                binding=self.binding,
+                                **self.ext_args)
+        repo = cmisClient.getDefaultRepository()
+        assert repo is not None
+        assert repo.getRepositoryId() is not None
+
+    def testGetRepository(self):
+        """Get a repository by repository ID"""
+        cmisClient = CmisClient(self.url, self.user, self.pwd,
+                                binding=self.binding,
+                                **self.ext_args)
+        repo = cmisClient.getDefaultRepository()
+        defaultRepoId = repo.getRepositoryId()
+        defaultRepoName = repo.getRepositoryName()
+        repo = cmisClient.getRepository(defaultRepoId)
+        assert defaultRepoId == repo.getRepositoryId()
+        assert defaultRepoName == repo.getRepositoryName()
+
+    # Error conditions
+    def testCmisClientBadUrl(self):
+        """Try to instantiate a CmisClient object with a known bad URL"""
+        cmisClient = CmisClient(self.url + 'foobar', self.user, self.pwd,
+                                binding=self.binding,
+                                **self.ext_args)
+        with pytest.raises(CmisException):
+            cmisClient.getRepositories()
+
+    def testGetRepositoryBadId(self):
+        """Try to get a repository with a bad repo ID"""
+        cmisClient = CmisClient(self.url, self.user, self.pwd,
+                                binding=self.binding,
+                                **self.ext_args)
+        with pytest.raises(ObjectNotFoundException):
+            cmisClient.getRepository('123FOO')

Added: chemistry/cmislib/branches/py3_compat/src/tests/test_document.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/src/tests/test_document.py?rev=1836987&view=auto
==============================================================================
--- chemistry/cmislib/branches/py3_compat/src/tests/test_document.py (added)
+++ chemistry/cmislib/branches/py3_compat/src/tests/test_document.py Sun Jul 29 16:51:06 2018
@@ -0,0 +1,598 @@
+# -*- coding: utf-8 -*-
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you under the Apache License, Version 2.0 (the
+#      "License"); you may not use this file except in compliance
+#      with the License.  You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#      Unless required by applicable law or agreed to in writing,
+#      software distributed under the License is distributed on an
+#      "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#      KIND, either express or implied.  See the License for the
+#      specific language governing permissions and limitations
+#      under the License.
+#
+import os
+from contextlib import closing
+from time import sleep
+
+import pytest
+
+from cmislib.exceptions import \
+    CmisException, \
+    NotSupportedException
+from .tools import skipIfAlfrescoPubBinding
+from .tools import skipIfAlfrescoBrowserBinding
+
+
+@pytest.mark.usefixtures('cmis_env', 'binary_files')
+class TestDocument:
+
+    """ Tests for the :class:`Document` class """
+
+    def testCheckout(self):
+        """Create a document in a test folder, then check it out"""
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        newDoc = self._testFolder.createDocument(
+            'testDocument', properties=props)
+        if not 'canCheckOut' in newDoc.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwcDoc = newDoc.checkout()
+        try:
+            assert newDoc.isCheckedOut()
+            assert 'cmis:objectId' in newDoc.getProperties()
+            assert 'cmis:objectId' in pwcDoc.getProperties()
+        finally:
+            pwcDoc.delete()
+
+    #CMIS-743
+    def testCheckoutAfterFetchByID(self):
+        """Create a test doc, fetch it by ID, then check it out"""
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        newDoc = self._testFolder.createDocument(
+            'testDocument', properties=props)
+        if not 'canCheckOut' in newDoc.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        newDocIdStr = str(newDoc.id)
+        newDoc = self._repo.getObject(newDocIdStr)
+        pwcDoc = newDoc.checkout()
+        try:
+            assert newDoc.isCheckedOut()
+            assert 'cmis:objectId' in newDoc.getProperties()
+            assert 'cmis:objectId' in pwcDoc.getProperties()
+        finally:
+            pwcDoc.delete()
+
+    def testCheckin(self):
+        """Create a document in a test folder, check it out, then in"""
+        testFilename = self.binary_filename_1
+
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        with open(self.binary_file_1, 'rb') as f:
+            testDoc = self._testFolder.createDocument(
+                testFilename, contentFile=f, properties=props)
+        assert testFilename == testDoc.getName()
+        if not 'canCheckOut' in testDoc.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwcDoc = testDoc.checkout()
+
+        try:
+            assert testDoc.isCheckedOut()
+            assert 'cmis:objectId' in testDoc.getProperties()
+            assert 'cmis:objectId' in pwcDoc.getProperties()
+            testDoc = pwcDoc.checkin()
+            assert not testDoc.isCheckedOut()
+        finally:
+            if testDoc.isCheckedOut():
+                pwcDoc.delete()
+
+    def testCheckinComment(self):
+        """Checkin a document with a comment"""
+        testFilename = self.binary_filename_1
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        with open(self.binary_file_1, 'rb') as f:
+            testDoc = self._testFolder.createDocument(
+                testFilename, contentFile=f, properties=props)
+        assert testFilename == testDoc.getName()
+        if not 'canCheckOut' in testDoc.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwcDoc = testDoc.checkout()
+        try:
+            assert testDoc.isCheckedOut()
+            testDoc = pwcDoc.checkin(checkinComment='Just a few changes')
+            assert not testDoc.isCheckedOut()
+            assert 'Just a few changes' == \
+                          testDoc.getProperties()['cmis:checkinComment']
+        finally:
+            if testDoc.isCheckedOut():
+                pwcDoc.delete()
+
+    @skipIfAlfrescoPubBinding
+    def testCheckinContentAndProperties(self):
+        """Checkin a document with a new content a modifed properties"""
+        testFilename = self.binary_filename_1
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        with open(self.binary_file_1, 'rb') as f:
+            testDoc = self._testFolder.createDocument(
+                testFilename, contentFile=f, properties=props)
+        assert testFilename == testDoc.getName()
+        if not 'canCheckOut' in testDoc.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwcDoc = testDoc.checkout()
+        try:
+            assert testDoc.isCheckedOut()
+            testFile2 = self.binary_file_2
+            testFile2Size = os.path.getsize(testFile2)
+            exportFile2 = testFile2.replace('.', 'export.')
+            contentFile2 = open(testFile2, 'rb')
+            props = {'cmis:name': 'testDocument2'}
+            testDoc = pwcDoc.checkin(
+                contentFile=contentFile2,
+                properties=props)
+            contentFile2.close()
+            assert not testDoc.isCheckedOut()
+            assert 'testDocument2' == testDoc.getName()
+
+            # expport the result
+            result = testDoc.getContentStream()
+            outfile = open(exportFile2, 'wb')
+            outfile.write(result.read())
+            result.close()
+            outfile.close()
+
+            # the file we exported should be the same size as the file we
+            # originally created
+            assert testFile2Size == os.path.getsize(exportFile2)
+
+        finally:
+            if testDoc.isCheckedOut():
+                pwcDoc.delete()
+
+    def testCheckinAfterGetPWC(self):
+        """Create a document in a test folder, check it out, call getPWC,
+        then checkin
+        """
+        if not self._repo.getCapabilities()['PWCUpdatable'] == True:
+            pytest.skip('Repository does not support PWCUpdatable, skipping')
+        testFilename = self.binary_filename_1
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        with open(self.binary_file_1, 'rb') as f:
+            testDoc = self._testFolder.createDocument(
+                testFilename, contentFile=f, properties=props)
+        assert testFilename == testDoc.getName()
+        # Alfresco has a bug where if you get the PWC this way
+        # the checkin will not be successful
+        if not 'canCheckOut' in testDoc.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        testDoc.checkout()
+        pwcDoc = testDoc.getPrivateWorkingCopy()
+        try:
+            assert testDoc.isCheckedOut()
+            assert 'cmis:objectId' in testDoc.getProperties()
+            assert 'cmis:objectId' in pwcDoc.getProperties()
+            testDoc = pwcDoc.checkin()
+            assert not testDoc.isCheckedOut()
+        finally:
+            if testDoc.isCheckedOut():
+                pwcDoc.delete()
+
+    def testCancelCheckout(self):
+        """Create a document in a test folder, check it out, then cancel
+        checkout"""
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        newDoc = self._testFolder.createDocument(
+            'testDocument', properties=props)
+        if not 'canCheckOut' in newDoc.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwcDoc = newDoc.checkout()
+        try:
+            assert newDoc.isCheckedOut()
+            assert 'cmis:objectId' in newDoc.getProperties()
+            assert 'cmis:objectId' in pwcDoc.getProperties()
+        finally:
+            pwcDoc.delete()
+        assert not newDoc.isCheckedOut()
+
+    def testDeleteDocument(self):
+        """Create a document in a test folder, then delete it"""
+        newDoc = self._testFolder.createDocument('testDocument')
+        children = self._testFolder.getChildren()
+        assert 1 == len(children.getResults())
+        newDoc.delete()
+        children = self._testFolder.getChildren()
+        assert 0 == len(children.getResults())
+
+    def testGetLatestVersion(self):
+        """Get latest version of an object"""
+        fileName = self.binary_filename_1
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        with open(self.binary_file_1, 'rb') as f:
+            doc10 = self._testFolder.createDocument(
+                fileName, contentFile=f, properties=props)
+        if not 'canCheckOut' in doc10.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwc = doc10.checkout()
+        doc11 = pwc.checkin(major='false')  # checkin a minor version, 1.1
+        if not 'canCheckOut' in doc11.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwc = doc11.checkout()
+        doc20 = pwc.checkin()  # checkin a major version, 2.0
+        doc20Id = doc20.getObjectId()
+        if not 'canCheckOut' in doc20.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwc = doc20.checkout()
+        doc21 = pwc.checkin(major='false')  # checkin a minor version, 2.1
+        doc21Id = doc21.getObjectId()
+
+        docLatest = doc10.getLatestVersion()
+        assert doc21Id == docLatest.getObjectId()
+
+        docLatestMajor = doc10.getLatestVersion(major='true')
+        assert doc20Id == docLatestMajor.getObjectId()
+
+    def testGetPropertiesOfLatestVersion(self):
+        """Get properties of latest version of an object"""
+        fileName = self.binary_filename_1
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        with open(self.binary_file_1, 'rb') as f:
+            doc10 = self._testFolder.createDocument(
+                fileName, contentFile=f, properties=props)
+        if not 'canCheckOut' in doc10.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwc = doc10.checkout()
+        doc11 = pwc.checkin(major='false')  # checkin a minor version, 1.1
+        if not 'canCheckOut' in doc11.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwc = doc11.checkout()
+        doc20 = pwc.checkin()  # checkin a major version, 2.0
+        # what comes back from a checkin may not include all props, so reload
+        doc20.reload()
+        doc20Label = doc20.getProperties()['cmis:versionLabel']
+        if not 'canCheckOut' in doc20.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwc = doc20.checkout()
+        doc21 = pwc.checkin(major='false')  # checkin a minor version, 2.1
+        # what comes back from a checkin may not include all props, so reload
+        doc21.reload()
+        doc21Label = doc21.getProperties()['cmis:versionLabel']
+
+        propsLatest = doc10.getPropertiesOfLatestVersion()
+        assert doc21Label == propsLatest['cmis:versionLabel']
+
+        propsLatestMajor = doc10.getPropertiesOfLatestVersion(major='true')
+        assert doc20Label == propsLatestMajor['cmis:versionLabel']
+
+    def testGetProperties(self):
+        """Create a document in a test folder, then get its properties"""
+        newDoc = self._testFolder.createDocument('testDocument')
+        assert 'testDocument' == newDoc.getName()
+        assert 'cmis:objectTypeId' in newDoc.getProperties()
+        assert 'cmis:objectId' in newDoc.getProperties()
+
+    def testAllowableActions(self):
+        """Create document in a test folder, then get its allowable actions"""
+        newDoc = self._testFolder.createDocument('testDocument')
+        actions = newDoc.getAllowableActions()
+        assert len(actions) > 0
+
+    def testUpdateProperties(self):
+        """Create a document in a test folder, then update its properties"""
+        newDoc = self._testFolder.createDocument('testDocument')
+        assert 'testDocument' == newDoc.getName()
+        props = {'cmis:name': 'testDocument2'}
+        newDoc.updateProperties(props)
+        assert 'testDocument2' == newDoc.getName()
+
+    def testSetContentStreamPWC(self):
+        """Set the content stream on the PWC"""
+        if self._repo.getCapabilities()['ContentStreamUpdatability'] == 'none':
+            pytest.skip(
+                'This repository does not allow content stream updates, '
+                'skipping')
+
+        testFile1 = self.binary_file_1
+        fileName1 = self.binary_filename_1
+        testFile1Size = os.path.getsize(testFile1)
+        exportFile1 = testFile1.replace('.', 'export.')
+        testFile2 = self.binary_file_2
+        testFile2Size = os.path.getsize(testFile2)
+        exportFile2 = testFile1.replace('.', 'export.')
+
+        # create a test document
+        with open(testFile1, 'rb') as contentFile:
+            newDoc = self._testFolder.createDocument(
+                fileName1, contentFile=contentFile)
+
+        # export the test document
+        result = newDoc.getContentStream()
+        with closing(result),  open(exportFile1, 'wb') as outfile:
+            outfile.write(result.read())
+
+        # the file we exported should be the same size as the file we
+        # originally created
+        assert testFile1Size == os.path.getsize(exportFile1)
+
+        # checkout the file
+        if newDoc.allowableActions.has_key('canCheckOut') and \
+                newDoc.allowableActions['canCheckOut'] == True:
+            pass
+        else:
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwc = newDoc.checkout()
+
+        # update the PWC with a new file
+        with open(testFile2, 'rb') as f:
+            pwc.setContentStream(f)
+
+        # checkin the PWC
+        newDoc = pwc.checkin()
+
+        # export the checked in document
+        result = newDoc.getContentStream()
+        with closing(result), open(exportFile2, 'wb') as outfile:
+            outfile.write(result.read())
+
+        # the file we exported should be the same size as the file we
+        # checked in after updating the PWC
+        assert testFile2Size == os.path.getsize(exportFile2)
+        os.remove(exportFile2)
+
+    def testSetContentStreamPWCMimeType(self):
+        """Check the mimetype after the PWC checkin"""
+        if self._repo.getCapabilities()['ContentStreamUpdatability'] == 'none':
+            print 'This repository does not allow content stream updates, skipping'
+            return
+
+        testFile1 = self.binary_file_1
+        fileName = testFile1.split('/')[-1]
+
+        # create a test document
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        with open(self.binary_file_1, 'rb') as f:
+            newDoc = self._testFolder.createDocument(
+                fileName, contentFile=f, properties=props)
+        origMimeType = newDoc.properties['cmis:contentStreamMimeType']
+
+        # checkout the file
+        if not 'canCheckOut' in newDoc.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwc = newDoc.checkout()
+
+        # update the PWC with a new file
+        with open(testFile1, 'rb') as f:
+            pwc.setContentStream(f)
+
+        # checkin the PWC
+        newDoc = pwc.checkin()
+
+        # CMIS-231 the checked in doc should have the same mime type as
+        # the original document
+        assert origMimeType == \
+                          newDoc.properties['cmis:contentStreamMimeType']
+
+    @skipIfAlfrescoPubBinding
+    @skipIfAlfrescoBrowserBinding
+    def testSetContentStreamDoc(self):
+        """Set the content stream on a doc that's not checked out"""
+        if self._repo.getCapabilities()['ContentStreamUpdatability'] != 'anytime':
+            pytest.skip('This repository does not allow content stream '
+                        'updates on the doc, skipping')
+
+        testFile1 = self.binary_file_1
+        testFile1Size = os.path.getsize(testFile1)
+        exportFile1 = testFile1.replace('.', 'export.')
+        testFile2 = self.binary_file_2
+        testFile2Size = os.path.getsize(testFile2)
+        exportFile2 = testFile2.replace('.', 'export.')
+
+        # create a test document
+        fileName = testFile1.split('/')[-1]
+        with open(testFile1, 'rb') as contentFile:
+            newDoc = self._testFolder.createDocument(
+                fileName, contentFile=contentFile)
+
+        # export the test document
+        result = newDoc.getContentStream()
+        with closing(result), open(exportFile1, 'wb') as outfile:
+            outfile.write(result.read())
+
+        # the file we exported should be the same size as the file we
+        # originally created
+        assert testFile1Size == os.path.getsize(exportFile1)
+
+        # update the PWC with a new file
+        with open(testFile2, 'rb') as f:
+            newDoc.setContentStream(f)
+
+        # export the checked in document
+        result = newDoc.getContentStream()
+        with closing(result),  open(exportFile2, 'wb') as outfile:
+            outfile.write(result.read())
+
+        # the file we exported should be the same size as the file we
+        # checked in after updating the PWC
+        assert testFile2Size == os.path.getsize(exportFile2)
+        os.remove(exportFile2)
+
+    def testDeleteContentStreamPWC(self):
+        """Delete the content stream of a PWC"""
+        if self._repo.getCapabilities()['ContentStreamUpdatability'] == 'none':
+            pytest.skip(
+                'This repository does not allow content stream updates, '
+                'skipping')
+        if not self._repo.getCapabilities()['PWCUpdatable'] == True:
+            pytest.skip('Repository does not support PWCUpdatable, skipping')
+
+        # create a test document
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        fileName = self.binary_filename_1
+        with open(self.binary_file_1, 'rb') as f:
+            newDoc = self._testFolder.createDocument(
+                fileName, contentFile=f, properties=props)
+        if not 'canCheckOut' in newDoc.allowableActions.keys():
+            print 'The test doc cannot be checked out...skipping'
+            return
+        pwc = newDoc.checkout()
+        pwc.deleteContentStream()
+        with pytest.raises(CmisException):
+            pwc.getContentStream()
+        pwc.delete()
+
+    def testCreateDocumentBinary(self):
+        """Create a binary document using a file from the file system"""
+        testFile = self.binary_file_1
+        testFilename = testFile.split('/')[-1]
+        with open(testFile, 'rb') as f:
+            newDoc = self._testFolder.createDocument(
+                testFilename, contentFile=f)
+        assert testFilename == newDoc.getName()
+
+        # test to make sure the file we get back is the same length
+        # as the file we sent
+        result = newDoc.getContentStream()
+        exportFilename = testFilename.replace('.', 'export.')
+        with closing(result), open(exportFilename, 'wb') as outfile:
+            outfile.write(result.read())
+        assert os.path.getsize(testFile) == \
+                          os.path.getsize(exportFilename)
+
+        # cleanup
+        os.remove(exportFilename)
+
+    def testCreateDocumentFromString(self):
+        """Create a new document from a string"""
+        documentName = 'testDocument'
+        contentString = 'Test content string'
+        newDoc = self._testFolder.createDocumentFromString(documentName,
+            contentString=contentString, contentType='text/plain')
+        assert documentName == newDoc.getName()
+        assert newDoc.getContentStream().read() == contentString
+
+    def testCreateDocumentPlain(self):
+        """Create a plain document using a file from the file system"""
+        testFilename = 'plain.txt'
+        with open(testFilename, 'w') as testFile:
+            testFile.write('This is a sample text file line 1.\n')
+            testFile.write('This is a sample text file line 2.\n')
+            testFile.write('This is a sample text file line 3.\n')
+
+        with open(testFilename, 'r') as contentFile:
+            newDoc = self._testFolder.createDocument(
+                testFilename, contentFile=contentFile)
+        assert testFilename == newDoc.getName()
+
+        # test to make sure the file we get back is the same length as the
+        # file we sent
+        result = newDoc.getContentStream()
+        exportFilename = testFilename.replace('txt', 'export.txt')
+        with closing(result), open(exportFilename, 'w') as outfile:
+            outfile.write(result.read())
+        assert os.path.getsize(testFilename) == \
+                          os.path.getsize(exportFilename)
+
+        # export
+        os.remove(exportFilename)
+        os.remove(testFilename)
+
+    def testGetAllVersions(self):
+        """Get all versions of an object"""
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        testDoc = self._testFolder.createDocument('testdoc', properties=props)
+        if not 'canCheckOut' in testDoc.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwc = testDoc.checkout()
+        doc = pwc.checkin()  # 2.0
+        if not 'canCheckOut' in doc.allowableActions.keys():
+            pytest.skip('The test doc cannot be checked out...skipping')
+        pwc = doc.checkout()
+        doc = pwc.checkin()  # 3.0
+        # what comes back from a checkin may not include all props, so reload
+        doc.reload()
+        # InMemory 0.9 is using 'V 3.0' so this test fails with that server
+        #self.assertEquals('3.0', doc.getProperties()['cmis:versionLabel'])
+        rs = doc.getAllVersions()
+        assert 3 == len(rs.getResults())
+#        for count in range(0, 3):
+#            if count == 0:
+#                self.assertEquals('true',
+#                             rs.getResults().values()[count].getProperties()['cmis:isLatestVersion'])
+#            else:
+#                self.assertEquals('false',
+#                             rs.getResults().values()[count].getProperties()['cmis:isLatestVersion'])
+
+    def testGetObjectParents(self):
+        """Gets all object parents of an CmisObject"""
+        childFolder = self._testFolder.createFolder('parentTest')
+        parentFolder = childFolder.getObjectParents().getResults()[0]
+        assert self._testFolder.getObjectId() == parentFolder.getObjectId()
+
+    def testGetObjectParentsWithinRootFolder(self):
+        """Gets all object parents of a root folder"""
+        rootFolder = self._repo.getRootFolder()
+        with pytest.raises(NotSupportedException):
+            rootFolder.getObjectParents()
+
+    def testGetObjectParentsMultiple(self):
+        """Gets all parents of a multi-filed object"""
+        if not self._repo.getCapabilities()['Multifiling']:
+            pytest.skip('This repository does not allow multifiling, skipping')
+
+        subFolder1 = self._testFolder.createFolder('sub1')
+        doc = subFolder1.createDocument('testdoc1')
+        assert len(subFolder1.getChildren()) == 1
+        subFolder2 = self._testFolder.createFolder('sub2')
+        assert len(subFolder2.getChildren()) == 0
+        subFolder2.addObject(doc)
+        assert len(subFolder2.getChildren()) == 1
+        assert subFolder1.getChildren()[0].name == subFolder2.getChildren()[0].name
+        parentNames = ['sub1', 'sub2']
+        for parent in doc.getObjectParents():
+            parentNames.remove(parent.name)
+        assert len(parentNames) == 0
+
+    def testGetPaths(self):
+        """Get the paths of a document"""
+        testDoc = self._testFolder.createDocument('testdoc')
+        # ask the test doc for its paths
+        paths = testDoc.getPaths()
+        assert len(paths) >= 1
+
+    @skipIfAlfrescoPubBinding
+    def testRelationship(self):
+        testDoc = self._testFolder.createDocument('testdoc')
+        testDoc2 = self._testFolder.createDocument('testdoc2')
+        relations = testDoc.getRelationships(relationshipDirection="either")
+        assert 0 == len(relations)
+        if not testDoc.getAllowableActions().get('canCreateRelationship'):
+            pytest.skip('createRelationship not supported, skipping')
+        if not self._repo.getTypeDefinition('R:cm:replaces'):
+            pytest.skip('createRelationship not supported, skipping')
+
+        relation = testDoc.createRelationship(testDoc2, 'R:cm:replaces')
+        assert testDoc.getObjectId() == relation.source.getObjectId()
+        assert testDoc2.getObjectId() == relation.target.getObjectId()
+        relations = testDoc.getRelationships()
+        assert 1 == len(relations)
+        relation = relations[0]
+        assert testDoc.getObjectId() == relation.source.getObjectId()
+        assert testDoc2.getObjectId() == relation.target.getObjectId()
+
+    def testRenditions(self):
+        """Get the renditions for a document"""
+        if not self._repo.getCapabilities().has_key('Renditions'):
+            pytest.skip('Repo does not support unfiling, skipping')
+
+        testDoc = self._testFolder.createDocumentFromString(
+            'testdoc.txt', contentString='test', contentType='text/plain')
+        sleep(10)
+        if (testDoc.getAllowableActions().has_key('canGetRenditions') and
+            testDoc.getAllowableActions()['canGetRenditions'] == True):
+            rends = testDoc.getRenditions()
+            assert len(rends) >= 1
+        else:
+            pytest.skip('Test doc does not have rendition, skipping')

Added: chemistry/cmislib/branches/py3_compat/src/tests/test_folder.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/src/tests/test_folder.py?rev=1836987&view=auto
==============================================================================
--- chemistry/cmislib/branches/py3_compat/src/tests/test_folder.py (added)
+++ chemistry/cmislib/branches/py3_compat/src/tests/test_folder.py Sun Jul 29 16:51:06 2018
@@ -0,0 +1,288 @@
+# -*- coding: utf-8 -*-
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you under the Apache License, Version 2.0 (the
+#      "License"); you may not use this file except in compliance
+#      with the License.  You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#      Unless required by applicable law or agreed to in writing,
+#      software distributed under the License is distributed on an
+#      "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#      KIND, either express or implied.  See the License for the
+#      specific language governing permissions and limitations
+#      under the License.
+#
+import pytest
+
+from cmislib.exceptions import \
+    CmisException
+from .tools import isInResultSet
+
+
+@pytest.mark.usefixtures('cmis_env')
+class TestFolder:
+
+    """ Tests for the :class:`Folder` class """
+
+    def testGetChildren(self):
+        """Get the children of the test folder"""
+        childFolderName1 = 'testchild1'
+        childFolderName2 = 'testchild2'
+        grandChildFolderName = 'testgrandchild'
+        childFolder1 = self._testFolder.createFolder(childFolderName1)
+        childFolder2 = self._testFolder.createFolder(childFolderName2)
+        grandChild = childFolder2.createFolder(grandChildFolderName)
+        resultSet = self._testFolder.getChildren()
+        assert resultSet is not None
+        assert 2 == len(resultSet.getResults())
+        assert isInResultSet(resultSet, childFolder1)
+        assert isInResultSet(resultSet, childFolder2)
+        assert not isInResultSet(resultSet, grandChild)
+
+    def testGetDescendants(self):
+        """Get the descendants of the root folder"""
+        childFolderName1 = 'testchild1'
+        childFolderName2 = 'testchild2'
+        grandChildFolderName1 = 'testgrandchild'
+        childFolder1 = self._testFolder.createFolder(childFolderName1)
+        childFolder2 = self._testFolder.createFolder(childFolderName2)
+        grandChild = childFolder1.createFolder(grandChildFolderName1)
+
+        # test getting descendants with depth=1
+        resultSet = self._testFolder.getDescendants(depth=1)
+        assert resultSet is not None
+        assert 2 == len(resultSet.getResults())
+        assert isInResultSet(resultSet, childFolder1)
+        assert isInResultSet(resultSet, childFolder2)
+        assert not isInResultSet(resultSet, grandChild)
+
+        # test getting descendants with depth=2
+        resultSet = self._testFolder.getDescendants(depth=2)
+        assert resultSet is not None
+        assert 3 == len(resultSet.getResults())
+        assert isInResultSet(resultSet, childFolder1)
+        assert isInResultSet(resultSet, childFolder2)
+        assert isInResultSet(resultSet, grandChild)
+
+        # test getting descendants with depth=-1
+        resultSet = self._testFolder.getDescendants()  # -1 is the default depth
+        assert resultSet is not None
+        assert 3 == len(resultSet.getResults())
+        assert isInResultSet(resultSet, childFolder1)
+        assert isInResultSet(resultSet, childFolder2)
+        assert isInResultSet(resultSet, grandChild)
+
+    def testGetTree(self):
+        """Get the folder tree of the test folder"""
+        childFolderName1 = 'testchild1'
+        childFolderName2 = 'testchild2'
+        grandChildFolderName1 = 'testgrandchild'
+        childFolder1 = self._testFolder.createFolder(childFolderName1)
+        childFolder1.createDocument('testdoc1')
+        childFolder2 = self._testFolder.createFolder(childFolderName2)
+        childFolder2.createDocument('testdoc2')
+        grandChild = childFolder1.createFolder(grandChildFolderName1)
+        grandChild.createDocument('testdoc3')
+
+        # test getting tree with depth=1
+        resultSet = self._testFolder.getTree(depth=1)
+        assert resultSet is not None
+        assert 2 == len(resultSet.getResults())
+        assert isInResultSet(resultSet, childFolder1)
+        assert isInResultSet(resultSet, childFolder2)
+        assert not isInResultSet(resultSet, grandChild)
+
+        # test getting tree with depth=2
+        resultSet = self._testFolder.getTree(depth=2)
+        assert resultSet is not None
+        assert 3 == len(resultSet.getResults())
+        assert isInResultSet(resultSet, childFolder1)
+        assert isInResultSet(resultSet, childFolder2)
+        assert isInResultSet(resultSet, grandChild)
+
+    def testDeleteEmptyFolder(self):
+        """Create a test folder, then delete it"""
+        folderName = 'testDeleteEmptyFolder folder'
+        testFolder = self._testFolder.createFolder(folderName)
+        assert folderName == testFolder.getName()
+        newFolder = testFolder.createFolder('testFolder')
+        testFolderChildren = testFolder.getChildren()
+        assert 1 == len(testFolderChildren.getResults())
+        newFolder.delete()
+        testFolderChildren = testFolder.getChildren()
+        assert 0 == len(testFolderChildren.getResults())
+
+    def testDeleteNonEmptyFolder(self):
+        """Create a test folder with something in it, then delete it"""
+        folderName = 'testDeleteNonEmptyFolder folder'
+        testFolder = self._testFolder.createFolder(folderName)
+        assert folderName == testFolder.getName()
+        newFolder = testFolder.createFolder('testFolder')
+        testFolderChildren = testFolder.getChildren()
+        assert 1 == len(testFolderChildren.getResults())
+        newFolder.createDocument('testDoc')
+        assert 1 == len(newFolder.getChildren().getResults())
+        newFolder.deleteTree()
+        testFolderChildren = testFolder.getChildren()
+        assert 0 == len(testFolderChildren.getResults())
+
+    def testGetProperties(self):
+        """Get the root folder, then get its properties"""
+        props = self._testFolder.getProperties()
+        assert props is not None
+        assert 'cmis:objectId' in props
+        assert props['cmis:objectId'] is not None
+        assert 'cmis:objectTypeId' in props
+        assert props['cmis:objectTypeId'] is not None
+        assert 'cmis:name' in props
+        assert props['cmis:name'] is not None
+
+    def testPropertyFilter(self):
+        """Test the properties filter"""
+        # names of folders and test docs
+        parentFolderName = 'testGetObjectByPath folder'
+        subFolderName = 'subfolder'
+
+        # create the folder structure
+        parentFolder = self._testFolder.createFolder(parentFolderName)
+        subFolder = parentFolder.createFolder(subFolderName)
+        subFolderPath = subFolder.getProperties().get("cmis:path")
+
+        # Per CMIS-170, CMIS providers are not required to filter the
+        # properties returned. So these tests will check only for the presence
+        # of the properties asked for, not the absence of properties that
+        # should be filtered if the server chooses to do so.
+
+        # test when used with getObjectByPath
+        searchFolder = self._repo.getObjectByPath(subFolderPath,
+                        filter='cmis:objectId,cmis:objectTypeId,cmis:baseTypeId')
+        assert subFolder.getObjectId() == searchFolder.getObjectId()
+        assert searchFolder.getProperties().has_key('cmis:objectId')
+        assert searchFolder.getProperties().has_key('cmis:objectTypeId')
+        assert searchFolder.getProperties().has_key('cmis:baseTypeId')
+
+        # test when used with getObjectByPath + reload
+        searchFolder = self._repo.getObjectByPath(subFolderPath,
+                        filter='cmis:objectId,cmis:objectTypeId,cmis:baseTypeId')
+        searchFolder.reload()
+        assert subFolder.getObjectId() == searchFolder.getObjectId()
+        assert searchFolder.getProperties().has_key('cmis:objectId')
+        assert searchFolder.getProperties().has_key('cmis:objectTypeId')
+        assert searchFolder.getProperties().has_key('cmis:baseTypeId')
+
+        # test when used with getObject
+        searchFolder = self._repo.getObject(subFolder.getObjectId(),
+                        filter='cmis:objectId,cmis:objectTypeId,cmis:baseTypeId')
+        assert subFolder.getObjectId() == searchFolder.getObjectId()
+        assert searchFolder.getProperties().has_key('cmis:objectId')
+        assert searchFolder.getProperties().has_key('cmis:objectTypeId')
+        assert searchFolder.getProperties().has_key('cmis:baseTypeId')
+
+        # test when used with getObject + reload
+        searchFolder = self._repo.getObject(subFolder.getObjectId(),
+                        filter='cmis:objectId,cmis:objectTypeId,cmis:baseTypeId')
+        searchFolder.reload()
+        assert subFolder.getObjectId() == searchFolder.getObjectId()
+        assert searchFolder.getProperties().has_key('cmis:objectId')
+        assert searchFolder.getProperties().has_key('cmis:objectTypeId')
+        assert searchFolder.getProperties().has_key('cmis:baseTypeId')
+
+        # test that you can do a reload with a reset filter
+        searchFolder.reload(filter='*')
+        assert searchFolder.getProperties().has_key('cmis:objectId')
+        assert searchFolder.getProperties().has_key('cmis:objectTypeId')
+        assert searchFolder.getProperties().has_key('cmis:baseTypeId')
+        assert searchFolder.getProperties().has_key('cmis:name')
+
+    def testUpdateProperties(self):
+        """Create a test folder, then update its properties"""
+        folderName = 'testUpdateProperties folder'
+        newFolder = self._testFolder.createFolder(folderName)
+        assert folderName == newFolder.getName()
+        folderName2 = 'testUpdateProperties folder2'
+        props = {'cmis:name': folderName2}
+        newFolder.updateProperties(props)
+        assert folderName2 == newFolder.getName()
+
+    def testSubFolder(self):
+        """Create a test folder, then create a test folder within that."""
+        parentFolder = self._testFolder.createFolder('testSubFolder folder')
+        assert 'cmis:objectId' in parentFolder.getProperties()
+        childFolder = parentFolder.createFolder('child folder')
+        assert 'cmis:objectId' in childFolder.getProperties()
+        assert childFolder.getProperties()['cmis:objectId'] is not None
+
+    def testAllowableActions(self):
+        """Create a test folder, then get its allowable actions"""
+        actions = self._testFolder.getAllowableActions()
+        assert len(actions) > 0
+
+    def testGetParent(self):
+        """Get a folder's parent using the getParent call"""
+        childFolder = self._testFolder.createFolder('parentTest')
+        parentFolder = childFolder.getParent()
+        assert self._testFolder.getObjectId() == parentFolder.getObjectId()
+
+    def testAddObject(self):
+        """Add an existing object to another folder"""
+        if not self._repo.getCapabilities()['Multifiling']:
+            print 'This repository does not allow multifiling, skipping'
+            return
+
+        subFolder1 = self._testFolder.createFolder('sub1')
+        doc = subFolder1.createDocument('testdoc1')
+        assert len(subFolder1.getChildren()) == 1
+        subFolder2 = self._testFolder.createFolder('sub2')
+        assert len(subFolder2.getChildren()) == 0
+        subFolder2.addObject(doc)
+        assert len(subFolder2.getChildren()) == 1
+        assert subFolder1.getChildren()[0].name == subFolder2.getChildren()[0].name
+
+    def testRemoveObject(self):
+        """Remove an existing object from a secondary folder"""
+        if not self._repo.getCapabilities()['Unfiling']:
+            print 'This repository does not allow unfiling, skipping'
+            return
+
+        subFolder1 = self._testFolder.createFolder('sub1')
+        doc = subFolder1.createDocument('testdoc1')
+        assert len(subFolder1.getChildren()) == 1
+        subFolder2 = self._testFolder.createFolder('sub2')
+        assert len(subFolder2.getChildren()) == 0
+        subFolder2.addObject(doc)
+        assert len(subFolder2.getChildren()) == 1
+        assert subFolder1.getChildren()[0].name == subFolder2.getChildren()[0].name
+        subFolder2.removeObject(doc)
+        assert len(subFolder2.getChildren()) == 0
+        assert len(subFolder1.getChildren()) == 1
+        assert doc.name == subFolder1.getChildren()[0].name
+
+    def testGetPaths(self):
+        """Get a folder's paths"""
+        # ask the root for its path
+        root = self._repo.getRootFolder()
+        paths = root.getPaths()
+        assert len(paths) == 1
+        assert paths[0] == '/'
+        # ask the test folder for its paths
+        paths = self._testFolder.getPaths()
+        assert len(paths) == 1
+
+    # Exceptions
+
+    def testBadParentFolder(self):
+        """Try to create a folder on a bad/bogus/deleted parent
+        folder object"""
+        firstFolder = self._testFolder.createFolder('testBadParentFolder folder')
+        assert 'cmis:objectId' in firstFolder.getProperties()
+        firstFolder.delete()
+        # folder isn't in the repo anymore, but I still have the object
+        # really, this seems like it ought to be an ObjectNotFoundException but
+        # not all CMIS providers report it as such
+        with pytest.raises(CmisException):
+            firstFolder.createFolder('bad parent')

Added: chemistry/cmislib/branches/py3_compat/src/tests/test_query.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/src/tests/test_query.py?rev=1836987&view=auto
==============================================================================
--- chemistry/cmislib/branches/py3_compat/src/tests/test_query.py (added)
+++ chemistry/cmislib/branches/py3_compat/src/tests/test_query.py Sun Jul 29 16:51:06 2018
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you under the Apache License, Version 2.0 (the
+#      "License"); you may not use this file except in compliance
+#      with the License.  You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#      Unless required by applicable law or agreed to in writing,
+#      software distributed under the License is distributed on an
+#      "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#      KIND, either express or implied.  See the License for the
+#      specific language governing permissions and limitations
+#      under the License.
+#
+from time import sleep
+
+import pytest
+
+from .tools import isInResultSet
+from .tools import skipIfAlfrescoBrowserBinding
+from .tools import skipIfAlfrescoPubBinding
+
+
+@pytest.mark.usefixtures('cmis_env')
+class TestQuery:
+    """ Tests related to running CMIS queries. """
+
+    @pytest.fixture(autouse=True)
+    def sampleContent(self, binary_files, cmis_env):
+        """
+        Creating a couple of test docs.
+        """
+        # I think this may be an Alfresco bug. The CMIS query results contain
+        # 1 less entry element than the number of search results. So this test
+        # will create two documents and search for the second one which should
+        # work in all repositories.
+        testFileName = self.binary_filename_2
+        with open(self.binary_file_2, 'rb') as f:
+            self._testContent = self._testFolder.createDocument(
+                testFileName, contentFile=f)
+        with open(self.binary_file_2, 'rb') as f:
+            self._testContent2 = self._testFolder.createDocument(
+                testFileName.replace('.', '2.'), contentFile=f)
+        
+    def testSimpleSelect(self):
+        """Execute simple select star from cmis:document"""
+        querySimpleSelect = "SELECT * FROM cmis:document"
+        resultSet = self._repo.query(querySimpleSelect)
+        assert isInResultSet(resultSet, self._testContent)
+
+    def testWildcardPropertyMatch(self):
+        """Find content w/wildcard match on cmis:name property"""
+        name = self._testContent.getProperties()['cmis:name']
+        querySimpleSelect = "SELECT * FROM cmis:document where cmis:name like '" + name[:7] + "%'"
+        resultSet = self._repo.query(querySimpleSelect)
+        assert isInResultSet(resultSet, self._testContent)
+
+    def testPropertyMatch(self):
+        """Find content matching cmis:name property"""
+        name = self._testContent2.getProperties()['cmis:name']
+        querySimpleSelect = "SELECT * FROM cmis:document where cmis:name = '" + name + "'"
+        resultSet = self._repo.query(querySimpleSelect)
+        assert isInResultSet(resultSet, self._testContent2)
+
+    @skipIfAlfrescoBrowserBinding
+    def testFullText(self):
+        """Find content using a full-text query"""
+        queryFullText = "SELECT cmis:objectId, cmis:name FROM cmis:document " \
+                        "WHERE contains('whitepaper')"
+        # on the first full text search the indexer may need a chance to
+        # do its thing
+        found = False
+        maxTries = self.max_full_text_tries
+        while not found and (maxTries > 0):
+            resultSet = self._repo.query(queryFullText)
+            found = isInResultSet(resultSet, self._testContent2)
+            if not found:
+                maxTries -= 1
+                print('Not found...sleeping for 10 secs. Remaining tries:%d'
+                      % maxTries)
+                sleep(10)
+        assert found
+
+    @skipIfAlfrescoPubBinding
+    @skipIfAlfrescoBrowserBinding
+    def testScore(self):
+        """Find content using FT, sorted by relevance score"""
+        queryScore = "SELECT cmis:objectId, cmis:name, Score() as relevance " \
+                     "FROM cmis:document WHERE contains('sample') " \
+                     "order by relevance DESC"
+
+        # on the first full text search the indexer may need a chance to
+        # do its thing
+        found = False
+        maxTries = self.max_full_text_tries
+        while not found and (maxTries > 0):
+            resultSet = self._repo.query(queryScore)
+            found = isInResultSet(resultSet, self._testContent2)
+            if not found:
+                maxTries -= 1
+                print 'Not found...sleeping for 10 secs. Remaining tries:%d' % maxTries
+                sleep(10)
+        assert found

Added: chemistry/cmislib/branches/py3_compat/src/tests/test_repository.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/src/tests/test_repository.py?rev=1836987&view=auto
==============================================================================
--- chemistry/cmislib/branches/py3_compat/src/tests/test_repository.py (added)
+++ chemistry/cmislib/branches/py3_compat/src/tests/test_repository.py Sun Jul 29 16:51:06 2018
@@ -0,0 +1,216 @@
+# -*- coding: utf-8 -*-
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you under the Apache License, Version 2.0 (the
+#      "License"); you may not use this file except in compliance
+#      with the License.  You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#      Unless required by applicable law or agreed to in writing,
+#      software distributed under the License is distributed on an
+#      "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#      KIND, either express or implied.  See the License for the
+#      specific language governing permissions and limitations
+#      under the License.
+#
+import pytest
+
+from cmislib.exceptions import \
+    ObjectNotFoundException
+
+
+@pytest.mark.usefixtures('cmis_env', 'binary_files')
+class TestRepository:
+
+    """ Tests for the :class:`Repository` class. """
+
+    def testRepositoryInfo(self):
+        """Retrieve repository info"""
+        repoInfo = self._repo.getRepositoryInfo()
+        assert 'repositoryId' in repoInfo
+        assert 'repositoryName' in repoInfo
+        assert 'repositoryDescription' in repoInfo
+        assert 'vendorName' in repoInfo
+        assert 'productName' in repoInfo
+        assert 'productVersion' in repoInfo
+        assert 'rootFolderId' in repoInfo
+        assert 'cmisVersionSupported' in repoInfo
+
+    def testRepositoryCapabilities(self):
+        """Retrieve repository capabilities"""
+        caps = self._repo.getCapabilities()
+        assert 'ACL' in caps
+        assert 'AllVersionsSearchable' in caps
+        assert 'Changes' in caps
+        assert 'ContentStreamUpdatability' in caps
+        assert 'GetDescendants' in caps
+        assert 'GetFolderTree' in caps
+        assert 'Multifiling' in caps
+        assert 'PWCSearchable' in caps
+        assert 'PWCUpdatable' in caps
+        assert 'Query' in caps
+        assert 'Renditions' in caps
+        assert 'Unfiling' in caps
+        assert 'VersionSpecificFiling' in caps
+        assert 'Join' in caps
+
+    def testGetRootFolder(self):
+        """Get the root folder of the repository"""
+        rootFolder = self._repo.getRootFolder()
+        assert rootFolder is not None
+        assert rootFolder.getObjectId() is not None
+
+    def testCreateFolder(self):
+        """Create a new folder in the root folder"""
+        folderName = 'testCreateFolder folder'
+        newFolder = self._repo.createFolder(self._rootFolder, folderName)
+        assert folderName == newFolder.getName()
+        newFolder.delete()
+
+    def testCreateDocument(self):
+        """Create a new 'content-less' document"""
+        documentName = 'testDocument'
+        newDoc = self._repo.createDocument(documentName, parentFolder=self._testFolder)
+        assert documentName == newDoc.getName()
+
+    def testCreateDocumentFromString(self):
+        """Create a new document from a string"""
+        documentName = 'testDocument'
+        contentString = 'Test content string'
+        newDoc = self._repo.createDocumentFromString(documentName,
+                                           parentFolder=self._testFolder,
+                                           contentString=contentString,
+                                           contentType='text/plain')
+        assert documentName == newDoc.getName()
+        assert newDoc.getContentStream().read() == contentString
+
+    # CMIS-279
+    def testCreateDocumentUnicode(self):
+        """Create a new doc with unicode characters in the name"""
+        documentName = u'abc cdeöäüß%§-_caféè.txt'
+        newDoc = self._repo.createDocument(documentName, parentFolder=self._testFolder)
+        assert documentName == newDoc.getName()
+
+    def testGetObject(self):
+        """Create a test folder then attempt to retrieve it as a
+        :class:`CmisObject` object using its object ID"""
+        folderName = 'testGetObject folder'
+        newFolder = self._repo.createFolder(self._testFolder, folderName)
+        objectId = newFolder.getObjectId()
+        someObject = self._repo.getObject(objectId)
+        assert folderName == someObject.getName()
+        newFolder.delete()
+
+    def testReturnVersion(self):
+        """Get latest and latestmajor versions of an object"""
+        fileName = self.binary_filename_1
+        props = {'cmis:objectTypeId': self.versionable_type_id}
+        with open(self.binary_file_1, 'rb') as f:
+            doc10 = self._testFolder.createDocument(
+                fileName, contentFile=f, properties=props)
+        doc10Id = doc10.getObjectId()
+        if not 'canCheckOut' in doc10.allowableActions.keys():
+            print 'The test doc cannot be checked out...skipping'
+            return
+        pwc = doc10.checkout()
+        doc11 = pwc.checkin(major='false')  # checkin a minor version, 1.1
+        if not 'canCheckOut' in doc11.allowableActions.keys():
+            print 'The test doc cannot be checked out...skipping'
+            return
+        pwc = doc11.checkout()
+        doc20 = pwc.checkin()  # checkin a major version, 2.0
+        doc20Id = doc20.getObjectId()
+        if not 'canCheckOut' in doc20.allowableActions.keys():
+            print 'The test doc cannot be checked out...skipping'
+            return
+        pwc = doc20.checkout()
+        doc21 = pwc.checkin(major='false')  # checkin a minor version, 2.1
+        doc21Id = doc21.getObjectId()
+
+        docLatest = self._repo.getObject(doc10Id, returnVersion='latest')
+        assert doc21Id == docLatest.getObjectId()
+
+        docLatestMajor = self._repo.getObject(doc10Id, returnVersion='latestmajor')
+        assert doc20Id == docLatestMajor.getObjectId()
+
+    def testGetFolder(self):
+        """Create a test folder then attempt to retrieve the Folder object
+        using its object ID"""
+        folderName = 'testGetFolder folder'
+        newFolder = self._repo.createFolder(self._testFolder, folderName)
+        objectId = newFolder.getObjectId()
+        someFolder = self._repo.getFolder(objectId)
+        assert folderName == someFolder.getName()
+        newFolder.delete()
+
+    def testGetObjectByPath(self):
+        """Create test objects (one folder, one document) then try to get
+        them by path"""
+        # names of folders and test docs (without and with unicode char)
+        for suffix in ['', u'_éà€$']:
+            parentFolderName = 'testGetObjectByPath folder' + suffix
+            subFolderName = 'subfolder' + suffix
+            docName = 'testdoc' + suffix
+
+            # create the folder structure
+            parentFolder = self._testFolder.createFolder(parentFolderName)
+            subFolder = parentFolder.createFolder(subFolderName)
+            # use the subfolder path to get the folder by path
+            subFolderPath = subFolder.getProperties().get("cmis:path")
+            searchFolder = self._repo.getObjectByPath(subFolderPath)
+            assert subFolder.getObjectId() == searchFolder.getObjectId()
+
+            # create a test doc
+            doc = subFolder.createDocument(docName)
+            # ask the doc for its paths
+            searchDocPaths = doc.getPaths()
+            # for each path in the list, try to get the object by path
+            # this is better than building a path with the doc's name b/c the name
+            # isn't guaranteed to be used as the path segment (see CMIS-232)
+            for path in searchDocPaths:
+                searchDoc = self._repo.getObjectByPath(path)
+                assert doc.getObjectId() == searchDoc.getObjectId()
+
+            # get the subfolder by path, then ask for its children
+            subFolder = self._repo.getObjectByPath(subFolderPath)
+            assert len(subFolder.getChildren().getResults()) == 1
+
+    # Create document without a parent folder is not yet implemented
+    # def testCreateUnfiledDocument(self):
+    #     '''Create a new unfiled document'''
+    #     if self._repo.getCapabilities()['Unfiling'] != True:
+    #         print 'Repo does not support unfiling, skipping'
+    #         return
+    #     documentName = 'testDocument'
+    #     newDoc = self._repo.createDocument(documentName)
+    #     self.assertEquals(documentName, newDoc.getName())
+
+    def testMoveDocument(self):
+        """Move a Document from one folder to another folder"""
+        subFolder1 = self._testFolder.createFolder('sub1')
+        doc = subFolder1.createDocument('testdoc1')
+        assert len(subFolder1.getChildren()) == 1
+        subFolder2 = self._testFolder.createFolder('sub2')
+        assert len(subFolder2.getChildren()) == 0
+        doc.move(subFolder1, subFolder2)
+        assert len(subFolder1.getChildren()) == 0
+        assert len(subFolder2.getChildren()) == 1
+        assert doc.name == subFolder2.getChildren()[0].name
+
+    #Exceptions
+
+    def testGetObjectBadId(self):
+        """Attempt to get an object using a known bad ID"""
+        # this object ID is implementation specific (Alfresco) but is universally
+        # bad so it should work for all repositories
+        with pytest.raises(ObjectNotFoundException):
+            self._repo.getObject(self._testFolder.getObjectId()[:-5] + 'BADID')
+
+    def testGetObjectBadPath(self):
+        """Attempt to get an object using a known bad path"""
+        with pytest.raises(ObjectNotFoundException):
+            self._repo.getObjectByPath('/123foo/BAR.jtp')

Added: chemistry/cmislib/branches/py3_compat/src/tests/test_type.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/src/tests/test_type.py?rev=1836987&view=auto
==============================================================================
--- chemistry/cmislib/branches/py3_compat/src/tests/test_type.py (added)
+++ chemistry/cmislib/branches/py3_compat/src/tests/test_type.py Sun Jul 29 16:51:06 2018
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you under the Apache License, Version 2.0 (the
+#      "License"); you may not use this file except in compliance
+#      with the License.  You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#      Unless required by applicable law or agreed to in writing,
+#      software distributed under the License is distributed on an
+#      "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#      KIND, either express or implied.  See the License for the
+#      specific language governing permissions and limitations
+#      under the License.
+#
+import pytest
+
+from cmislib.model import CmisClient
+
+
+@pytest.mark.usefixtures('cmis_conf')
+class TestType:
+
+    """
+    Tests for the :class:`ObjectType` class (and related methods in the
+    :class:`Repository` class.
+    """
+
+    def testTypeDescendants(self):
+        """Get the descendant types of the repository."""
+
+        cmisClient = CmisClient(self.url, self.user, self.pwd,
+                                binding=self.binding,
+                                **self.ext_args)
+        repo = cmisClient.getDefaultRepository()
+        typeDefs = repo.getTypeDescendants()
+        folderDef = None
+        for typeDef in typeDefs:
+            if typeDef.getTypeId() == 'cmis:folder':
+                folderDef = typeDef
+                break
+        assert folderDef
+        assert folderDef.baseId
+
+    def testTypeChildren(self):
+        """Get the child types for this repository and make sure cmis:folder
+        is in the list."""
+
+        #This test would be more interesting if there was a standard way to
+        #deploy a custom model. Then we could look for custom types.
+
+        cmisClient = CmisClient(self.url, self.user, self.pwd,
+                                binding=self.binding,
+                                **self.ext_args)
+        repo = cmisClient.getDefaultRepository()
+        typeDefs = repo.getTypeChildren()
+        folderDef = None
+        for typeDef in typeDefs:
+            if typeDef.getTypeId() == 'cmis:folder':
+                folderDef = typeDef
+                break
+        assert folderDef
+        assert folderDef.baseId
+
+    def testTypeDefinition(self):
+        """Get the cmis:document type and test a few props of the type."""
+        cmisClient = CmisClient(self.url, self.user, self.pwd,
+                                binding=self.binding,
+                                **self.ext_args)
+        repo = cmisClient.getDefaultRepository()
+        docTypeDef = repo.getTypeDefinition('cmis:document')
+        assert 'cmis:document' == docTypeDef.getTypeId()
+        assert docTypeDef.baseId
+
+    def testTypeProperties(self):
+        """Get the properties for a type."""
+        cmisClient = CmisClient(self.url, self.user, self.pwd,
+                                binding=self.binding,
+                                **self.ext_args)
+        repo = cmisClient.getDefaultRepository()
+        docTypeDef = repo.getTypeDefinition('cmis:document')
+        assert 'cmis:document' == docTypeDef.getTypeId()
+        props = docTypeDef.getProperties().values()
+        assert len(props) > 0
+        for prop in props:
+            if prop.queryable:
+                assert prop.queryName
+            assert prop.propertyType

Added: chemistry/cmislib/branches/py3_compat/src/tests/tools.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/branches/py3_compat/src/tests/tools.py?rev=1836987&view=auto
==============================================================================
--- chemistry/cmislib/branches/py3_compat/src/tests/tools.py (added)
+++ chemistry/cmislib/branches/py3_compat/src/tests/tools.py Sun Jul 29 16:51:06 2018
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you under the Apache License, Version 2.0 (the
+#      "License"); you may not use this file except in compliance
+#      with the License.  You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#      Unless required by applicable law or agreed to in writing,
+#      software distributed under the License is distributed on an
+#      "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#      KIND, either express or implied.  See the License for the
+#      specific language governing permissions and limitations
+#      under the License.
+#
+import pytest
+
+
+def isInCollection(collection, targetDoc):
+    """
+    Util function that searches a list of objects for a matching target
+    object.
+    """
+    for doc in collection:
+        # hacking around a bizarre thing in Alfresco which is that when the
+        # PWC comes back it has an object ID of say 123ABC but when you look
+        # in the checked out collection the object ID of the PWC is now
+        # 123ABC;1.0. What is that ;1.0? I don't know, but object IDs are
+        # supposed to be immutable so I'm not sure what's going on there.
+        if doc.getObjectId().startswith(targetDoc.getObjectId()):
+            return True
+    return False
+
+
+def isInResultSet(resultSet, targetDoc):
+    """
+    Util function that searches a :class:`ResultSet` for a specified target
+    object. Note that this function will do a getNext on every page of the
+    result set until it finds what it is looking for or reaches the end of
+    the result set. For every item in the result set, the properties
+    are retrieved. Long story short: this could be an expensive call.
+    """
+    done = False
+    while not done:
+        if resultSet.hasObject(targetDoc.getObjectId()):
+            return True
+        if resultSet.hasNext():
+            resultSet.getNext()
+        else:
+            done = True
+
+
+def skipIf(fixtureIds):
+    def skipIf_decorator(func):
+        def func_wrap(self):
+            if self.fixture_id in fixtureIds:
+                pytest.skip(
+                    "%s not supported in %s" % (func, self.fixture_id)
+                )
+            func(self)
+        return func_wrap
+    return skipIf_decorator
+
+
+def skipIfAlfrescoBrowserBinding(func):
+    return skipIf(['alfresco-BrowserBinding'])(func)
+
+def skipIfAlfrescoPubBinding(func):
+    return skipIf(['alfresco-AtomPubBinding'])(func)
\ No newline at end of file



Mime
View raw message