Skip to content

Commit cb6dcc6

Browse files
whiteki08jxxghp
authored andcommitted
refactor jellyfin module load logic in unittest
1 parent 43c421b commit cb6dcc6

1 file changed

Lines changed: 88 additions & 77 deletions

File tree

tests/test_jellyfin.py

Lines changed: 88 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -8,89 +8,94 @@
88

99
def _load_jellyfin_module():
1010
module_name = "_test_jellyfin_module"
11-
if module_name in sys.modules:
12-
return sys.modules[module_name]
13-
14-
if "app.log" not in sys.modules:
15-
log_module = types.ModuleType("app.log")
16-
17-
class _Logger:
18-
def info(self, *_args, **_kwargs):
19-
pass
20-
21-
def warning(self, *_args, **_kwargs):
22-
pass
23-
24-
def error(self, *_args, **_kwargs):
25-
pass
26-
27-
def debug(self, *_args, **_kwargs):
28-
pass
29-
30-
log_module.logger = _Logger()
31-
sys.modules["app.log"] = log_module
32-
33-
if "app.core.config" not in sys.modules:
34-
config_module = types.ModuleType("app.core.config")
35-
config_module.settings = types.SimpleNamespace(SUPERUSER="admin", USER_AGENT="MoviePilot")
36-
sys.modules["app.core.config"] = config_module
37-
38-
if "app.schemas" not in sys.modules:
39-
schemas_module = types.ModuleType("app.schemas")
40-
schemas_module.MediaType = types.SimpleNamespace(MOVIE=types.SimpleNamespace(value="movie"))
41-
schemas_module.MediaServerItem = object
42-
schemas_module.MediaServerLibrary = object
43-
schemas_module.Statistic = object
44-
schemas_module.WebhookEventInfo = object
45-
schemas_module.MediaServerItemUserState = object
46-
schemas_module.MediaServerPlayItem = object
47-
sys.modules["app.schemas"] = schemas_module
48-
49-
if "app.utils.http" not in sys.modules:
50-
http_module = types.ModuleType("app.utils.http")
51-
52-
class _RequestUtils:
53-
def __init__(self, *args, **kwargs):
54-
pass
55-
56-
def get_res(self, *args, **kwargs):
57-
return None
58-
59-
http_module.RequestUtils = _RequestUtils
60-
sys.modules["app.utils.http"] = http_module
61-
62-
if "app.utils.url" not in sys.modules:
63-
url_module = types.ModuleType("app.utils.url")
64-
65-
class _UrlUtils:
66-
@staticmethod
67-
def standardize_base_url(host):
68-
if not host:
69-
return host
70-
if not host.endswith("/"):
71-
host += "/"
72-
if not host.startswith("http://") and not host.startswith("https://"):
73-
host = "http://" + host
11+
app_module = types.ModuleType("app")
12+
core_module = types.ModuleType("app.core")
13+
utils_module = types.ModuleType("app.utils")
14+
log_module = types.ModuleType("app.log")
15+
config_module = types.ModuleType("app.core.config")
16+
schemas_module = types.ModuleType("app.schemas")
17+
http_module = types.ModuleType("app.utils.http")
18+
url_module = types.ModuleType("app.utils.url")
19+
20+
class _Logger:
21+
def info(self, *_args, **_kwargs):
22+
pass
23+
24+
def warning(self, *_args, **_kwargs):
25+
pass
26+
27+
def error(self, *_args, **_kwargs):
28+
pass
29+
30+
def debug(self, *_args, **_kwargs):
31+
pass
32+
33+
class _RequestUtils:
34+
def __init__(self, *args, **kwargs):
35+
pass
36+
37+
def get_res(self, *args, **kwargs):
38+
return None
39+
40+
class _UrlUtils:
41+
@staticmethod
42+
def standardize_base_url(host):
43+
if not host:
7444
return host
75-
76-
@staticmethod
77-
def combine_url(host, path=None, query=None):
78-
from urllib.parse import urljoin
79-
80-
if path is None:
81-
path = "/"
82-
host = _UrlUtils.standardize_base_url(host)
83-
return urljoin(host, path)
84-
85-
url_module.UrlUtils = _UrlUtils
86-
sys.modules["app.utils.url"] = url_module
45+
if not host.endswith("/"):
46+
host += "/"
47+
if not host.startswith("http://") and not host.startswith("https://"):
48+
host = "http://" + host
49+
return host
50+
51+
@staticmethod
52+
def combine_url(host, path=None, query=None):
53+
from urllib.parse import urljoin
54+
55+
if path is None:
56+
path = "/"
57+
host = _UrlUtils.standardize_base_url(host)
58+
return urljoin(host, path)
59+
60+
log_module.logger = _Logger()
61+
config_module.settings = types.SimpleNamespace(SUPERUSER="admin", USER_AGENT="MoviePilot")
62+
schemas_module.MediaType = types.SimpleNamespace(MOVIE=types.SimpleNamespace(value="movie"))
63+
schemas_module.MediaServerItem = object
64+
schemas_module.MediaServerLibrary = object
65+
schemas_module.Statistic = object
66+
schemas_module.WebhookEventInfo = object
67+
schemas_module.MediaServerItemUserState = object
68+
schemas_module.MediaServerPlayItem = object
69+
http_module.RequestUtils = _RequestUtils
70+
url_module.UrlUtils = _UrlUtils
71+
72+
app_module.schemas = schemas_module
73+
app_module.log = log_module
74+
app_module.core = core_module
75+
app_module.utils = utils_module
76+
core_module.config = config_module
77+
utils_module.http = http_module
78+
utils_module.url = url_module
79+
80+
stub_modules = {
81+
"app": app_module,
82+
"app.log": log_module,
83+
"app.core": core_module,
84+
"app.core.config": config_module,
85+
"app.schemas": schemas_module,
86+
"app.utils": utils_module,
87+
"app.utils.http": http_module,
88+
"app.utils.url": url_module,
89+
}
90+
for stub_module in stub_modules.values():
91+
stub_module._jellyfin_test_stub = True
8792

8893
jellyfin_path = Path(__file__).resolve().parents[1] / "app" / "modules" / "jellyfin" / "jellyfin.py"
8994
spec = importlib.util.spec_from_file_location(module_name, jellyfin_path)
9095
module = importlib.util.module_from_spec(spec)
91-
sys.modules[module_name] = module
9296
assert spec and spec.loader
93-
spec.loader.exec_module(module)
97+
with patch.dict(sys.modules, stub_modules):
98+
spec.loader.exec_module(module)
9499
return module
95100

96101

@@ -107,6 +112,12 @@ def json(self):
107112

108113

109114
class JellyfinUserResolutionTest(unittest.TestCase):
115+
def test_loader_does_not_leave_stub_modules_in_sys_modules(self):
116+
self.assertNotIn("_test_jellyfin_module", sys.modules)
117+
self.assertFalse(getattr(sys.modules.get("app.log"), "_jellyfin_test_stub", False))
118+
self.assertFalse(getattr(sys.modules.get("app.core.config"), "_jellyfin_test_stub", False))
119+
self.assertFalse(getattr(sys.modules.get("app.utils.http"), "_jellyfin_test_stub", False))
120+
110121
def _build_client(self) -> Jellyfin:
111122
client = Jellyfin.__new__(Jellyfin)
112123
client._host = "http://jellyfin.local:8096"

0 commit comments

Comments
 (0)