test: cover profile completeness counting

This commit is contained in:
mARTin-B78 2026-09-04 09:33:45 +02:00
parent 97c0958ef0
commit 0fd39d4acb
6 changed files with 20 additions and 3 deletions

View File

@ -50,6 +50,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
and avoids unnecessary duplicate assignments when distinct catalogue voices are available.
- **4 GiB Container Validation.** Verified the current image serves the application under a hard 4 GiB cgroup limit
with no OOM kill; the probe recorded approximately 50.6 MiB idle memory and 0.09% CPU.
- **Profile Completeness Coverage.** Added browser regression coverage for empty, partial, and fully populated
character-sheet counts used by the library table and profile sorting.
- **STT Cancellation Safety.** Queued transcription cancels before consuming the single STT slot, and timed-out
requests keep the device slot held until the underlying worker actually exits.
- **Credential Boundary Review.** Provider credentials are now documented as server-only; only the explicitly

View File

@ -167,7 +167,7 @@ the first block before investing in architecture or polish.
- [ ] Character parsing and phantom-speaker prevention.
- [x] Voice-matching constraints reject invented voice IDs and avoid unnecessary duplicate assignments.
- [ ] Profile-completeness counting.
- [x] Profile-completeness counting for empty, partial, and fully populated sheets.
- [x] Rating persistence.
- [x] STT endpoint normalization and backend-response shape handling.
- [x] ComfyUI workflow submission, prompt injection, polling, and image retrieval.

View File

@ -1 +1 @@
1.23.4
1.23.5

File diff suppressed because one or more lines are too long

View File

@ -10,6 +10,8 @@ const _CHAR_PROFILE_COMPLETENESS_FIELDS = [
'mannerisms', 'communication_style', 'voice_pattern', 'secret', 'conflict_style',
'win_condition', 'reputation', 'religious_beliefs', 'notes', 'inventory',
];
// Stable read-only metadata for diagnostics and browser regression tests.
window._CHAR_PROFILE_COMPLETENESS_FIELDS = _CHAR_PROFILE_COMPLETENESS_FIELDS;
const _CHAR_TABLE_COLUMN_DEFS = [
['select', 'Select'], ['avatar', 'Avatar'], ['name', 'Name'], ['gender', 'Gender'],

View File

@ -141,3 +141,16 @@ test('character appearance forms stay in one record and switch the detail view',
await expect(page.locator('.lcd-form-switcher select')).toHaveValue('');
await expect.poll(() => page.evaluate(() => window._libDetailRec?.sheet?.active_form_id || '')).toBe('');
});
test('profile completeness counter distinguishes empty, partial, and full sheets', async ({ page }) => {
await page.goto('/', { waitUntil: 'domcontentloaded' });
await page.waitForFunction(() => typeof window._charProfileCompleteness === 'function', null, { timeout: 15_000 });
const counts = await page.evaluate(() => ({
empty: window._charProfileCompleteness({}),
partial: window._charProfileCompleteness({ gender: 'F', profession: 'captain', inventory: ['lantern'] }),
full: window._charProfileCompleteness(Object.fromEntries(window._CHAR_PROFILE_COMPLETENESS_FIELDS.map(key => [key, 'filled']))),
}));
expect(counts.empty.filled).toBe(0);
expect(counts.partial.filled).toBe(3);
expect(counts.full.filled).toBe(counts.full.total);
});