Make fixtures function scoped and add new tests

This commit is contained in:
R. Richard 2019-05-22 22:31:55 +02:00
parent 9cb8ef0e72
commit b44fd200c6
2 changed files with 73 additions and 67 deletions

View File

@ -41,7 +41,7 @@ class FileManager: # pylint: disable=too-many-instance-attributes
@allowed_directories.setter @allowed_directories.setter
def allowed_directories(self, directories): def allowed_directories(self, directories):
self._allowed_directories = directories self._allowed_directories = [realpath(directory) for directory in directories]
@property @property
def filename(self): def filename(self):

View File

@ -1,97 +1,103 @@
# pylint: disable=redefined-outer-name # pylint: disable=redefined-outer-name
from secrets import token_urlsafe from secrets import token_urlsafe
from os.path import join
from os import chdir, mkdir, symlink
from pathlib import Path from pathlib import Path
from shutil import rmtree from tempfile import TemporaryDirectory
from os.path import join, realpath
from os import mkdir, rmdir, remove, symlink
import pytest import pytest
from filemanager import FileManager from file_manager import FileManager
WORKDIR = realpath('test_filemanager') class ManagerContext:
def __init__(self, folder, manager):
self.folder = folder
self.manager = manager
def workdir_pref(path): def join(self, path):
return join(WORKDIR, path) return join(self.folder, path)
@pytest.fixture(scope='module')
def manager(): @pytest.fixture()
def context():
dirs = [] dirs = []
mkdir(WORKDIR)
for i in range(3): with TemporaryDirectory() as workdir:
node = workdir_pref('dir_'+str(i).zfill(2)) chdir(workdir)
for name in ["allowed", "excluded", "invis"]:
node = join(workdir, name)
mkdir(node) mkdir(node)
Path(join(node, 'empty.txt')).touch() Path(join(node, 'empty.txt')).touch()
Path(join(node, 'empty.bin')).touch() Path(join(node, 'empty.bin')).touch()
dirs.append(node) dirs.append(node)
yield FileManager(dirs[0], dirs[:-1], exclude=['*/dir_01/*', '*.bin']) yield ManagerContext(
rmtree(WORKDIR) workdir,
FileManager(dirs[0], dirs[:-1], exclude=['*/excluded/*'])
)
@pytest.mark.parametrize('subdir', ['dir_00', 'dir_01']) @pytest.mark.parametrize('subdir', ['allowed/', 'excluded/'])
def test_select_allowed_dirs(manager, subdir): def test_select_allowed_dirs(context, subdir):
manager.workdir = workdir_pref(subdir) context.manager.workdir = context.join(subdir)
assert manager.workdir == workdir_pref(subdir) assert context.manager.workdir == context.join(subdir)
newdir = workdir_pref(join(subdir, 'deep')) newdir = context.join(subdir+'deep')
mkdir(newdir) mkdir(newdir)
manager.workdir = newdir context.manager.workdir = newdir
assert manager.workdir == newdir assert context.manager.workdir == newdir
rmdir(newdir)
@pytest.mark.parametrize('excdir', ['/', workdir_pref('dir_02')]) @pytest.mark.parametrize('invdir', ['', 'invis'])
def test_select_excluded_dirs(manager, excdir): def test_select_forbidden_dirs(context, invdir):
allowed = manager.allowed_directories fullpath = context.join(invdir)
with pytest.raises(OSError): with pytest.raises(OSError):
manager.workdir = excdir context.manager.workdir = fullpath
assert manager.workdir != excdir assert context.manager.workdir != fullpath
manager.allowed_directories = allowed+[excdir] context.manager.allowed_directories += [fullpath]
manager.workdir = excdir context.manager.workdir = fullpath
assert manager.workdir == excdir assert context.manager.workdir == fullpath
manager.allowed_directories = allowed
@pytest.mark.parametrize('filename', ['another.txt', '*.txt']) @pytest.mark.parametrize('filename', ['another.txt', '*.txt'])
def test_select_allowed_files(manager, filename): def test_select_allowed_files(context, filename):
manager.workdir = workdir_pref('dir_00') Path(context.join('allowed/'+filename)).touch()
newfile = workdir_pref(join('dir_00', filename)) assert filename in context.manager.files
Path(newfile).touch() context.manager.filename = filename
assert filename in manager.files assert context.manager.filename == filename
manager.filename = filename
assert manager.filename == filename
remove(newfile)
@pytest.mark.parametrize('path', [ @pytest.mark.parametrize('path', [
['dir_00', 'illegal.bin'], {'dir': 'allowed/', 'file': 'illegal.bin'},
['dir_01', 'legal.txt'] {'dir': 'excluded/', 'file': 'legal.txt'},
{'dir': 'allowed/', 'file': token_urlsafe(16)+'.bin'},
{'dir': 'excluded/', 'file': token_urlsafe(16)+'.txt'},
{'dir': 'allowed/', 'file': token_urlsafe(32)+'.bin'},
{'dir': 'excluded/', 'file': token_urlsafe(32)+'.txt'}
]) ])
def test_select_excluded_files(manager, path): def test_select_excluded_files(context, path):
manager.workdir = workdir_pref(path[0]) context.manager.workdir = context.join(path['dir'])
newfile = workdir_pref(join(path[0], path[1])) context.manager.exclude = ['*/excluded/*', '*.bin']
Path(newfile).touch() Path(context.join(path['dir']+path['file'])).touch()
assert path[1] not in manager.files assert path['file'] not in context.manager.files
with pytest.raises(OSError): with pytest.raises(OSError):
manager.filename = path[1] context.manager.filename = path['file']
remove(newfile)
@pytest.mark.parametrize('path', [ @pytest.mark.parametrize('path', [
['dir_02/empty.txt', 'dir_00/link.txt'], {'src': 'excluded/empty.txt', 'dst': 'allowed/link.txt'},
['dir_01/empty.txt', 'dir_00/link.bin'] {'src': 'invis/empty.txt', 'dst': 'allowed/link.txt'},
{'src': 'excluded/empty.txt', 'dst': 'allowed/'+token_urlsafe(16)+'.txt'},
{'src': 'invis/empty.txt', 'dst': 'allowed/'+token_urlsafe(16)+'.txt'},
{'src': 'excluded/empty.txt', 'dst': 'allowed/'+token_urlsafe(32)+'.txt'},
{'src': 'invis/empty.txt', 'dst': 'allowed/'+token_urlsafe(32)+'.txt'}
]) ])
def test_select_excluded_symlinks(manager, path): def test_select_excluded_symlinks(context, path):
manager.workdir = workdir_pref('dir_00') symlink(context.join(path['src']), context.join(path['dst']))
link = workdir_pref(path[1]) assert path['dst'] not in context.manager.files
symlink(workdir_pref(path[0]), link)
assert path[1] not in manager.files
remove(link)
def test_read_write_file(manager): def test_read_write_file(context):
for _ in range(128): for _ in range(128):
manager.workdir = workdir_pref('dir_00') context.manager.filename = 'empty.txt'
manager.filename = 'empty.txt'
content = token_urlsafe(32) content = token_urlsafe(32)
manager.file_contents = content context.manager.file_contents = content
assert manager.file_contents == content assert context.manager.file_contents == content
with open(workdir_pref('dir_00/empty.txt'), "r") as ifile: with open(context.join('allowed/empty.txt'), "r") as ifile:
assert ifile.read() == content assert ifile.read() == content