108 lines
3.3 KiB
TypeScript
108 lines
3.3 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
import { eventsFields } from '@/lib/__tests__/schemaFixtures'
|
|
import {
|
|
clearStoredColumns,
|
|
columnsStorageKey,
|
|
defaultColumnKeys,
|
|
readStoredColumns,
|
|
resolveColumnKeys,
|
|
storeColumns,
|
|
toggleColumnKeys,
|
|
} from '@/lib/entryColumns'
|
|
|
|
const KEY = 'renewcms-content-columns-events'
|
|
const ALL = eventsFields.map((field) => field.key)
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals()
|
|
localStorage.clear()
|
|
})
|
|
|
|
describe('defaultColumnKeys', () => {
|
|
it('takes the first four fields', () => {
|
|
expect(defaultColumnKeys(eventsFields)).toEqual(['title', 'starts_on', 'ends_on', 'online'])
|
|
})
|
|
|
|
it('takes fewer when the type has fewer', () => {
|
|
expect(defaultColumnKeys(eventsFields.slice(0, 2))).toEqual(['title', 'starts_on'])
|
|
})
|
|
})
|
|
|
|
describe('resolveColumnKeys', () => {
|
|
it.each([
|
|
['nothing stored', null, ['title', 'starts_on', 'ends_on', 'online']],
|
|
['not an array', 'title', ['title', 'starts_on', 'ends_on', 'online']],
|
|
['an empty array', [], ['title', 'starts_on', 'ends_on', 'online']],
|
|
['only unknown keys', ['gone'], ['title', 'starts_on', 'ends_on', 'online']],
|
|
['unknown keys dropped', ['title', 'gone', 'capacity'], ['title', 'capacity']],
|
|
['schema order, not stored order', ['capacity', 'title'], ['title', 'capacity']],
|
|
['non-string items ignored', [1, null, 'title'], ['title']],
|
|
['more than six, first six in schema order', [...ALL].reverse(), ALL.slice(0, 6)],
|
|
['duplicates counted once', ['title', 'title', 'online'], ['title', 'online']],
|
|
])('%s', (_, stored, expected) => {
|
|
expect(resolveColumnKeys(eventsFields, stored)).toEqual(expected)
|
|
})
|
|
})
|
|
|
|
describe('toggleColumnKeys', () => {
|
|
it('adds a key in schema order', () => {
|
|
expect(toggleColumnKeys(eventsFields, ['title', 'capacity'], 'online', true)).toEqual([
|
|
'title',
|
|
'online',
|
|
'capacity',
|
|
])
|
|
})
|
|
|
|
it('removes a key', () => {
|
|
expect(toggleColumnKeys(eventsFields, ['title', 'online'], 'online', false)).toEqual([
|
|
'title',
|
|
])
|
|
})
|
|
|
|
it('never removes the last field column', () => {
|
|
const one = ['capacity']
|
|
|
|
expect(toggleColumnKeys(eventsFields, one, 'capacity', false)).toEqual(['capacity'])
|
|
})
|
|
|
|
it('refuses a seventh column', () => {
|
|
const six = ALL.slice(0, 6)
|
|
|
|
expect(toggleColumnKeys(eventsFields, six, 'description', true)).toBe(six)
|
|
})
|
|
})
|
|
|
|
describe('storage', () => {
|
|
it('uses one key per type', () => {
|
|
expect(columnsStorageKey('events')).toBe(KEY)
|
|
expect(columnsStorageKey('recipes')).toBe('renewcms-content-columns-recipes')
|
|
})
|
|
|
|
it('writes, reads and clears', () => {
|
|
storeColumns('events', ['title', 'capacity'])
|
|
|
|
expect(localStorage.getItem(KEY)).toBe('["title","capacity"]')
|
|
expect(readStoredColumns('events')).toEqual(['title', 'capacity'])
|
|
|
|
clearStoredColumns('events')
|
|
|
|
expect(localStorage.getItem(KEY)).toBeNull()
|
|
})
|
|
|
|
it.each(['not json', '{', ''])('reads "%s" as nothing usable', (raw) => {
|
|
localStorage.setItem(KEY, raw)
|
|
|
|
expect(resolveColumnKeys(eventsFields, readStoredColumns('events'))).toEqual(
|
|
defaultColumnKeys(eventsFields),
|
|
)
|
|
})
|
|
|
|
it('swallows a throwing or missing localStorage', () => {
|
|
vi.stubGlobal('localStorage', undefined)
|
|
|
|
expect(readStoredColumns('events')).toBeNull()
|
|
expect(() => storeColumns('events', ['title'])).not.toThrow()
|
|
expect(() => clearStoredColumns('events')).not.toThrow()
|
|
})
|
|
})
|