def setUp(self): self.db_path = tempfile.mkdtemp() self.datastore = CodernityDataStore(self.db_path)
class DataStoreTests(TestCase): def setUp(self): self.db_path = tempfile.mkdtemp() self.datastore = CodernityDataStore(self.db_path) def tearDown(self): self.datastore.close() rmtree(self.db_path) def test_newly_added_video_has_no_downloads(self): path = "/data/Series/Season 1/01 Title.mkv" video = Video.fromname("Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv") self.datastore.add_video(path, video) downloads = self.datastore.get_downloads_for_video(path) self.assertEqual(downloads, {}) def test_added_sub_is_returned(self): path = "/data/Series/Season 1/01 Title.mkv" video = Video.fromname("Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv") self.datastore.add_video(path, video) provider = "davessubs" sub_id = "ABC123" lang = Language.fromietf("en") score = 123 self.datastore.add_download(path, provider, sub_id, lang, score) downloads = self.datastore.get_downloads_for_video(path) self.assertEqual(downloads, {lang: [{"provider": provider, "sub_id": sub_id, "lang": lang, "score": score}]}) def test_added_subs_are_returned_by_lang(self): path = "/data/Series/Season 1/01 Title.mkv" video = Video.fromname("Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv") self.datastore.add_video(path, video) provider1 = "davessubs" sub_id1 = "ABC123" lang1 = Language.fromietf("en") score1 = 123 provider2 = "stevesubs" sub_id2 = "steve123" lang2 = lang1 score2 = 120 provider3 = "pablosubs" sub_id3 = "umdoistres" lang3 = Language.fromietf("pt-BR") score3 = 150 self.datastore.add_download(path, provider1, sub_id1, lang1, score1) self.datastore.add_download(path, provider2, sub_id2, lang2, score2) self.datastore.add_download(path, provider3, sub_id3, lang3, score3) downloads = self.datastore.get_downloads_for_video(path) self.assertEqual( downloads, { lang1: [ {"provider": provider1, "sub_id": sub_id1, "lang": lang1, "score": score1}, {"provider": provider2, "sub_id": sub_id2, "lang": lang2, "score": score2}, ], lang3: [{"provider": provider3, "sub_id": sub_id3, "lang": lang3, "score": score3}], }, ) def test_replacing_video_for_path_removes_downloads(self): path = "/data/Series/Season 1/01 Title.mkv" video = Video.fromname("Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv") self.datastore.add_video(path, video) provider = "davessubs" sub_id = "ABC123" lang = Language.fromietf("en") score = 123 self.datastore.add_download(path, provider, sub_id, lang, score) video2 = Video.fromname("Series.S01E02.Title.720p.BDRip-ReleaseGroup2.mkv") self.datastore.add_video(path, video) downloads = self.datastore.get_downloads_for_video(path) self.assertEqual(downloads, {}) def test_get_incomplete_videos_returns_nothing_when_no_videos_exist(self): lang = Language.fromietf("en") incomplete = self.datastore.get_incomplete_videos([lang], 100, 100, datetime.utcnow() - timedelta(days=1)) @parameterized.expand( [ ("no videos returns empty", [], []), ( "video with no downloads returns all languages", [ { "path": "/data/Series/Season 1/02 Title.mkv", "name": "Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [], } ], [(0, [("en", 0), ("pt-BR", 0)])], ), ( "excludes languages with downloads >= desired", [ { "path": "/data/Series/Season 1/02 Title.mkv", "name": "Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [("davesubs", "ds123", "en", 100)], } ], [(0, [("pt-BR", 0)])], ), ( "excludes video when all languages have downloads >= desired", [ { "path": "/data/Series/Season 1/02 Title.mkv", "name": "Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [("davesubs", "ds123", "en", 100), ("pablosubs", "ps16", "pt-BR", 123)], } ], [], ), ( "includes languages with downloads < desired", [ { "path": "/data/Series/Season 1/02 Title.mkv", "name": "Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [("davesubs", "ds123", "en", 100), ("pablosubs", "ps16", "pt-BR", 80)], } ], [(0, [("pt-BR", 80)])], ), ( "returns highest score for language when multiple downloads found", [ { "path": "/data/Series/Season 1/02 Title.mkv", "name": "Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [ ("davesubs", "ds123", "en", 100), ("pablosubs", "ps16", "pt-BR", 83), ("pablosubs", "ps22", "pt-BR", 80), ], } ], [(0, [("pt-BR", 83)])], ), ( "excludes language if any score >= desired", [ { "path": "/data/Series/Season 1/02 Title.mkv", "name": "Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [ ("davesubs", "ds123", "en", 100), ("stevesubs", "steve69", "en", 83), ("pablosubs", "ps22", "pt-BR", 80), ], } ], [(0, [("pt-BR", 80)])], ), ( "uses different desired score for movies", [ { "path": "/data/Title (2016)/Title.mkv", "name": "Title.2016.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [("davesubs", "ds123", "en", 80), ("pablosubs", "ps16", "pt-BR", 79)], } ], [(0, [("pt-BR", 79)])], ), ( "returns multiple videos", [ { "path": "/data/Series/Season 1/02 Title.mkv", "name": "Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [("pablosubs", "ps16", "pt-BR", 80)], }, { "path": "/data/Series/Season 1/03 Title.mkv", "name": "Series.S01E03.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [("davesubs", "ds123", "en", 100)], }, ], [(0, [("en", 0), ("pt-BR", 80)]), (1, [("pt-BR", 0)])], ), ( "returns multiple videos", [ { "path": "/data/Series/Season 1/02 Title.mkv", "name": "Series.S01E02.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [], "age": timedelta(days=2), }, { "path": "/data/Series/Season 1/03 Title.mkv", "name": "Series.S01E03.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [("davesubs", "ds123", "en", 80)], "age": timedelta(days=2), }, { "path": "/data/Series/Season 1/03 Title.mkv", "name": "Series.S01E03.Title.720p.WEB-DL.DD5.1.H264-ReleaseGroup.mkv", "downloads": [], "age": timedelta(hours=23), }, ], [(2, [("en", 0), ("pt-BR", 0)])], ), ], testcase_func_name=lambda func, num, param: "%s_%s" % (func.__name__, parameterized.to_safe_name(param.args[0])), ) def test_get_incomplete_videos(self, name, videos, expected): for video in videos: added = datetime.utcnow() - video["age"] if "age" in video else timedelta(0) self.datastore.add_video(video["path"], Video.fromname(video["name"]), added) for provider, sub_id, lang, score in video["downloads"]: self.datastore.add_download(video["path"], provider, sub_id, Language.fromietf(lang), score) lang1 = Language.fromietf("en") lang2 = Language.fromietf("pt-BR") incomplete = self.datastore.get_incomplete_videos( [lang1, lang2], 80, 100, datetime.utcnow() - timedelta(days=1) ) self.assertEqual(len(incomplete), len(expected)) for video_idx, needs in expected: actual = next(video for video in incomplete if video["path"] == videos[video_idx]["path"]) self.assertEqual(actual["video"].name, videos[video_idx]["name"]) self.assertEqual(len(actual["needs"]), len(needs)) for lang, score in needs: actual_need = next(need for need in actual["needs"] if str(need["lang"]) == lang) self.assertEqual(actual_need["current_score"], score)