fix(notification): handle empty channel configuration

This commit is contained in:
jxxghp
2026-09-02 11:38:13 +08:00
parent 0024880577
commit 92464b754a
2 changed files with 26 additions and 4 deletions
@@ -83,7 +83,7 @@ type NotificationConfigInput = Partial<NotificationConf> & {
}
interface NotificationConfigResponse {
value?: NotificationConfigInput[]
value?: NotificationConfigInput[] | null
}
type NotificationLoadState = 'idle' | 'loading' | 'ready' | 'error'
@@ -184,8 +184,9 @@ function normalizeNotification(notification: NotificationConfigInput, index: num
}
}
function normalizeNotificationList(value: NotificationConfigInput[] = []) {
return value.map((notification, index) => normalizeNotification(notification, index))
/** 将后端尚未创建的空配置与已有渠道统一为可编辑列表。 */
function normalizeNotificationList(value?: NotificationConfigInput[] | null) {
return (value ?? []).map((notification, index) => normalizeNotification(notification, index))
}
function notificationNameKey(name: string) {
@@ -91,7 +91,7 @@ const templateFixture = {
subscribeComplete: '{}',
}
function mockLoadedSettings(channels = notificationsFixture) {
function mockLoadedSettings(channels: typeof notificationsFixture | null = notificationsFixture) {
mocks.apiGet.mockImplementation((endpoint: string) => {
if (endpoint === 'system/setting/Notifications') {
return { success: true, data: { value: structuredClone(channels) } }
@@ -178,6 +178,27 @@ describe('AccountSettingNotification', () => {
)
})
it('treats a null notification configuration as empty and allows the first channel to be saved', async () => {
mockLoadedSettings(null)
const user = userEvent.setup()
await renderNotificationSettings()
await waitFor(() => expect(mocks.apiGet).toHaveBeenCalledWith('system/setting/Notifications'))
expect(screen.queryByText('加载通知渠道失败,请刷新后重试')).not.toBeInTheDocument()
const channelCard = getCard('通知渠道')
await user.click(channelCard.getAllByRole('button').at(-1)!)
await user.click(await screen.findByText('Telegram', { selector: '.v-list-item-title' }))
expect(screen.getByText('通知1 / telegram')).toBeInTheDocument()
await user.click(channelCard.getByRole('button', { name: '保存' }))
await waitFor(() =>
expect(mocks.apiPost).toHaveBeenCalledWith('notification/config', [
expect.objectContaining({ id: expect.any(String), name: '通知1', type: 'telegram' }),
]),
)
})
it('creates a unique automatic channel name, removes channels, and saves the current order once', async () => {
const user = userEvent.setup()
await renderNotificationSettings()