From e0f57c22b1eade299867f9d006d0321fece6e8e7 Mon Sep 17 00:00:00 2001 From: Dariusz L Date: Fri, 7 Aug 2026 03:37:18 +0200 Subject: [PATCH] test: lock SHA256 source precedence --- tests/test_search_hash_methods.mjs | 7 +++++- tests/test_unified_helpers.py | 34 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/tests/test_search_hash_methods.mjs b/tests/test_search_hash_methods.mjs index cf1a160..a5c0c80 100644 --- a/tests/test_search_hash_methods.mjs +++ b/tests/test_search_hash_methods.mjs @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import test from 'node:test'; import { searchHashMethods } from '../web/resolver/search/search_hash_methods.js'; -import { getSha256Field, normalizeSha256 } from '../web/resolver/utils/hash_utils.js'; +import { firstValidSha256, getSha256Field, normalizeSha256 } from '../web/resolver/utils/hash_utils.js'; import { normalizeSourceKey } from '../web/resolver/utils/source_labels.js'; function createDialog(overrides = {}) { @@ -33,6 +33,11 @@ test('shared SHA-256 normalization preserves the accepted input contract', () => assert.equal(normalizeSha256(null), ''); }); +test('first valid SHA-256 helper preserves candidate order while skipping invalid values', () => { + assert.equal(firstValidSha256('invalid', `SHA256:${hashA.toUpperCase()}`, hashB), hashA); + assert.equal(firstValidSha256('invalid', '', null), ''); +}); + test('search hash normalization accepts SHA-256 prefixes and rejects invalid values', () => { const dialog = createDialog(); assert.equal(normalizeSha256(`sha256:${hashA.toUpperCase()}`), hashA); diff --git a/tests/test_unified_helpers.py b/tests/test_unified_helpers.py index 7043fa6..3846ec5 100644 --- a/tests/test_unified_helpers.py +++ b/tests/test_unified_helpers.py @@ -58,6 +58,40 @@ class UnifiedHelpersTests(unittest.TestCase): self.assertEqual("", extract_file_sha256({"hashes": []})) self.assertEqual("fallback", extract_file_sha256({"sha256": "", "hash": "fallback"})) + def test_extract_sha256_from_metadata_uses_first_valid_source(self): + preferred = "a" * 64 + fallback = "b" * 64 + + self.assertEqual( + preferred, + extract_sha256_from_metadata({ + "sha256": preferred, + "hash": fallback, + "hashes": {"SHA256": fallback}, + "file_info": {"sha256": fallback}, + }), + ) + self.assertEqual( + fallback, + extract_sha256_from_metadata({ + "sha256": "invalid", + "hash": fallback, + }), + ) + self.assertEqual( + preferred, + extract_sha256_from_metadata({ + "sha256": "invalid", + "hashes": {"SHA256": preferred, "sha256": fallback}, + }), + ) + self.assertEqual( + fallback, + extract_sha256_from_metadata({ + "file_info": {"sha256": "invalid", "hash": fallback}, + }), + ) + def test_looks_like_model_file_huggingface(self): # Valid HuggingFace URLs self.assertTrue(looks_like_model_file("https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors"))