Group settings with explicit modes and one save action
This commit is contained in:
@@ -2,7 +2,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { newFixture, type Fixture } from '../helpers/fixture.js';
|
||||
|
||||
let fixture: Fixture;
|
||||
import { defaultFleetSettings as defaults } from '../../src/lib/fleet-settings.js';
|
||||
import { defaultFleetSettings as defaults, additionalConcurrencyKeys, fleetSettingLabels, settingDisplayValue, settingHelp,
|
||||
settingMinimum, settingsGroups, settingUnit, settingZeroMode, validateFleetSettings, type FleetSettings } from '../../src/lib/fleet-settings.js';
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
fixture = await newFixture([]);
|
||||
@@ -139,3 +140,52 @@ it('saves a section without overwriting changes in the other section', async ()
|
||||
expect(response.status).toBe(200);
|
||||
expect(await GET().json()).toMatchObject({ deployKeepDays: 42, rebuildConcurrency: 2 });
|
||||
});
|
||||
|
||||
describe('settings presentation semantics', () => {
|
||||
it('places every saved setting in exactly one searchable group', () => {
|
||||
const grouped = settingsGroups.flatMap(group => group.keys);
|
||||
expect(grouped.length).toBe(Object.keys(defaults).length);
|
||||
expect(new Set(grouped).size).toBe(grouped.length);
|
||||
expect([...grouped].sort()).toEqual(Object.keys(defaults).sort());
|
||||
expect(settingsGroups.map(group => group.title)).toEqual([
|
||||
'Concurrency', 'Operation history', 'Matches & players', 'Telemetry & metrics', 'Files & versions', 'Accounts & audit'
|
||||
]);
|
||||
});
|
||||
|
||||
it('distinguishes an unlimited cap from permanent retention, age expiry, and minimum counts', () => {
|
||||
for (const key of [...additionalConcurrencyKeys, 'telemetryMaxPerServer', 'telemetryMaxTotal'] as (keyof FleetSettings)[]) {
|
||||
expect(settingZeroMode(key)).toBe('No limit');
|
||||
}
|
||||
for (const key of Object.keys(defaults) as (keyof FleetSettings)[]) {
|
||||
if (key.endsWith('Days') && !['versionKeepDays', 'gameFileGraceDays'].includes(key)) expect(settingZeroMode(key)).toBe('Forever');
|
||||
if (settingMinimum(key) === 1) expect(settingZeroMode(key)).toBeNull();
|
||||
}
|
||||
expect(settingZeroMode('versionKeepDays')).toBe('No age expiry');
|
||||
expect(settingZeroMode('gameFileGraceDays')).toBe('No delay');
|
||||
expect(settingZeroMode('versionKeepCount')).toBe('No minimum');
|
||||
expect(settingZeroMode('historyKeepCount')).toBe('No minimum');
|
||||
expect(settingHelp.versionKeepDays).toContain('version count policy may still remove');
|
||||
expect(settingHelp.versionKeepCount).toContain('a positive count removes older unused versions');
|
||||
});
|
||||
|
||||
it('formats numeric values and defaults without changing their stored meaning', () => {
|
||||
const original = structuredClone(defaults);
|
||||
for (const key of Object.keys(defaults) as (keyof FleetSettings)[]) {
|
||||
const zero = settingZeroMode(key);
|
||||
if (zero) {
|
||||
expect(settingDisplayValue(key, 0)).toBe(zero);
|
||||
expect(validateFleetSettings({ ...defaults, [key]: 0 })[key]).toBe(0);
|
||||
}
|
||||
expect(settingDisplayValue(key, 1)).toBe(`1 ${settingUnit(key).slice(0, -1)}`);
|
||||
expect(settingDisplayValue(key, 14)).toBe(`14 ${settingUnit(key)}`);
|
||||
expect(validateFleetSettings({ ...defaults, [key]: 14 })[key]).toBe(14);
|
||||
}
|
||||
expect(settingDisplayValue('telemetryMaxTotal', 10_000)).toBe('10,000 records');
|
||||
expect(settingDisplayValue('preparationConcurrency', 2)).toBe('2 hosts');
|
||||
expect(settingDisplayValue('versionKeepCount', 1)).toBe('1 version');
|
||||
expect(settingDisplayValue('matchKeepDays', NaN)).toBe('—');
|
||||
expect(defaults).toEqual(original);
|
||||
expect(fleetSettingLabels.destroyConcurrency).toBe('Concurrent server removals');
|
||||
expect(fleetSettingLabels.destroyConcurrencyPerHost).toBe('Concurrent server removals per host');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user