add tests
This commit is contained in:
+21
-3
@@ -1,4 +1,8 @@
|
||||
import pytest
|
||||
import os
|
||||
|
||||
from pathlib import Path
|
||||
from dotenv import load_dotenv
|
||||
|
||||
import groove.db
|
||||
|
||||
@@ -6,6 +10,20 @@ from sqlalchemy import create_engine, insert
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope='function')
|
||||
def env():
|
||||
root = Path(__file__).parent / Path('fixtures')
|
||||
load_dotenv(Path('test/fixtures/env'))
|
||||
os.environ['GROOVE_ON_DEMAND_ROOT'] = str(root)
|
||||
os.environ['MEDIA_ROOT'] = str(root / Path('media'))
|
||||
return os.environ
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def auth():
|
||||
return (os.environ.get('USERNAME'), os.environ.get('PASSWORD'))
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def in_memory_engine():
|
||||
return create_engine('sqlite:///:memory:', future=True)
|
||||
@@ -32,9 +50,9 @@ def db(in_memory_db):
|
||||
# create tracks
|
||||
query = insert(groove.db.track)
|
||||
in_memory_db.execute(query, [
|
||||
{'id': 1, 'relpath': '/UNKLE/Psyence Fiction/01 Guns Blazing (Drums of Death, Part 1).flac'},
|
||||
{'id': 2, 'relpath': '/UNKLE/Psyence Fiction/02 UNKLE (Main Title Theme).flac'},
|
||||
{'id': 3, 'relpath': '/UNKLE/Psyence Fiction/03 Bloodstain.flac'}
|
||||
{'id': 1, 'relpath': 'UNKLE/Psyence Fiction/01 Guns Blazing (Drums of Death, Part 1).flac'},
|
||||
{'id': 2, 'relpath': 'UNKLE/Psyence Fiction/02 UNKLE (Main Title Theme).flac'},
|
||||
{'id': 3, 'relpath': 'UNKLE/Psyence Fiction/03 Bloodstain.flac'}
|
||||
])
|
||||
|
||||
# create playlists
|
||||
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
# Will be overwritten by test setup
|
||||
GROOVE_ON_DEMAND_ROOT=.
|
||||
MEDIA_ROOT=.
|
||||
|
||||
# where to store the database
|
||||
DATABASE_PATH=test.db
|
||||
|
||||
# Admin user credentials
|
||||
USERNAME=test_username
|
||||
PASSWORD=test_password
|
||||
|
||||
# Web interface configuration
|
||||
HOST=127.0.0.1
|
||||
PORT=2323
|
||||
THEMES_PATH=themes
|
||||
STATIC_PATH=static
|
||||
DEFAULT_THEME=default_theme
|
||||
SECRET_KEY=fnord
|
||||
|
||||
# Media scanner configuration
|
||||
MEDIA_GLOB=*.mp3,*.flac,*.m4a
|
||||
|
||||
# Set this value to enable debugging
|
||||
DEBUG=1
|
||||
+1
@@ -0,0 +1 @@
|
||||
DRUMS OF DEATH YALL
|
||||
Vendored
Vendored
+1
@@ -0,0 +1 @@
|
||||
favicon.ico
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
# Default Theme Fixture
|
||||
|
||||
This directory is a test fixture used for verifying theme handling.
|
||||
|
||||
## Credits
|
||||
|
||||
```
|
||||
author: Theme Author
|
||||
author_link: link to my soundcloud
|
||||
version: 1.3
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
/* test.css */
|
||||
Binary file not shown.
@@ -0,0 +1,13 @@
|
||||
import pytest
|
||||
import os
|
||||
|
||||
from groove import path
|
||||
from groove.exceptions import ConfigurationError
|
||||
|
||||
|
||||
def test_missing_theme_root(monkeypatch):
|
||||
broken_env = {k: v for (k, v) in os.environ.items()}
|
||||
broken_env['GROOVE_ON_DEMAND_ROOT'] = '/dev/null/missing'
|
||||
monkeypatch.setattr(os, 'environ', broken_env)
|
||||
with pytest.raises(ConfigurationError):
|
||||
path.themes_root()
|
||||
@@ -0,0 +1,19 @@
|
||||
from groove.webserver import requests
|
||||
|
||||
|
||||
def test_signing():
|
||||
signed = requests.encode(['foo', 'bar'], uri='fnord')
|
||||
assert requests.verify(signed, signed)
|
||||
|
||||
|
||||
def test_signing_wrong_secret_key(env):
|
||||
signed = requests.encode(['foo', 'bar'], uri='fnord')
|
||||
env['SECRET_KEY'] = 'wrong key'
|
||||
invalid = requests.encode(['foo', 'bar'], uri='fnord')
|
||||
assert not requests.verify(invalid, signed)
|
||||
|
||||
|
||||
def test_signing_wrong_uri(env):
|
||||
signed = requests.encode(['foo', 'bar'], uri='fnord')
|
||||
invalid = requests.encode(['foo', 'bar'], uri='a bad guess')
|
||||
assert not requests.verify(invalid, signed)
|
||||
@@ -4,8 +4,10 @@ from pathlib import Path
|
||||
from unittest.mock import MagicMock
|
||||
from sqlalchemy import func
|
||||
|
||||
import groove.exceptions
|
||||
from groove.db import scanner, track
|
||||
|
||||
|
||||
fixture_tracks = [
|
||||
"/test/Spookey Ruben/Modes of Transportation, Volume 1/Spookey Ruben - Modes of Transportation, Volume 1 - 01 Terra Magnifica.flac",
|
||||
"/test/Spookey Ruben/Modes of Transportation, Volume 1/Spookey Ruben - Modes of Transportation, Volume 1 - 02 These Days Are Old.flac",
|
||||
@@ -62,5 +64,5 @@ def test_scanner(monkeypatch, in_memory_db, media):
|
||||
|
||||
def test_scanner_no_media_root(in_memory_db):
|
||||
del os.environ['MEDIA_ROOT']
|
||||
with pytest.raises(SystemExit):
|
||||
with pytest.raises(groove.exceptions.ConfigurationError):
|
||||
assert scanner.media_scanner(root=None, db=in_memory_db)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import pytest
|
||||
from groove.webserver import themes
|
||||
from groove.exceptions import ThemeConfigurationError
|
||||
|
||||
|
||||
def test_load_theme():
|
||||
theme = themes.load_theme('default_theme')
|
||||
assert theme.name == 'default_theme'
|
||||
assert theme.author == 'Theme Author'
|
||||
assert theme.author_link == 'link to my soundcloud'
|
||||
assert theme.version == '1.3'
|
||||
|
||||
|
||||
def test_load_broken_theme():
|
||||
with pytest.raises(ThemeConfigurationError):
|
||||
themes.load_theme('alt_theme')
|
||||
+47
-9
@@ -1,13 +1,12 @@
|
||||
import pytest
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import atheris
|
||||
import bottle
|
||||
from boddle import boddle
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from groove import webserver
|
||||
from groove.webserver import webserver
|
||||
|
||||
|
||||
def test_server():
|
||||
@@ -16,19 +15,58 @@ def test_server():
|
||||
assert bottle.response.status_code == 200
|
||||
|
||||
|
||||
def test_auth_with_valid_credentials():
|
||||
with boddle(auth=(os.environ.get('USERNAME'), os.environ.get('PASSWORD'))):
|
||||
@pytest.mark.parametrize('track_id, expected', [
|
||||
('1', 200),
|
||||
('99', 404)
|
||||
])
|
||||
def test_serve_track(monkeypatch, track_id, expected, db):
|
||||
monkeypatch.setattr(webserver.requests, 'verify', MagicMock())
|
||||
with boddle():
|
||||
response = webserver.serve_track('ignored', track_id, db=db)
|
||||
assert response.status_code == expected
|
||||
|
||||
|
||||
def test_static_not_from_theme():
|
||||
with boddle():
|
||||
response = webserver.serve_static('favicon.ico')
|
||||
assert response.status_code == 200
|
||||
assert response.body.read() == b'favicon.ico\n'
|
||||
|
||||
|
||||
def test_static_from_theme():
|
||||
with boddle():
|
||||
response = webserver.serve_static('test.css')
|
||||
assert response.status_code == 200
|
||||
assert response.body.read() == b'/* test.css */\n'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('slug, expected', [
|
||||
('non-existent-slug', False),
|
||||
('playlist-one', True),
|
||||
])
|
||||
def test_search_playlist(slug, expected, auth, db):
|
||||
with boddle(auth=auth):
|
||||
response = webserver.search_playlist(slug, db)
|
||||
assert response.status_code == 200
|
||||
|
||||
if expected:
|
||||
assert slug in response.body
|
||||
else:
|
||||
assert response.body == {}
|
||||
|
||||
|
||||
def test_auth_with_valid_credentials(auth):
|
||||
with boddle(auth=auth):
|
||||
webserver.build()
|
||||
assert bottle.response.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_auth_random_input():
|
||||
|
||||
def auth(fuzzed_input):
|
||||
with boddle(auth=(fuzzed_input, fuzzed_input)):
|
||||
response = webserver.build()
|
||||
assert response.status_code == 401
|
||||
|
||||
atheris.Setup([sys.argv[0], "-atheris_runs=100000"], auth)
|
||||
try:
|
||||
atheris.Fuzz()
|
||||
@@ -44,11 +82,11 @@ def test_auth_random_input():
|
||||
])
|
||||
def test_playlist(db, slug, expected):
|
||||
with boddle():
|
||||
response = webserver.get_playlist(slug, db)
|
||||
response = webserver.serve_playlist(slug, db)
|
||||
assert response.status_code == expected
|
||||
|
||||
|
||||
def test_playlist_on_empty_db(in_memory_db):
|
||||
with boddle():
|
||||
response = webserver.get_playlist('some-slug', in_memory_db)
|
||||
response = webserver.serve_playlist('some-slug', in_memory_db)
|
||||
assert response.status_code == 404
|
||||
|
||||
Reference in New Issue
Block a user