From 1cf8a8be75aa96a0a6bca834b33ff12f453b4188 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sun, 12 Feb 2023 17:37:27 -0500 Subject: [PATCH] tests: add pytest (#101) --- .dockerignore | 1 + .github/workflows/python-tests.yml | 37 +++++++++ tests/conftest.py | 22 +++++ tests/unit/__init__.py | 0 tests/unit/test_code.py | 118 +++++++++++++++++++++++++++ tests/unit/test_youtube_dl_helper.py | 26 ++++++ 6 files changed, 204 insertions(+) create mode 100644 .github/workflows/python-tests.yml create mode 100644 tests/conftest.py create mode 100644 tests/unit/__init__.py create mode 100644 tests/unit/test_code.py create mode 100644 tests/unit/test_youtube_dl_helper.py diff --git a/.dockerignore b/.dockerignore index 12b14e84..20f90261 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,6 +6,7 @@ # ignore directories docs/ +tests/ # ignore venv when building locally venv/ diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml new file mode 100644 index 00000000..2248c749 --- /dev/null +++ b/.github/workflows/python-tests.yml @@ -0,0 +1,37 @@ +--- +name: Python Tests + +on: + pull_request: + branches: [master, nightly] + types: [opened, synchronize, reopened] + +jobs: + pytest: + strategy: + fail-fast: false + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '2.7' + + - name: Install python dependencies + shell: bash + run: | + # requests is required to install python-plexapi + python -m pip --no-python-version-warning --disable-pip-version-check install --upgrade \ + pip setuptools requests + python -m pip --no-python-version-warning --disable-pip-version-check install -r requirements-dev.txt + python -m pip --no-python-version-warning --disable-pip-version-check install -r requirements.txt + + - name: Test with pytest + run: | + python -m pytest -v diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..dbdff526 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,22 @@ +# standard imports +import os +import sys + +# lib imports +from plexhints.agent_kit import Agent +import pytest + +# add Contents directory to the system path +if os.path.isdir('Contents'): + sys.path.append('Contents') + + # local imports + from Code import Themerr +else: + raise Exception('Contents directory not found') + + +@pytest.fixture +def agent(): + # type: () -> Agent + return Themerr() diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/test_code.py b/tests/unit/test_code.py new file mode 100644 index 00000000..c5f51abd --- /dev/null +++ b/tests/unit/test_code.py @@ -0,0 +1,118 @@ +# local imports +from Code import ValidatePrefs +from Code import default_prefs +from plexhints.agent_kit import Media +from plexhints.model_kit import Movie +from plexhints.object_kit import MessageContainer, SearchResult + +# setup items to test +test_items = dict( + a=dict( + primary_agent='dev.lizardbyte.retroarcher-plex', + rating_key=1, + title='007 - GoldenEye (USA)', + year=1997, + id='{igdb-1638}', + category='games', + ), + b=dict( + primary_agent='com.plexapp.agents.themoviedb', + rating_key=2, + title='GoldenEye', + year=1995, + id='710', + category='movies', + ), + c=dict( + primary_agent='com.plexapp.agents.imdb', + rating_key=3, + title='GoldenEye', + year=1995, + id='tt0113189', + category='movies', + ) +) + + +def test_validate_prefs(): + result_container = ValidatePrefs() + assert isinstance(result_container, MessageContainer) + assert result_container.header == "Success" + assert "Provided preference values are ok" in result_container.message + + # invalidate prefs, cannot do this due to: + # TypeError: '_PreferenceSet' object does not support item assignment + # Code.Prefs['int_plexapi_plexapi_timeout'] = 'not an integer' + # result_container = ValidatePrefs() + # assert isinstance(result_container, MessageContainer) + # assert result_container.header == "Error" + # assert "must be an integer" in result_container.message + + # add a default pref and make sure it is not in DefaultPrefs.json + default_prefs['new_pref'] = 'new_value' + result_container = ValidatePrefs() + assert isinstance(result_container, MessageContainer) + assert result_container.header == "Error" + assert "missing from 'DefaultPrefs.json'" in result_container.message + + +def test_start(): + # todo + pass + + +def test_main(): + # todo + pass + + +def test_themerr_search(agent): + for key, item in test_items.items(): + media = Media.Movie() + media.primary_metadata = Movie() + + media.primary_agent = item['primary_agent'] + media.primary_metadata.id = item['id'] + media.primary_metadata.title = item['title'] + media.primary_metadata.year = item['year'] + + database = None + item_id = item['id'] + if item['category'] == 'games': + database = item['id'][1:-1].split('-')[0] + item_id = item['id'][1:-1].split('-')[-1] + elif item['category'] == 'movies': + database = item['primary_agent'].split('.')[-1] + + results = agent.search(results=SearchResult(), media=media, lang='en', manual=False) + + for result in results.__items__: + # print(result.__dict__) + assert result.name == item['title'] + assert result.year == item['year'] + assert result.id == "%s-%s-%s" % (item['category'], database, item_id) + + +def test_themerr_update(agent): + metadata = Movie() + + for key, item in test_items.items(): + media = Movie() + + database = None + item_id = item['id'] + if item['category'] == 'games': + database = item['id'][1:-1].split('-')[0] + item_id = item['id'][1:-1].split('-')[-1] + elif item['category'] == 'movies': + database = item['primary_agent'].split('.')[-1] + + media.id = item['rating_key'] + metadata.title = item['title'] + metadata.year = item['year'] + metadata.id = "%s-%s-%s" % (item['category'], database, item_id) + + # this won't actually upload a theme since we're not working with a real Plex Server + metadata = agent.update(metadata=metadata, media=media, lang='en', force=True) + + assert isinstance(metadata, Movie) diff --git a/tests/unit/test_youtube_dl_helper.py b/tests/unit/test_youtube_dl_helper.py new file mode 100644 index 00000000..15a9a68b --- /dev/null +++ b/tests/unit/test_youtube_dl_helper.py @@ -0,0 +1,26 @@ +# lib imports +import pytest +from youtube_dl import DownloadError + +# local imports +from Code import youtube_dl_helper + + +def test_process_youtube(): + # test valid urls + valid_urls = [ + 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', + ] + for url in valid_urls: + audio_url = youtube_dl_helper.process_youtube(url=url) + assert audio_url is not None + assert audio_url.startswith('https://') + + # test invalid urls + invalid_urls = [ + 'https://www.youtube.com/watch?v=notavideoid', + 'https://blahblahblah', + ] + for url in invalid_urls: + with pytest.raises(DownloadError): + youtube_dl_helper.process_youtube(url=url)