From 2d36b461cf0b3f2bd5101cdd1c87dc415c9ee5cc Mon Sep 17 00:00:00 2001 From: pixelpaws Date: Sun, 5 Oct 2025 14:43:21 +0800 Subject: [PATCH] test(utils): add coverage for helper utilities --- tests/utils/test_file_utils.py | 51 +++++++++++++++++++++++++++++++ tests/utils/test_lora_metadata.py | 45 +++++++++++++++++++++++++++ tests/utils/test_utils.py | 38 ++++++++++++++++++++++- 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 tests/utils/test_file_utils.py create mode 100644 tests/utils/test_lora_metadata.py diff --git a/tests/utils/test_file_utils.py b/tests/utils/test_file_utils.py new file mode 100644 index 00000000..df75c764 --- /dev/null +++ b/tests/utils/test_file_utils.py @@ -0,0 +1,51 @@ +import hashlib +import os + +import pytest + +from py.utils.file_utils import ( + calculate_sha256, + find_preview_file, + get_preview_extension, +) + + +@pytest.mark.asyncio +async def test_calculate_sha256(tmp_path): + file_path = tmp_path / "sample.bin" + file_path.write_bytes(b"test-bytes") + + expected_hash = hashlib.sha256(b"test-bytes").hexdigest() + + result = await calculate_sha256(str(file_path)) + + assert result == expected_hash + + +def test_find_preview_file_returns_normalized_path(tmp_path): + file_path = tmp_path / "model.preview.png" + file_path.write_bytes(b"") + + result = find_preview_file("model", str(tmp_path)) + + assert result == str(file_path).replace(os.sep, "/") + + +def test_find_preview_file_supports_example_extension(tmp_path): + file_path = tmp_path / "model.example.0.jpeg" + file_path.write_bytes(b"") + + result = find_preview_file("model", str(tmp_path)) + + assert result == str(file_path).replace(os.sep, "/") + + +@pytest.mark.parametrize( + "preview_name,expected", + [ + ("/path/to/model.preview.png", ".preview.png"), + ("/path/to/model.png", ".png"), + ], +) +def test_get_preview_extension(preview_name, expected): + assert get_preview_extension(preview_name) == expected diff --git a/tests/utils/test_lora_metadata.py b/tests/utils/test_lora_metadata.py new file mode 100644 index 00000000..b9c46a3e --- /dev/null +++ b/tests/utils/test_lora_metadata.py @@ -0,0 +1,45 @@ +import pytest + +from py.utils import lora_metadata + + +class DummySafeOpen: + def __init__(self, metadata): + self._metadata = metadata + + def __enter__(self): + return self + + def __exit__(self, *args): + return False + + def metadata(self): + return self._metadata + + +@pytest.mark.asyncio +async def test_extract_lora_metadata_returns_base_model(monkeypatch, tmp_path): + file_path = tmp_path / "model.safetensors" + file_path.write_bytes(b"") + + monkeypatch.setattr( + lora_metadata, + "safe_open", + lambda *args, **kwargs: DummySafeOpen({"ss_base_model_version": "sdxl"}), + ) + + metadata = await lora_metadata.extract_lora_metadata(str(file_path)) + + assert metadata == {"base_model": "SDXL 1.0"} + + +@pytest.mark.asyncio +async def test_extract_lora_metadata_handles_errors(monkeypatch): + def raising_safe_open(*_, **__): + raise RuntimeError("boom") + + monkeypatch.setattr(lora_metadata, "safe_open", raising_safe_open) + + metadata = await lora_metadata.extract_lora_metadata("missing.safetensors") + + assert metadata == {"base_model": "Unknown"} diff --git a/tests/utils/test_utils.py b/tests/utils/test_utils.py index 8d1d2e93..71013918 100644 --- a/tests/utils/test_utils.py +++ b/tests/utils/test_utils.py @@ -1,7 +1,10 @@ import pytest from py.services.settings_manager import settings -from py.utils.utils import calculate_relative_path_for_model +from py.utils.utils import ( + calculate_recipe_fingerprint, + calculate_relative_path_for_model, +) @pytest.fixture @@ -32,3 +35,36 @@ def test_calculate_relative_path_for_embedding_replaces_spaces(isolated_settings relative_path = calculate_relative_path_for_model(model_data, "embedding") assert relative_path == "Base_Model/tag_with_space" + + +def test_calculate_relative_path_for_model_uses_mappings_and_defaults(isolated_settings): + isolated_settings["download_path_templates"]["lora"] = "{base_model}/{first_tag}/{author}" + isolated_settings["base_model_path_mappings"] = {"SDXL": "SDXL-mapped"} + + model_data = { + "base_model": "SDXL", + "tags": [], + "civitai": {"id": 12, "creator": {"username": "Creator"}}, + } + + relative_path = calculate_relative_path_for_model(model_data, "lora") + + assert relative_path == "SDXL-mapped/no tags/Creator" + + +def test_calculate_recipe_fingerprint_filters_and_sorts(): + loras = [ + {"hash": "ABC", "strength": 0.1234}, + {"hash": "", "isDeleted": True, "modelVersionId": 42, "strength": 0.5}, + {"hash": "def", "weight": 0.345}, + {"hash": "skip", "exclude": True, "strength": 0.9}, + {"hash": "", "strength": 0.1}, + ] + + fingerprint = calculate_recipe_fingerprint(loras) + + assert fingerprint == "42:0.5|abc:0.12|def:0.34" + + +def test_calculate_recipe_fingerprint_empty_input(): + assert calculate_recipe_fingerprint([]) == ""