1"""
2tests.test_nzbstuff - Testing functions in nzbstuff.py
3"""
4import sabnzbd.nzbstuff as nzbstuff
5from sabnzbd.config import ConfigCat
6from sabnzbd.constants import NORMAL_PRIORITY
7from sabnzbd.filesystem import globber
8
9from tests.testhelper import *
10
11
12@pytest.mark.usefixtures("clean_cache_dir")
13class TestNZO:
14    @set_config({"download_dir": SAB_CACHE_DIR})
15    def test_nzo_basic(self):
16        # Need to create the Default category, as we would in normal instance
17        # Otherwise it will try to save the config
18        def_cat = ConfigCat("*", {"pp": 3, "script": "None", "priority": NORMAL_PRIORITY})
19
20        # Create empty object, normally used to grab URL's
21        nzo = nzbstuff.NzbObject("test_basic")
22        assert nzo.work_name == "test_basic"
23        assert not nzo.files
24        assert not nzo.created
25
26        # Create NZB-file to import
27        nzb_data = create_and_read_nzb("basic_rar5")
28
29        # Very basic test of NZO creation with data
30        nzo = nzbstuff.NzbObject("test_basic_data", nzb=nzb_data)
31        assert nzo.final_name == "test_basic_data"
32        assert nzo.files
33        assert nzo.files[0].filename == "testfile.rar"
34        assert nzo.bytes == 120
35        assert nzo.files[0].bytes == 120
36
37        # work_name can be trimmed in Windows due to max-path-length
38        assert "test_basic_data".startswith(nzo.work_name)
39        assert os.path.exists(nzo.admin_path)
40
41        # Check if there's an nzf file and the backed-up nzb
42        assert globber(nzo.admin_path, "*.nzb.gz")
43        assert globber(nzo.admin_path, "SABnzbd_nzf*")
44
45        # Should have picked up the default category settings
46        assert nzo.cat == "*"
47        assert nzo.script == def_cat.script() == "None"
48        assert nzo.priority == def_cat.priority() == NORMAL_PRIORITY
49        assert nzo.repair and nzo.unpack and nzo.delete
50
51        # TODO: More checks!
52
53
54class TestNZBStuffHelpers:
55    @pytest.mark.parametrize(
56        "argument, name, password",
57        [
58            ("my_awesome_nzb_file{{password}}", "my_awesome_nzb_file", "password"),
59            ("file_with_text_after_pw{{passw0rd}}_[180519]", "file_with_text_after_pw", "passw0rd"),
60            ("file_without_pw", "file_without_pw", None),
61            ("multiple_pw{{first-pw}}_{{second-pw}}", "multiple_pw", "first-pw}}_{{second-pw"),  # Greed is Good
62            ("デビアン", "デビアン", None),  # Unicode
63            ("Gentoo_Hobby_Edition {{secret}}", "Gentoo_Hobby_Edition", "secret"),  # Space between name and password
64            ("Mandrake{{top{{secret}}", "Mandrake", "top{{secret"),  # Double opening {{
65            ("Красная}}{{Шляпа}}", "Красная}}", "Шляпа"),  # Double closing }}
66            ("{{Jobname{{PassWord}}", "{{Jobname", "PassWord"),  # {{ at start
67            ("Hello/kITTY", "Hello", "kITTY"),  # Notation with slash
68            ("/Jobname", "/Jobname", None),  # Slash at start
69            ("Jobname/Top{{Secret}}", "Jobname", "Top{{Secret}}"),  # Slash with braces
70            ("Jobname / Top{{Secret}}", "Jobname", "Top{{Secret}}"),  # Slash with braces and extra spaces
71            ("לינוקס/معلومات سرية", "לינוקס", "معلومات سرية"),  # LTR with slash
72            ("לינוקס{{معلومات سرية}}", "לינוקס", "معلومات سرية"),  # LTR with brackets
73            ("thư điện tử password=mật_khẩu", "thư điện tử", "mật_khẩu"),  # Password= notation
74            ("password=PartOfTheJobname", "password=PartOfTheJobname", None),  # Password= at the start
75            ("Job}}Name{{FTW", "Job}}Name{{FTW", None),  # Both {{ and }} present but incorrect order (no password)
76            ("./Text", "./Text", None),  # Name would end up empty after the function strips the dot
77        ],
78    )
79    def test_scan_password(self, argument, name, password):
80        assert nzbstuff.scan_password(argument) == (name, password)
81
82    def test_create_work_name(self):
83        # Only test stuff specific for create_work_name
84        # The sanitizing is already tested in tests for sanitize_foldername
85        file_names = {
86            "my_awesome_nzb_file.pAr2.nZb": "my_awesome_nzb_file",
87            "my_awesome_nzb_file.....pAr2.nZb": "my_awesome_nzb_file",
88            "my_awesome_nzb_file....par2..": "my_awesome_nzb_file",
89            " my_awesome_nzb_file  .pAr.nZb": "my_awesome_nzb_file",
90            "with.extension.and.period.par2.": "with.extension.and.period",
91            "nothing.in.here": "nothing.in.here",
92            "  just.space  ": "just.space",
93            "http://test.par2  ": "http://test.par2",
94        }
95
96        for file_name, clean_file_name in file_names.items():
97            assert nzbstuff.create_work_name(file_name) == clean_file_name
98
99    @pytest.mark.parametrize(
100        "subject, filename",
101        [
102            ('Great stuff (001/143) - "Filename.txt" yEnc (1/1)', "Filename.txt"),
103            (
104                '"910a284f98ebf57f6a531cd96da48838.vol01-03.par2" yEnc (1/3)',
105                "910a284f98ebf57f6a531cd96da48838.vol01-03.par2",
106            ),
107            ('Subject-KrzpfTest [02/30] - ""KrzpfTest.part.nzb"" yEnc', "KrzpfTest.part.nzb"),
108            (
109                '[PRiVATE]-[WtFnZb]-[Supertje-_S03E11-12_-blabla_+_blabla_WEBDL-480p.mkv]-[4/12] - "" yEnc 9786 (1/1366)',
110                "Supertje-_S03E11-12_-blabla_+_blabla_WEBDL-480p.mkv",
111            ),
112            (
113                '[N3wZ] MAlXD245333\\::[PRiVATE]-[WtFnZb]-[Show.S04E04.720p.AMZN.WEBRip.x264-GalaxyTV.mkv]-[1/2] - "" yEnc  293197257 (1/573)',
114                "Show.S04E04.720p.AMZN.WEBRip.x264-GalaxyTV.mkv",
115            ),
116            (
117                'reftestnzb bf1664007a71 [1/6] - "20b9152c-57eb-4d02-9586-66e30b8e3ac2" yEnc (1/22) 15728640',
118                "20b9152c-57eb-4d02-9586-66e30b8e3ac2",
119            ),
120            (
121                "Re: REQ Author Child's The Book-Thanks much - Child, Lee - Author - The Book.epub (1/1)",
122                "REQ Author Child's The Book-Thanks much - Child, Lee - Author - The Book.epub",
123            ),
124            ('63258-0[001/101] - "63258-2.0" yEnc (1/250) (1/250)', "63258-2.0"),
125            (
126                "Singer - A Album (2005) - [04/25] - 02 Sweetest Somebody (I Know).flac",
127                "- 02 Sweetest Somebody (I Know).flac",
128            ),
129            ("<>random!>", "<>random!>"),
130            ("nZb]-[Supertje-_S03E11-12_", "nZb]-[Supertje-_S03E11-12_"),
131            ("Bla [Now it's done.exe]", "Now it's done.exe"),
132            (
133                '[PRiVATE]-[WtFnZb]-[Video_(2001)_AC5.1_-RELEASE_[TAoE].mkv]-[1/23] - "" yEnc 1234567890 (1/23456)',
134                '[PRiVATE]-[WtFnZb]-[Video_(2001)_AC5.1_-RELEASE_[TAoE].mkv]-[1/23] - "" yEnc 1234567890 (1/23456)',
135            ),
136        ],
137    )
138    def test_name_extractor(self, subject, filename):
139        assert nzbstuff.name_extractor(subject) == filename
140