根因:Status() 硬编码 UidValidity=1。数据库重建后消息 ID 空间 完全变化(uid 2-166 对应完全不同的邮件),但 UIDVALIDITY 不变, Thunderbird 认为本地缓存(旧 uid 1-166)仍然有效,只下载"新增" (uid 167:*)与"缺失"(2,4,8,9)的少数邮件——列表只剩 1-3 封, 每次刷新数量随机。 修复(RFC 3501 UIDVALIDITY 语义):新增 mailbox_states 表, 每(用户,文件夹)首次访问随机生成并持久化 UIDVALIDITY;数据库 重建后新值触发客户端丢弃缓存全量重同步。0 值修正,不同用户/ 文件夹互相独立。 新增 TestMailboxStateUidValidity 单元测试。
57 lines
1.2 KiB
Go
57 lines
1.2 KiB
Go
package store
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"mail_go/internal/db"
|
|
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// TestMailboxStateUidValidity 验证 UIDVALIDITY:首次访问随机生成、重复访问
|
|
// 稳定返回、0 值被修正、不同邮箱互不影响。
|
|
func TestMailboxStateUidValidity(t *testing.T) {
|
|
gdb, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := gdb.AutoMigrate(&db.MailboxState{}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s := newMailboxStateStore(gdb)
|
|
|
|
// 首次访问:随机非 0
|
|
v1, err := s.UidValidity(1, "INBOX")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if v1 == 0 {
|
|
t.Fatal("UIDVALIDITY 不应为 0")
|
|
}
|
|
// 重复访问:稳定
|
|
v2, err := s.UidValidity(1, "INBOX")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if v1 != v2 {
|
|
t.Fatalf("UIDVALIDITY 不稳定: %d != %d", v1, v2)
|
|
}
|
|
// 不同邮箱:独立
|
|
v3, err := s.UidValidity(1, "Sent")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if v3 == v1 {
|
|
t.Fatal("不同邮箱的 UIDVALIDITY 不应相同")
|
|
}
|
|
// 不同用户:独立
|
|
v4, err := s.UidValidity(2, "INBOX")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if v4 == v1 {
|
|
t.Fatal("不同用户的 UIDVALIDITY 不应相同")
|
|
}
|
|
}
|