# Path: ddsc/core/util.py
# def mode_allows_group_or_other(st_mode):
#     """
#     Returns True if st_mode bitset has group or other permissions
#     :param st_mode: int: bit set from a file
#     :return: bool: true when group or other has some permissions
#     """
#     return (st_mode & stat.S_IRWXO or st_mode & stat.S_IRWXG) != 0
# 
# def verify_file_private(filename):
#     """
#     Raises ValueError the file permissions allow group/other
#     On windows this never raises due to the implementation of stat.
#     """
#     if platform.system().upper() != 'WINDOWS':
#         filename = os.path.expanduser(filename)
#         if os.path.exists(filename):
#             file_stat = os.stat(filename)
#             if mode_allows_group_or_other(file_stat.st_mode):
#                 raise DDSUserException(CONFIG_FILE_PERMISSIONS_ERROR)
# 
# class ProjectDetailsList(object):
#     """
#     Walks a project and saves the project name and filenames to [str] filenames property.
#     """
#     def __init__(self, long_format):
#         self.long_format = long_format
#         self.details = []
#         self.id_to_path = {}
# 
#     def walk_project(self, project):
#         """
#         Walks a project and saves the project name and filenames to [str] filenames property.
#         :param project: LocalProject project we will read details from.
#         """
#         # This method will call visit_project, visit_folder, and visit_file below as it walks the project tree.
#         ProjectWalker.walk_project(project, self)
# 
#     def visit_project(self, item):
#         if self.long_format:
#             self.details.append("{} - Project {} Contents:".format(item.id, item.name))
#         else:
#             self.details.append("Project {} Contents:".format(item.name))
# 
#     def visit_folder(self, item, parent):
#         name = self.get_name(item, parent)
#         self.id_to_path[item.id] = name
#         if self.long_format:
#             self.details.append('{}\t{}'.format(item.id, name))
#         else:
#             self.details.append(name)
# 
#     def visit_file(self, item, parent):
#         name = self.get_name(item, parent)
#         if self.long_format:
#             self.details.append('{}\t{}\t({}:{})'.format(item.id, name, item.hash_alg, item.file_hash))
#         else:
#             self.details.append(name)
# 
#     def get_name(self, item, parent):
#         if parent:
#             if parent.kind == KindType.project_str:
#                 return '{}{}'.format(REMOTE_PATH_SEP, item.name)
#             parent_name = self.id_to_path.get(parent.id)
#             if parent_name:
#                 return "{}{}{}".format(parent_name, REMOTE_PATH_SEP, item.name)
#         return item.name
# 
# class KindType(object):
#     """
#     The types of items that are part of a project. Strings are from the duke-data-service.
#     """
#     file_str = 'dds-file'
#     folder_str = 'dds-folder'
#     project_str = 'dds-project'
# 
#     @staticmethod
#     def is_file(item):
#         return item.kind == KindType.file_str
# 
#     @staticmethod
#     def is_folder(item):
#         return item.kind == KindType.folder_str
# 
#     @staticmethod
#     def is_project(item):
#         return item.kind == KindType.project_str
# 
# Path: ddsc/exceptions.py
# class DDSUserException(Exception):
#     """
#     Exception with an error message to be displayed to the user on the command line.
#     """
#     pass


from unittest import TestCase
from ddsc.core.util import mode_allows_group_or_other, verify_file_private, ProjectDetailsList, KindType
from ddsc.exceptions import DDSUserException
from mock import patch, Mock
import subprocess
import os
import tempfile
        self.assertEqual(expected_details, project_details_list.details)

    def test_visit_methods_long_format(self):
        project_details_list = ProjectDetailsList(long_format=True)
        project_details_list.visit_project(self.mock_project_item)
        project_details_list.visit_folder(self.mock_folder_item, self.mock_project_item)
        project_details_list.visit_file(self.mock_file_item, self.mock_folder_item)
        expected_details = [
            '123 - Project mouse Contents:',
            '456\t/data',
            '789\t/data/results.csv\t(md5:abcdefg)',
        ]
        self.assertEqual(expected_details, project_details_list.details)

    def test_get_name_with_project_parent(self):
        item = Mock()
        item.name = 'file1.txt'
        parent = Mock()
        parent.kind = KindType.project_str
        parent.id = 'abc123'
        project_details_list = ProjectDetailsList(long_format=True)
        name = project_details_list.get_name(item, parent)
        self.assertEqual(name, '/file1.txt')

    def test_get_name_no_parent(self):
        item = Mock()
        item.name = 'file1.txt'
        parent = Mock()
        parent.kind = KindType.project_str
        parent.id = 'abc123'

