refactor(app): 优化后台任务退出与外部 IMAP 认证

- 统一用 `WaitGroup` 管理后台 worker,关闭时等待任务结束后再释放数据库连接。
- 将外部 IMAP 的 OAuth 认证切换为 `XOAUTH2` 客户端实现,并补充对应格式测试。
- 调整发送队列的故障恢复逻辑,超时中断后恢复为排队状态以便重新投递。
This commit is contained in:
LanQin
2026-06-25 21:36:59 +08:00
parent 081cfad02d
commit efcdc691de
4 changed files with 66 additions and 9 deletions
+24
View File
@@ -62,6 +62,13 @@ func newTestAppWithConfig(t *testing.T, cfg Config) *App {
return a
}
func stopTestWorkers(a *App) {
if a != nil && a.workerCancel != nil {
a.workerCancel()
a.workerWG.Wait()
}
}
func defaultAdminUserAndMailbox(t *testing.T, a *App) (*User, *Mailbox) {
t.Helper()
ctx := context.Background()
@@ -581,6 +588,21 @@ func TestExternalIMAPOAuthEmailFromIDToken(t *testing.T) {
}
}
func TestExternalIMAPXOAUTH2ClientFormat(t *testing.T) {
client := newExternalIMAPXOAUTH2Client("user@example.com", "access-token")
mech, initialResponse, err := client.Start()
if err != nil {
t.Fatal(err)
}
if mech != "XOAUTH2" {
t.Fatalf("mechanism=%q, want XOAUTH2", mech)
}
want := "user=user@example.com\x01auth=Bearer access-token\x01\x01"
if string(initialResponse) != want {
t.Fatalf("initial response=%q, want %q", string(initialResponse), want)
}
}
func mustOAuthStateFromURL(t *testing.T, rawURL string) string {
t.Helper()
u, err := url.Parse(rawURL)
@@ -1588,6 +1610,7 @@ func TestMailSendRollsBackSentCopyWhenQueueInsertFails(t *testing.T) {
func TestSendQueueRecoversStaleSendingItems(t *testing.T) {
a := newTestApp(t)
stopTestWorkers(a)
host, port, received := startCapturingSMTP(t, 1)
a.cfg.SMTPHost = host
a.cfg.SMTPPort = port
@@ -1637,6 +1660,7 @@ func TestSendQueueRecoversStaleSendingItems(t *testing.T) {
func TestSendQueueStaleDeliveredMarkerDoesNotRedeliver(t *testing.T) {
a := newTestApp(t)
stopTestWorkers(a)
host, port, received := startCapturingSMTP(t, 1)
a.cfg.SMTPHost = host
a.cfg.SMTPPort = port