text: #!/usr/bin/env python
  
  # Copyright (C) 2007-2016 Giampaolo Rodola' <g.rodola@gmail.com>.
  # Use of this source code is governed by MIT license that can be
  # found in the LICENSE file.
  
  import os
  import tempfile
  
  from pyftpdlib._compat import getcwdu
  from pyftpdlib._compat import u
  from pyftpdlib.filesystems import AbstractedFS
  from pyftpdlib.test import HOME
  from pyftpdlib.test import POSIX
  from pyftpdlib.test import safe_remove
  from pyftpdlib.test import TESTFN
  from pyftpdlib.test import touch
  from pyftpdlib.test import unittest
  from pyftpdlib.test import VERBOSITY
  
  if POSIX:
      from pyftpdlib.filesystems import UnixFilesystem
  
  
  class TestAbstractedFS(unittest.TestCase):
      """Test for conversion utility methods of AbstractedFS class."""
  
      def setUp(self):
          safe_remove(TESTFN)
  
      tearDown = setUp
  
      def test_ftpnorm(self):
          # Tests for ftpnorm method.
          ae = self.assertEqual
          fs = AbstractedFS(u('/'), None)
  
          fs._cwd = u('/')
          ae(fs.ftpnorm(u('')), u('/'))
          ae(fs.ftpnorm(u('/')), u('/'))
          ae(fs.ftpnorm(u('.')), u('/'))
          ae(fs.ftpnorm(u('..')), u('/'))
          ae(fs.ftpnorm(u('a')), u('/a'))
          ae(fs.ftpnorm(u('/a')), u('/a'))
          ae(fs.ftpnorm(u('/a/')), u('/a'))
          ae(fs.ftpnorm(u('a/..')), u('/'))
          ae(fs.ftpnorm(u('a/b')), '/a/b')
          ae(fs.ftpnorm(u('a/b/..')), u('/a'))
          ae(fs.ftpnorm(u('a/b/../..')), u('/'))
          fs._cwd = u('/sub')
          ae(fs.ftpnorm(u('')), u('/sub'))
          ae(fs.ftpnorm(u('/')), u('/'))
          ae(fs.ftpnorm(u('.')), u('/sub'))
          ae(fs.ftpnorm(u('..')), u('/'))
          ae(fs.ftpnorm(u('a')), u('/sub/a'))
          ae(fs.ftpnorm(u('a/')), u('/sub/a'))
          ae(fs.ftpnorm(u('a/..')), u('/sub'))
          ae(fs.ftpnorm(u('a/b')), u('/sub/a/b'))
          ae(fs.ftpnorm(u('a/b/')), u('/sub/a/b'))
          ae(fs.ftpnorm(u('a/b/..')), u('/sub/a'))
          ae(fs.ftpnorm(u('a/b/../..')), u('/sub'))
          ae(fs.ftpnorm(u('a/b/../../..')), u('/'))
          ae(fs.ftpnorm(u('//')), u('/'))  # UNC paths must be collapsed
  
      def test_ftp2fs(self):
          # Tests for ftp2fs method.
          def join(x, y):
              return os.path.join(x, y.replace('/', os.sep))
  
          ae = self.assertEqual
          fs = AbstractedFS(u('/'), None)
  
          def goforit(root):
              fs._root = root
              fs._cwd = u('/')
              ae(fs.ftp2fs(u('')), root)
              ae(fs.ftp2fs(u('/')), root)
              ae(fs.ftp2fs(u('.')), root)
              ae(fs.ftp2fs(u('..')), root)
              ae(fs.ftp2fs(u('a')), join(root, u('a')))
              ae(fs.ftp2fs(u('/a')), join(root, u('a')))
              ae(fs.ftp2fs(u('/a/')), join(root, u('a')))
              ae(fs.ftp2fs(u('a/..')), root)
              ae(fs.ftp2fs(u('a/b')), join(root, u(r'a/b')))
              ae(fs.ftp2fs(u('/a/b')), join(root, u(r'a/b')))
              ae(fs.ftp2fs(u('/a/b/..')), join(root, u('a')))
              ae(fs.ftp2fs(u('/a/b/../..')), root)
              fs._cwd = u('/sub')
              ae(fs.ftp2fs(u('')), join(root, u('sub')))
              ae(fs.ftp2fs(u('/')), root)
              ae(fs.ftp2fs(u('.')), join(root, u('sub')))
              ae(fs.ftp2fs(u('..')), root)
              ae(fs.ftp2fs(u('a')), join(root, u('sub/a')))
              ae(fs.ftp2fs(u('a/')), join(root, u('sub/a')))
              ae(fs.ftp2fs(u('a/..')), join(root, u('sub')))
              ae(fs.ftp2fs(u('a/b')), join(root, 'sub/a/b'))
              ae(fs.ftp2fs(u('a/b/..')), join(root, u('sub/a')))
              ae(fs.ftp2fs(u('a/b/../..')), join(root, u('sub')))
              ae(fs.ftp2fs(u('a/b/../../..')), root)
              # UNC paths must be collapsed
              ae(fs.ftp2fs(u('//a')), join(root, u('a')))
  
          if os.sep == '\\':
              goforit(u(r'C:\dir'))
              goforit(u('C:\\'))
              # on DOS-derived filesystems (e.g. Windows) this is the same
              # as specifying the current drive directory (e.g. 'C:\\')
              goforit(u('\\'))
          elif os.sep == '/':
              goforit(u('/home/user'))
              goforit(u('/'))
          else:
              # os.sep == ':'? Don't know... let's try it anyway
              goforit(getcwdu())
  
      def test_fs2ftp(self):
          # Tests for fs2ftp method.
          def join(x, y):
              return os.path.join(x, y.replace('/', os.sep))
  
          ae = self.assertEqual
          fs = AbstractedFS(u('/'), None)
  
          def goforit(root):
              fs._root = root
              ae(fs.fs2ftp(root), u('/'))
              ae(fs.fs2ftp(join(root, u('/'))), u('/'))
              ae(fs.fs2ftp(join(root, u('.'))), u('/'))
              # can't escape from root
              ae(fs.fs2ftp(join(root, u('..'))), u('/'))
              ae(fs.fs2ftp(join(root, u('a'))), u('/a'))
              ae(fs.fs2ftp(join(root, u('a/'))), u('/a'))
              ae(fs.fs2ftp(join(root, u('a/..'))), u('/'))
              ae(fs.fs2ftp(join(root, u('a/b'))), u('/a/b'))
              ae(fs.fs2ftp(join(root, u('a/b'))), u('/a/b'))
              ae(fs.fs2ftp(join(root, u('a/b/..'))), u('/a'))
              ae(fs.fs2ftp(join(root, u('/a/b/../..'))), u('/'))
              fs._cwd = u('/sub')
              ae(fs.fs2ftp(join(root, 'a/')), u('/a'))
  
          if os.sep == '\\':
              goforit(u(r'C:\dir'))
              goforit(u('C:\\'))
              # on DOS-derived filesystems (e.g. Windows) this is the same
              # as specifying the current drive directory (e.g. 'C:\\')
              goforit(u('\\'))
              fs._root = u(r'C:\dir')
              ae(fs.fs2ftp(u('C:\\')), u('/'))
              ae(fs.fs2ftp(u('D:\\')), u('/'))
              ae(fs.fs2ftp(u('D:\\dir')), u('/'))
          elif os.sep == '/':
              goforit(u('/'))
              if os.path.realpath('/__home/user') != '/__home/user':
                  self.fail('Test skipped (symlinks not allowed).')
              goforit(u('/__home/user'))
              fs._root = u('/__home/user')
              ae(fs.fs2ftp(u('/__home')), u('/'))
              ae(fs.fs2ftp(u('/')), u('/'))
              ae(fs.fs2ftp(u('/__home/userx')), u('/'))
          else:
              # os.sep == ':'? Don't know... let's try it anyway
              goforit(getcwdu())
  
      def test_validpath(self):
          # Tests for validpath method.
          fs = AbstractedFS(u('/'), None)
          fs._root = HOME
          self.assertTrue(fs.validpath(HOME))
          self.assertTrue(fs.validpath(HOME + '/'))
          self.assertFalse(fs.validpath(HOME + 'bar'))
  
      if hasattr(os, 'symlink'):
  
          def test_validpath_validlink(self):
              # Test validpath by issuing a symlink pointing to a path
              # inside the root directory.
              fs = AbstractedFS(u('/'), None)
              fs._root = HOME
              TESTFN2 = TESTFN + '1'
              try:
                  touch(TESTFN)
                  os.symlink(TESTFN, TESTFN2)
                  self.assertTrue(fs.validpath(u(TESTFN)))
              finally:
                  safe_remove(TESTFN, TESTFN2)
  
          def test_validpath_external_symlink(self):
              # Test validpath by issuing a symlink pointing to a path
              # outside the root directory.
              fs = AbstractedFS(u('/'), None)
              fs._root = HOME
              # tempfile should create our file in /tmp directory
              # which should be outside the user root.  If it is
              # not we just skip the test.
              with tempfile.NamedTemporaryFile() as file:
                  try:
                      if HOME == os.path.dirname(file.name):
                          return
                      os.symlink(file.name, TESTFN)
                      self.assertFalse(fs.validpath(u(TESTFN)))
                  finally:
                      safe_remove(TESTFN)
  
  
  @unittest.skipUnless(POSIX, "UNIX only")
  class TestUnixFilesystem(unittest.TestCase):
  
      def test_case(self):
          root = getcwdu()
          fs = UnixFilesystem(root, None)
          self.assertEqual(fs.root, root)
          self.assertEqual(fs.cwd, root)
          cdup = os.path.dirname(root)
          self.assertEqual(fs.ftp2fs(u('..')), cdup)
          self.assertEqual(fs.fs2ftp(root), root)
  
  
  if __name__ == '__main__':
      unittest.main(verbosity=VERBOSITY)
  