mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
test(frontend): extend coverage for comfyui widgets and helpers
This commit is contained in:
142
tests/frontend/pages/statistics.dashboard.test.js
Normal file
142
tests/frontend/pages/statistics.dashboard.test.js
Normal file
@@ -0,0 +1,142 @@
|
||||
import { describe, it, beforeEach, afterEach, expect, vi } from 'vitest';
|
||||
import { renderTemplate, resetDom } from '../utils/domFixtures.js';
|
||||
|
||||
const { CORE_MODULE, UI_HELPERS_MODULE, STATISTICS_MODULE } = vi.hoisted(() => ({
|
||||
CORE_MODULE: new URL('../../../static/js/core.js', import.meta.url).pathname,
|
||||
UI_HELPERS_MODULE: new URL('../../../static/js/utils/uiHelpers.js', import.meta.url).pathname,
|
||||
STATISTICS_MODULE: new URL('../../../static/js/statistics.js', import.meta.url).pathname,
|
||||
}));
|
||||
|
||||
const appCoreInitializeMock = vi.fn();
|
||||
const showToastMock = vi.fn();
|
||||
|
||||
vi.mock(CORE_MODULE, () => ({
|
||||
appCore: {
|
||||
initialize: appCoreInitializeMock,
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock(UI_HELPERS_MODULE, () => ({
|
||||
showToast: showToastMock,
|
||||
}));
|
||||
|
||||
describe('Statistics dashboard rendering', () => {
|
||||
beforeEach(() => {
|
||||
resetDom();
|
||||
appCoreInitializeMock.mockResolvedValue();
|
||||
showToastMock.mockReset();
|
||||
globalThis.Chart = undefined;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
delete window.statsManager;
|
||||
});
|
||||
|
||||
it('hydrates dashboard panels with fetched data and wires tab interactions', async () => {
|
||||
renderTemplate('statistics.html');
|
||||
|
||||
const dataset = {
|
||||
'/api/lm/stats/collection-overview': {
|
||||
data: {
|
||||
total_models: 4,
|
||||
total_size: 4096,
|
||||
total_generations: 200,
|
||||
lora_count: 2,
|
||||
checkpoint_count: 1,
|
||||
embedding_count: 1,
|
||||
unused_loras: 1,
|
||||
unused_checkpoints: 0,
|
||||
unused_embeddings: 0,
|
||||
lora_size: 2048,
|
||||
checkpoint_size: 1024,
|
||||
embedding_size: 1024,
|
||||
},
|
||||
},
|
||||
'/api/lm/stats/usage-analytics': {
|
||||
data: {
|
||||
top_loras: [
|
||||
{ name: 'Lora A', base_model: 'SDXL', folder: 'loras', usage_count: 10 },
|
||||
],
|
||||
top_checkpoints: [
|
||||
{ name: 'Checkpoint A', base_model: 'SDXL', folder: 'checkpoints', usage_count: 5 },
|
||||
],
|
||||
top_embeddings: [
|
||||
{ name: 'Embedding A', base_model: 'SDXL', folder: 'embeddings', usage_count: 7 },
|
||||
],
|
||||
usage_timeline: [
|
||||
{ date: '2024-01-01', lora_usage: 5, checkpoint_usage: 3, embedding_usage: 2 },
|
||||
],
|
||||
},
|
||||
},
|
||||
'/api/lm/stats/base-model-distribution': {
|
||||
data: {
|
||||
loras: { SDXL: 2 },
|
||||
checkpoints: { SDXL: 1 },
|
||||
embeddings: { SDXL: 1 },
|
||||
},
|
||||
},
|
||||
'/api/lm/stats/tag-analytics': {
|
||||
data: {
|
||||
top_tags: [
|
||||
{ tag: 'anime', count: 5 },
|
||||
{ tag: 'photo', count: 3 },
|
||||
],
|
||||
total_unique_tags: 2,
|
||||
},
|
||||
},
|
||||
'/api/lm/stats/storage-analytics': {
|
||||
data: {
|
||||
loras: [
|
||||
{ name: 'Lora A', base_model: 'SDXL', size: 2048, usage_count: 10 },
|
||||
],
|
||||
checkpoints: [
|
||||
{ name: 'Checkpoint A', base_model: 'SDXL', size: 1024, usage_count: 5 },
|
||||
],
|
||||
embeddings: [],
|
||||
},
|
||||
},
|
||||
'/api/lm/stats/insights': {
|
||||
data: {
|
||||
insights: [
|
||||
{
|
||||
type: 'info',
|
||||
title: 'Balance usage',
|
||||
description: 'Redistribute usage across models.',
|
||||
suggestion: 'Try lesser-used checkpoints.',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const { StatisticsManager } = await import(STATISTICS_MODULE);
|
||||
const manager = new StatisticsManager();
|
||||
const refreshSpy = vi.spyOn(manager, 'refreshChartsInPanel');
|
||||
vi.spyOn(manager, 'fetchData').mockImplementation((endpoint) => Promise.resolve(dataset[endpoint]));
|
||||
|
||||
await manager.initialize();
|
||||
|
||||
expect(manager.initialized).toBe(true);
|
||||
expect(document.querySelectorAll('.metric-card').length).toBeGreaterThan(0);
|
||||
expect(document.querySelector('#topLorasList .model-item')).not.toBeNull();
|
||||
expect(document.querySelector('#tagCloud').textContent).toContain('anime');
|
||||
expect(document.querySelector('#insightsList .insight-card')).not.toBeNull();
|
||||
|
||||
const usageButton = document.querySelector('.tab-button[data-tab="usage"]');
|
||||
usageButton.click();
|
||||
|
||||
expect(refreshSpy).toHaveBeenCalledWith('usage');
|
||||
expect(document.getElementById('usage-panel').classList.contains('active')).toBe(true);
|
||||
expect(document.querySelector('.tab-button.active').dataset.tab).toBe('usage');
|
||||
});
|
||||
|
||||
it('surfaces an error toast when statistics data fails to load', async () => {
|
||||
const { StatisticsManager } = await import(STATISTICS_MODULE);
|
||||
const manager = new StatisticsManager();
|
||||
vi.spyOn(manager, 'fetchData').mockRejectedValue(new Error('unavailable'));
|
||||
|
||||
await manager.loadAllData();
|
||||
|
||||
expect(showToastMock).toHaveBeenCalledWith('toast.general.statisticsLoadFailed', {}, 'error');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user