olivetin/frontend/resources/vue/stores/searchIndex.test.mjs

198 lines
6.6 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import {
MAX_SEARCH_HINT_ACTIONS,
MAX_SEARCH_HINT_DASHBOARDS,
MAX_SEARCH_HINT_ENTITIES_PER_TYPE,
clearSearchIndex,
dashboardRoutePath,
indexRootDashboardEntries,
indexSearchHints,
indexSystemNavigation,
searchIndexItems
} from '../stores/searchIndex.js'
function resetIndex () {
clearSearchIndex()
}
test('dashboardRoutePath maps Actions to root', () => {
assert.equal(dashboardRoutePath('Actions'), '/')
})
test('dashboardRoutePath builds dashboard and entity paths', () => {
assert.equal(dashboardRoutePath('Servers'), '/dashboards/Servers')
assert.equal(
dashboardRoutePath('Servers', 'host', 'web01'),
'/dashboards/Servers/host/web01'
)
})
test('indexSearchHints indexes entities and actions', () => {
resetIndex()
indexSearchHints({
entities: [
{ title: 'web01', type: 'host', uniqueKey: '0' },
{ title: '', type: 'host', uniqueKey: '1' },
{ title: 'skip', type: '', uniqueKey: 'x' }
],
actions: [
{ title: 'Ping Host', bindingId: 'bind-ping' },
{ title: '', bindingId: 'bind-empty-title' },
{ title: 'Ignored', bindingId: '' }
]
})
const byId = Object.fromEntries(searchIndexItems.value.map((item) => [item.id, item]))
assert.equal(byId['entity:host:0'].title, 'web01')
assert.equal(byId['entity:host:0'].path, '/entity-details/host/0')
assert.equal(byId['entity:host:0'].description, 'host')
assert.equal(byId['entity:host:1'].title, '1')
assert.equal(byId['action:bind-ping'].title, 'Ping Host')
assert.equal(byId['action:bind-ping'].path, '/action/bind-ping')
assert.equal(byId['action:bind-ping'].category, 'Actions')
assert.equal(byId['action:bind-empty-title'].title, 'bind-empty-title')
assert.equal(Object.keys(byId).includes('entity:host:x'), false)
assert.equal(Object.keys(byId).includes('action:'), false)
})
test('indexRootDashboardEntries indexes ACL-filtered dashboards', () => {
resetIndex()
indexRootDashboardEntries([
{ title: 'Actions', category: '' },
{ title: 'My Server', category: 'Infrastructure' },
{ title: '', category: 'Ignored' }
])
const byId = Object.fromEntries(searchIndexItems.value.map((item) => [item.id, item]))
assert.equal(byId['dashboard:Actions'].path, '/')
assert.equal(byId['dashboard:My Server'].path, '/dashboards/My Server')
assert.equal(byId['dashboard:My Server'].description, 'Infrastructure')
assert.equal(byId['dashboard:My Server'].category, 'Dashboards')
})
test('indexSearchHints replaces prior entity and action snapshots', () => {
resetIndex()
indexSearchHints({
entities: [{ title: 'old', type: 'host', uniqueKey: 'old' }],
actions: [{ title: 'Old Action', bindingId: 'old-action' }]
})
indexRootDashboardEntries([{ title: 'Old Board', category: '' }])
indexSearchHints({
entities: [{ title: 'new', type: 'host', uniqueKey: 'new' }],
actions: [{ title: 'New Action', bindingId: 'new-action' }]
})
indexRootDashboardEntries([{ title: 'New Board', category: 'Ops' }])
const byId = Object.fromEntries(searchIndexItems.value.map((item) => [item.id, item]))
assert.equal(byId['entity:host:old'], undefined)
assert.equal(byId['action:old-action'], undefined)
assert.equal(byId['dashboard:Old Board'], undefined)
assert.equal(byId['entity:host:new'].title, 'new')
assert.equal(byId['action:new-action'].title, 'New Action')
assert.equal(byId['dashboard:New Board'].description, 'Ops')
})
test('caps actions globally, entities per type, and dashboards from root entries', () => {
resetIndex()
const actions = []
for (let i = 0; i < MAX_SEARCH_HINT_ACTIONS + 20; i++) {
actions.push({ title: `Action ${i}`, bindingId: `a-${i}` })
}
const entities = []
for (let i = 0; i < MAX_SEARCH_HINT_ENTITIES_PER_TYPE + 20; i++) {
entities.push({ title: `Host ${i}`, type: 'host', uniqueKey: `${i}` })
entities.push({ title: `Container ${i}`, type: 'container', uniqueKey: `${i}` })
}
const dashboards = []
for (let i = 0; i < MAX_SEARCH_HINT_DASHBOARDS + 20; i++) {
dashboards.push({ title: `Board ${i}`, category: '' })
}
indexSearchHints({ actions, entities })
indexRootDashboardEntries(dashboards)
const items = searchIndexItems.value
assert.equal(items.filter((item) => item.category === 'Actions').length, MAX_SEARCH_HINT_ACTIONS)
assert.equal(items.filter((item) => item.category === 'Dashboards').length, MAX_SEARCH_HINT_DASHBOARDS)
assert.equal(
items.filter((item) => item.category === 'Entities' && item.description === 'host').length,
MAX_SEARCH_HINT_ENTITIES_PER_TYPE
)
assert.equal(
items.filter((item) => item.category === 'Entities' && item.description === 'container').length,
MAX_SEARCH_HINT_ENTITIES_PER_TYPE
)
})
test('indexSystemNavigation always includes entities and respects visibility flags', () => {
resetIndex()
indexSystemNavigation({
showLogs: true,
showDiagnostics: false,
entitiesTitle: 'Entities',
logsTitle: 'Logs',
diagnosticsTitle: 'Diagnostics'
})
let byId = Object.fromEntries(searchIndexItems.value.map((item) => [item.id, item]))
assert.equal(byId['nav:entities'].path, '/entities')
assert.equal(byId['nav:logs'].path, '/logs')
assert.equal(byId['nav:diagnostics'], undefined)
indexSystemNavigation({
showLogs: false,
showDiagnostics: true
})
byId = Object.fromEntries(searchIndexItems.value.map((item) => [item.id, item]))
assert.equal(byId['nav:entities'].path, '/entities')
assert.equal(byId['nav:logs'], undefined)
assert.equal(byId['nav:diagnostics'].path, '/diagnostics')
})
test('entities appear before actions in searchIndexItems', () => {
resetIndex()
indexSearchHints({
entities: [{ title: 'server1', type: 'host', uniqueKey: '0' }],
actions: [{ title: 'server1', bindingId: 'bind-server1' }]
})
const titlesByCategory = searchIndexItems.value.map((item) => [item.category, item.title])
const entityIndex = titlesByCategory.findIndex(([category]) => category === 'Entities')
const actionIndex = titlesByCategory.findIndex(([category]) => category === 'Actions')
assert.ok(entityIndex >= 0)
assert.ok(actionIndex >= 0)
assert.ok(entityIndex < actionIndex)
})
test('search index has no Logs category', () => {
resetIndex()
indexSearchHints({
entities: [{ title: 'web01', type: 'host', uniqueKey: '0' }],
actions: [{ title: 'Backup', bindingId: 'bind-backup' }]
})
indexRootDashboardEntries([{ title: 'Ops', category: '' }])
indexSystemNavigation({ showLogs: true, showDiagnostics: true })
assert.equal(
searchIndexItems.value.some((item) => item.category === 'Logs'),
false
)
})