135 lines
6.1 KiB
JavaScript
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)
|
|
})
|