def test_build_file_metadata(self, root_provider_fixtures):
        od_path = OneDrivePath.new_from_response(root_provider_fixtures['file_metadata'], 'root')

        metadata = OneDriveFileMetadata(root_provider_fixtures['file_metadata'], od_path)
        assert metadata.provider == 'onedrive'
        assert metadata.created_utc == '2017-08-17T17:49:39+00:00'
        assert metadata.materialized_path == '/toes.txt'
        assert metadata.extra == {
            'id': root_provider_fixtures['file_id'],
            'etag': 'aRjRENTBFNDAwREZFN0Q0RSEyOTEuMg',
            'webView': 'https://1drv.ms/t/s!AE59_g1ADtX0giM',
        }
        assert metadata.name == 'toes.txt'
        assert metadata.path == '/{}'.format(root_provider_fixtures['file_id'])
        assert metadata.size == 11
        assert metadata.size_as_int == 11
        assert metadata.modified == '2017-08-17T17:49:50.38Z'
        assert metadata.modified_utc == '2017-08-17T17:49:50+00:00'
        assert metadata.content_type == 'text/plain'
        assert metadata.etag == 'aRjRENTBFNDAwREZFN0Q0RSEyOTEuMg'

        action_url = ('http://localhost:7777/v1/resources/mst3k/providers'
                     '/onedrive/{}'.format(root_provider_fixtures['file_id']))
        assert metadata._json_api_links('mst3k') == {
            'delete': None,
            'upload': None,
            'move': action_url,
            'download': action_url,
        }
    def test_build_file_metadata(self, root_provider_fixtures):
        od_path = OneDrivePath.new_from_response(
            root_provider_fixtures['file_metadata'], 'root')

        metadata = OneDriveFileMetadata(
            root_provider_fixtures['file_metadata'], od_path)
        assert metadata.provider == 'onedrive'
        assert metadata.created_utc == '2017-08-17T17:49:39+00:00'
        assert metadata.materialized_path == '/toes.txt'
        assert metadata.extra == {
            'id': root_provider_fixtures['file_id'],
            'etag': 'aRjRENTBFNDAwREZFN0Q0RSEyOTEuMg',
            'webView': 'https://1drv.ms/t/s!AE59_g1ADtX0giM',
        }
        assert metadata.name == 'toes.txt'
        assert metadata.path == '/{}'.format(root_provider_fixtures['file_id'])
        assert metadata.size == 11
        assert metadata.size_as_int == 11
        assert metadata.modified == '2017-08-17T17:49:50.38Z'
        assert metadata.modified_utc == '2017-08-17T17:49:50+00:00'
        assert metadata.content_type == 'text/plain'
        assert metadata.etag == 'aRjRENTBFNDAwREZFN0Q0RSEyOTEuMg'

        action_url = ('http://localhost:7777/v1/resources/mst3k/providers'
                      '/onedrive/{}'.format(root_provider_fixtures['file_id']))
        assert metadata._json_api_links('mst3k') == {
            'delete': None,
            'upload': None,
            'move': action_url,
            'download': action_url,
        }
    def test_folder_in_root(self, root_provider_fixtures):
        od_path = OneDrivePath.new_from_response(root_provider_fixtures['folder_metadata'], 'root')

        assert od_path.identifier == root_provider_fixtures['folder_id']
        assert str(od_path) == '/teeth/'
        assert len(od_path.parts) == 2
        ids = [x.identifier for x in od_path.parts]
        assert ids == ['root', root_provider_fixtures['folder_id']]
    def test_folder_in_root(self, root_provider_fixtures):
        od_path = OneDrivePath.new_from_response(
            root_provider_fixtures['folder_metadata'], 'root')

        assert od_path.identifier == root_provider_fixtures['folder_id']
        assert str(od_path) == '/teeth/'
        assert len(od_path.parts) == 2
        ids = [x.identifier for x in od_path.parts]
        assert ids == ['root', root_provider_fixtures['folder_id']]
    def test_file_in_root(self, subfolder_provider_fixtures):
        od_path = OneDrivePath.new_from_response(subfolder_provider_fixtures['file_metadata'],
                                                 subfolder_provider_fixtures['root_id'])

        assert od_path.identifier == subfolder_provider_fixtures['file_id']
        assert str(od_path) == '/bicuspid.txt'
        assert len(od_path.parts) == 2
        ids = [x.identifier for x in od_path.parts]
        assert ids == [subfolder_provider_fixtures['root_id'],
                       subfolder_provider_fixtures['file_id']]
    def test_subfolder_base_is_folder(self, subfolder_provider_fixtures):
        od_path = OneDrivePath.new_from_response(subfolder_provider_fixtures['folder_metadata'],
                                                 subfolder_provider_fixtures['root_id'])

        assert od_path.identifier == subfolder_provider_fixtures['folder_id']
        assert str(od_path) == '/crushers/'
        assert len(od_path.parts) == 2
        ids = [x.identifier for x in od_path.parts]
        assert ids == [subfolder_provider_fixtures['root_id'],
                       subfolder_provider_fixtures['folder_id']]
    def test_insert_zero_ids(self, path_fixtures):
        file_metadata = path_fixtures['deeply_nested_file_metadata']
        od_path = OneDrivePath.new_from_response(file_metadata, 'root')

        file_id = path_fixtures['deeply_nested_file_id']
        assert od_path.identifier == file_id
        assert str(od_path) == '/deep/deeper/deepest/positively abyssyal/the kraken.txt'
        assert len(od_path.parts) == 6
        ids = [x.identifier for x in od_path.parts]
        assert ids == ['root', None, None, None, 'F4D50E400DFE7D4E!298', file_id]
    def test_file_in_subdir(self, root_provider_fixtures):
        od_path = OneDrivePath.new_from_response(root_provider_fixtures['subfile_metadata'], 'root')

        assert od_path.identifier == root_provider_fixtures['subfile_id']
        assert str(od_path) == '/teeth/bicuspid.txt'
        assert len(od_path.parts) == 3
        ids = [x.identifier for x in od_path.parts]
        assert ids == ['root',
                       root_provider_fixtures['folder_id'],
                       root_provider_fixtures['subfile_id']]
    def test_file_in_subdir(self, root_provider_fixtures):
        od_path = OneDrivePath.new_from_response(
            root_provider_fixtures['subfile_metadata'], 'root')

        assert od_path.identifier == root_provider_fixtures['subfile_id']
        assert str(od_path) == '/teeth/bicuspid.txt'
        assert len(od_path.parts) == 3
        ids = [x.identifier for x in od_path.parts]
        assert ids == [
            'root', root_provider_fixtures['folder_id'],
            root_provider_fixtures['subfile_id']
        ]
    def test_file_in_subdir(self, subfolder_provider_fixtures):
        od_path = OneDrivePath.new_from_response(subfolder_provider_fixtures['subfile_metadata'],
                                                 subfolder_provider_fixtures['root_id'],
                                                 base_folder_metadata=subfolder_provider_fixtures['root_metadata'])

        assert od_path.identifier == subfolder_provider_fixtures['subfile_id']
        assert str(od_path) == '/crushers/molars.txt'
        assert len(od_path.parts) == 3
        ids = [x.identifier for x in od_path.parts]
        assert ids == [subfolder_provider_fixtures['root_id'],
                       subfolder_provider_fixtures['folder_id'],
                       subfolder_provider_fixtures['subfile_id']]
    def test_file_in_root(self, subfolder_provider_fixtures):
        od_path = OneDrivePath.new_from_response(
            subfolder_provider_fixtures['file_metadata'],
            subfolder_provider_fixtures['root_id'])

        assert od_path.identifier == subfolder_provider_fixtures['file_id']
        assert str(od_path) == '/bicuspid.txt'
        assert len(od_path.parts) == 2
        ids = [x.identifier for x in od_path.parts]
        assert ids == [
            subfolder_provider_fixtures['root_id'],
            subfolder_provider_fixtures['file_id']
        ]
    def test_subfolder_base_is_folder(self, subfolder_provider_fixtures):
        od_path = OneDrivePath.new_from_response(
            subfolder_provider_fixtures['folder_metadata'],
            subfolder_provider_fixtures['root_id'])

        assert od_path.identifier == subfolder_provider_fixtures['folder_id']
        assert str(od_path) == '/crushers/'
        assert len(od_path.parts) == 2
        ids = [x.identifier for x in od_path.parts]
        assert ids == [
            subfolder_provider_fixtures['root_id'],
            subfolder_provider_fixtures['folder_id']
        ]
    def test_insert_zero_ids(self, path_fixtures):
        file_metadata = path_fixtures['deeply_nested_file_metadata']
        od_path = OneDrivePath.new_from_response(file_metadata, 'root')

        file_id = path_fixtures['deeply_nested_file_id']
        assert od_path.identifier == file_id
        assert str(
            od_path
        ) == '/deep/deeper/deepest/positively abyssyal/the kraken.txt'
        assert len(od_path.parts) == 6
        ids = [x.identifier for x in od_path.parts]
        assert ids == [
            'root', None, None, None, 'F4D50E400DFE7D4E!298', file_id
        ]
    def test_file_in_subdir(self, subfolder_provider_fixtures):
        od_path = OneDrivePath.new_from_response(
            subfolder_provider_fixtures['subfile_metadata'],
            subfolder_provider_fixtures['root_id'],
            base_folder_metadata=subfolder_provider_fixtures['root_metadata'])

        assert od_path.identifier == subfolder_provider_fixtures['subfile_id']
        assert str(od_path) == '/crushers/molars.txt'
        assert len(od_path.parts) == 3
        ids = [x.identifier for x in od_path.parts]
        assert ids == [
            subfolder_provider_fixtures['root_id'],
            subfolder_provider_fixtures['folder_id'],
            subfolder_provider_fixtures['subfile_id']
        ]
    async def validate_path(self, path: str, **kwargs) -> OneDrivePath:
        logger.debug('validate_path self::{} path::{} kwargs::{}'.format(repr(self), path, kwargs))

        if path == '/':
            return OneDrivePath(path, _ids=[self.folder])

        resp = await self.make_request(
            'GET', self._build_item_url(path),
            expects=(200, ),
            throws=exceptions.MetadataError
        )
        logger.debug('validate_path resp::{}'.format(repr(resp)))
        data = await resp.json()
        logger.debug('validate_path data::{}'.format(json.dumps(data)))

        # If base folder isn't root or the immediate parent of the requested path, then we need
        # to verify that it actually is an ancestor of path.  Otherwise, a malicious user could
        # try to get access to a file outside of the configured root.
        base_folder = None
        if self.folder != 'root' and self.folder != data['parentReference']['id']:
            base_folder_resp = await self.make_request(
                'GET', self._build_item_url(self.folder),
                expects=(200, ),
                throws=exceptions.MetadataError
            )
            logger.debug('validate_path base_folder_resp::{}'.format(repr(base_folder_resp)))
            base_folder = await base_folder_resp.json()
            logger.debug('validate_path base_folder::{}'.format(json.dumps(base_folder)))

            base_full_path = urlparse.quote(
                '{}/{}/'.format(
                    urlparse.unquote(base_folder['parentReference']['path']),
                    base_folder['name']
                ),
                self.dont_escape_these
            )

            if not data['parentReference']['path'].startswith(base_full_path):
                # the requested file is NOT a child of self.folder
                raise exceptions.NotFoundError(path)  # TESTME

        od_path = OneDrivePath.new_from_response(data, self.folder,
                                                 base_folder_metadata=base_folder)
        logger.debug('validate_path od_path.parts::{}'.format(repr(od_path._parts)))
        return od_path
    def test_build_folder_metadata(self, root_provider_fixtures):
        od_path = OneDrivePath.new_from_response(root_provider_fixtures['folder_metadata'], 'root')

        metadata = OneDriveFolderMetadata(root_provider_fixtures['folder_metadata'], od_path)
        assert metadata.provider == 'onedrive'
        assert metadata.name == 'teeth'
        assert metadata.path == '/F4D50E400DFE7D4E!290/'
        assert metadata.etag == 'aRjRENTBFNDAwREZFN0Q0RSEyOTAuMA'
        assert metadata.materialized_path == '/teeth/'
        assert metadata.extra == {
            'id': 'F4D50E400DFE7D4E!290',
            'etag': 'aRjRENTBFNDAwREZFN0Q0RSEyOTAuMA',
            'webView': 'https://1drv.ms/f/s!AE59_g1ADtX0giI',
            'modified_utc': '2017-08-17T17:53:21+00:00',
            'created_utc': '2017-08-17T17:49:26+00:00',
        }

        assert metadata._json_api_links('mst3k') == {
            'delete': None,
            'upload': None,
            'move': ('http://localhost:7777/v1/resources/mst3k/providers'
                     '/onedrive/{}/'.format(root_provider_fixtures['folder_id'])),
            'new_folder': None,
        }
 def test_fails_without_base_folder(self, root_provider_fixtures):
     with pytest.raises(Exception):
         od_path = OneDrivePath.new_from_response(
             root_provider_fixtures['file_metadata'])
    async def validate_v1_path(self, path: str, **kwargs) -> OneDrivePath:
        """validate that ``path`` exists and matches the implicit semantics.

        See `provider.BaseProvider.validate_v1_path` for more.

        :param str path: A string representing the requested path. This will be everthing after
                         the provider name in the url.
        :param dict \*\*kwargs: Query parameters and other parameters splatted into the call.
        :raises: NotFoundError
        :rtype: OneDrivePath
        :return: a OneDrivePath object representing the new path.
        """
        logger.debug('validate_v1_path self::{} path::{} kwargs::{}'.format(repr(self),
                                                                            path, kwargs))

        if path == '/':
            return OneDrivePath(path, _ids=[self.folder])

        resp = await self.make_request(
            'GET', self._build_item_url(path),
            expects=(200, ),
            throws=exceptions.MetadataError
        )
        logger.debug('validate_v1_path resp::{}'.format(repr(resp)))
        data = await resp.json()
        logger.debug('validate_v1_path data::{}'.format(json.dumps(data)))

        implicit_folder = path.endswith('/')
        explicit_folder = data.get('folder', None) is not None
        if implicit_folder != explicit_folder:
            raise exceptions.NotFoundError(path)

        # If base folder isn't root or the immediate parent of the requested path, then we need
        # to verify that it actually is an ancestor of path.  Otherwise, a malicious user could
        # try to get access to a file outside of the configured root.
        base_folder = None
        if self.folder != 'root' and self.folder != data['parentReference']['id']:
            base_folder_resp = await self.make_request(
                'GET', self._build_item_url(self.folder),
                expects=(200, ),
                throws=exceptions.MetadataError
            )
            logger.debug('validate_v1_path base_folder_resp::{}'.format(repr(base_folder_resp)))
            base_folder = await base_folder_resp.json()
            logger.debug('validate_v1_path base_folder::{}'.format(json.dumps(base_folder)))

            base_full_path = urlparse.quote(
                '{}/{}/'.format(
                    urlparse.unquote(base_folder['parentReference']['path']),
                    base_folder['name']
                ),
                self.dont_escape_these
            )

            if not data['parentReference']['path'].startswith(base_full_path):
                # the requested file is NOT a child of self.folder
                raise exceptions.NotFoundError(path)

        od_path = OneDrivePath.new_from_response(data, self.folder,
                                                 base_folder_metadata=base_folder)
        logger.debug('validate_v1_path od_path.parts::{}'.format(repr(od_path._parts)))
        return od_path
 def test_fails_without_base_folder(self, root_provider_fixtures):
     with pytest.raises(Exception):
         od_path = OneDrivePath.new_from_response(root_provider_fixtures['file_metadata'])