package email import ( "net" "strings" "testing" "time" ) func TestFetchSinceRun(t *testing.T) { mk := func(subject string) string { return "Subject: " + subject + "\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nbody\r\n" } f := &fakeIMAP{ uids: []uint32{1, 2, 3}, msgs: map[uint32]string{1: mk("one"), 2: mk("two"), 3: mk("three")}, } fs := FetchSince{ Addr: "mail.example:993", User: "kami", Mailbox: "INBOX", Timeout: 5 * time.Second, Since: time.Date(2026, 7, 30, 0, 0, 0, 0, time.UTC), Max: 2, Skip: func(uid uint32) bool { return uid == 3 }, } msgs, err := fs.RunWith("secret", func(addr string, timeout time.Duration) (*Conn, error) { cli, srv := net.Pipe() go f.serve(t, srv) return NewConn(cli, timeout) }) if err != nil { t.Fatalf("run: %v", err) } // Newest first, the already-seen UID skipped, Max respected. if len(msgs) != 2 { t.Fatalf("got %d messages, want 2: %+v", len(msgs), msgs) } if msgs[0].Subject != "two" || msgs[1].Subject != "one" { t.Errorf("subjects = %q,%q, want two,one (newest first)", msgs[0].Subject, msgs[1].Subject) } if strings.Contains(strings.Join(f.cmds, " "), "UID FETCH 3") { t.Error("a skipped UID must not be fetched again") } } func TestFetchSinceRequiresConfig(t *testing.T) { if _, err := (FetchSince{}).Run("secret"); err == nil { t.Fatal("an unconfigured mailbox must not be read") } }