208 lines
6.9 KiB
TypeScript
208 lines
6.9 KiB
TypeScript
import { describe, it, expect, vi } from 'vitest';
|
|
|
|
import { buildGroupSortExtras } from './groupSortState';
|
|
|
|
describe('buildGroupSortExtras — summary bar scenarios', () => {
|
|
it('switching to status sort clears status set via summary bar', () => {
|
|
// sort='name', status='error' (set via summary bar) → setSortBy('status')
|
|
// → status cleared (entering grouped-by-status mode resets the filter)
|
|
const setUrlState = vi.fn();
|
|
const extras = makeExtras({ sort: 'name', status: 'error' }, setUrlState);
|
|
extras.setSortBy('status', false);
|
|
expect(setUrlState).toHaveBeenCalledWith({
|
|
groupBy: null,
|
|
groupFilter: null,
|
|
sort: 'status',
|
|
order: 'asc',
|
|
page: 0,
|
|
status: null,
|
|
});
|
|
});
|
|
|
|
it('switching to a different sort preserves status set via summary bar', () => {
|
|
// sort='name', status='error' (set via summary bar) → setSortBy('type')
|
|
// → status persists (cross-dimension, type cleared, status untouched)
|
|
const setUrlState = vi.fn();
|
|
const extras = makeExtras({ sort: 'name', status: 'error' }, setUrlState);
|
|
extras.setSortBy('type', false);
|
|
expect(setUrlState).toHaveBeenCalledWith({
|
|
groupBy: null,
|
|
groupFilter: null,
|
|
sort: 'type',
|
|
order: 'asc',
|
|
page: 0,
|
|
type: null,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('buildGroupSortExtras — sort bar group scenarios', () => {
|
|
it('leaving status sort clears status set via sort bar group', () => {
|
|
// sort='status', status='error' (set via sort bar group) → setSortBy('name')
|
|
// → status cleared (leaving grouped-by-status mode)
|
|
const setUrlState = vi.fn();
|
|
const extras = makeExtras({ sort: 'status', status: 'error' }, setUrlState);
|
|
extras.setSortBy('name', false);
|
|
expect(setUrlState).toHaveBeenCalledWith({
|
|
groupBy: null,
|
|
groupFilter: null,
|
|
sort: 'name',
|
|
order: 'asc',
|
|
page: 0,
|
|
status: null,
|
|
});
|
|
});
|
|
|
|
it('clicking a sort bar group value sets sort and filter together', () => {
|
|
// sort='name' → setGroupFilter('status', 'error')
|
|
// → sort=status, status=error
|
|
const setUrlState = vi.fn();
|
|
const extras = makeExtras({ sort: 'name' }, setUrlState);
|
|
extras.setGroupFilter({ group: 'status', groupValue: 'error' });
|
|
expect(setUrlState).toHaveBeenCalledWith({
|
|
groupBy: null,
|
|
groupFilter: null,
|
|
sort: 'status',
|
|
order: 'asc',
|
|
page: 0,
|
|
status: 'error',
|
|
});
|
|
});
|
|
|
|
it('deselecting a sort bar group value keeps sort, clears filter, changes order', () => {
|
|
// sort='status', status='error' (set via sort bar group) → setGroupFilter('status', null)
|
|
// → sort stays status, status cleared, order toggles
|
|
const setUrlState = vi.fn();
|
|
const extras = makeExtras(
|
|
{ sort: 'status', status: 'error', order: 'asc' },
|
|
setUrlState
|
|
);
|
|
extras.setGroupFilter({ group: 'status', groupValue: null });
|
|
expect(setUrlState).toHaveBeenCalledWith({
|
|
groupBy: null,
|
|
groupFilter: null,
|
|
sort: 'status',
|
|
order: 'desc',
|
|
page: 0,
|
|
status: null,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('buildGroupSortExtras — cross-dimension AND filter scenarios', () => {
|
|
it('status set via summary bar persists when switching to a different sort bar group option', () => {
|
|
// sort='name', status='error' (set via summary bar) → setGroupFilter('type', 'stack')
|
|
// → sort=type, type=stack, status=error preserved (AND filter)
|
|
const setUrlState = vi.fn();
|
|
const extras = makeExtras({ sort: 'name', status: 'error' }, setUrlState);
|
|
extras.setGroupFilter({ group: 'type', groupValue: 'stack' });
|
|
expect(setUrlState).toHaveBeenCalledWith({
|
|
groupBy: null,
|
|
groupFilter: null,
|
|
sort: 'type',
|
|
order: 'asc',
|
|
page: 0,
|
|
type: 'stack',
|
|
});
|
|
});
|
|
|
|
it('status set via summary bar persists through a second sort bar group switch, old group dimension clears', () => {
|
|
// sort='type', type='stack', status='error' (set via summary bar, AND filter)
|
|
// → setGroupFilter('platform', 'docker')
|
|
// → sort=platform, type cleared, status still persists
|
|
const setUrlState = vi.fn();
|
|
const extras = makeExtrasWithPlatform(
|
|
{ sort: 'type', type: 'stack', status: 'error' },
|
|
setUrlState
|
|
);
|
|
extras.setGroupFilter({ group: 'platform', groupValue: 'docker' });
|
|
expect(setUrlState).toHaveBeenCalledWith({
|
|
groupBy: null,
|
|
groupFilter: null,
|
|
sort: 'platform',
|
|
order: 'asc',
|
|
page: 0,
|
|
platform: 'docker',
|
|
type: null,
|
|
});
|
|
});
|
|
|
|
it('status set via sort bar group clears when switching to a different sort bar group option', () => {
|
|
// sort='status', status='error' (set via sort bar group) → setGroupFilter('type', 'stack')
|
|
// → status cleared (was the old sort dimension)
|
|
const setUrlState = vi.fn();
|
|
const extras = makeExtras({ sort: 'status', status: 'error' }, setUrlState);
|
|
extras.setGroupFilter({ group: 'type', groupValue: 'stack' });
|
|
expect(setUrlState).toHaveBeenCalledWith({
|
|
sort: 'type',
|
|
order: 'asc',
|
|
page: 0,
|
|
type: 'stack',
|
|
status: null,
|
|
groupBy: null,
|
|
groupFilter: null,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('buildGroupSortExtras — override scenarios', () => {
|
|
it('summary bar overrides status set via sort bar group (last write wins)', () => {
|
|
// setStatus is handled by the view, not buildGroupSortExtras.
|
|
// Verify that groupFilter reflects the current URL status when sort=status.
|
|
const extras = makeExtras({ sort: 'status', status: 'healthy' });
|
|
expect(extras.groupFilter).toBe('healthy');
|
|
});
|
|
|
|
it('toggling sort direction preserves the active sort bar group filter', () => {
|
|
const setUrlState = vi.fn();
|
|
const extras = makeExtras({ sort: 'status', status: 'error' }, setUrlState);
|
|
extras.setSortBy('status', true);
|
|
expect(setUrlState).toHaveBeenCalledWith({
|
|
groupBy: null,
|
|
groupFilter: null,
|
|
sort: 'status',
|
|
order: 'desc',
|
|
page: 0,
|
|
});
|
|
});
|
|
});
|
|
|
|
function makeExtras(
|
|
urlState: {
|
|
sort: string;
|
|
status?: string | null;
|
|
type?: string | null;
|
|
order?: 'desc' | 'asc';
|
|
},
|
|
setUrlState = vi.fn()
|
|
) {
|
|
const order = urlState.order || 'asc';
|
|
return buildGroupSortExtras({
|
|
urlState: { status: null, type: null, order, ...urlState },
|
|
setUrlState,
|
|
defaultSort: 'name',
|
|
sortKeys: ['name', 'status', 'type'] as const,
|
|
dimensions: [{ key: 'status' }, { key: 'type' }],
|
|
});
|
|
}
|
|
|
|
function makeExtrasWithPlatform(
|
|
urlState: {
|
|
sort: string;
|
|
status?: string | null;
|
|
type?: string | null;
|
|
platform?: string | null;
|
|
order?: 'asc' | 'desc';
|
|
},
|
|
setUrlState = vi.fn()
|
|
) {
|
|
const order = urlState.order || 'asc';
|
|
return buildGroupSortExtras({
|
|
urlState: { status: null, type: null, platform: null, order, ...urlState },
|
|
setUrlState,
|
|
defaultSort: 'name',
|
|
sortKeys: ['name', 'status', 'type', 'platform'] as const,
|
|
dimensions: [{ key: 'status' }, { key: 'type' }, { key: 'platform' }],
|
|
});
|
|
}
|