ff1ffbbfa3
- 列表接口加 keyword(标题/内容模糊)与 startDate/endDate(年月日闭区间)参数, 两端控制器透传,服务端补筛选日志 - 两端铃铛面板:搜索框(防抖 300ms)+ 日期区间 + 按年月日分组 + 翻页, 面板改 Teleport 到 body(挂在顶栏时会被页面 el-select 压住,提 z-index 无效) - 固化可见范围回归测试:超管全量/管理员只看本组/普通用户只看自己, 含读写两侧的 user_id+audience 裁剪断言与两端控制器身份来源断言
130 lines
4.1 KiB
TypeScript
130 lines
4.1 KiB
TypeScript
import { test } from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import {
|
|
formatNotificationTime,
|
|
formatUnreadBadge,
|
|
groupNotificationsByDay,
|
|
hasNewNotification,
|
|
readLastNotifiedId,
|
|
writeLastNotifiedId,
|
|
} from '../src/layout/notification-bell-model.ts'
|
|
|
|
function createStorage() {
|
|
const store = new Map<string, string>()
|
|
return {
|
|
getItem: (key: string) => (store.has(key) ? (store.get(key) as string) : null),
|
|
setItem: (key: string, value: string) => {
|
|
store.set(key, String(value))
|
|
},
|
|
removeItem: (key: string) => {
|
|
store.delete(key)
|
|
},
|
|
}
|
|
}
|
|
|
|
function setupWindow() {
|
|
const localStorage = createStorage()
|
|
const globalScope = globalThis as Record<string, unknown>
|
|
const previous = globalScope.window
|
|
globalScope.window = { localStorage }
|
|
return {
|
|
localStorage,
|
|
restore: () => {
|
|
globalScope.window = previous
|
|
},
|
|
}
|
|
}
|
|
|
|
test('test_未读徽标:0 与非法值不显示、超过 99 显示 99+', () => {
|
|
assert.equal(formatUnreadBadge(0), '')
|
|
assert.equal(formatUnreadBadge(-3), '')
|
|
assert.equal(formatUnreadBadge(null), '')
|
|
assert.equal(formatUnreadBadge(undefined), '')
|
|
assert.equal(formatUnreadBadge(Number.NaN), '')
|
|
assert.equal(formatUnreadBadge(1), '1')
|
|
assert.equal(formatUnreadBadge(99), '99')
|
|
assert.equal(formatUnreadBadge(100), '99+')
|
|
})
|
|
|
|
test('test_新通知判定:latestId 需大于已提醒 id', () => {
|
|
assert.equal(hasNewNotification(0, 0), false)
|
|
assert.equal(hasNewNotification(null, 5), false)
|
|
assert.equal(hasNewNotification(5, 5), false)
|
|
assert.equal(hasNewNotification(4, 5), false)
|
|
assert.equal(hasNewNotification(6, 5), true)
|
|
assert.equal(hasNewNotification(6, 0), true)
|
|
assert.equal(hasNewNotification(6, null), true)
|
|
})
|
|
|
|
test('test_已提醒 id 按管理员读写并容错', () => {
|
|
setupWindow()
|
|
assert.equal(readLastNotifiedId(7), 0, '未写入时按 0 处理')
|
|
|
|
writeLastNotifiedId(7, 88)
|
|
assert.equal(readLastNotifiedId(7), 88)
|
|
assert.equal(readLastNotifiedId(8), 0, '不同管理员互不影响')
|
|
|
|
writeLastNotifiedId(7, 0)
|
|
assert.equal(readLastNotifiedId(7), 88, '非法 id 不覆盖已有值')
|
|
|
|
window.localStorage.setItem('admin-notification:last-notified-id:7', 'broken')
|
|
assert.equal(readLastNotifiedId(7), 0, '损坏值按 0 处理')
|
|
|
|
assert.equal(readLastNotifiedId(null), readLastNotifiedId('0'), '空 uid 归一为 0 号键')
|
|
})
|
|
|
|
test('test_时间展示:今天/昨天/更早', () => {
|
|
const now = new Date(2026, 8, 13, 15, 30)
|
|
assert.equal(formatNotificationTime(new Date(2026, 8, 13, 9, 5).toISOString(), now), '09:05')
|
|
assert.equal(formatNotificationTime(new Date(2026, 8, 12, 23, 59).toISOString(), now), '昨天 23:59')
|
|
assert.equal(formatNotificationTime(new Date(2026, 8, 1, 8, 0).toISOString(), now), '09-01 08:00')
|
|
assert.equal(formatNotificationTime(null, now), '')
|
|
assert.equal(formatNotificationTime('not-a-date', now), '')
|
|
})
|
|
|
|
test('test_按年月日分组:今天/昨天/更早,组内保持原顺序', () => {
|
|
const now = new Date(2026, 8, 13, 15, 30)
|
|
const items = [
|
|
{ id: 4, createdAt: new Date(2026, 8, 13, 15, 0).toISOString() },
|
|
{ id: 3, createdAt: new Date(2026, 8, 13, 9, 0).toISOString() },
|
|
{ id: 2, createdAt: new Date(2026, 8, 12, 23, 0).toISOString() },
|
|
{ id: 1, createdAt: new Date(2026, 8, 1, 8, 0).toISOString() },
|
|
]
|
|
|
|
const groups = groupNotificationsByDay(items, now)
|
|
|
|
assert.equal(groups.length, 3)
|
|
assert.deepEqual(
|
|
groups.map((group) => [group.day, group.label]),
|
|
[
|
|
['2026-09-13', '今天'],
|
|
['2026-09-12', '昨天'],
|
|
['2026-09-01', '2026年9月1日'],
|
|
],
|
|
)
|
|
assert.deepEqual(
|
|
groups[0].items.map((item) => item.id),
|
|
[4, 3],
|
|
'同一天的多条合为一组且保持倒序',
|
|
)
|
|
})
|
|
|
|
test('test_按年月日分组:时间缺失/非法归入未知时间组', () => {
|
|
const now = new Date(2026, 8, 13, 15, 30)
|
|
const groups = groupNotificationsByDay(
|
|
[
|
|
{ id: 2, createdAt: null },
|
|
{ id: 1, createdAt: 'not-a-date' },
|
|
],
|
|
now,
|
|
)
|
|
|
|
assert.equal(groups.length, 1)
|
|
assert.equal(groups[0].day, '')
|
|
assert.equal(groups[0].label, '未知时间')
|
|
assert.deepEqual(
|
|
groups[0].items.map((item) => item.id),
|
|
[2, 1],
|
|
)
|
|
})
|