Files
telegram-downloader/tests/utils/test_format.py
T
yuming cf40343c51
部署到群晖 / deploy (push) Failing after 10m45s
初始化 telegram-downloader 并接入群晖 CI/CD
2026-04-22 21:29:03 +08:00

256 lines
8.5 KiB
Python

"""Unittest module for media downloader."""
import os
import sys
import unittest
from dataclasses import asdict
from unittest.mock import patch
from utils.format import (
Link,
create_progress_bar,
extract_info_from_link,
format_byte,
get_byte_from_str,
replace_date_time,
truncate_filename,
validate_title,
)
sys.path.append("..") # Adds higher directory to python modules path.
class FormatTestCase(unittest.TestCase):
def test_format_byte(self):
byte_list = [
"KB",
"MB",
"GB",
"TB",
"PB",
"EB",
"ZB",
"YB",
"BB",
"NB",
"DB",
"CB",
]
self.assertEqual(format_byte(0.1), "0.8b")
self.assertEqual(format_byte(1), "1B")
for i, value in enumerate(byte_list):
self.assertEqual(format_byte(pow(1024, i + 1)), "1.0" + value)
try:
format_byte(-1)
except Exception as e:
self.assertEqual(isinstance(e, ValueError), True)
def test_replace_date_time(self):
self.assertEqual(
replace_date_time(""),
"",
)
# split by '.'
self.assertEqual(
replace_date_time("xxxxx 2020.03.08 xxxxxxxxx"),
"xxxxx 2020-03-08 00:00:00 xxxxxxxxx",
)
# split by '-'
self.assertEqual(
replace_date_time("xxxxx 2020-03-08 xxxxxxxxxxxx"),
"xxxxx 2020-03-08 00:00:00 xxxxxxxxxxxx",
)
# split by '/'
self.assertEqual(
replace_date_time("xasd as 2020/03/08 21321fszv"),
"xasd as 2020-03-08 00:00:00 21321fszv",
)
# more different date
self.assertEqual(
replace_date_time("xxxxx 2020.03.08 2020.03.09 14:51 xxxxxxxxx"),
"xxxxx 2020-03-08 00:00:00 2020-03-09 14:51:00 xxxxxxxxx",
)
# more space
self.assertEqual(
replace_date_time("xxxxx 2020.03.08 2020.03.09 14:51 xxxxxxxxx"),
"xxxxx 2020-03-08 00:00:00 2020-03-09 14:51:00 xxxxxxxxx",
)
# more date format
self.assertEqual(
replace_date_time("xasd as 2020/03 21321fszv"),
"xasd as 2020-03-01 00:00:00 21321fszv",
)
self.assertEqual(
replace_date_time("xasd as 2020-03 21321fszv"),
"xasd as 2020-03-01 00:00:00 21321fszv",
)
self.assertEqual(
replace_date_time("xasd as 2020.03 21321fszv"),
"xasd as 2020-03-01 00:00:00 21321fszv",
)
def test_get_byte_from_str(self):
# B
self.assertEqual(get_byte_from_str("2B"), 2)
# KB
self.assertEqual(get_byte_from_str("2KB"), 2 * 1024)
self.assertEqual(get_byte_from_str("1024KB"), 1024 * 1024)
self.assertEqual(get_byte_from_str("2024KB"), 2024 * 1024)
self.assertEqual(get_byte_from_str("4000KB"), 4000 * 1024)
# MB
self.assertEqual(get_byte_from_str("2MB"), 2 * 1024 * 1024)
self.assertEqual(get_byte_from_str("1024MB"), 1024 * 1024 * 1024)
# GB
self.assertEqual(get_byte_from_str("2GB"), 2 * 1024 * 1024 * 1024)
# TB
self.assertEqual(get_byte_from_str("2TB"), 2 * 1024 * 1024 * 1024 * 1024)
self.assertEqual(get_byte_from_str("1024TB"), 1024 * 1024 * 1024 * 1024 * 1024)
# more str
self.assertEqual(get_byte_from_str("2BW"), 2)
self.assertEqual(get_byte_from_str("2WBW"), None)
self.assertEqual(get_byte_from_str("2CB"), None)
def test_extract_info_from_link(self):
test_cases = [
("https://t.me/", Link(group_id=None)),
("https://t.me/username/1234", Link(group_id="username", post_id=1234)),
("https://t.me/username", Link(group_id="username")),
("https://t.me/c/213213/91011", Link(group_id=-100213213, post_id=91011)),
(
"https://t.me/test123/1/1234",
Link(group_id="test123", topic_id=1, post_id=1234),
),
("me", Link(group_id="me")),
("self", Link(group_id="self")),
(
"https://t.me/opencfdchannel/4434?comment=360409",
Link(group_id="opencfdchannel", comment_id=360409),
),
("https://t.me/telegram/193", Link(group_id="telegram", post_id=193)),
(
"https://t.me/c/1697797156/151",
Link(group_id=-1001697797156, post_id=151),
),
(
"https://t.me/iFreeKnow/45662/55005",
Link(group_id="iFreeKnow", topic_id=45662, post_id=55005),
),
(
"https://t.me/c/1492447836/251015/251021",
Link(group_id=-1001492447836, topic_id=251015, post_id=251021),
),
]
for link, expected in test_cases:
result = extract_info_from_link(link)
self.assertEqual(asdict(result), asdict(expected))
def test_create_progress_bar(self):
progress = 50
progress_bar = create_progress_bar(progress)
self.assertEqual(progress_bar, "█████░░░░░")
def test_create_progress_bar_with_custom_bars(self):
progress = 75
total_bars = 20
progress_bar = create_progress_bar(progress, total_bars)
self.assertEqual(progress_bar, "███████████████░░░░░")
class TestTruncateFilename(unittest.TestCase):
def test_truncate_filename(self):
test_cases = [
("testfile.txt", 240, "testfile.txt"),
("testfile.txt", 5, "t.txt"),
("a" * 240 + ".txt", 240, "a" * 236 + ".txt"),
("a" * 241 + ".txt", 240, "a" * 236 + ".txt"),
]
for path, limit, expected in test_cases:
self.assertEqual(truncate_filename(path, limit), expected)
@unittest.skipIf(sys.platform.startswith("win"), "requires Unix-based system")
def test_linux_filename_too_long(self):
long_filename = "a" * 265 + ".txt"
with self.assertRaises(OSError):
with open(long_filename, "w") as f:
f.write("test")
long_filename = "a" * 265 + ".txt"
long_filename = truncate_filename(long_filename) + ".temp"
try:
with open(long_filename, "w") as f:
f.write("test")
os.remove(long_filename)
except Exception:
self.assertEqual(False, True)
@unittest.skipIf(not sys.platform.startswith("win"), "requires Windows system")
def test_windows_filename_too_long(self):
long_filename = "a" * 265 + ".txt"
with self.assertRaises(OSError):
with open(long_filename, "w") as f:
f.write("test")
long_filename = "a" * 265 + ".txt"
long_filename = truncate_filename(long_filename) + ".temp"
try:
with open(long_filename, "w") as f:
f.write("test")
os.remove(long_filename)
except Exception:
self.assertEqual(False, True)
@patch("builtins.open", unittest.mock.mock_open())
def test_file_creation(self):
file_name = "a" * 240 + ".txt"
truncated_file_name = truncate_filename(file_name)
with open(truncated_file_name, "w") as f:
f.write("test")
open.assert_called_once_with(truncated_file_name, "w")
class TestValidateTitle(unittest.TestCase):
def test_validate_title(self):
test_cases = [
("Hello, World!", "Hello, World!"),
("Invalid/Title", "Invalid_Title"),
("File\\Name", "File_Name"),
("Colons:Are:Not:Allowed", "Colons_Are_Not_Allowed"),
("Asterisks*In*Title", "Asterisks_In_Title"),
("Question?Mark", "Question_Mark"),
('Double"Quotes', "Double_Quotes"),
("Less<Than", "Less_Than"),
("Greater>Than", "Greater_Than"),
("Pipe|Symbol", "Pipe_Symbol"),
("Multi\nLine", "Multi_Line"),
]
for title, expected in test_cases:
with self.subTest(title=title, expected=expected):
self.assertEqual(validate_title(title), expected)
@patch("utils.format.re.sub")
def test_mock_re_sub(self, mock_re_sub):
title = "Invalid/Title"
mock_re_sub.return_value = "Mocked_Title"
result = validate_title(title)
self.assertEqual(result, "Mocked_Title")
mock_re_sub.assert_called_once_with(r"[/\\:*?\"<>|\n]", "_", title)