mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
207 lines
6.4 KiB
Python
207 lines
6.4 KiB
Python
import shutil
|
|
from pathlib import Path
|
|
from typing import List, Iterable
|
|
|
|
import pytest
|
|
from sqlalchemy.orm import Session
|
|
|
|
from modules.files import lib
|
|
from modules.files.models import File
|
|
from wrolpi.errors import InvalidFile
|
|
from wrolpi.media_path import MediaPathType
|
|
from wrolpi.vars import PROJECT_DIR
|
|
|
|
|
|
def assert_files(session: Session, expected):
|
|
files = {str(i.path.relative) for i in session.query(File).all()}
|
|
assert files == set(expected)
|
|
|
|
|
|
def test_list_files(make_files_structure, test_directory):
|
|
files = [
|
|
'archives/bar.txt',
|
|
'archives/baz/bar.txt',
|
|
'archives/baz/foo.txt',
|
|
'archives/foo.txt',
|
|
'empty directory/',
|
|
'videos/other video.mp4',
|
|
'videos/some video.mp4',
|
|
]
|
|
make_files_structure(files)
|
|
|
|
def check_list_files(path, expected):
|
|
result = lib.list_files(path)
|
|
result = sorted(result)
|
|
assert [str(i.relative_to(test_directory)) for i in result] == expected
|
|
|
|
check_list_files([], ['archives', 'empty directory', 'videos'])
|
|
# Falsey directories are ignored.
|
|
check_list_files([None, ''], ['archives', 'empty directory', 'videos'])
|
|
check_list_files(['empty directory'], ['archives', 'empty directory', 'videos'])
|
|
check_list_files(['empty directory'], ['archives', 'empty directory', 'videos'])
|
|
# Trailing slash is ignored.
|
|
check_list_files(['empty directory/'], ['archives', 'empty directory', 'videos'])
|
|
|
|
check_list_files(['archives'], [
|
|
'archives',
|
|
'archives/bar.txt',
|
|
'archives/baz',
|
|
'archives/foo.txt',
|
|
'empty directory',
|
|
'videos',
|
|
])
|
|
check_list_files(['archives/baz'], [
|
|
'archives',
|
|
'archives/bar.txt',
|
|
'archives/baz',
|
|
'archives/baz/bar.txt',
|
|
'archives/baz/foo.txt',
|
|
'archives/foo.txt',
|
|
'empty directory',
|
|
'videos',
|
|
])
|
|
# Including duplicate directories does not change results.
|
|
check_list_files(['archives/baz', 'archives'], [
|
|
'archives',
|
|
'archives/bar.txt',
|
|
'archives/baz',
|
|
'archives/baz/bar.txt',
|
|
'archives/baz/foo.txt',
|
|
'archives/foo.txt',
|
|
'empty directory',
|
|
'videos',
|
|
])
|
|
check_list_files(['videos'], [
|
|
'archives',
|
|
'empty directory',
|
|
'videos',
|
|
'videos/other video.mp4',
|
|
'videos/some video.mp4',
|
|
])
|
|
# All files and directories are listed.
|
|
check_list_files(['videos', 'archives/baz'], [
|
|
'archives',
|
|
'archives/bar.txt',
|
|
'archives/baz',
|
|
'archives/baz/bar.txt',
|
|
'archives/baz/foo.txt',
|
|
'archives/foo.txt',
|
|
'empty directory',
|
|
'videos',
|
|
'videos/other video.mp4',
|
|
'videos/some video.mp4',
|
|
])
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'directories,expected', [
|
|
([Path('foo')], [Path('foo')]),
|
|
([Path('foo'), Path('bar')], [Path('foo'), Path('bar')]),
|
|
([Path('foo'), Path('foo/bar'), Path('baz')], [Path('foo/bar'), Path('baz')]),
|
|
([Path('foo/bar'), Path('foo'), Path('baz')], [Path('foo/bar'), Path('baz')]),
|
|
([Path('baz'), Path('foo/bar'), Path('foo')], [Path('baz'), Path('foo/bar')]),
|
|
([Path('foo/bar'), Path('foo'), Path('foo/bar/baz')], [Path('foo/bar/baz')]),
|
|
]
|
|
)
|
|
def test_filter_parent_directories(directories, expected):
|
|
assert lib.filter_parent_directories(directories) == expected
|
|
|
|
|
|
def test_delete_file(make_files_structure, test_directory):
|
|
"""
|
|
File in the media directory can be deleted.
|
|
"""
|
|
files = [
|
|
'archives/foo.txt',
|
|
'bar.txt',
|
|
'baz/',
|
|
]
|
|
make_files_structure(files)
|
|
|
|
lib.delete_file('bar.txt')
|
|
assert (test_directory / 'archives/foo.txt').is_file()
|
|
assert not (test_directory / 'bar.txt').is_file()
|
|
assert (test_directory / 'baz').is_dir()
|
|
|
|
lib.delete_file('archives/foo.txt')
|
|
assert not (test_directory / 'archives/foo.txt').is_file()
|
|
assert not (test_directory / 'bar.txt').is_file()
|
|
|
|
with pytest.raises(InvalidFile):
|
|
lib.delete_file('baz')
|
|
with pytest.raises(InvalidFile):
|
|
lib.delete_file('does not exist')
|
|
|
|
assert (test_directory / 'baz').is_dir()
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'path,expected',
|
|
[
|
|
('foo.mp4', ['foo']),
|
|
('foo bar.txt', ['foo', 'bar']),
|
|
('foo_bar.mp4', ['foo', 'bar']),
|
|
('foo-bar', ['foo-bar']),
|
|
('123 foo bar', ['123', 'foo', 'bar']),
|
|
('123foo bar', ['123foo', 'bar']),
|
|
]
|
|
)
|
|
def test_split_file_name(path, expected):
|
|
assert lib.split_file_name(Path(path)) == expected
|
|
|
|
|
|
def test_refresh_files(test_session, make_files_structure, test_directory):
|
|
files = make_files_structure([
|
|
'foo.txt',
|
|
'bar.txt',
|
|
'baz.txt',
|
|
])
|
|
foo, bar, baz = files
|
|
|
|
def get_relative_strs(files_: Iterable[MediaPathType]) -> List[str]:
|
|
return sorted([str(i.path.path.relative_to(test_directory)) for i in files_])
|
|
|
|
lib.refresh_files()
|
|
results = test_session.query(File)
|
|
assert get_relative_strs(results) == ['bar.txt', 'baz.txt', 'foo.txt']
|
|
|
|
baz.unlink()
|
|
|
|
lib.refresh_files()
|
|
results = test_session.query(File)
|
|
assert get_relative_strs(results) == ['bar.txt', 'foo.txt']
|
|
|
|
foo.unlink()
|
|
bar.unlink()
|
|
|
|
lib.refresh_files()
|
|
results = test_session.query(File)
|
|
assert get_relative_strs(results) == []
|
|
|
|
|
|
def test_mime_type(test_session, make_files_structure, test_directory):
|
|
"""Files module uses the `file` command to get the mimetype of each file."""
|
|
from PIL import Image
|
|
|
|
foo, bar, baz, empty = make_files_structure([
|
|
'dir/foo text.txt',
|
|
'dir/bar.jpeg',
|
|
'dir/baz.mp4',
|
|
'dir/empty',
|
|
])
|
|
foo.write_text('some text')
|
|
Image.new('RGB', (25, 25), color='grey').save(bar)
|
|
shutil.copy(PROJECT_DIR / 'test/big_buck_bunny_720p_1mb.mp4', baz)
|
|
|
|
lib.refresh_files()
|
|
assert_files(test_session, ['dir/foo text.txt', 'dir/bar.jpeg', 'dir/baz.mp4', 'dir/empty'])
|
|
|
|
foo = test_session.query(File).filter_by(path=f'{test_directory}/dir/foo text.txt').one()
|
|
bar = test_session.query(File).filter_by(path=f'{test_directory}/dir/bar.jpeg').one()
|
|
baz = test_session.query(File).filter_by(path=f'{test_directory}/dir/baz.mp4').one()
|
|
empty = test_session.query(File).filter_by(path=f'{test_directory}/dir/empty').one()
|
|
|
|
assert foo.mimetype == 'text/plain'
|
|
assert bar.mimetype == 'image/jpeg'
|
|
assert baz.mimetype == 'video/mp4'
|
|
assert empty.mimetype == 'inode/x-empty'
|