fix(notifications): the smtp test names its failure and the log carries it (#2196)

testSmtp logged nothing and the transport ran on nodemailer's two-minute defaults while the client gave up after eight seconds, so every failure was a generic toast over an empty log. The transport gets real timeouts, every outcome is logged without credentials, and a classified, scrubbed cause (auth, DNS, refused, filtered port, TLS mismatch, certificate) goes into the response the admin sees; the channel test calls wait long enough to receive it. The password field also rendered its mask as value, so replacing a stored password silently saved the bullets as part of the new one; it is a placeholder now, on desktop and the phone admin.
This commit is contained in:
Maurice
2026-09-02 19:58:13 +02:00
committed by Maurice
parent 1e6ab069cd
commit b6a86275f6
11 changed files with 593 additions and 20 deletions
+17
View File
@@ -864,4 +864,21 @@ describe('client > multipart uploads', () => {
expect(post.mock.calls[1][0]).toBe('/backup/upload-restore')
expect(((post.mock.calls[1][1] as FormData).get('backup') as File).name).toBe('backup.zip')
})
it('FE-APISURF-053: every channel test outlives the 8s global timeout', async () => {
const post = spyPost()
// The server budgets up to 20s for an SMTP dial and 10s for a webhook or
// ntfy ping; aborting at 8s threw away the reason and left the admin with a
// bare "failed" (#2196).
await notificationsApi.testSmtp('a@b.c')
await notificationsApi.testWebhook('https://hook')
await notificationsApi.testNtfy({ topic: 't' })
await notificationsApi.testChannel('plugin/ch')
expect(post.mock.calls).toHaveLength(4)
for (const call of post.mock.calls) {
expect(call[2]).toMatchObject({ timeout: 40000 })
}
})
})