# Path: ddsc/core/util.py
# def mode_allows_group_or_other(st_mode):
#     """
#     Returns True if st_mode bitset has group or other permissions
#     :param st_mode: int: bit set from a file
#     :return: bool: true when group or other has some permissions
#     """
#     return (st_mode & stat.S_IRWXO or st_mode & stat.S_IRWXG) != 0
# 
# def verify_file_private(filename):
#     """
#     Raises ValueError the file permissions allow group/other
#     On windows this never raises due to the implementation of stat.
#     """
#     if platform.system().upper() != 'WINDOWS':
#         filename = os.path.expanduser(filename)
#         if os.path.exists(filename):
#             file_stat = os.stat(filename)
#             if mode_allows_group_or_other(file_stat.st_mode):
#                 raise DDSUserException(CONFIG_FILE_PERMISSIONS_ERROR)
# 
# class ProjectDetailsList(object):
#     """
#     Walks a project and saves the project name and filenames to [str] filenames property.
#     """
#     def __init__(self, long_format):
#         self.long_format = long_format
#         self.details = []
#         self.id_to_path = {}
# 
#     def walk_project(self, project):
#         """
#         Walks a project and saves the project name and filenames to [str] filenames property.
#         :param project: LocalProject project we will read details from.
#         """
#         # This method will call visit_project, visit_folder, and visit_file below as it walks the project tree.
#         ProjectWalker.walk_project(project, self)
# 
#     def visit_project(self, item):
#         if self.long_format:
#             self.details.append("{} - Project {} Contents:".format(item.id, item.name))
#         else:
#             self.details.append("Project {} Contents:".format(item.name))
# 
#     def visit_folder(self, item, parent):
#         name = self.get_name(item, parent)
#         self.id_to_path[item.id] = name
#         if self.long_format:
#             self.details.append('{}\t{}'.format(item.id, name))
#         else:
#             self.details.append(name)
# 
#     def visit_file(self, item, parent):
#         name = self.get_name(item, parent)
#         if self.long_format:
#             self.details.append('{}\t{}\t({}:{})'.format(item.id, name, item.hash_alg, item.file_hash))
#         else:
#             self.details.append(name)
# 
#     def get_name(self, item, parent):
#         if parent:
#             if parent.kind == KindType.project_str:
#                 return '{}{}'.format(REMOTE_PATH_SEP, item.name)
#             parent_name = self.id_to_path.get(parent.id)
#             if parent_name:
#                 return "{}{}{}".format(parent_name, REMOTE_PATH_SEP, item.name)
#         return item.name
# 
# class KindType(object):
#     """
#     The types of items that are part of a project. Strings are from the duke-data-service.
#     """
#     file_str = 'dds-file'
#     folder_str = 'dds-folder'
#     project_str = 'dds-project'
# 
#     @staticmethod
#     def is_file(item):
#         return item.kind == KindType.file_str
# 
#     @staticmethod
#     def is_folder(item):
#         return item.kind == KindType.folder_str
# 
#     @staticmethod
#     def is_project(item):
#         return item.kind == KindType.project_str
# 
# Path: ddsc/exceptions.py
# class DDSUserException(Exception):
#     """
#     Exception with an error message to be displayed to the user on the command line.
#     """
#     pass


# Path: ddsc/tests/test_util.py
from unittest import TestCase
from ddsc.core.util import mode_allows_group_or_other, verify_file_private, ProjectDetailsList, KindType
from ddsc.exceptions import DDSUserException
from mock import patch, Mock
import subprocess
import os
import tempfile

        self.assertEqual(expected_details, project_details_list.details)

    def test_visit_methods_long_format(self):
        project_details_list = ProjectDetailsList(long_format=True)
        project_details_list.visit_project(self.mock_project_item)
        project_details_list.visit_folder(self.mock_folder_item, self.mock_project_item)
        project_details_list.visit_file(self.mock_file_item, self.mock_folder_item)
        expected_details = [
            '123 - Project mouse Contents:',
            '456\t/data',
            '789\t/data/results.csv\t(md5:abcdefg)',
        ]
        self.assertEqual(expected_details, project_details_list.details)

    def test_get_name_with_project_parent(self):
        item = Mock()
        item.name = 'file1.txt'
        parent = Mock()
        parent.kind = KindType.project_str
        parent.id = 'abc123'
        project_details_list = ProjectDetailsList(long_format=True)
        name = project_details_list.get_name(item, parent)
        self.assertEqual(name, '/file1.txt')

    def test_get_name_no_parent(self):
        item = Mock()
        item.name = 'file1.txt'
        parent = Mock()
        parent.kind = KindType.project_str
        parent.id = 'abc123'

        project_details_list = ProjectDetailsList(long_format=True)