diff --git a/modules/videos/channel/api.py b/modules/videos/channel/api.py index f3297fc6..b32fc2e5 100644 --- a/modules/videos/channel/api.py +++ b/modules/videos/channel/api.py @@ -4,9 +4,8 @@ from http import HTTPStatus from sanic import response, Blueprint from sanic.request import Request -from wrolpi.common import logger, wrol_mode_check, get_relative_to_media_directory, make_media_directory, \ +from wrolpi.common import logger, wrol_mode_check, make_media_directory, \ get_media_directory -from wrolpi.errors import UnknownDirectory from wrolpi.root_api import json_response from wrolpi.schema import validate_doc, JSONErrorResponse from .lib import get_minimal_channels, delete_channel, update_channel, get_channel, create_channel @@ -53,16 +52,10 @@ def channel_get(_: Request, link: str): ) @wrol_mode_check def channel_post(_: Request, data: dict): - try: - # Channel directory is relative to the media directory. Channel directory may not be in "videos" directory! - data['directory'] = get_media_directory() / data['directory'] - except UnknownDirectory: - if data['mkdir']: - make_media_directory(data['directory']) - data['directory'] = get_relative_to_media_directory(data['directory']) - else: - raise - print(data['directory']) + # Channel directory is relative to the media directory. Channel directory may not be in "videos" directory! + data['directory'] = get_media_directory() / data['directory'] + if data.get('mkdir') is True: + make_media_directory(data['directory']) if download_frequency := data.get('download_frequency'): try: diff --git a/modules/videos/channel/test/test_api.py b/modules/videos/channel/test/test_api.py index f333d636..b859e62a 100644 --- a/modules/videos/channel/test/test_api.py +++ b/modules/videos/channel/test/test_api.py @@ -613,6 +613,7 @@ def test_download_channel_no_refresh(test_session, download_channel, video_downl """ A Channel cannot be downloaded until it has been refreshed. """ + def check_refreshed(expected: bool): channel = test_session.query(Channel).one() assert channel.refreshed == expected @@ -625,3 +626,26 @@ def test_download_channel_no_refresh(test_session, download_channel, video_downl video_download_manager.do_downloads_sync() check_refreshed(True) + + +def test_channel_post_directory(test_session, test_client, test_directory): + """ + A Channel can be created with or without an existing directory. + """ + # Channel can be created with a missing directory. + data = dict(name='foo', directory='foo') + request, response = test_client.post('/api/videos/channels', content=json.dumps(data)) + assert response.status_code == HTTPStatus.CREATED + directory = test_session.query(Channel).filter_by(link='foo').one().directory.path + assert (test_directory / 'foo') == directory + assert not directory.is_dir() + assert directory.is_absolute() + + # Channel can be created and have its directory be created. + data = dict(name='bar', directory='bar', mkdir=True) + request, response = test_client.post('/api/videos/channels', content=json.dumps(data)) + assert response.status_code == HTTPStatus.CREATED + directory = test_session.query(Channel).filter_by(link='bar').one().directory.path + assert (test_directory / 'bar') == directory + assert directory.is_dir() + assert directory.is_absolute() diff --git a/modules/videos/channel/test/test_models.py b/modules/videos/channel/test/test_models.py new file mode 100644 index 00000000..e5b8653e --- /dev/null +++ b/modules/videos/channel/test/test_models.py @@ -0,0 +1,9 @@ +def test_delete_channel_no_url(test_session, test_client, channel_factory): + """ + A Channel can be deleted even if it has no URL. + """ + channel = channel_factory() + channel.url = None + test_session.commit() + + channel.delete_with_videos() diff --git a/modules/videos/models.py b/modules/videos/models.py index d2d5a05c..b57ee1b7 100644 --- a/modules/videos/models.py +++ b/modules/videos/models.py @@ -294,7 +294,7 @@ class Channel(ModelHelper, Base): session = Session.object_session(self) # Delete the video records, but not the video files! session.query(Video).filter_by(channel_id=self.id).delete() - if download := self.get_download(): + if self.url and (download := self.get_download()): session.delete(download) session.delete(self) diff --git a/requirements.txt b/requirements.txt index 3be844ef..8afc5846 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,12 @@ alembic==1.7.5 beautifulsoup4==4.10.0 cachetools==5.0.0 +mock==4.0.3 Pillow==9.0.0 Pint==0.18 psycopg2-binary==2.9.3 pytest-asyncio==0.17.0 +pytest==6.2.5 pytz==2021.3 PyYAML==6.0 requests==2.27.1 diff --git a/wrolpi/conftest.py b/wrolpi/conftest.py index 72bbf183..8ae1bb6b 100644 --- a/wrolpi/conftest.py +++ b/wrolpi/conftest.py @@ -9,6 +9,7 @@ from unittest import mock from uuid import uuid1 import pytest +import pytest_asyncio import yaml from sanic_testing.testing import SanicTestClient from sqlalchemy.engine import Engine, create_engine @@ -50,7 +51,7 @@ def test_db() -> Tuple[Engine, Session]: return test_engine, session -@pytest.fixture() +@pytest_asyncio.fixture() def test_session() -> Session: """ Pytest Fixture to get a test database session. @@ -73,7 +74,7 @@ def test_session() -> Session: conn.close() -@pytest.fixture(autouse=True) +@pytest_asyncio.fixture(autouse=True) def test_directory() -> pathlib.Path: """ Overwrite the media directory with a temporary directory. @@ -85,7 +86,7 @@ def test_directory() -> pathlib.Path: yield tmp_path -@pytest.fixture(autouse=True) +@pytest_asyncio.fixture(autouse=True) def test_config(): """ Create a test config based off the example config.