Files
client-web/src/modules/first-leg/utils/orderColumnPreferences.test.mjs
T

135 lines
6.1 KiB
JavaScript

import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
import ts from 'typescript'
import { computed, effectScope, ref, watch } from 'vue'
import { readOrderColumnPreferences, saveOrderColumnPreferences } from './orderColumnPreferences.ts'
const page = readFileSync(new URL('../views/FirstLegOrdersView.vue', import.meta.url), 'utf8')
const columnSource = page.slice(page.indexOf('const fixedOrderColumns:'), page.indexOf('const tablePage ='))
const columnScript = ts.transpileModule(columnSource, { compilerOptions: { target: ts.ScriptTarget.ES2022 } }).outputText
const createColumns = new Function('auth', 'ref', 'computed', 'watch', 'readOrderColumnPreferences', 'saveOrderColumnPreferences', `${columnScript}
return { visibleColumnKeys, orderedColumnKeys, visibleOrderColumns, draggedColumnKey, moveOrderColumn, dropOrderColumn, resetOrderColumns }
`)
function mockStorage(t) {
const original = Object.getOwnPropertyDescriptor(globalThis, 'localStorage')
const entries = new Map()
const storage = {
getItem: key => entries.get(key) ?? null,
setItem: (key, value) => entries.set(key, value),
}
Object.defineProperty(globalThis, 'localStorage', { configurable: true, value: storage })
t.after(() => {
if (original) Object.defineProperty(globalThis, 'localStorage', original)
else delete globalThis.localStorage
})
return storage
}
function openColumns(t, ownerId = 'customer-one') {
const scope = effectScope()
const columns = scope.run(() => createColumns({ user: { id: ownerId } }, ref, computed, watch, readOrderColumnPreferences, saveOrderColumnPreferences))
t.after(() => scope.stop())
return { ...columns, close: () => scope.stop() }
}
test('restores checked fields and both arrow and drag ordering after a fresh page setup', t => {
mockStorage(t)
const columns = openColumns(t)
columns.visibleColumnKeys.value.push('destinationWarehouse', 'grossWeight', 'volume')
columns.visibleColumnKeys.value.splice(columns.visibleColumnKeys.value.indexOf('createdAt'), 1)
columns.moveOrderColumn('destinationWarehouse', -1)
columns.draggedColumnKey.value = 'grossWeight'
columns.dropOrderColumn('status')
const visibleKeys = [...columns.visibleColumnKeys.value]
const orderedKeys = [...columns.orderedColumnKeys.value]
const renderedKeys = columns.visibleOrderColumns.value.map(column => column.key)
columns.close()
const refreshed = openColumns(t)
assert.deepEqual(refreshed.visibleColumnKeys.value, visibleKeys)
assert.deepEqual(refreshed.orderedColumnKeys.value, orderedKeys)
assert.deepEqual(refreshed.visibleOrderColumns.value.map(column => column.key), renderedKeys)
assert.deepEqual(renderedKeys.slice(0, 3), ['selection', 'actions', 'inboundCode'])
assert.equal(renderedKeys[3], 'grossWeight')
})
test('persists restore-default and intentionally hiding every selectable field', t => {
mockStorage(t)
const columns = openColumns(t)
const defaults = [...columns.visibleColumnKeys.value]
const defaultOrder = [...columns.orderedColumnKeys.value]
columns.visibleColumnKeys.value = []
columns.close()
const refreshed = openColumns(t)
assert.deepEqual(refreshed.visibleColumnKeys.value, [])
assert.deepEqual(refreshed.visibleOrderColumns.value.map(column => column.key), ['selection', 'actions', 'inboundCode'])
refreshed.moveOrderColumn('grossWeight', -1)
refreshed.resetOrderColumns()
refreshed.close()
const reset = openColumns(t)
assert.deepEqual(reset.visibleColumnKeys.value, defaults)
assert.deepEqual(reset.orderedColumnKeys.value, defaultOrder)
})
test('keeps the field selection separate for each signed-in account', t => {
mockStorage(t)
const first = openColumns(t)
first.visibleColumnKeys.value = ['volume']
first.close()
const second = openColumns(t, 'customer-two')
assert.notDeepEqual(second.visibleColumnKeys.value, ['volume'])
second.visibleColumnKeys.value = ['grossWeight']
second.close()
assert.deepEqual(openColumns(t).visibleColumnKeys.value, ['volume'])
assert.deepEqual(openColumns(t, 'customer-two').visibleColumnKeys.value, ['grossWeight'])
})
test('discards unknown, duplicate and invalid keys and includes newly available fields in ordering', t => {
mockStorage(t)
saveOrderColumnPreferences('customer-one', {
visibleColumnKeys: ['volume', 'removed', 'volume', null, 3],
orderedColumnKeys: ['volume', 'removed', 'volume', false],
})
assert.deepEqual(readOrderColumnPreferences('customer-one', ['status', 'volume', 'newField'], ['status']), {
visibleColumnKeys: ['volume'],
orderedColumnKeys: ['volume', 'status', 'newField'],
})
})
test('uses the original defaults for missing or damaged saved preferences', t => {
const storage = mockStorage(t)
const defaults = { visibleColumnKeys: ['status'], orderedColumnKeys: ['status', 'volume'] }
assert.deepEqual(readOrderColumnPreferences('customer-one', ['status', 'volume'], ['status']), defaults)
saveOrderColumnPreferences('customer-one', defaults)
const realGetItem = storage.getItem
for (const saved of ['{invalid', 'null', '[]', '42', '{"visibleColumnKeys":"status","orderedColumnKeys":[]}']) {
storage.getItem = () => saved
assert.deepEqual(readOrderColumnPreferences('customer-one', ['status', 'volume'], ['status']), defaults)
}
storage.getItem = realGetItem
})
test('keeps column controls usable when browser storage is blocked', t => {
const storage = mockStorage(t)
storage.getItem = () => { throw new Error('Storage denied') }
storage.setItem = () => { throw new Error('Storage denied') }
const columns = openColumns(t)
assert.ok(columns.visibleColumnKeys.value.includes('status'))
assert.doesNotThrow(() => { columns.visibleColumnKeys.value.push('volume') })
assert.doesNotThrow(() => columns.resetOrderColumns())
})
test('does not read or save preferences without an account', t => {
const storage = mockStorage(t)
let storageCalls = 0
storage.getItem = () => { storageCalls++; return null }
storage.setItem = () => { storageCalls++ }
const columns = openColumns(t, '')
columns.visibleColumnKeys.value = ['volume']
assert.equal(openColumns(t, '').visibleColumnKeys.value.includes('status'), true)
assert.equal(storageCalls, 0)
})