# MousikóFídi
# Copyright (C) 2019 Hristos N. Triantafillou
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import pytest
import shutil
import sys
import tempfile
import yaml
from datetime import datetime
from flask import session
from mousikofidi import (
app,
breadcrumb_links_from_path,
browse_dir,
browse_file,
config_to_string,
dir_dict,
file_dict,
file_metadata,
get_metadata_dict,
get_metadata_value,
get_playlists,
handle_playlist_cmd,
init,
is_audio_file,
is_valid_path,
make_unique_slugs,
paths_list,
quote,
request_context,
select_cover_art,
select_css,
select_logo,
title_slug,
)
THIS_DIR = os.path.abspath(sys.argv[-1])
# A fresh copy to go back to
app._fidiConfig = app.fidiConfig.copy()
@pytest.fixture
def client():
with app.test_client() as client:
yield client
def test_audio_dict_flac():
example_dir = os.path.join(THIS_DIR, "example").strip("/")
f = os.path.join(THIS_DIR, "example", "real.flac")
m = get_metadata_dict(f)
d = file_dict(f, m, "audio")
assert d == {
"album": "MousikóFídi Test Album",
"artist": "MousikóFídi Test Artist",
"genre": "MousikóFídi Test",
"length": "0:04",
"title": "MousikóFídi Test FLAC",
"title_mobile": "MousikóFídi Test FLAC",
"track": "34",
"type": "audio",
"tracktotal": "0",
"file_name": "real.flac",
"file_name_mobile": "real.flac",
"file_path": "{}/real.flac".format(example_dir),
"slug": "mousikófíditestflac",
}
def test_audio_dict_mp3():
example_dir = os.path.join(THIS_DIR, "example").strip("/")
f = os.path.join(THIS_DIR, "example", "real.mp3")
m = get_metadata_dict(f)
d = file_dict(f, m, "audio")
assert d == {
"album": "MousikóFídi Test Album",
"artist": "MousikóFídi Test Artist",
"genre": "MousikóFídi Test",
"length": "0:04",
"title": "MousikóFídi Test MP3",
"title_mobile": "MousikóFídi Test MP3",
"track": "34",
"type": "audio",
"tracktotal": "1",
"file_name": "real.mp3",
"file_name_mobile": "real.mp3",
"file_path": "{}/real.mp3".format(example_dir),
"slug": "mousikófíditestmp3",
}
def test_audio_dict_ogg():
example_dir = os.path.join(THIS_DIR, "example").strip("/")
f = os.path.join(THIS_DIR, "example", "real.ogg")
m = get_metadata_dict(f)
d = file_dict(f, m, "audio")
assert d == {
"album": "MousikóFídi Test Album",
"artist": "MousikóFídi Test Artist",
"genre": "MousikóFídi Test",
"length": "0:00",
"title": "MousikóFídi Test OGG",
"title_mobile": "MousikóFídi Test OGG",
"track": "34",
"type": "audio",
"tracktotal": None,
"file_name": "real.ogg",
"file_name_mobile": "real.ogg",
"file_path": "{}/real.ogg".format(example_dir),
"slug": "mousikófíditestogg",
}
def test_audio_metadata_fake_flac():
fake = file_metadata(os.path.join(THIS_DIR, "example", "fake.flac"))
assert fake == {}
def test_audio_metadata_real_flac():
real = file_metadata(os.path.join(THIS_DIR, "example", "real.flac"))
assert real == {
"TITLE": "MousikóFídi Test FLAC",
"ARTIST": "MousikóFídi Test Artist",
"ALBUM": "MousikóFídi Test Album",
"COMMENT": "FLAC Comment!",
"DATE": "2019-08-08",
"ENCODED-BY": "FLAC Encoded-by",
"TRACKNUMBER": "34",
"TRACKTOTAL": "0",
"GENRE": "MousikóFídi Test",
"LYRICS": "Test FLAC Lyrics!",
"length": "0:04",
}
def test_audio_metadata_fake_mp3():
fake = file_metadata(os.path.join(THIS_DIR, "example", "fake.mp3"))
assert fake == {}
def test_audio_metadata_real_mp3():
real = file_metadata(os.path.join(THIS_DIR, "example", "real.mp3"))
assert real == {
"TIT2": "MousikóFídi Test MP3",
"TPE1": "MousikóFídi Test Artist",
"TALB": "MousikóFídi Test Album",
"COMM": "MP3 Comment!",
"TDRC": "2019-08-08",
"TRCK": "34 / 1",
"TPOS": "1",
"TCON": "MousikóFídi Test",
"TENC": "MP3 Encoded-by!",
"TLEN": "12345",
"USLT": "MP3 Lyrics Text!",
"length": "0:04",
}
def test_audio_metadata_fake_ogg():
fake = file_metadata(os.path.join(THIS_DIR, "example", "fake.ogg"))
assert fake == {}
def test_audio_metadata_real_ogg():
real = file_metadata(os.path.join(THIS_DIR, "example", "real.ogg"))
assert real == {
"TITLE": "MousikóFídi Test OGG",
"ARTIST": "MousikóFídi Test Artist",
"ALBUM": "MousikóFídi Test Album",
"COMMENT": "OGG Comment!",
"DATE": "2019-08-08",
"TRACKNUMBER": "34",
"GENRE": "MousikóFídi Test",
"ENCODED-BY": "OGG Encoded-by!",
"LYRICS": "OGG Lyrics!",
"length": "0:00",
}
def test_breadcrumb_links_from_path_dir():
example_dir = os.path.join(THIS_DIR, "example")
# TODO: somehow use url_for() here;
# RuntimeError: Attempted to generate a URL without the application context being pushed. This has to be executed when application context is available.
dir_detail_url = "/browse/{}".format(example_dir.strip("/"))
expected_string = '<a href="{url}">{full_path}</a>'.format(
full_path=example_dir, url=dir_detail_url
)
with app.test_request_context(dir_detail_url):
link_string = breadcrumb_links_from_path(example_dir, [example_dir])
assert link_string == expected_string
def test_breadcrumb_links_from_path_file():
example_dir = os.path.join(THIS_DIR, "example")
file_path = os.path.join(example_dir, "real.flac")
url = "/browse/{}".format(example_dir.strip("/"))
expected_string = '<a href="{url}">{path}</a> / real.flac'.format(
path=example_dir, url=url
)
with app.test_request_context(url):
link_string = breadcrumb_links_from_path(file_path, [example_dir])
assert link_string == expected_string
def test_breadcrumb_links_from_path_deep_dir():
tmpdir = tempfile.mkdtemp()
base = os.path.join(tmpdir, "flac")
tmpdeep = os.path.join(base, "SomeArtist", "SomeAlbum", "SomeDisc")
os.makedirs(tmpdeep)
expected_string = '<a href="{url1}">{dir1}</a> / <a href="{url2}">{dir2}</a> / <a href="{url3}">{dir3}</a> / <a href="{url4}">{dir4}</a>'.format(
dir1=os.path.join(tmpdir, "flac"),
dir2="SomeArtist",
dir3="SomeAlbum",
dir4="SomeDisc",
url1="/browse/{}/flac".format(tmpdir.strip("/")),
url2="/browse/{}/flac/SomeArtist".format(tmpdir.strip("/")),
url3="/browse/{}/flac/SomeArtist/SomeAlbum".format(tmpdir.strip("/")),
url4="/browse/{}/flac/SomeArtist/SomeAlbum/SomeDisc".format(tmpdir.strip("/")),
)
with app.test_request_context(
"/browse/{}/flac/SomeArtist/SomeAlbum/SomeDisc".format(tmpdir.strip("/"))
):
link_string = breadcrumb_links_from_path(tmpdeep, [base])
shutil.rmtree(tmpdir)
assert link_string == expected_string
def test_breadcrumb_links_from_path_deep_file():
tmpdir = tempfile.mkdtemp()
base = os.path.join(tmpdir, "flac")
tmpdeep = os.path.join(base, "SomeArtist", "SomeAlbum", "SomeDisc")
os.makedirs(tmpdeep)
expected_string = '<a href="{url1}">{dir1}</a> / <a href="{url2}">{dir2}</a> / <a href="{url3}">{dir3}</a> / <a href="{url4}">{dir4}</a> / real.flac'.format(
dir1=os.path.join(tmpdir, "flac"),
dir2="SomeArtist",
dir3="SomeAlbum",
dir4="SomeDisc",
url1="/browse/{}/flac".format(tmpdir.strip("/")),
url2="/browse/{}/flac/SomeArtist".format(tmpdir.strip("/")),
url3="/browse/{}/flac/SomeArtist/SomeAlbum".format(tmpdir.strip("/")),
url4="/browse/{}/flac/SomeArtist/SomeAlbum/SomeDisc".format(tmpdir.strip("/")),
)
deepfile = os.path.join(tmpdeep, "real.flac")
shutil.copy(os.path.join(THIS_DIR, "example", "real.flac"), tmpdeep)
with app.test_request_context(
"/browse/{}/flac/SomeArtist/SomeAlbum/SomeDisc/real.flac".format(
tmpdir.strip("/")
)
):
link_string = breadcrumb_links_from_path(deepfile, [base])
shutil.rmtree(tmpdir)
assert link_string == expected_string
def test_browse_dir():
example_dir = os.path.join(THIS_DIR, "example")
with app.test_request_context("/browse/" + example_dir.strip("/")):
c = request_context(init(use_config=os.path.join(example_dir, "fidi.yml")))
actual_dict = browse_dir(c, example_dir)
sourcedir = sys.argv[-1]
favicon = select_logo(app.fidiConfig, "favicon_path")
logo = select_logo(app.fidiConfig, "logo_path")
audio_list = [
{
"album": None,
"artist": None,
"genre": None,
"length": None,
"title": None,
"title_mobile": None,
"track": None,
"type": "audio",
"tracktotal": None,
"file_name": "fake.flac",
"file_name_mobile": "fake.flac",
"file_path": "{}/example/fake.flac".format(sourcedir).strip("/"),
"slug": "fakeflac",
},
{
"album": None,
"artist": None,
"genre": None,
"length": None,
"title": None,
"title_mobile": None,
"track": None,
"type": "audio",
"tracktotal": None,
"file_name": "fake.mp3",
"file_name_mobile": "fake.mp3",
"file_path": "{}/example/fake.mp3".format(sourcedir).strip("/"),
"slug": "fakemp3",
},
{
"album": None,
"artist": None,
"genre": None,
"length": None,
"title": None,
"title_mobile": None,
"track": None,
"type": "audio",
"tracktotal": None,
"file_name": "fake.ogg",
"file_name_mobile": "fake.ogg",
"file_path": "{}/example/fake.ogg".format(sourcedir).strip("/"),
"slug": "fakeogg",
},
{
"type": "audio",
"album": "MousikóFídi Test Album",
"artist": "MousikóFídi Test Artist",
"genre": "MousikóFídi Test",
"length": "0:04",
"title": "MousikóFídi Test FLAC",
"title_mobile": "MousikóFídi Test FLAC",
"track": "34",
"tracktotal": "0",
"file_name": "real.flac",
"file_name_mobile": "real.flac",
"file_path": "{}/example/real.flac".format(sourcedir).strip("/"),
"slug": "mousikófíditestflac",
},
{
"type": "audio",
"album": "MousikóFídi Test Album",
"artist": "MousikóFídi Test Artist",
"genre": "MousikóFídi Test",
"length": "0:04",
"title": "MousikóFídi Test MP3",
"title_mobile": "MousikóFídi Test MP3",
"track": "34",
"tracktotal": "1",
"file_name": "real.mp3",
"file_name_mobile": "real.mp3",
"file_path": "{}/example/real.mp3".format(sourcedir).strip("/"),
"slug": "mousikófíditestmp3",
},
{
"type": "audio",
"album": "MousikóFídi Test Album",
"artist": "MousikóFídi Test Artist",
"genre": "MousikóFídi Test",
"length": "0:00",
"title": "MousikóFídi Test OGG",
"title_mobile": "MousikóFídi Test OGG",
"track": "34",
"tracktotal": None,
"file_name": "real.ogg",
"file_name_mobile": "real.ogg",
"file_path": "{}/example/real.ogg".format(sourcedir).strip("/"),
"slug": "mousikófíditestogg",
},
]
video_list = [
{
"album": None,
"artist": None,
"genre": None,
"length": None,
"title": None,
"title_mobile": None,
"track": None,
"tracktotal": None,
"type": "video",
"file_name": "fake.mp4",
"file_name_mobile": "fake.mp4",
"file_path": "{}/example/fake.mp4".format(sourcedir).strip("/"),
"slug": "fakemp4",
},
{
"album": None,
"artist": None,
"genre": None,
"length": None,
"title": None,
"title_mobile": None,
"track": None,
"tracktotal": None,
"type": "video",
"file_name": "fake.webm",
"file_name_mobile": "fake.webm",
"file_path": "{}/example/fake.webm".format(sourcedir).strip("/"),
"slug": "fakewebm",
},
{
"type": "video",
"album": "MousikóFídi Test Album",
"artist": "MousikóFídi Test Artist",
"genre": "MousikóFídi Test Genre",
"length": "0:06",
"title": "MousikóFídi Test MP4",
"title_mobile": "MousikóFídi Test MP4",
"track": "34",
"tracktotal": "100",
"file_name": "real.mp4",
"file_name_mobile": "real.mp4",
"file_path": "{}/example/real.mp4".format(sourcedir).strip("/"),
"slug": "mousikófíditestmp4",
},
]
expected_dict = {
"audio_player": True,
"add_all_button": True,
"debug": False,
"favicon_path": favicon,
"icons": False,
"logo_path": logo,
"cover_art": "/serve/{}/MousikoFidi%20Sample%20Cover%20Art.png".format(
example_dir.strip("/")
),
"css": [
"/css/normalize.min.css",
"/fa/css/fontawesome.min.css",
"/fa/css/solid.min.css",
"/css/water/light.standalone.min.css",
"/css/fidi.min.css",
],
"file_list": [
"{}/fake.flac".format(example_dir),
"{}/fake.mp3".format(example_dir),
"{}/fake.mp4".format(example_dir),
"{}/fake.ogg".format(example_dir),
"{}/fake.webm".format(example_dir),
"{}/real.flac".format(example_dir),
"{}/real.mp3".format(example_dir),
"{}/real.mp4".format(example_dir),
"{}/real.ogg".format(example_dir),
],
"music_dirs": [
{
"full_path": "/home/username/music/flac",
"path": "home/username/music/flac",
},
{
"full_path": "/home/username/music/ogg",
"path": "home/username/music/ogg",
},
{
"full_path": "/home/username/video/mp4",
"path": "home/username/video/mp4",
},
],
"playlist_dir": "/home/username/music/playlists",
"playlist_save": True,
"playlists": [],
"preload_audio": False,
"preload_video": False,
"secret_key": True,
"site_name": "MousikóFídi - Your Music Cloud",
"queue": [],
"theme": "light",
"username": None,
"video_player": True,
"page_name": "{}/example".format(sourcedir),
"page_path": "",
"search": False,
"playlist_add": True,
"playlist_rm": False,
"item_type": "dir",
"dir_list": [
{"name": "runit", "path": "{}/example/runit".format(sourcedir).strip("/")}
],
"audio_list": audio_list,
"video_list": video_list,
"item_list": sorted(audio_list + video_list, key=lambda n: n["file_name"]),
}
assert actual_dict == expected_dict
def test_browse_dir_empty(client):
empty_dir = os.path.join(THIS_DIR, "example", "runit", "control")
empty_url = "/browse/" + empty_dir.strip("/")
dir_list = []
dir_list.append(empty_dir)
app.fidiConfig["config"]["music_dirs"] = dir_list
with app.app_context():
rv = client.get(empty_url)
assert (
b'<h2 class="bold center">No <a href="https://mousikofidi.info/user_guide/#valid-media-types">valid media files</a> were found here!</h2>'
in rv.data
)
def test_browse_file():
example_dir = os.path.join(THIS_DIR, "example")
with app.test_request_context("/browse/" + example_dir.strip("/")):
c = request_context(init(use_config=os.path.join(example_dir, "fidi.yml")))
actual_dict = browse_file(c, example_dir)
sourcedir = sys.argv[-1]
favicon = select_logo(app.fidiConfig, "favicon_path")
logo = select_logo(app.fidiConfig, "logo_path")
expected_dict = {
"album": None,
"artist": None,
"date": None,
"genre": None,
"length": None,
"title": None,
"track": None,
"tracktotal": None,
"debug": False,
"favicon_path": favicon,
"icons": False,
"logo_path": logo,
"page_name": "example",
"css": [
"/css/normalize.min.css",
"/fa/css/fontawesome.min.css",
"/fa/css/solid.min.css",
"/css/water/light.standalone.min.css",
"/css/fidi.min.css",
],
"music_dirs": [
{
"full_path": "/home/username/music/flac",
"path": "home/username/music/flac",
},
{
"full_path": "/home/username/music/ogg",
"path": "home/username/music/ogg",
},
{
"full_path": "/home/username/video/mp4",
"path": "home/username/video/mp4",
},
],
"full_path": sourcedir + "/example",
"path": sourcedir.strip("/") + "/example",
"playlist_dir": "/home/username/music/playlists",
"playlist_save": True,
"playlists": [],
"preload_audio": False,
"preload_video": False,
"search": False,
"secret_key": True,
"site_name": "MousikóFídi - Your Music Cloud",
"queue": [],
"theme": "light",
"username": None,
"file_name": "example",
"page_path": "",
"cover_art": "/serve/{}/example/MousikoFidi%20Sample%20Cover%20Art.png".format(
sourcedir.strip("/")
),
}
assert actual_dict == expected_dict
def test_config_to_string():
example_config = os.path.join(THIS_DIR, "example", "fidi.yml")
config_string = config_to_string(example_config)
assert (
config_string
== """config:
cover_art: true
favicon_path: /fidi.png
holidays: true
icons: false
logo_path: /fidi.png
music_dirs:
- /home/username/music/flac
- /home/username/music/ogg
- /home/username/video/mp4
playlist:
dir: /home/username/music/playlists
save: true
preload_audio: false
preload_video: false
secret_key: CHANGE ME TO SOMETHING ELSE!!!!
site_name: MousikóFídi - Your Music Cloud
theme: light
"""
)
def test_dir_dict():
example_dir = os.path.join(THIS_DIR, "example")
d = os.path.join(THIS_DIR, "example")
dd = dir_dict(d)
assert dd == {"name": "example", "path": "{}".format(example_dir).strip("/")}
def test_make_unique_slugs():
example_dir = os.path.join(THIS_DIR, "example")
with app.test_request_context("/browse/" + example_dir):
c = request_context(
init(use_config=os.path.join(THIS_DIR, "example", "fidi.yml"))
)
browse_dir(c, example_dir)
new_dict = make_unique_slugs(c["item_list"])
used_slugs = []
for item in new_dict:
assert item["slug"] not in used_slugs
used_slugs.append(item["slug"])
def test_request_context():
with app.test_request_context("/"):
c = init(use_config=os.path.join(THIS_DIR, "example", "fidi.yml"))
r = request_context(c)
favicon = select_logo(c, "favicon_path")
logo = select_logo(c, "logo_path")
assert r == {
"css": [
"/css/normalize.min.css",
"/fa/css/fontawesome.min.css",
"/fa/css/solid.min.css",
"/css/water/light.standalone.min.css",
"/css/fidi.min.css",
],
"debug": False,
"favicon_path": favicon,
"icons": False,
"logo_path": logo,
"music_dirs": [
{
"full_path": "/home/username/music/flac",
"path": "home/username/music/flac",
},
{
"full_path": "/home/username/music/ogg",
"path": "home/username/music/ogg",
},
{
"full_path": "/home/username/video/mp4",
"path": "home/username/video/mp4",
},
],
"playlist_dir": "/home/username/music/playlists",
"playlist_save": True,
"playlists": [],
"preload_audio": False,
"preload_video": False,
"search": False,
"secret_key": True,
"site_name": "MousikóFídi - Your Music Cloud",
"queue": [],
"theme": "light",
"username": None,
}
def test_select_cover_art_false():
app.fidiConfig["config"]["cover_art"] = False
example_dir = os.path.join(THIS_DIR, "example")
real_flac = os.path.join(example_dir, "real.flac")
cover_art = select_cover_art(real_flac)
assert cover_art is None
def test_select_cover_art_true():
app.fidiConfig["config"]["cover_art"] = True
example_dir = os.path.join(THIS_DIR, "example")
cover_art_path = os.path.join(
example_dir, quote("MousikoFidi Sample Cover Art.png")
).strip("/")
real_flac = os.path.join(example_dir, "real.flac")
with app.test_request_context("/"):
cover_art = select_cover_art(real_flac)
assert cover_art == "/serve/{}".format(cover_art_path)
def test_select_logo_no_holiday():
c = {
"config": {
"favicon_path": "/fidi.png",
"logo_path": "/fidi.png",
"holidays": False,
}
}
favicon = select_logo(c, "favicon_path")
logo = select_logo(c, "logo_path")
assert favicon == "/fidi.png"
assert logo == "/fidi.png"
def test_select_logo_apr_holiday():
c = {
"config": {
"favicon_path": "/fidi.png",
"logo_path": "/fidi.png",
"holidays": True,
}
}
fake_apr_str = "2019-04-20 15:04:00 -0500"
fake_apr = datetime.strptime(fake_apr_str, "%Y-%m-%d %H:%M:%S %z")
favicon = select_logo(c, "favicon_path", fakenow=fake_apr)
logo = select_logo(c, "logo_path", fakenow=fake_apr)
assert favicon == "/fidi-420.png"
assert logo == "/fidi-420.png"
def test_select_logo_aug_holiday():
c = {
"config": {
"favicon_path": "/fidi.png",
"logo_path": "/fidi.png",
"holidays": True,
}
}
fake_aug_str = "2019-08-09 15:04:00 -0500"
fake_aug = datetime.strptime(fake_aug_str, "%Y-%m-%d %H:%M:%S %z")
favicon = select_logo(c, "favicon_path", fakenow=fake_aug)
logo = select_logo(c, "logo_path", fakenow=fake_aug)
assert favicon == "/fidi-birth.png"
assert logo == "/fidi-birth.png"
def test_select_logo_oct_holiday():
c = {
"config": {
"favicon_path": "/fidi.png",
"logo_path": "/fidi.png",
"holidays": True,
}
}
fake_oct_str = "2019-10-31 15:04:00 -0500"
fake_oct = datetime.strptime(fake_oct_str, "%Y-%m-%d %H:%M:%S %z")
favicon = select_logo(c, "favicon_path", fakenow=fake_oct)
logo = select_logo(c, "logo_path", fakenow=fake_oct)
assert favicon == "/fidi-oct.png"
assert logo == "/fidi-oct.png"
def test_select_logo_dec_holiday():
c = {
"config": {
"favicon_path": "/fidi.png",
"logo_path": "/fidi.png",
"holidays": True,
}
}
fake_dec_str = "2019-12-15 15:04:00 -0500"
fake_dec = datetime.strptime(fake_dec_str, "%Y-%m-%d %H:%M:%S %z")
favicon = select_logo(c, "favicon_path", fakenow=fake_dec)
logo = select_logo(c, "logo_path", fakenow=fake_dec)
assert favicon == "/fidi-dec.png"
assert logo == "/fidi-dec.png"
def test_select_favicon_custom():
c = {
"config": {
"favicon_path": "https://my.favicon.tld/mine.ico",
"holidays": False,
"logo_path": "/fidi.png",
}
}
favicon = select_logo(c, "favicon_path")
assert favicon == "https://my.favicon.tld/mine.ico"
def test_select_logo_custom():
c = {
"config": {
"favicon_path": "/fidi.png",
"logo_path": "https://my.logo.tld/logo.png",
"holidays": False,
}
}
logo = select_logo(c, "logo_path")
assert logo == "https://my.logo.tld/logo.png"
def test_select_css_custom():
app.fidiConfig["config"]["theme"] = "https://my.theme.tld/mytheme.css"
with app.test_request_context("/"):
css, theme = select_css()
assert css[0] == "/css/normalize.min.css"
assert css[1] == "/fa/css/fontawesome.min.css"
assert css[2] == "/fa/css/solid.min.css"
assert css[3] == "/css/fidi.min.css"
assert css[4] == "https://my.theme.tld/mytheme.css"
assert theme == "custom"
def test_select_css_light():
app.fidiConfig["config"]["theme"] = "light"
with app.test_request_context("/"):
css, theme = select_css()
assert css[0] == "/css/normalize.min.css"
assert css[1] == "/fa/css/fontawesome.min.css"
assert css[2] == "/fa/css/solid.min.css"
assert css[3] == "/css/water/light.standalone.min.css"
assert css[4] == "/css/fidi.min.css"
assert theme == "light"
def test_select_css_dark():
app.fidiConfig["config"]["theme"] = "dark"
with app.test_request_context("/"):
css, theme = select_css()
assert css[0] == "/css/normalize.min.css"
assert css[1] == "/fa/css/fontawesome.min.css"
assert css[2] == "/fa/css/solid.min.css"
assert css[3] == "/css/water/dark.standalone.min.css"
assert css[4] == "/css/fidi.min.css"
assert theme == "dark"
def test_select_css_nes():
app.fidiConfig["config"]["theme"] = "nes"
with app.test_request_context("/"):
css, theme = select_css()
assert css[0] == "/css/normalize.min.css"
assert css[1] == "/fa/css/fontawesome.min.css"
assert css[2] == "/fa/css/solid.min.css"
assert css[3] == "/css/nes/nes.min.css"
assert css[4] == "/css/fidi.min.css"
assert css[5] == "/css/fidi-nes.min.css"
assert theme == "nes"
def test_select_css_terminal():
app.fidiConfig["config"]["theme"] = "terminal"
with app.test_request_context("/"):
css, theme = select_css()
assert css[0] == "/css/normalize.min.css"
assert css[1] == "/fa/css/fontawesome.min.css"
assert css[2] == "/fa/css/solid.min.css"
assert css[3] == "/css/terminal.min.css"
assert css[4] == "/css/fidi.min.css"
assert theme == "terminal"
def test_select_css_terminal_green():
app.fidiConfig["config"]["theme"] = "terminal-green"
with app.test_request_context("/"):
css, theme = select_css()
assert css[0] == "/css/normalize.min.css"
assert css[1] == "/fa/css/fontawesome.min.css"
assert css[2] == "/fa/css/solid.min.css"
assert css[3] == "/css/terminal-green.min.css"
assert css[4] == "/css/fidi.min.css"
assert theme == "terminal-green"
def test_select_css_terminal_solarized():
app.fidiConfig["config"]["theme"] = "terminal-solarized"
with app.test_request_context("/"):
css, theme = select_css()
# Reset the config
app.fidiConfig["config"]["theme"] = "light"
assert css[0] == "/css/normalize.min.css"
assert css[1] == "/fa/css/fontawesome.min.css"
assert css[2] == "/fa/css/solid.min.css"
assert css[3] == "/css/terminal-solarized.min.css"
assert css[4] == "/css/fidi.min.css"
assert theme == "terminal-solarized"
def test_handle_playlist_cmd_add():
with app.test_request_context("/"):
example_dir = os.path.join(THIS_DIR, "example")
c = init(use_config=os.path.join(example_dir, "fidi.yml"))
ctx = request_context(c)
f = os.path.join(THIS_DIR, "example", "real.flac")
d = handle_playlist_cmd("add", f, ctx)
favicon = select_logo(c, "favicon_path")
logo = select_logo(c, "logo_path")
expected_dict = {
"css": [
"/css/normalize.min.css",
"/fa/css/fontawesome.min.css",
"/fa/css/solid.min.css",
"/css/water/light.standalone.min.css",
"/css/fidi.min.css",
],
"debug": False,
"favicon_path": favicon,
"icons": False,
"logo_path": logo,
"music_dirs": [
{
"full_path": "/home/username/music/flac",
"path": "home/username/music/flac",
},
{
"full_path": "/home/username/music/ogg",
"path": "home/username/music/ogg",
},
{
"full_path": "/home/username/video/mp4",
"path": "home/username/video/mp4",
},
],
"playlist_dir": "/home/username/music/playlists",
"playlist_save": True,
"playlists": [],
"preload_audio": False,
"preload_video": False,
"search": False,
"secret_key": True,
"site_name": "MousikóFídi - Your Music Cloud",
"queue": ["{}/real.flac".format(example_dir)],
"theme": "light",
"username": None,
}
assert d == expected_dict
# # TODO: A test is needed that posts to the bulk endpoint and is able to
# # subsequently check the user playlist, either by viewing the page or by
# # inspecting the context value.
# # def test_handle_playlist_cmd_bulk(client):
# # pass
def test_handle_playlist_cmd_add_multi():
with app.test_request_context("/"):
example_dir = os.path.join(THIS_DIR, "example")
c = init(use_config=os.path.join(example_dir, "fidi.yml"))
f = os.path.join(example_dir, "real.flac")
f2 = os.path.join(example_dir, "real.mp3")
f3 = os.path.join(example_dir, "real.ogg")
f4 = os.path.join(example_dir, "fake.mp4")
f5 = os.path.join(example_dir, "fake.webm")
d = request_context(c)
d2 = handle_playlist_cmd("add", f, d)
d3 = handle_playlist_cmd("add", f2, d2)
d4 = handle_playlist_cmd("add", f3, d3)
d5 = handle_playlist_cmd("add", f4, d4)
d6 = handle_playlist_cmd("add", f5, d5)
favicon = select_logo(c, "favicon_path")
logo = select_logo(c, "logo_path")
expected_dict = {
"css": [
"/css/normalize.min.css",
"/fa/css/fontawesome.min.css",
"/fa/css/solid.min.css",
"/css/water/light.standalone.min.css",
"/css/fidi.min.css",
],
"debug": False,
"favicon_path": favicon,
"icons": False,
"logo_path": logo,
"music_dirs": [
{
"full_path": "/home/username/music/flac",
"path": "home/username/music/flac",
},
{
"full_path": "/home/username/music/ogg",
"path": "home/username/music/ogg",
},
{
"full_path": "/home/username/video/mp4",
"path": "home/username/video/mp4",
},
],
"playlist_dir": "/home/username/music/playlists",
"playlist_save": True,
"playlists": [],
"preload_audio": False,
"preload_video": False,
"search": False,
"secret_key": True,
"site_name": "MousikóFídi - Your Music Cloud",
"queue": [
"{}/real.flac".format(example_dir),
"{}/real.mp3".format(example_dir),
"{}/real.ogg".format(example_dir),
"{}/fake.mp4".format(example_dir),
"{}/fake.webm".format(example_dir),
],
"theme": "light",
"username": None,
}
assert d6 == expected_dict
def test_handle_playlist_cmd_clear():
with app.test_request_context("/"):
example_dir = os.path.join(THIS_DIR, "example")
c = init(use_config=os.path.join(example_dir, "fidi.yml"))
ctx = request_context(c)
f = os.path.join(THIS_DIR, "example", "real.flac")
d = handle_playlist_cmd("clear", f, ctx)
favicon = select_logo(c, "favicon_path")
logo = select_logo(c, "logo_path")
expected_dict = {
"css": [
"/css/normalize.min.css",
"/fa/css/fontawesome.min.css",
"/fa/css/solid.min.css",
"/css/water/light.standalone.min.css",
"/css/fidi.min.css",
],
"debug": False,
"favicon_path": favicon,
"icons": False,
"logo_path": logo,
"music_dirs": [
{
"full_path": "/home/username/music/flac",
"path": "home/username/music/flac",
},
{
"full_path": "/home/username/music/ogg",
"path": "home/username/music/ogg",
},
{
"full_path": "/home/username/video/mp4",
"path": "home/username/video/mp4",
},
],
"playlist_dir": "/home/username/music/playlists",
"playlist_save": True,
"playlists": [],
"preload_audio": False,
"preload_video": False,
"search": False,
"secret_key": True,
"site_name": "MousikóFídi - Your Music Cloud",
"queue": [],
"theme": "light",
"username": None,
}
assert d == expected_dict
# # TODO: This
# # def test_handle_playlist_cmd_save():
# # tmpdir = tempfile.mkdtemp()
# # context = {"playlist_dir": tmpdir}
# # handle_playlist_cmd("save", "%2Fsave", context)
# # TODO: And this
# # def test_handle_playlist_cmd_load():
# # tmpdir = tempfile.mkdtemp()
# # context = {"playlist_dir": tmpdir}
# # handle_playlist_cmd("save", "%2Fsave", context)
def test_handle_playlist_cmd_rm():
with app.test_request_context("/"):
example_dir = os.path.join(THIS_DIR, "example")
c = init(use_config=os.path.join(example_dir, "fidi.yml"))
f = os.path.join(THIS_DIR, "example", "real.flac")
f2 = os.path.join(THIS_DIR, "example", "real.mp3")
f3 = os.path.join(THIS_DIR, "example", "real.ogg")
f4 = os.path.join(THIS_DIR, "example", "fake.mp4")
f5 = os.path.join(THIS_DIR, "example", "fake.webm")
d = request_context(c)
d2 = handle_playlist_cmd("add", f, d)
d3 = handle_playlist_cmd("add", f2, d2)
d4 = handle_playlist_cmd("add", f3, d3)
d5 = handle_playlist_cmd("add", f4, d4)
d6 = handle_playlist_cmd("add", f5, d5)
d7 = handle_playlist_cmd("rm", f4, d6)
favicon = select_logo(c, "favicon_path")
logo = select_logo(c, "logo_path")
expected_dict = {
"css": [
"/css/normalize.min.css",
"/fa/css/fontawesome.min.css",
"/fa/css/solid.min.css",
"/css/water/light.standalone.min.css",
"/css/fidi.min.css",
],
"debug": False,
"favicon_path": favicon,
"icons": False,
"logo_path": logo,
"music_dirs": [
{
"full_path": "/home/username/music/flac",
"path": "home/username/music/flac",
},
{
"full_path": "/home/username/music/ogg",
"path": "home/username/music/ogg",
},
{
"full_path": "/home/username/video/mp4",
"path": "home/username/video/mp4",
},
],
"playlist_dir": "/home/username/music/playlists",
"playlist_save": True,
"playlists": [],
"preload_audio": False,
"preload_video": False,
"search": False,
"secret_key": True,
"site_name": "MousikóFídi - Your Music Cloud",
"queue": [
"{}/real.flac".format(example_dir),
"{}/real.mp3".format(example_dir),
"{}/real.ogg".format(example_dir),
"{}/fake.webm".format(example_dir),
],
"theme": "light",
"username": None,
}
assert d7 == expected_dict
def test_init():
c = init(use_config=os.path.join(THIS_DIR, "example", "fidi.yml"))
assert c == {
"config": {
"cover_art": True,
"favicon_path": "/fidi.png",
"holidays": True,
"icons": False,
"logo_path": "/fidi.png",
"music_dirs": [
"/home/username/music/flac",
"/home/username/music/ogg",
"/home/username/video/mp4",
],
"playlist": {"dir": "/home/username/music/playlists", "save": True},
"preload_audio": False,
"preload_video": False,
"search": False,
"secret_key": True,
"site_name": "MousikóFídi - Your Music Cloud",
"theme": "light",
}
}
# TODO: test init() with no cfg file
def test_get_metadata_dict_real_audio():
f = os.path.join(THIS_DIR, "example", "real.flac")
d = get_metadata_dict(f)
assert d == {
"album": "MousikóFídi Test Album",
"artist": "MousikóFídi Test Artist",
"comment": "FLAC Comment!",
"date": "2019-08-08",
"encoded_by": "FLAC Encoded-by",
"genre": "MousikóFídi Test",
"length": "0:04",
"lyrics": "Test FLAC Lyrics!",
"title": "MousikóFídi Test FLAC",
"track": "34",
"tracktotal": "0",
}
def test_get_metadata_dict_fake_video():
f = os.path.join(THIS_DIR, "example", "fake.webm")
d = get_metadata_dict(f)
assert d == {
"album": None,
"artist": None,
"date": None,
"genre": None,
"length": None,
"title": None,
"track": None,
"tracktotal": None,
}
def test_get_metadata_value():
example_flac = os.path.join(THIS_DIR, "example", "real.flac")
metadata = file_metadata(example_flac)
value = get_metadata_value(["ALBUM", "TALB"], metadata)
assert value == "MousikóFídi Test Album"
def test_get_metadata_value_none():
example_flac = os.path.join(THIS_DIR, "example", "fake.flac")
metadata = file_metadata(example_flac)
value = get_metadata_value(["ALBUM", "TALB"], metadata)
assert value is None
def test_get_playlists():
mdir = tempfile.mkdtemp()
pdir = tempfile.mkdtemp()
config_string = """config:
favicon_path: /fidi.png
logo_path: /fidi.png
music_dirs:
- {mdir}
playlist:
dir: {pdir}
save: true
preload_audio: false
preload_video: false
site_name: TestSite
theme: dark
""".format(
mdir=mdir, pdir=pdir
)
config_file = tempfile.mkstemp(suffix=".yml")[1]
edir = os.path.join(THIS_DIR, "example")
shutil.copy(os.path.join(edir, "real.flac"), mdir)
shutil.copy(os.path.join(edir, "real.mp3"), mdir)
shutil.copy(os.path.join(edir, "real.ogg"), mdir)
plist1 = os.path.join(pdir, "PLAYLIST FILE 1.m3u")
plist2 = os.path.join(pdir, "PLAYLIST FILE 2.m3u")
plist3 = os.path.join(pdir, "PLAYLIST FILE 3.m3u")
plist4 = os.path.join(pdir, "PLAYLIST FILE 4.m3u")
real_flac = os.path.join(mdir, "real.flac")
real_mp3 = os.path.join(mdir, "real.mp3")
real_ogg = os.path.join(mdir, "real.ogg")
with open(plist1, "w") as f1:
f1.write(real_flac)
f1.write("\n")
f1.write(real_mp3)
f1.write("\n")
f1.write(real_ogg)
f1.write("\n")
with open(plist2, "w") as f2:
f2.write(real_flac)
f2.write("\n")
f2.write(real_flac)
f2.write("\n")
f2.write(real_mp3)
f2.write("\n")
f2.write(real_ogg)
f2.write("\n")
with open(plist3, "w") as f3:
f3.write(real_flac)
f3.write("\n")
f3.write(real_flac)
f3.write("\n")
f3.write(real_mp3)
f3.write("\n")
f3.write(real_mp3)
f3.write("\n")
f3.write(real_ogg)
f3.write("\n")
with open(plist4, "w") as f4:
f4.write(real_flac)
f4.write("\n")
f4.write(real_flac)
f4.write("\n")
f4.write(real_mp3)
f4.write("\n")
f4.write(real_mp3)
f4.write("\n")
f4.write(real_ogg)
f4.write("\n")
f4.write(real_ogg)
f4.write("\n")
with open(config_file, "w") as f:
for line in config_string:
f.write(line)
c = init(use_config=config_file)
playlists = get_playlists(c["config"]["playlist"]["dir"])
os.remove(config_file)
shutil.rmtree(mdir)
shutil.rmtree(pdir)
assert playlists[0]["count"] == 3
assert playlists[0]["filename"] == "PLAYLIST FILE 1.m3u"
assert playlists[0]["name"] == "PLAYLIST FILE 1"
assert playlists[1]["count"] == 4
assert playlists[1]["filename"] == "PLAYLIST FILE 2.m3u"
assert playlists[1]["name"] == "PLAYLIST FILE 2"
assert playlists[2]["count"] == 5
assert playlists[2]["filename"] == "PLAYLIST FILE 3.m3u"
assert playlists[2]["name"] == "PLAYLIST FILE 3"
assert playlists[3]["count"] == 6
assert playlists[3]["filename"] == "PLAYLIST FILE 4.m3u"
assert playlists[3]["name"] == "PLAYLIST FILE 4"
def test_is_audio_file_flac():
testfile = os.path.join(THIS_DIR, "example", "real.flac")
is_audio = is_audio_file(testfile)
assert is_audio is True
def test_is_audio_file_mp3():
testfile = os.path.join(THIS_DIR, "example", "real.mp3")
is_audio = is_audio_file(testfile)
assert is_audio is True
def test_is_audio_file_ogg():
testfile = os.path.join(THIS_DIR, "example", "real.ogg")
is_audio = is_audio_file(testfile)
assert is_audio is True
def test_is_audio_file_is_not():
testfile = os.path.join(THIS_DIR, "example", "fidi.yml")
is_audio = is_audio_file(testfile)
assert is_audio is False
def test_is_valid_path_is():
with app.test_request_context("/"):
example_dir = os.path.join(THIS_DIR, "example")
c = init(use_config=os.path.join(example_dir, "fidi.yml"))
dirlist = []
dirlist.append(example_dir)
c["config"]["music_dirs"] = dirlist
ctx = request_context(c)
is_valid = is_valid_path(ctx, example_dir)
assert is_valid is True
def test_is_valid_path_is_with_extra_slash():
with app.test_request_context("/"):
example_dir = os.path.join(THIS_DIR, "example/")
c = init(use_config=os.path.join(example_dir, "fidi.yml"))
dirlist = []
dirlist.append(example_dir)
c["config"]["music_dirs"] = dirlist
ctx = request_context(c)
is_valid = is_valid_path(ctx, example_dir)
assert is_valid is True
def test_is_valid_path_isnt():
with app.test_request_context("/"):
example_dir = os.path.join(THIS_DIR, "example")
c = init(use_config=os.path.join(example_dir, "fidi.yml"))
dirlist = []
dirlist.append(example_dir)
c["config"]["music_dirs"] = dirlist
ctx = request_context(c)
is_valid = is_valid_path(ctx, os.path.join(example_dir, "..", ".."))
assert is_valid is False
def test_paths_list():
cf = os.path.join(THIS_DIR, "example", "fidi.yml")
s = config_to_string(cf)
d = yaml.load(s, Loader=yaml.BaseLoader)
md = d["config"]["music_dirs"]
pl = paths_list(md)
expected_pl = [
{"full_path": "/home/username/music/flac", "path": "home/username/music/flac"},
{"full_path": "/home/username/music/ogg", "path": "home/username/music/ogg"},
{"full_path": "/home/username/video/mp4", "path": "home/username/video/mp4"},
]
assert pl == expected_pl
def test_title_slug():
slug = title_slug("S o me! T|N$ Crzy@( ajhsjh )1148 &")
assert slug == "sometncrzyajhsjh1148"
def test_video_dict():
example_dir = os.path.join(THIS_DIR, "example")
f = os.path.join(example_dir, "fake.mp4")
m = get_metadata_dict(f)
d = file_dict(f, m, "video")
assert d == {
"album": None,
"artist": None,
"genre": None,
"length": None,
"title": None,
"title_mobile": None,
"track": None,
"tracktotal": None,
"type": "video",
"file_name": "fake.mp4",
"file_name_mobile": "fake.mp4",
"file_path": "{}/fake.mp4".format(example_dir).strip("/"),
"slug": "fakemp4",
}
def test_about(client):
url = "/about"
with app.app_context():
rv = client.get(url)
assert rv.status == "200 OK"
def test_index_http_code(client):
site_name = "COOL TEST SITE"
page_name = "Welcome"
title = '<title id="title" data-sitename="{s}">{p} | {s}</title>'.format(
p=page_name, s=site_name
)
url = "/"
app.fidiConfig["config"]["site_name"] = site_name
with app.app_context():
rv = client.get(url)
favicon = select_logo(app.fidiConfig, "favicon_path")
logo = select_logo(app.fidiConfig, "logo_path")
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert rv.status == "200 OK"
assert bytes(title, "utf8") in rv.data
assert (
bytes('<h4 class="center">Welcome to {}!</h4>'.format(site_name), "utf8")
in rv.data
)
assert (
bytes(
'<a href="https://mousikofidi.info/"><img src="{}" title="The MousikóFídi logo, by Ogenfald, and a link to the MousikóFídi home page (with online documentation)."></a>'.format(
logo
),
"utf8",
)
in rv.data
)
assert bytes('<link rel="icon" href="{}">'.format(favicon), "utf8") in rv.data
def test_index(client):
mdir = tempfile.mkdtemp()
pdir = tempfile.mkdtemp()
app.fidiConfig["config"]["music_dirs"] = [mdir]
app.fidiConfig["config"]["playlist"]["dir"] = pdir
app.fidiConfig["config"]["site_name"] = "Pdir Test"
with app.test_client() as tc:
rv = tc.get("/")
shutil.rmtree(mdir)
shutil.rmtree(pdir)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert rv.status == "200 OK"
assert (
bytes(
'<title id="title" data-sitename="Pdir Test">Welcome | Pdir Test</title>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%201">', "utf8"
)
not in rv.data
)
assert bytes("PLAYLIST FILE 1", "utf8") not in rv.data
assert (
bytes(" <td>\n 3\n </td>\n", "utf8") not in rv.data
)
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%202">', "utf8"
)
not in rv.data
)
assert bytes("PLAYLIST FILE 2", "utf8") not in rv.data
assert (
bytes(" <td>\n 4\n </td>\n", "utf8") not in rv.data
)
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%203">', "utf8"
)
not in rv.data
)
assert bytes("PLAYLIST FILE 3", "utf8") not in rv.data
assert (
bytes(" <td>\n 5\n </td>\n", "utf8") not in rv.data
)
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%204">', "utf8"
)
not in rv.data
)
assert bytes("PLAYLIST FILE 4", "utf8") not in rv.data
assert (
bytes(" <td>\n 6\n </td>\n", "utf8") not in rv.data
)
def test_index_dark_theme(client):
site_name = "COOL TEST SITE"
page_name = "Welcome"
title = '<title id="title" data-sitename="{s}">{p} | {s}</title>'.format(
p=page_name, s=site_name
)
url = "/"
app.fidiConfig["config"]["site_name"] = site_name
app.fidiConfig["config"]["theme"] = "dark"
with app.app_context():
rv = client.get(url)
favicon = select_logo(app.fidiConfig, "favicon_path")
logo = select_logo(app.fidiConfig, "logo_path")
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert (
b'<link href="/css/water/dark.standalone.min.css" rel="stylesheet" type="text/css">'
in rv.data
)
assert bytes(title, "utf8") in rv.data
assert (
bytes('<h4 class="center">Welcome to {}!</h4>'.format(site_name), "utf8")
in rv.data
)
assert (
bytes(
'<a href="https://mousikofidi.info/"><img src="{}" title="The MousikóFídi logo, by Ogenfald, and a link to the MousikóFídi home page (with online documentation)."></a>'.format(
logo
),
"utf8",
)
in rv.data
)
assert bytes('<link rel="icon" href="{}">'.format(favicon), "utf8") in rv.data
def test_index_light_theme(client):
site_name = "COOL TEST SITE"
page_name = "Welcome"
title = '<title id="title" data-sitename="{s}">{p} | {s}</title>'.format(
p=page_name, s=site_name
)
url = "/"
app.fidiConfig["config"]["site_name"] = site_name
app.fidiConfig["config"]["theme"] = "light"
with app.app_context():
rv = client.get(url)
favicon = select_logo(app.fidiConfig, "favicon_path")
logo = select_logo(app.fidiConfig, "logo_path")
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert (
b'<link href="/css/water/light.standalone.min.css" rel="stylesheet" type="text/css">'
in rv.data
)
assert bytes(title, "utf8") in rv.data
assert (
bytes('<h4 class="center">Welcome to {}!</h4>'.format(site_name), "utf8")
in rv.data
)
assert (
bytes(
'<a href="https://mousikofidi.info/"><img src="{}" title="The MousikóFídi logo, by Ogenfald, and a link to the MousikóFídi home page (with online documentation)."></a>'.format(
logo
),
"utf8",
)
in rv.data
)
assert bytes('<link rel="icon" href="{}">'.format(favicon), "utf8") in rv.data
def test_index_nes_theme(client):
site_name = "COOL TEST SITE"
page_name = "Welcome"
title = '<title id="title" data-sitename="{s}">{p} | {s}</title>'.format(
p=page_name, s=site_name
)
url = "/"
app.fidiConfig["config"]["site_name"] = site_name
app.fidiConfig["config"]["theme"] = "nes"
with app.app_context():
rv = client.get(url)
favicon = select_logo(app.fidiConfig, "favicon_path")
logo = select_logo(app.fidiConfig, "logo_path")
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert (
b'<link href="/css/nes/nes.min.css" rel="stylesheet" type="text/css">'
in rv.data
)
assert (
b'<link href="/css/fidi-nes.min.css" rel="stylesheet" type="text/css">'
in rv.data
)
assert bytes(title, "utf8") in rv.data
assert (
bytes('<h4 class="center">Welcome to {}!</h4>'.format(site_name), "utf8")
in rv.data
)
assert (
bytes(
'<a href="https://mousikofidi.info/"><img src="{}" title="The MousikóFídi logo, by Ogenfald, and a link to the MousikóFídi home page (with online documentation)."></a>'.format(
logo
),
"utf8",
)
in rv.data
)
assert bytes('<link rel="icon" href="{}">'.format(favicon), "utf8") in rv.data
def test_index_terminal_theme(client):
site_name = "COOL TEST SITE"
page_name = "Welcome"
title = '<title id="title" data-sitename="{s}">{p} | {s}</title>'.format(
p=page_name, s=site_name
)
url = "/"
app.fidiConfig["config"]["site_name"] = site_name
app.fidiConfig["config"]["theme"] = "terminal"
# favicon =
with app.app_context():
rv = client.get(url)
favicon = select_logo(app.fidiConfig, "favicon_path")
logo = select_logo(app.fidiConfig, "logo_path")
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert (
b'<link href="/css/terminal.min.css" rel="stylesheet" type="text/css">'
in rv.data
)
assert bytes(title, "utf8") in rv.data
assert (
bytes('<h4 class="center">Welcome to {}!</h4>'.format(site_name), "utf8")
in rv.data
)
assert (
bytes(
'<a href="https://mousikofidi.info/"><img src="{}" title="The MousikóFídi logo, by Ogenfald, and a link to the MousikóFídi home page (with online documentation)."></a>'.format(
logo
),
"utf8",
)
in rv.data
)
assert bytes('<link rel="icon" href="{}">'.format(favicon), "utf8") in rv.data
def test_index_terminal_green_theme(client):
site_name = "COOL TEST SITE"
page_name = "Welcome"
title = '<title id="title" data-sitename="{s}">{p} | {s}</title>'.format(
p=page_name, s=site_name
)
url = "/"
app.fidiConfig["config"]["site_name"] = site_name
app.fidiConfig["config"]["theme"] = "terminal-green"
with app.app_context():
rv = client.get(url)
favicon = select_logo(app.fidiConfig, "favicon_path")
logo = select_logo(app.fidiConfig, "logo_path")
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert (
b'<link href="/css/terminal-green.min.css" rel="stylesheet" type="text/css">'
in rv.data
)
assert bytes(title, "utf8") in rv.data
assert (
bytes('<h4 class="center">Welcome to {}!</h4>'.format(site_name), "utf8")
in rv.data
)
assert (
bytes(
'<a href="https://mousikofidi.info/"><img src="{}" title="The MousikóFídi logo, by Ogenfald, and a link to the MousikóFídi home page (with online documentation)."></a>'.format(
logo
),
"utf8",
)
in rv.data
)
assert bytes('<link rel="icon" href="{}">'.format(favicon), "utf8") in rv.data
def test_index_terminal_solarized_theme(client):
site_name = "COOL TEST SITE"
page_name = "Welcome"
title = '<title id="title" data-sitename="{s}">{p} | {s}</title>'.format(
p=page_name, s=site_name
)
url = "/"
app.fidiConfig["config"]["site_name"] = site_name
app.fidiConfig["config"]["theme"] = "terminal-solarized"
with app.app_context():
rv = client.get(url)
favicon = select_logo(app.fidiConfig, "favicon_path")
logo = select_logo(app.fidiConfig, "logo_path")
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert (
b'<link href="/css/terminal-solarized.min.css" rel="stylesheet" type="text/css">'
in rv.data
)
assert bytes(title, "utf8") in rv.data
assert (
bytes('<h4 class="center">Welcome to {}!</h4>'.format(site_name), "utf8")
in rv.data
)
assert (
bytes(
'<a href="https://mousikofidi.info/"><img src="{}" title="The MousikóFídi logo, by Ogenfald, and a link to the MousikóFídi home page (with online documentation)."></a>'.format(
logo
),
"utf8",
)
in rv.data
)
assert bytes('<link rel="icon" href="{}">'.format(favicon), "utf8") in rv.data
def test_browse_http_code(client):
example_dir = os.path.join(THIS_DIR, "example")
dir_list = []
dir_list.append(example_dir)
site_name = "COOL TEST SITE"
url = "/browse"
app.fidiConfig["config"]["music_dirs"] = dir_list
app.fidiConfig["config"]["site_name"] = site_name
with app.app_context():
rv = client.get(url)
favicon = select_logo(app.fidiConfig, "favicon_path")
logo = select_logo(app.fidiConfig, "logo_path")
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert rv.status == "200 OK"
assert bytes(example_dir, "utf8") in rv.data
assert (
bytes(
'<title id="title" data-sitename="{n}">Media Dirs | {n}</title>'.format(
n=site_name
),
"utf8",
)
in rv.data
)
assert bytes('<th class="center">Your Media Dirs</th>', "utf8") in rv.data
assert (
bytes(
'<a class="bold mobile-big" href="/browse/{}">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert bytes('<div id="top"></div>', "utf8") in rv.data
assert (
bytes(
'<div id="top-link"><a class="bold" href="#top" title="Click this triangle to navigate back to the top of the current page without reloading it."></a></div> ',
"utf8",
)
in rv.data
)
assert (
bytes(
'<img alt="Fidi Logo and home link" src="{}" title="The MousikóFídi logo, and a link to the main index page.">'.format(
logo
),
"utf8",
)
in rv.data
)
assert bytes('<link rel="icon" href="{}">'.format(favicon), "utf8") in rv.data
def test_browse(client):
mdir = tempfile.mkdtemp()
pdir = tempfile.mkdtemp()
app.fidiConfig["config"]["music_dirs"] = [mdir]
app.fidiConfig["config"]["playlist"]["dir"] = pdir
app.fidiConfig["config"]["site_name"] = "Pdir Test"
with app.test_client() as tc:
rv = tc.get("/browse")
shutil.rmtree(mdir)
shutil.rmtree(pdir)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert rv.status == "200 OK"
assert (
bytes(
'<title id="title" data-sitename="Pdir Test">Media Dirs | Pdir Test</title>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%201">', "utf8"
)
not in rv.data
)
assert bytes("PLAYLIST FILE 1", "utf8") not in rv.data
assert (
bytes(" <td>\n 3\n </td>\n", "utf8") not in rv.data
)
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%202">', "utf8"
)
not in rv.data
)
assert bytes("PLAYLIST FILE 2", "utf8") not in rv.data
assert (
bytes(" <td>\n 4\n </td>\n", "utf8") not in rv.data
)
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%203">', "utf8"
)
not in rv.data
)
assert bytes("PLAYLIST FILE 3", "utf8") not in rv.data
assert (
bytes(" <td>\n 5\n </td>\n", "utf8") not in rv.data
)
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%204">', "utf8"
)
not in rv.data
)
assert bytes("PLAYLIST FILE 4", "utf8") not in rv.data
assert (
bytes(" <td>\n 6\n </td>\n", "utf8") not in rv.data
)
def test_dir_detail_found(client):
example_dir = os.path.join(THIS_DIR, "example")
dir_list = []
dir_list.append(example_dir)
site_name = "COOL TEST SITE"
url = "/browse" + example_dir
app.fidiConfig["config"]["music_dirs"] = dir_list
app.fidiConfig["config"]["site_name"] = site_name
app.fidiConfig["config"]["theme"] = "dark"
favicon = select_logo(app.fidiConfig, "favicon_path")
logo = select_logo(app.fidiConfig, "logo_path")
with app.app_context():
rv = client.get(url)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert rv.status == "200 OK"
assert bytes(example_dir, "utf8") in rv.data
assert bytes(example_dir, "utf8") in rv.data
assert b"fake.flac" in rv.data
assert b"fake.mp3" in rv.data
assert b"fake.ogg" in rv.data
assert b"fake.webm" in rv.data
assert b"34/0" not in rv.data
assert bytes("MousikóFídi Test Album", "utf8") in rv.data
assert bytes("MousikóFídi Test Artist", "utf8") in rv.data
assert bytes("MousikóFídi Test FLAC", "utf8") in rv.data
assert bytes("MousikóFídi Test MP3", "utf8") in rv.data
assert bytes("MousikóFídi Test MP4", "utf8") in rv.data
assert bytes("MousikóFídi Test OGG", "utf8") in rv.data
assert bytes("MousikóFídi Test MP4", "utf8") in rv.data
assert bytes("0:04", "utf8") in rv.data
assert bytes("0:06", "utf8") in rv.data
assert b"34/100" in rv.data
assert (
bytes(
'<title id="title" data-sitename="{n}">{d} | {n}</title>'.format(
d=example_dir, n=site_name
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<h4 class="center mobile-big"><a href="/browse/{0}">{1}</a></h4>'.format(
example_dir.strip("/"), example_dir
),
"utf8",
)
in rv.data
)
assert bytes('<link rel="icon" href="{}">'.format(favicon), "utf8") in rv.data
assert (
bytes(
' link" src="{}" title="The MousikóFídi logo, and a link to the '.format(
logo
),
"utf8",
)
in rv.data
)
assert (
b'<link href="/css/water/dark.standalone.min.css" rel="stylesheet" type="text/css">'
in rv.data
)
assert (
b'<link href="/css/fidi.min.css" rel="stylesheet" type="text/css">' in rv.data
)
assert (
bytes(
'<h2 class="center"><a href="/" title="The site name, and a link to the main index page.">{}</a></h2>'.format(
site_name
),
"utf8",
)
in rv.data
)
assert bytes('<div class="center" id="player">', "utf8") in rv.data
assert (
bytes(
'<p id="now-playing" title="The status of the current track. Click the track title to jump to it in the playlist.">Paused: <span class="bold" id="playing-title" title="The title of the current track."></span></p>',
"utf8",
)
in rv.data
)
assert (
bytes('<div data-nowplaying-num="0" id="now-playing-num"></div>', "utf8")
in rv.data
)
assert bytes('<div data-randorder="none" id="randorder"></div>', "utf8") in rv.data
assert bytes('<audio id="audio" controls>', "utf8") in rv.data
assert bytes("</audio>", "utf8") in rv.data
assert (
bytes(
'<button data-cmd="prev" id="prev" title="Click to skip to the previous track in the list.">Previous</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-cmd="fwd" id="next" title="Click to skip to the next track in the list.">Next</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="repeat" title="Click to toggle between no repeat, repeat one track, and repeat all tracks.">No Repeat</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="shuffle" title="Click to toggle between a shuffled track order on and off.">Shuffle Off</button>',
"utf8",
)
in rv.data
)
assert (
bytes('<div data-nowplaying-num="0" id="video-now-playing-num"></div>', "utf8")
in rv.data
)
assert (
bytes('<div data-randorder="none" id="vid-randorder"></div>', "utf8") in rv.data
)
assert bytes('<div id="videoplayer"></div>', "utf8") in rv.data
assert (
bytes('<video poster="{}" id="video" controls>'.format(logo), "utf8") in rv.data
)
assert bytes("<source>", "utf8") in rv.data
assert bytes("</video>", "utf8") in rv.data
assert (
bytes(
'<button data-cmd="prev" id="vid-prev" title="Click to skip to the previous track in the list.">Previous</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-cmd="fwd" id="vid-next" title="Click to skip to the next track in the list.">Next</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="vid-repeat" title="Click to toggle between no repeat, repeat one track, and repeat all tracks.">No Repeat</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="vid-shuffle" title="Click to toggle between a shuffled track order on and off.">Shuffle Off</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<div id="top-link"><a class="bold" href="#top" title="Click this triangle to navigate back to the top of the current page without reloading it."></a></div>',
"utf8",
)
in rv.data
)
assert b'<div id="audio-time-link" class="center">' in rv.data
assert (
b'<button id="audio-time-link" title="Click this button to have a link to this track at the current time put into your clipboard.">'
in rv.data
)
assert b"Current Time Link" in rv.data
assert b'<button id="video-time-link" title="Click this button to have a link to this track at the current time put into your clipboard.">'
assert b"Current Time Link</button>"
def test_dir_detail_not_found():
example_dir = os.path.join(THIS_DIR, "zexample")
with app.test_client() as c:
rv = c.get("/browse/" + example_dir.strip("/"))
assert rv.status == "404 NOT FOUND"
def test_dir_detail_not_found_real_with_extra(client):
example_dir = os.path.join(THIS_DIR, "example")
dir_list = []
dir_list.append(example_dir)
url = "/browse" + example_dir.strip("/") + "extragarbage"
app.fidiConfig["config"]["music_dirs"] = dir_list
with app.app_context():
rv = client.get(url)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert rv.status == "404 NOT FOUND"
def test_dir_detail_not_found_real_with_plus_sign(client):
example_dir = os.path.join(THIS_DIR, "example")
tempdir = "/tmp/valid + dir + ( with ) + [ pluses ]"
os.mkdir(tempdir)
shutil.copy(os.path.join(example_dir, "real.mp3"), tempdir)
dir_list = []
dir_list.append(example_dir)
dir_list.append(tempdir)
url = "/browse/" + tempdir.strip("/")
with app.app_context():
app.fidiConfig["config"]["music_dirs"] = dir_list
rv = client.get(url)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
shutil.rmtree(tempdir)
assert rv.status == "200 OK"
def test_file_detail_real_flac(client):
example_dir = os.path.join(THIS_DIR, "example", "real.flac")
dir_list = []
dir_list.append(example_dir)
site_name = "COOL TEST SITE"
url = "/browse/" + example_dir.strip("/")
app.fidiConfig["config"]["favicon_path"] = "/cool-favicon.png"
app.fidiConfig["config"]["music_dirs"] = dir_list
app.fidiConfig["config"]["site_name"] = site_name
app.fidiConfig["config"]["theme"] = "dark"
with app.app_context():
rv = client.get(url)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert rv.status == "200 OK"
assert bytes(example_dir, "utf8") in rv.data
assert b"Track: 34" in rv.data
assert b"Released: 2019-08-08" in rv.data
assert bytes("Genre: MousikóFídi Test", "utf8") in rv.data
assert bytes('"MousikóFídi Test Album"', "utf8") in rv.data
assert bytes("MousikóFídi Test Album", "utf8") in rv.data
assert bytes("MousikóFídi Test FLAC", "utf8") in rv.data
assert bytes(
'<img data-stat="off" id="cover-art" src="/serve/{}/example/MousikoFidi%20Sample%20Cover%20Art.png" title="The cover art for files in this directory. Click to adjust size (up to three sizes).">'.format(
example_dir.strip("/")
),
"utf8",
)
assert (
bytes(
'<audio id="single" controls src="/serve/{}">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form class="center" action="/playlist/add/{}" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<title id="title" data-sitename="{0}">MousikóFídi Test FLAC | {0}</title>'.format(
site_name
),
"utf8",
)
in rv.data
)
assert (
b'<button id="time-link" title="Click this button to have a link to this track at the current time put into your clipboard.">'
in rv.data
)
assert b"Current Time Link" in rv.data
assert (
bytes(
'<p class="center"><span class="bold">Comment: </span>FLAC Comment!</p>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<p class="center"><span class="bold">Encoded by: </span>FLAC Encoded-by</p>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<p class="center"><span class="bold">Lyrics: </span>Test FLAC Lyrics!</p>',
"utf8",
)
in rv.data
)
def test_file_detail_real_mp3(client):
example_dir = os.path.join(THIS_DIR, "example", "real.mp3")
dir_list = []
dir_list.append(example_dir)
site_name = "COOL TEST SITE"
url = "/browse/" + example_dir.strip("/")
app.fidiConfig["config"]["favicon_path"] = "/cool-favicon.png"
app.fidiConfig["config"]["music_dirs"] = dir_list
app.fidiConfig["config"]["site_name"] = site_name
app.fidiConfig["config"]["theme"] = "dark"
with app.app_context():
rv = client.get(url)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert rv.status == "200 OK"
assert bytes(example_dir.strip("/"), "utf8") in rv.data
assert bytes("Genre: MousikóFídi Test", "utf8") in rv.data
assert bytes('"MousikóFídi Test Album"', "utf8") in rv.data
assert bytes("MousikóFídi Test Artist", "utf8") in rv.data
assert bytes("MousikóFídi Test Album", "utf8") in rv.data
assert bytes("MousikóFídi Test Artist", "utf8") in rv.data
assert bytes("MousikóFídi Test MP3", "utf8") in rv.data
assert bytes(
'<img data-stat="off" id="cover-art" src="/serve/{}/example/MousikoFidi%20Sample%20Cover%20Art.png" title="The cover art for files in this directory. Click to adjust size (up to three sizes).">'.format(
example_dir.strip("/")
),
"utf8",
)
assert (
bytes(
'<audio id="single" controls src="/serve/{}">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form class="center" action="/playlist/add/{}" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<title id="title" data-sitename="{0}">MousikóFídi Test MP3 | {0}</title>'.format(
site_name
),
"utf8",
)
in rv.data
)
assert (
b'<button id="time-link" title="Click this button to have a link to this track at the current time put into your clipboard.">'
in rv.data
)
assert b"Current Time Link" in rv.data
assert (
bytes(
'<p class="center"><span class="bold">Comment: </span>MP3 Comment!</p>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<p class="center"><span class="bold">Encoded by: </span>MP3 Encoded-by!</p>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<p class="center"><span class="bold">Lyrics: </span>MP3 Lyrics Text!</p>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="video-theater-view" title=\'Click this button to toggle "theater view" on the video player.\'>Theater View: Off</button>',
"utf8",
)
not in rv.data
)
def test_file_detail_real_mp4(client):
example_dir = os.path.join(THIS_DIR, "example", "real.mp4")
dir_list = []
dir_list.append(example_dir)
logo = select_logo(app.fidiConfig, "logo_path")
site_name = "COOL TEST SITE"
url = "/browse/" + example_dir.strip("/")
app.fidiConfig["config"]["favicon_path"] = "/cool-favicon.png"
app.fidiConfig["config"]["music_dirs"] = dir_list
app.fidiConfig["config"]["site_name"] = site_name
app.fidiConfig["config"]["theme"] = "dark"
with app.app_context():
rv = client.get(url)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert rv.status == "200 OK"
assert bytes(example_dir, "utf8") in rv.data
assert bytes("Genre: MousikóFídi Test Genre", "utf8") in rv.data
assert bytes('"MousikóFídi Test MP4"', "utf8") in rv.data
assert bytes('"MousikóFídi Test Album"', "utf8") in rv.data
assert bytes("MousikóFídi Test Artist", "utf8") in rv.data
assert bytes("MousikóFídi Test Album", "utf8") in rv.data
assert bytes("MousikóFídi Test Artist", "utf8") in rv.data
assert bytes("MousikóFídi Test MP4", "utf8") in rv.data
assert bytes(
'<img data-stat="off" id="cover-art" src="/serve/{}/example/MousikoFidi%20Sample%20Cover%20Art.png" title="The cover art for files in this directory. Click to adjust size (up to three sizes).">'.format(
example_dir.strip("/")
),
"utf8",
)
assert (
bytes('<video poster="{}" id="single" controls>'.format(logo), "utf8")
in rv.data
)
assert b"Track: 34/100" in rv.data
assert (
bytes(
'<source src="/serve/{}" type="video/mp4">'.format(example_dir.strip("/")),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form class="center" action="/playlist/add/{}" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<title id="title" data-sitename="{0}">{1} | {0}</title>'.format(
site_name, "MousikóFídi Test MP4"
),
"utf8",
)
in rv.data
)
assert (
b'<button id="time-link" title="Click this button to have a link to this track at the current time put into your clipboard.">'
in rv.data
)
assert b"Current Time Link" in rv.data
assert (
bytes(
'<p class="center"><span class="bold">Comment: </span>MP4 Comment!</p>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<p class="center"><span class="bold">Encoded by: </span>MP4 Encoded-by!</p>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<p class="center"><span class="bold">Lyrics: </span>MP4 Lyrics!</p>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="video-theater-view" title=\'Click this button to toggle "theater view" on the video player.\'>Theater View: Off</button>',
"utf8",
)
in rv.data
)
def test_file_detail_real_ogg(client):
example_dir = os.path.join(THIS_DIR, "example", "real.ogg")
dir_list = []
dir_list.append(example_dir)
site_name = "COOL TEST SITE"
url = "/browse" + example_dir
app.fidiConfig["config"]["favicon_path"] = "/cool-favicon.png"
app.fidiConfig["config"]["music_dirs"] = dir_list
app.fidiConfig["config"]["site_name"] = site_name
app.fidiConfig["config"]["theme"] = "dark"
with app.app_context():
rv = client.get(url)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert rv.status == "200 OK"
assert bytes(example_dir, "utf8") in rv.data
assert b"Track: 34" in rv.data
assert b"Released: 2019-08-08" in rv.data
assert bytes("Genre: MousikóFídi Test", "utf8") in rv.data
assert bytes('"MousikóFídi Test Album"', "utf8") in rv.data
assert bytes("MousikóFídi Test Album", "utf8") in rv.data
assert bytes("MousikóFídi Test OGG", "utf8") in rv.data
assert bytes(
'<img data-stat="off" id="cover-art" src="/serve/{}/example/MousikoFidi%20Sample%20Cover%20Art.png" title="The cover art for files in this directory. Click to adjust size (up to three sizes).">'.format(
example_dir.strip("/")
),
"utf8",
)
assert (
bytes(
'<audio id="single" controls src="/serve/{}">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form class="center" action="/playlist/add/{}" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<title id="title" data-sitename="{0}">MousikóFídi Test OGG | {0}</title>'.format(
site_name
),
"utf8",
)
in rv.data
)
assert (
b'<button id="time-link" title="Click this button to have a link to this track at the current time put into your clipboard.">'
in rv.data
)
assert b"Current Time Link" in rv.data
assert (
bytes(
'<p class="center"><span class="bold">Comment: </span>OGG Comment!</p>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<p class="center"><span class="bold">Encoded by: </span>OGG Encoded-by!</p>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<p class="center"><span class="bold">Lyrics: </span>OGG Lyrics!</p>',
"utf8",
)
in rv.data
)
# TODO: Test name truncating in file_dict()
def test_playlist_empty(client):
url = "/queue"
with app.app_context():
rv = client.get(url)
assert rv.status == "200 OK"
assert (
bytes(
'<p class="bold center">There are no playlists. You can create one by browsing and adding tracks with the "+" button.</p>',
"utf8",
)
in rv.data
)
assert bytes('<li><a href="/queue">Playlist</a></li>', "utf8") not in rv.data
assert (
bytes(
'<form action="/playlist/clear/all" class="center" id="playlistctl" method="post">',
"utf8",
)
not in rv.data
)
assert (
bytes(
'<input class="center" id="clear" name="clear" title="Remove all tracks from your queue." value="Clear Queue" type="submit" />',
"utf8",
)
not in rv.data
)
assert bytes("</form>", "utf8") not in rv.data
def test_playlist_with_audio_and_video(client):
example_dir = os.path.join(THIS_DIR, "example")
url = "/queue"
logo = select_logo(app.fidiConfig, "logo_path")
with app.test_client() as tc:
f = os.path.join(example_dir, "real.flac")
f2 = os.path.join(example_dir, "real.mp3")
f3 = os.path.join(example_dir, "real.mp4")
f4 = os.path.join(example_dir, "real.ogg")
f5 = os.path.join(example_dir, "fake.mp4")
f6 = os.path.join(example_dir, "fake.webm")
with tc.session_transaction() as sess:
sess["queue"] = [f, f2, f3, f4, f5, f6]
rv = tc.get(url)
assert (
bytes(
'<form action="/playlist/clear/all" class="center" id="playlistctl" method="post">',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input class="center" id="clear" name="clear" title="Remove all tracks from your queue." value="Clear Queue" type="submit" />',
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/save/save" class="center" id="playlistctl" method="post">',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input class="center" id="save" name="save" title="Save this queue as an .m3u file. Note that doing so will reload the page, stopping any playback." value="Save Queue" type="submit" />',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input id="file-name" name="file-name" type="text" placeholder="Name" title="File name for the playlist to be saved. Only alphanumeric charatcers, spaces, underscores, and plus signs are allowed." required/>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input id="item-list" name="bulk-list" type="hidden" value="['{0}/real.flac', '{0}/real.mp3', '{0}/real.mp4', '{0}/real.ogg', '{0}/fake.mp4', '{0}/fake.webm']">'.format(
example_dir
),
"utf8",
)
in rv.data
)
assert bytes('<h4 class="center">Audio Tracks</h4>', "utf8") in rv.data
assert bytes('<h4 class="center">Video Tracks</h4>', "utf8") in rv.data
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.flac" data-num="0" data-path="{0}/real.flac" data-title="MousikóFídi Test FLAC" id="mousikófíditestflac" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.flac" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert bytes("MousikóFídi Test FLAC", "utf8") in rv.data
assert bytes("MousikóFídi Test MP3", "utf8") in rv.data
assert bytes("MousikóFídi Test OGG", "utf8") in rv.data
assert bytes("MousikóFídi Test Album", "utf8") in rv.data
assert (
bytes(
'<form action="/playlist/rm/{}/real.flac" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes('<input class="bold red X" type="submit" value="X">', "utf8") in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.mp3" data-num="0" data-path="{0}/real.mp3" data-title="MousikóFídi Test MP3" id="mousikófíditestmp3" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.mp3" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/real.mp3" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<div class="video-arrow" data-browse="/browse/{0}/real.mp4" data-num="0" data-path="{0}/real.mp4" data-title="MousikóFídi Test MP4" id="mousikófíditestmp4" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big video-title" href="/browse/{}/real.mp4" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/real.mp4" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.ogg" data-num="0" data-path="{0}/real.ogg" data-title="MousikóFídi Test OGG" id="mousikófíditestogg" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.ogg" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/real.ogg" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<div class="video-arrow" data-browse="/browse/{0}/fake.mp4" data-num="0" data-path="{0}/fake.mp4" data-title="fake.mp4" id="fakemp4" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big video-title" href="/browse/{}/fake.mp4" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/fake.mp4" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<div class="video-arrow" data-browse="/browse/{0}/fake.webm" data-num="0" data-path="{0}/fake.webm" data-title="fake.webm" id="fakewebm" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big video-title" href="/browse/{}/fake.webm" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/fake.webm" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert bytes('<div class="center" id="player">', "utf8") in rv.data
assert (
bytes(
'<p id="now-playing" title="The status of the current track. Click the track title to jump to it in the playlist.">Paused: <span class="bold" id="playing-title" title="The title of the current track."></span></p>',
"utf8",
)
in rv.data
)
assert (
bytes('<div data-nowplaying-num="0" id="now-playing-num"></div>', "utf8")
in rv.data
)
assert bytes('<div data-randorder="none" id="randorder"></div>', "utf8") in rv.data
assert bytes('<audio id="audio" controls>', "utf8") in rv.data
assert bytes("</audio>", "utf8") in rv.data
assert (
bytes(
'<button data-cmd="prev" id="prev" title="Click to skip to the previous track in the list.">Previous</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-cmd="fwd" id="next" title="Click to skip to the next track in the list.">Next</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="repeat" title="Click to toggle between no repeat, repeat one track, and repeat all tracks.">No Repeat</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="shuffle" title="Click to toggle between a shuffled track order on and off.">Shuffle Off</button>',
"utf8",
)
in rv.data
)
assert (
bytes('<div data-nowplaying-num="0" id="video-now-playing-num"></div>', "utf8")
in rv.data
)
assert (
bytes('<div data-randorder="none" id="vid-randorder"></div>', "utf8") in rv.data
)
assert bytes('<div id="videoplayer"></div>', "utf8") in rv.data
assert (
bytes('<video poster="{}" id="video" controls>'.format(logo), "utf8") in rv.data
)
assert bytes("<source>", "utf8") in rv.data
assert bytes("</video>", "utf8") in rv.data
assert (
bytes(
'<button data-cmd="prev" id="vid-prev" title="Click to skip to the previous track in the list.">Previous</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-cmd="fwd" id="vid-next" title="Click to skip to the next track in the list.">Next</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="vid-repeat" title="Click to toggle between no repeat, repeat one track, and repeat all tracks.">No Repeat</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="vid-shuffle" title="Click to toggle between a shuffled track order on and off.">Shuffle Off</button>',
"utf8",
)
in rv.data
)
assert bytes('<div id="top"></div>', "utf8") in rv.data
assert (
bytes(
'<div id="top-link"><a class="bold" href="#top" title="Click this triangle to navigate back to the top of the current page without reloading it."></a></div>',
"utf8",
)
in rv.data
)
def test_playlist_with_audio_no_video(client):
example_dir = os.path.join(THIS_DIR, "example")
url = "/queue"
logo = select_logo(app.fidiConfig, "logo_path")
with app.test_client() as tc:
f = os.path.join(example_dir, "real.flac")
f2 = os.path.join(example_dir, "real.mp3")
f3 = os.path.join(example_dir, "real.ogg")
with tc.session_transaction() as sess:
sess["queue"] = [f, f2, f3]
rv = tc.get(url)
assert (
bytes(
'<form action="/playlist/clear/all" class="center" id="playlistctl" method="post">',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input class="center" id="clear" name="clear" title="Remove all tracks from your queue." value="Clear Queue" type="submit" />',
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/save/save" class="center" id="playlistctl" method="post">',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input class="center" id="save" name="save" title="Save this queue as an .m3u file. Note that doing so will reload the page, stopping any playback." value="Save Queue" type="submit" />',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input id="file-name" name="file-name" type="text" placeholder="Name" title="File name for the playlist to be saved. Only alphanumeric charatcers, spaces, underscores, and plus signs are allowed." required/>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input id="item-list" name="bulk-list" type="hidden" value="['{0}/real.flac', '{0}/real.mp3', '{0}/real.ogg']">'.format(
example_dir
),
"utf8",
)
in rv.data
)
assert bytes('<h4 class="center">Audio Tracks</h4>', "utf8") in rv.data
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.flac" data-num="0" data-path="{0}/real.flac" data-title="MousikóFídi Test FLAC" id="mousikófíditestflac" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.flac" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert bytes("MousikóFídi Test FLAC", "utf8") in rv.data
assert bytes("MousikóFídi Test MP3", "utf8") in rv.data
assert bytes("MousikóFídi Test OGG", "utf8") in rv.data
assert bytes("MousikóFídi Test Album", "utf8") in rv.data
assert (
bytes(
'<form action="/playlist/rm/{}/real.flac" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes('<input class="bold red X" type="submit" value="X">', "utf8") in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.mp3" data-num="0" data-path="{0}/real.mp3" data-title="MousikóFídi Test MP3" id="mousikófíditestmp3" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.mp3" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/real.mp3" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<div class="video-arrow" data-browse="/browse/{0}/real.mp4" data-num="0" data-path="{0}/real.mp4" data-title="MousikóFídi Test MP4" id="mousikófíditestmp4" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<a class="mobile-big video-title" href="/browse/{}/real.mp4">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/real.mp4" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.ogg" data-num="0" data-path="{0}/real.ogg" data-title="MousikóFídi Test OGG" id="mousikófíditestogg" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.ogg" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/real.ogg" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<div class="video-arrow" data-browse="/browse/{0}/fake.mp4" data-num="0" data-path="{0}/fake.mp4" data-title="fake.mp4" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<a class="mobile-big video-title" href="/browse/{}/fake.mp4">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/fake.mp4" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<div class="video-arrow" data-browse="/browse/{0}/fake.webm" data-num="0" data-path="{0}/fake.webm" data-title="fake.webm" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<a class="mobile-big video-title" href="/browse/{}/fake.webm">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/fake.webm" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert bytes('<div class="center" id="player">', "utf8") in rv.data
assert (
bytes(
'<p id="now-playing" title="The status of the current track. Click the track title to jump to it in the playlist.">Paused: <span class="bold" id="playing-title" title="The title of the current track."></span></p>',
"utf8",
)
in rv.data
)
assert (
bytes('<div data-nowplaying-num="0" id="now-playing-num"></div>', "utf8")
in rv.data
)
assert bytes('<div data-randorder="none" id="randorder"></div>', "utf8") in rv.data
assert bytes('<audio id="audio" controls>', "utf8") in rv.data
assert bytes("</audio>", "utf8") in rv.data
assert (
bytes(
'<button data-cmd="prev" id="prev" title="Click to skip to the previous track in the list.">Previous</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-cmd="fwd" id="next" title="Click to skip to the next track in the list.">Next</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="repeat" title="Click to toggle between no repeat, repeat one track, and repeat all tracks.">No Repeat</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="shuffle" title="Click to toggle between a shuffled track order on and off.">Shuffle Off</button>',
"utf8",
)
in rv.data
)
assert (
bytes('<div data-nowplaying-num="0" id="video-now-playing-num"></div>', "utf8")
not in rv.data
)
assert (
bytes('<div data-randorder="none" id="vid-randorder"></div>', "utf8")
not in rv.data
)
assert bytes('<div id="videoplayer"></div>', "utf8") not in rv.data
assert (
bytes('<video poster="{}" id="video" controls>'.format(logo), "utf8")
not in rv.data
)
assert bytes("<source>", "utf8") not in rv.data
assert bytes("</video>", "utf8") not in rv.data
assert (
bytes(
'<button data-cmd="prev" id="vid-prev" title="Click to skip to the previous track in the list.">Previous</button>',
"utf8",
)
not in rv.data
)
assert (
bytes(
'<button data-cmd="fwd" id="vid-next" title="Click to skip to the next track in the list.">Next</button>',
"utf8",
)
not in rv.data
)
assert (
bytes(
'<button data-stat="off" id="vid-repeat" title="Click to toggle between no repeat, repeat one track, and repeat all tracks.">No Repeat</button>',
"utf8",
)
not in rv.data
)
assert (
bytes(
'<button data-stat="off" id="vid-shuffle" title="Click to toggle between a shuffled track order on and off.">Shuffle Off</button>',
"utf8",
)
not in rv.data
)
assert bytes('<div id="top"></div>', "utf8") in rv.data
assert (
bytes(
'<div id="top-link"><a class="bold" href="#top" title="Click this triangle to navigate back to the top of the current page without reloading it."></a></div>',
"utf8",
)
in rv.data
)
def test_playlist_no_audio_with_video(client):
example_dir = os.path.join(THIS_DIR, "example")
url = "/queue"
logo = select_logo(app.fidiConfig, "logo_path")
with app.test_client() as tc:
f = os.path.join(example_dir, "real.mp4")
f2 = os.path.join(example_dir, "fake.mp4")
f3 = os.path.join(example_dir, "fake.webm")
with tc.session_transaction() as sess:
sess["queue"] = [f, f2, f3]
rv = tc.get(url)
assert (
bytes(
'<form action="/playlist/clear/all" class="center" id="playlistctl" method="post">',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input class="center" id="clear" name="clear" title="Remove all tracks from your queue." value="Clear Queue" type="submit" />',
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/save/save" class="center" id="playlistctl" method="post">',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input class="center" id="save" name="save" title="Save this queue as an .m3u file. Note that doing so will reload the page, stopping any playback." value="Save Queue" type="submit" />',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input id="file-name" name="file-name" type="text" placeholder="Name" title="File name for the playlist to be saved. Only alphanumeric charatcers, spaces, underscores, and plus signs are allowed." required/>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input id="item-list" name="bulk-list" type="hidden" value="['{0}/real.mp4', '{0}/fake.mp4', '{0}/fake.webm']">'.format(
example_dir
),
"utf8",
)
in rv.data
)
assert bytes('<h4 class="center">Audio Tracks</h4>', "utf8") not in rv.data
assert bytes('<h4 class="center">Files:</h4>', "utf8") not in rv.data
assert bytes('<h4 class="center">Video Tracks</h4>', "utf8") in rv.data
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.flac" data-num="0" data-path="{0}/real.flac" data-title="MousikóFídi Test Title" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.flac" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert bytes("MousikóFídi Test MP4", "utf8") in rv.data
assert bytes("MousikóFídi Test Album", "utf8") in rv.data
assert (
bytes(
'<form action="/playlist/rm/{}/real.flac" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes('<input class="bold red X" type="submit" value="X">', "utf8") in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.mp3" data-num="0" data-path="{0}/real.mp3" data-title="MousikóFídi Test Title" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.mp3" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/real.mp3" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<div class="video-arrow" data-browse="/browse/{0}/real.mp4" data-num="0" data-path="{0}/real.mp4" data-title="MousikóFídi Test MP4" id="mousikófíditestmp4" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big video-title" href="/browse/{}/real.mp4" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/real.mp4" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.ogg" data-num="0" data-path="{0}/real.ogg" data-title="MousikóFídi Test Title" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.ogg" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/real.ogg" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
not in rv.data
)
assert (
bytes(
'<div class="video-arrow" data-browse="/browse/{0}/fake.mp4" data-num="0" data-path="{0}/fake.mp4" data-title="fake.mp4" id="fakemp4" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big video-title" href="/browse/{}/fake.mp4" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/fake.mp4" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<div class="video-arrow" data-browse="/browse/{0}/fake.webm" data-num="0" data-path="{0}/fake.webm" data-title="fake.webm" id="fakewebm" title="Click to play this track."></div>'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big video-title" href="/browse/{}/fake.webm" title="This track\'s title.">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<form action="/playlist/rm/{}/fake.webm" class="center" method="post">'.format(
example_dir.strip("/")
),
"utf8",
)
in rv.data
)
assert bytes('<div class="center" id="player">', "utf8") not in rv.data
assert (
bytes(
'<p id="now-playing" title="The status of the current track. Click the track title to jump to it in the playlist.">Paused: <span class="bold" id="playing-title" title="The title of the current track."></span></p>',
"utf8",
)
not in rv.data
)
assert (
bytes('<div data-nowplaying-num="0" id="now-playing-num"></div>', "utf8")
not in rv.data
)
assert (
bytes('<div data-randorder="none" id="randorder"></div>', "utf8") not in rv.data
)
assert bytes('<audio id="audio" controls>', "utf8") not in rv.data
assert bytes("</audio>", "utf8") not in rv.data
assert (
bytes(
'<button data-cmd="prev" id="prev" title="Click to skip to the previous track in the list.">Previous</button>',
"utf8",
)
not in rv.data
)
assert (
bytes(
'<button data-cmd="fwd" id="next" title="Click to skip to the next track in the list.">Next</button>',
"utf8",
)
not in rv.data
)
assert (
bytes(
'<button data-stat="off" id="repeat" title="Click to toggle between no repeat, repeat one track, and repeat all tracks.">No Repeat</button>',
"utf8",
)
not in rv.data
)
assert (
bytes(
'<button data-stat="off" id="shuffle" title="Click to toggle between a shuffled track order on and off.">Shuffle Off</button>',
"utf8",
)
not in rv.data
)
assert (
bytes('<div data-nowplaying-num="0" id="video-now-playing-num"></div>', "utf8")
in rv.data
)
assert (
bytes('<div data-randorder="none" id="vid-randorder"></div>', "utf8") in rv.data
)
assert bytes('<div id="videoplayer"></div>', "utf8") in rv.data
assert (
bytes('<video poster="{}" id="video" controls>'.format(logo), "utf8") in rv.data
)
assert bytes("<source>", "utf8") in rv.data
assert bytes("</video>", "utf8") in rv.data
assert (
bytes(
'<button data-cmd="prev" id="vid-prev" title="Click to skip to the previous track in the list.">Previous</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-cmd="fwd" id="vid-next" title="Click to skip to the next track in the list.">Next</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="vid-repeat" title="Click to toggle between no repeat, repeat one track, and repeat all tracks.">No Repeat</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="vid-shuffle" title="Click to toggle between a shuffled track order on and off.">Shuffle Off</button>',
"utf8",
)
in rv.data
)
assert bytes('<div id="top"></div>', "utf8") in rv.data
assert (
bytes(
'<div id="top-link"><a class="bold" href="#top" title="Click this triangle to navigate back to the top of the current page without reloading it."></a></div>',
"utf8",
)
in rv.data
)
# def test_playlistctl_add(client):
# pass
# def test_playlistctl_clear(client):
# pass
# def test_playlistctl_rm(client):
# pass
def test_playlist_detail_nothing(client):
with app.test_client() as tc:
rv = tc.get("/playlist/idkjaja")
assert rv.status == "404 NOT FOUND"
def test_playlist_detail_real_with_bad(client):
edir = os.path.join(THIS_DIR, "example")
mdir = tempfile.mkdtemp()
pdir = tempfile.mkdtemp()
shutil.copy(os.path.join(edir, "real.flac"), mdir)
shutil.copy(os.path.join(edir, "real.mp3"), mdir)
shutil.copy(os.path.join(edir, "real.ogg"), mdir)
plist1 = os.path.join(pdir, "PLAYLIST FILE 1.m3u")
real_flac = os.path.join(mdir, "real.flac")
real_mp3 = os.path.join(mdir, "real.mp3")
real_ogg = os.path.join(mdir, "real.ogg")
with open(plist1, "w") as f1:
f1.write(real_flac)
f1.write("\n")
f1.write(real_mp3)
f1.write("\n")
f1.write(real_ogg)
f1.write("\n")
f1.write("/path/to/somefakefile.mp4")
f1.write("\n")
f1.write("/path/to/somefakefile.ogg")
f1.write("\n")
app.fidiConfig["config"]["music_dirs"] = [mdir]
app.fidiConfig["config"]["playlist"]["dir"] = pdir
app.fidiConfig["config"]["site_name"] = "Pdir Test"
with app.test_client() as tc:
rv = tc.get("/playlist/" + quote("PLAYLIST FILE 1"))
assert rv.status == "200 OK"
assert (
bytes(
'<title id="title" data-sitename="Pdir Test">Playlist: PLAYLIST FILE 1 | Pdir Test</title>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<h2 class="center"><a href="/playlists">View All Playlists</a></h2>',
"utf8",
)
in rv.data
)
assert (
bytes('<h2 class="bold center">Playlist Name: PLAYLIST FILE 1</h2>', "utf8")
in rv.data
)
assert (
bytes(
'<form action="/playlist/load/load-with-redirect" class="center" id="playlistctl" method="post">',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input id="to-load" name="to-load" type="hidden" value="PLAYLIST FILE 1">',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input class="plus" type="submit" value="+" title="Add this track to the queue.">',
"utf8",
)
in rv.data
)
assert (
bytes('<div class="anchor" id="mousikófíditestflac-target">', "utf8") in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.flac" data-num="0" data-path="{0}/real.flac" data-title="MousikóFídi Test FLAC" id="mousikófíditestflac" title="Click to play this track."></div>'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.flac" title="This track\'s title.">'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert bytes("MousikóFídi Test FLAC\n", "utf8") in rv.data
assert bytes("MousikóFídi Test MP3\n", "utf8") in rv.data
assert bytes("MousikóFídi Test OGG\n", "utf8") in rv.data
assert bytes("0:04", "utf8") in rv.data
assert (
bytes('<div class="anchor" id="mousikófíditestmp3-target">', "utf8") in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.mp3" data-num="0" data-path="{0}/real.mp3" data-title="MousikóFídi Test MP3" id="mousikófíditestmp3" title="Click to play this track."></div>'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.mp3" title="This track\'s title.">'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert bytes("MousikóFídi Test Album\n", "utf8") in rv.data
assert bytes("MousikóFídi Test Artist\n", "utf8") in rv.data
assert (
bytes('<div class="anchor" id="mousikófíditestogg-target">', "utf8") in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.ogg" data-num="0" data-path="{0}/real.ogg" data-title="MousikóFídi Test OGG" id="mousikófíditestogg" title="Click to play this track."></div>'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.ogg" title="This track\'s title.">'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<p id="now-playing" title="The status of the current track. Click the track title to jump to it in the playlist.">Paused: <span class="bold" id="playing-title" title="The title of the current track."></span></p>',
"utf8",
)
in rv.data
)
assert (
bytes('<div data-nowplaying-num="0" id="now-playing-num"></div>', "utf8")
in rv.data
)
assert bytes('<div data-randorder="none" id="randorder"></div>', "utf8") in rv.data
assert bytes('<audio id="audio" controls>', "utf8") in rv.data
assert bytes("</audio>", "utf8") in rv.data
assert (
bytes(
'<button data-cmd="prev" id="prev" title="Click to skip to the previous track in the list.">Previous</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-cmd="fwd" id="next" title="Click to skip to the next track in the list.">Next</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="repeat" title="Click to toggle between no repeat, repeat one track, and repeat all tracks.">No Repeat</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="shuffle" title="Click to toggle between a shuffled track order on and off.">Shuffle Off</button>',
"utf8",
)
in rv.data
)
assert b"somefakefile.mp4" not in rv.data
assert b"somefakefile.ogg" not in rv.data
shutil.rmtree(mdir)
shutil.rmtree(pdir)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
def test_playlist_detail_real(client):
edir = os.path.join(THIS_DIR, "example")
mdir = tempfile.mkdtemp()
pdir = tempfile.mkdtemp()
shutil.copy(os.path.join(edir, "real.flac"), mdir)
shutil.copy(os.path.join(edir, "real.mp3"), mdir)
shutil.copy(os.path.join(edir, "real.ogg"), mdir)
plist1 = os.path.join(pdir, "PLAYLIST FILE 1.m3u")
real_flac = os.path.join(mdir, "real.flac")
real_mp3 = os.path.join(mdir, "real.mp3")
real_ogg = os.path.join(mdir, "real.ogg")
with open(plist1, "w") as f1:
f1.write(real_flac)
f1.write("\n")
f1.write(real_mp3)
f1.write("\n")
f1.write(real_ogg)
f1.write("\n")
app.fidiConfig["config"]["music_dirs"] = [mdir]
app.fidiConfig["config"]["playlist"]["dir"] = pdir
app.fidiConfig["config"]["site_name"] = "Pdir Test"
with app.test_client() as tc:
rv = tc.get("/playlist/" + quote("PLAYLIST FILE 1"))
assert rv.status == "200 OK"
assert (
bytes(
'<title id="title" data-sitename="Pdir Test">Playlist: PLAYLIST FILE 1 | Pdir Test</title>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<h2 class="center"><a href="/playlists">View All Playlists</a></h2>',
"utf8",
)
in rv.data
)
assert (
bytes('<h2 class="bold center">Playlist Name: PLAYLIST FILE 1</h2>', "utf8")
in rv.data
)
assert (
bytes(
'<form action="/playlist/load/load-with-redirect" class="center" id="playlistctl" method="post">',
"utf8",
)
in rv.data
)
assert (
bytes(
'<input id="to-load" name="to-load" type="hidden" value="PLAYLIST FILE 1">',
"utf8",
)
in rv.data
)
assert (
bytes('<div class="anchor" id="mousikófíditestflac-target">', "utf8") in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.flac" data-num="0" data-path="{0}/real.flac" data-title="MousikóFídi Test FLAC" id="mousikófíditestflac" title="Click to play this track."></div>'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.flac" title="This track\'s title.">'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert bytes(" MousikóFídi Test FLAC\n", "utf8") in rv.data
assert bytes("0:04", "utf8") in rv.data
assert (
bytes('<div class="anchor" id="mousikófíditestmp3-target">', "utf8") in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.mp3" data-num="0" data-path="{0}/real.mp3" data-title="MousikóFídi Test MP3" id="mousikófíditestmp3" title="Click to play this track."></div>'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.mp3" title="This track\'s title.">'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert bytes("MousikóFídi Test MP3\n", "utf8") in rv.data
assert bytes("MousikóFídi Test OGG\n", "utf8") in rv.data
assert bytes("MousikóFídi Test Album\n", "utf8") in rv.data
assert bytes("MousikóFídi Test Artist\n", "utf8") in rv.data
assert (
bytes('<div class="anchor" id="mousikófíditestogg-target">', "utf8") in rv.data
)
assert (
bytes(
'<div class="play-arrow" data-browse="/browse/{0}/real.ogg" data-num="0" data-path="{0}/real.ogg" data-title="MousikóFídi Test OGG" id="mousikófíditestogg" title="Click to play this track."></div>'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="mobile-big" href="/browse/{}/real.ogg" title="This track\'s title.">'.format(
mdir.strip("/")
),
"utf8",
)
in rv.data
)
assert (
bytes(
'<p id="now-playing" title="The status of the current track. Click the track title to jump to it in the playlist.">Paused: <span class="bold" id="playing-title" title="The title of the current track."></span></p>',
"utf8",
)
in rv.data
)
assert (
bytes('<div data-nowplaying-num="0" id="now-playing-num"></div>', "utf8")
in rv.data
)
assert bytes('<div data-randorder="none" id="randorder"></div>', "utf8") in rv.data
assert bytes('<audio id="audio" controls>', "utf8") in rv.data
assert bytes("</audio>", "utf8") in rv.data
assert (
bytes(
'<button data-cmd="prev" id="prev" title="Click to skip to the previous track in the list.">Previous</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-cmd="fwd" id="next" title="Click to skip to the next track in the list.">Next</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="repeat" title="Click to toggle between no repeat, repeat one track, and repeat all tracks.">No Repeat</button>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<button data-stat="off" id="shuffle" title="Click to toggle between a shuffled track order on and off.">Shuffle Off</button>',
"utf8",
)
in rv.data
)
shutil.rmtree(mdir)
shutil.rmtree(pdir)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
def test_playlists_no_playlists(client):
with app.test_client() as tc:
rv = tc.get("/playlists")
assert rv.status == "200 OK"
assert b"Nothing here!" in rv.data
def test_playlists_yes_playlists(client):
edir = os.path.join(THIS_DIR, "example")
mdir = tempfile.mkdtemp()
pdir = tempfile.mkdtemp()
shutil.copy(os.path.join(edir, "real.flac"), mdir)
shutil.copy(os.path.join(edir, "real.mp3"), mdir)
shutil.copy(os.path.join(edir, "real.ogg"), mdir)
plist1 = os.path.join(pdir, "PLAYLIST FILE 1.m3u")
plist2 = os.path.join(pdir, "PLAYLIST FILE 2.m3u")
plist3 = os.path.join(pdir, "PLAYLIST FILE 3.m3u")
plist4 = os.path.join(pdir, "PLAYLIST FILE 4.m3u")
real_flac = os.path.join(mdir, "real.flac")
real_mp3 = os.path.join(mdir, "real.mp3")
real_ogg = os.path.join(mdir, "real.ogg")
with open(plist1, "w") as f1:
f1.write(real_flac)
f1.write("\n")
f1.write(real_mp3)
f1.write("\n")
f1.write(real_ogg)
f1.write("\n")
with open(plist2, "w") as f2:
f2.write(real_flac)
f2.write("\n")
f2.write(real_flac)
f2.write("\n")
f2.write(real_mp3)
f2.write("\n")
f2.write(real_ogg)
f2.write("\n")
with open(plist3, "w") as f3:
f3.write(real_flac)
f3.write("\n")
f3.write(real_flac)
f3.write("\n")
f3.write(real_mp3)
f3.write("\n")
f3.write(real_mp3)
f3.write("\n")
f3.write(real_ogg)
f3.write("\n")
with open(plist4, "w") as f4:
f4.write(real_flac)
f4.write("\n")
f4.write(real_flac)
f4.write("\n")
f4.write(real_mp3)
f4.write("\n")
f4.write(real_mp3)
f4.write("\n")
f4.write(real_ogg)
f4.write("\n")
f4.write(real_ogg)
f4.write("\n")
app.fidiConfig["config"]["music_dirs"] = [mdir]
app.fidiConfig["config"]["playlist"]["dir"] = pdir
app.fidiConfig["config"]["site_name"] = "Pdir Test"
with app.test_client() as tc:
rv = tc.get("/playlists")
assert rv.status == "200 OK"
assert (
bytes(
'<title id="title" data-sitename="Pdir Test">Playlists | Pdir Test</title>',
"utf8",
)
in rv.data
)
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%201">', "utf8"
)
in rv.data
)
assert bytes("PLAYLIST FILE 1", "utf8") in rv.data
assert bytes(" <td>\n 3\n </td>\n", "utf8") in rv.data
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%202">', "utf8"
)
in rv.data
)
assert bytes("PLAYLIST FILE 2", "utf8") in rv.data
assert bytes(" <td>\n 4\n </td>\n", "utf8") in rv.data
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%203">', "utf8"
)
in rv.data
)
assert bytes("PLAYLIST FILE 3", "utf8") in rv.data
assert bytes(" <td>\n 5\n </td>\n", "utf8") in rv.data
assert (
bytes(
'<a class="bold mobile-big" href="/playlist/PLAYLIST%20FILE%204">', "utf8"
)
in rv.data
)
assert bytes("PLAYLIST FILE 4", "utf8") in rv.data
assert bytes(" <td>\n 6\n </td>\n", "utf8") in rv.data
assert bytes('<div id="top"></div>', "utf8") in rv.data
assert (
bytes(
'<div id="top-link"><a class="bold" href="#top" title="Click this triangle to navigate back to the top of the current page without reloading it."></a></div> ',
"utf8",
)
in rv.data
)
shutil.rmtree(mdir)
shutil.rmtree(pdir)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
def test_serve_file(client):
example_dir = os.path.join(THIS_DIR, "example")
dir_list = []
dir_list.append(example_dir)
file_path = os.path.join(example_dir, "real.flac")
url = "/browse" + file_path
app.fidiConfig["config"]["music_dirs"] = dir_list
with app.app_context():
rv = client.get(url)
# Reset the config
app.fidiConfig = app._fidiConfig.copy()
assert rv.status == "200 OK"
def test_settings(client):
url = "/settings"
with app.app_context():
rv = client.get(url)
assert rv.status == "200 OK"
assert (
bytes(
'<form class="center" id="settings" action="/settings/edit" method="post">',
"utf8",
)
in rv.data
)
assert bytes('<option value="dark" selected>Dark</option>', "utf8") in rv.data
assert (
bytes('<option value="disabled" selected>Disabled</option>', "utf8") in rv.data
)
def test_settings_edit(client):
url = "/settings/edit"
app.secret_key = "SO SECRET!!!"
with app.app_context():
client.post(url, data={"theme": "light"})
assert session["theme"] == "light"
with app.app_context():
client.post(url, data={"theme": "dark"})
assert session["theme"] == "dark"
with app.app_context():
client.post(url, data={"theme": "nes"})
assert session["theme"] == "nes"
with app.app_context():
client.post(url, data={"icons": "enabled"})
assert session["icons"] is True
with app.app_context():
client.post(url, data={"icons": "disabled"})
assert session["icons"] is False