110 lines
4.3 KiB
JavaScript
110 lines
4.3 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
|
|
import {
|
|
getModelCardUrl,
|
|
getSourceKeyFromUrl,
|
|
parseHuggingFaceFileUrl,
|
|
} from '../web/resolver/utils/url_utils.js';
|
|
import { getSourceKeyFromText } from '../web/resolver/utils/source_labels.js';
|
|
|
|
test('source URL parsing normalizes supported provider hosts', () => {
|
|
const cases = [
|
|
['https://huggingface.co/owner/repo', 'huggingface'],
|
|
['https://www.huggingface.co/owner/repo', 'huggingface'],
|
|
['https://cdn.civarchive.com/models/1', 'civarchive'],
|
|
['https://civitai.com/models/1', 'civitai'],
|
|
['https://www.civitai.red/models/1', 'civitai'],
|
|
['https://unknown.example/models/1', ''],
|
|
['not a URL', ''],
|
|
];
|
|
|
|
for (const [value, expected] of cases) {
|
|
assert.equal(getSourceKeyFromUrl(value), expected, value);
|
|
}
|
|
});
|
|
|
|
test('source URL parsing can preserve text fallback semantics', () => {
|
|
assert.equal(getSourceKeyFromUrl('CivArchive mirror', { fallbackToText: true }), 'civarchive');
|
|
assert.equal(getSourceKeyFromUrl('LoRA Archive result', { fallbackToText: true }), 'lora_manager_archive');
|
|
assert.equal(getSourceKeyFromUrl('unknown.example/model', { fallbackToText: true }), '');
|
|
});
|
|
|
|
test('source text parsing normalizes provider aliases', () => {
|
|
assert.equal(getSourceKeyFromText('Hugging Face result'), 'huggingface');
|
|
assert.equal(getSourceKeyFromText('Civ Archive result'), 'civarchive');
|
|
assert.equal(getSourceKeyFromText('CivitAI result'), 'civitai');
|
|
assert.equal(getSourceKeyFromText('LoRA Archive result'), 'lora_manager_archive');
|
|
assert.equal(getSourceKeyFromText('unknown'), '');
|
|
});
|
|
|
|
test('Hugging Face file URLs expose repository, revision, path, and filename', () => {
|
|
assert.deepEqual(
|
|
parseHuggingFaceFileUrl('https://www.huggingface.co/owner/repo/blob/main/folder/model%20file.safetensors'),
|
|
{
|
|
repo: 'owner/repo',
|
|
revision: 'main',
|
|
path: 'folder/model file.safetensors',
|
|
filename: 'model file.safetensors',
|
|
}
|
|
);
|
|
assert.deepEqual(
|
|
parseHuggingFaceFileUrl('https://huggingface.co/owner/repo/resolve/v1.0/model.safetensors'),
|
|
{
|
|
repo: 'owner/repo',
|
|
revision: 'v1.0',
|
|
path: 'model.safetensors',
|
|
filename: 'model.safetensors',
|
|
}
|
|
);
|
|
});
|
|
|
|
test('Hugging Face URL parsing rejects unsupported and malformed URLs', () => {
|
|
assert.equal(parseHuggingFaceFileUrl(''), null);
|
|
assert.equal(parseHuggingFaceFileUrl('https://example.com/owner/repo/blob/main/file'), null);
|
|
assert.equal(parseHuggingFaceFileUrl('https://huggingface.co/owner/repo/tree/main/file'), null);
|
|
assert.equal(parseHuggingFaceFileUrl('https://huggingface.co/owner/repo/blob/main'), null);
|
|
assert.equal(parseHuggingFaceFileUrl('https://huggingface.co/%E0%A4%A/owner/blob/main/file'), null);
|
|
assert.equal(parseHuggingFaceFileUrl('not a URL'), null);
|
|
});
|
|
|
|
test('model card URLs reconstruct direct Hugging Face downloads', () => {
|
|
assert.equal(
|
|
getModelCardUrl('https://huggingface.co/owner/repo/resolve/main/folder/model.safetensors'),
|
|
'https://huggingface.co/owner/repo/blob/main/folder/model.safetensors'
|
|
);
|
|
assert.equal(
|
|
getModelCardUrl('https://huggingface.co/owner/repo/resolve/v1.0/folder/model file.safetensors'),
|
|
'https://huggingface.co/owner/repo/blob/v1.0/folder/model%20file.safetensors'
|
|
);
|
|
});
|
|
|
|
test('model card URLs fall back to repository pages for generic Hugging Face URLs', () => {
|
|
assert.equal(
|
|
getModelCardUrl('https://huggingface.co/owner/repo'),
|
|
'https://huggingface.co/owner/repo'
|
|
);
|
|
assert.equal(
|
|
getModelCardUrl('https://huggingface.co/owner/repo/resolve/main'),
|
|
'https://huggingface.co/owner/repo'
|
|
);
|
|
});
|
|
|
|
test('model card URLs convert CivitAI download links to model pages', () => {
|
|
assert.equal(
|
|
getModelCardUrl('https://civitai.com/api/download/models/123456'),
|
|
'https://civitai.com/models/123456'
|
|
);
|
|
assert.equal(
|
|
getModelCardUrl('https://civitai.com/models/987654/version/2'),
|
|
'https://civitai.com/models/987654'
|
|
);
|
|
});
|
|
|
|
test('model card URL parsing returns null for unsupported or incomplete links', () => {
|
|
assert.equal(getModelCardUrl(null), null);
|
|
assert.equal(getModelCardUrl('https://example.com/model.safetensors'), null);
|
|
assert.equal(getModelCardUrl('https://civitai.com/api/download/models/no-id'), null);
|
|
assert.equal(getModelCardUrl('https://huggingface.co/not-a-repository'), null);
|
|
});
|