+
+
Title: {posted_title}
+
https://ddownload.com/example
+
+
+ """
+ with patch(
+ "quasarr.search.sources.dl._fetch_thread_page",
+ return_value=FakeResponse(
+ html, "https://www.source.invalid/thread.1/"
+ ),
+ ):
+ release = _date_release_from_thread(
+ FakeSharedState(),
+ "https://www.source.invalid/thread.1/",
+ search_string,
+ episode_date,
+ )
+
+ self.assertEqual(expected_title, release["title"])
+
def test_matches_compact_ct_style_spelling(self):
current_year = datetime.now().year
diff --git a/tests/test_hostname_capabilities.py b/tests/test_hostname_capabilities.py
index ec8c2186..4e7b24d0 100644
--- a/tests/test_hostname_capabilities.py
+++ b/tests/test_hostname_capabilities.py
@@ -1,5 +1,7 @@
+import inspect
import unittest
+from quasarr.constants import SEARCH_CAT_SHOWS
from quasarr.providers.html_images import FLAG_SVGS, LANGUAGE_FLAG_EMOJI
from quasarr.search.sources import get_sources
from quasarr.search.sources.helpers import get_source_metadata
@@ -30,6 +32,48 @@ def test_flag_assets_cover_every_used_language(self):
self.assertIn(language, LANGUAGE_FLAG_EMOJI)
self.assertIn(language, FLAG_SVGS)
+ def test_date_numbering_sources_accept_shared_date_context(self):
+ for key, source in get_sources().items():
+ if (
+ SEARCH_CAT_SHOWS not in source.supported_categories
+ or not source.supports_date_numbering
+ ):
+ continue
+ with self.subTest(source=key):
+ self.assertIn(
+ "episode_date",
+ inspect.signature(source.search).parameters,
+ )
+
+ def test_date_numbering_enabled_for_all_compatible_tv_sources(self):
+ expected = {
+ "by",
+ "dd",
+ "dj",
+ "dl",
+ "dt",
+ "dw",
+ "fx",
+ "he",
+ "hs",
+ "mb",
+ "nk",
+ "nx",
+ "rm",
+ "sf",
+ "sj",
+ "sl",
+ "wd",
+ "wx",
+ }
+ actual = {
+ key
+ for key, source in get_sources().items()
+ if SEARCH_CAT_SHOWS in source.supported_categories
+ and source.supports_date_numbering
+ }
+ self.assertEqual(expected, actual)
+
class SourceMetadataTests(unittest.TestCase):
def test_metadata_exposes_expected_keys_for_every_source(self):
diff --git a/tests/test_utils_release_matching.py b/tests/test_utils_release_matching.py
index fc358a71..f104d0ff 100644
--- a/tests/test_utils_release_matching.py
+++ b/tests/test_utils_release_matching.py
@@ -1,9 +1,16 @@
# -*- coding: utf-8 -*-
import unittest
+from datetime import date
from quasarr.constants import SEARCH_CAT_SHOWS
-from quasarr.providers.utils import is_valid_release, normalize_optional_int
+from quasarr.providers.utils import (
+ canonicalize_date_numbered_title,
+ date_numbering_search_strings,
+ is_valid_release,
+ normalize_optional_int,
+ parse_episode_date,
+)
class ReleaseMatchingUtilsTests(unittest.TestCase):
@@ -14,33 +21,93 @@ def test_normalize_optional_int_parses_numbers(self):
self.assertEqual(4, normalize_optional_int("4"))
def test_date_numbered_tv_release_matches_date_components(self):
+ episode_date = date(2031, 6, 19)
self.assertTrue(
is_valid_release(
- "Sample.Show.2026.06.19.1080p.WEB.h264-GRP",
+ "Sample.Show.2031.06.19.1080p.WEB.h264-GRP",
SEARCH_CAT_SHOWS,
"Sample Show",
- season=2026,
+ season=2031,
episode="06/19",
- episode_year=2026,
- episode_month=6,
- episode_day=19,
+ episode_date=episode_date,
)
)
def test_date_numbered_tv_release_rejects_wrong_date(self):
+ episode_date = date(2031, 6, 19)
self.assertFalse(
is_valid_release(
- "Sample.Show.2026.06.18.1080p.WEB.h264-GRP",
+ "Sample.Show.2031.06.18.1080p.WEB.h264-GRP",
SEARCH_CAT_SHOWS,
"Sample Show",
- season=2026,
+ season=2031,
episode="06/19",
- episode_year=2026,
- episode_month=6,
- episode_day=19,
+ episode_date=episode_date,
)
)
+ def test_date_numbered_tv_release_accepts_verified_imdb_search(self):
+ episode_date = date(2031, 6, 19)
+ self.assertTrue(
+ is_valid_release(
+ "Sample.Show.2031.06.19.1080p.WEB.h264-GRP",
+ SEARCH_CAT_SHOWS,
+ "tt0000001",
+ season=2031,
+ episode="06/19",
+ episode_date=episode_date,
+ )
+ )
+
+ def test_parse_episode_date_validates_calendar_date(self):
+ self.assertEqual(date(2031, 2, 3), parse_episode_date(2031, "02/03"))
+ self.assertIsNone(parse_episode_date(2031, "02/30"))
+ self.assertIsNone(parse_episode_date(2031, "2"))
+
+ def test_date_numbering_canonicalizes_generic_scheduled_title(self):
+ episode_date = date(2031, 2, 3)
+ self.assertEqual(
+ "Sample.Monday.Night.Showcase.2031.02.03.1080p-GRP",
+ canonicalize_date_numbered_title(
+ "Sample.Showcase.2031.02.03.1080p-GRP",
+ "Sample Monday Night Showcase",
+ episode_date,
+ ),
+ )
+
+ def test_wwe_raw_uses_generic_schedule_alias_and_canonical_title(self):
+ episode_date = date(2031, 2, 3)
+ search_strings = date_numbering_search_strings(
+ "WWE Monday Night RAW", episode_date
+ )
+
+ self.assertIn("WWE RAW 2031.02.03", search_strings)
+ self.assertEqual(
+ "WWE.Monday.Night.RAW.2031.02.03.1080p-GRP",
+ canonicalize_date_numbered_title(
+ "WWE.RAW.2031.02.03.1080p-GRP",
+ "WWE Monday Night RAW",
+ episode_date,
+ ),
+ )
+
+ def test_wwe_smackdown_uses_generic_schedule_and_case_variants(self):
+ episode_date = date(2031, 2, 3)
+ search_strings = date_numbering_search_strings(
+ "WWE Friday Night SmackDown", episode_date
+ )
+
+ self.assertIn("WWE SmackDown 2031.02.03", search_strings)
+ self.assertIn("WWE Smackdown 2031.02.03", search_strings)
+ self.assertEqual(
+ "WWE.Friday.Night.SmackDown.2031.02.03.1080p-GRP",
+ canonicalize_date_numbered_title(
+ "WWE.SmackDown.2031.02.03.1080p-GRP",
+ "WWE Friday Night SmackDown",
+ episode_date,
+ ),
+ )
+
if __name__ == "__main__":
unittest.main()