6 "github.com/mjl-/mox/imapclient"
7 "github.com/mjl-/mox/store"
10func TestListBasic(t *testing.T) {
14 tc.client.Login("mjl@mox.example", password0)
16 ulist := func(name string, flags ...string) imapclient.UntaggedList {
20 return imapclient.UntaggedList{Flags: flags, Separator: '/', Mailbox: name}
23 tc.last(tc.client.List("INBOX"))
24 tc.xuntagged(ulist("Inbox"))
26 tc.last(tc.client.List("Inbox"))
27 tc.xuntagged(ulist("Inbox"))
29 tc.last(tc.client.List("%"))
30 tc.xuntagged(ulist("Archive", `\Archive`), ulist("Drafts", `\Drafts`), ulist("Inbox"), ulist("Junk", `\Junk`), ulist("Sent", `\Sent`), ulist("Trash", `\Trash`))
32 tc.last(tc.client.List("*"))
33 tc.xuntagged(ulist("Archive", `\Archive`), ulist("Drafts", `\Drafts`), ulist("Inbox"), ulist("Junk", `\Junk`), ulist("Sent", `\Sent`), ulist("Trash", `\Trash`))
35 tc.last(tc.client.List("A*"))
36 tc.xuntagged(ulist("Archive", `\Archive`))
38 tc.client.Create("Inbox/todo")
40 tc.last(tc.client.List("Inbox*"))
41 tc.xuntagged(ulist("Inbox"), ulist("Inbox/todo"))
43 tc.last(tc.client.List("Inbox/%"))
44 tc.xuntagged(ulist("Inbox/todo"))
46 tc.last(tc.client.List("Inbox/*"))
47 tc.xuntagged(ulist("Inbox/todo"))
49 // Leading full INBOX is turned into Inbox, so mailbox matches.
50 tc.last(tc.client.List("INBOX/*"))
51 tc.xuntagged(ulist("Inbox/todo"))
53 // No match because we are only touching various casings of the full "INBOX".
54 tc.last(tc.client.List("INBO*"))
58func TestListExtended(t *testing.T) {
59 defer mockUIDValidity()()
64 tc.client.Login("mjl@mox.example", password0)
66 ulist := func(name string, flags ...string) imapclient.UntaggedList {
70 return imapclient.UntaggedList{Flags: flags, Separator: '/', Mailbox: name}
73 uidvals := map[string]uint32{}
74 use := store.DefaultInitialMailboxes.SpecialUse
75 for _, name := range []string{"Inbox", use.Archive, use.Draft, use.Junk, use.Sent, use.Trash} {
78 for _, name := range store.DefaultInitialMailboxes.Regular {
81 var uidvalnext uint32 = 2
82 uidval := func(name string) uint32 {
83 v, ok := uidvals[name]
92 ustatus := func(name string) imapclient.UntaggedStatus {
93 attrs := map[imapclient.StatusAttr]int64{
94 imapclient.StatusMessages: 0,
95 imapclient.StatusUIDNext: 1,
96 imapclient.StatusUIDValidity: int64(uidval(name)),
97 imapclient.StatusUnseen: 0,
98 imapclient.StatusDeleted: 0,
99 imapclient.StatusSize: 0,
100 imapclient.StatusRecent: 0,
101 imapclient.StatusAppendLimit: 0,
103 return imapclient.UntaggedStatus{Mailbox: name, Attrs: attrs}
107 Fsubscribed = `\Subscribed`
108 Fhaschildren = `\HasChildren`
109 Fhasnochildren = `\HasNoChildren`
110 Fnonexistent = `\NonExistent`
111 Farchive = `\Archive`
118 // untaggedlist with flags subscribed and hasnochildren
119 xlist := func(name string, flags ...string) imapclient.UntaggedList {
120 flags = append([]string{Fhasnochildren, Fsubscribed}, flags...)
121 return ulist(name, flags...)
124 xchildlist := func(name string, flags ...string) imapclient.UntaggedList {
125 u := ulist(name, flags...)
126 comp := imapclient.TaggedExtComp{String: "SUBSCRIBED"}
127 u.Extended = []imapclient.MboxListExtendedItem{{Tag: "CHILDINFO", Val: imapclient.TaggedExtVal{Comp: &comp}}}
131 tc.last(tc.client.ListFull(false, "INBOX"))
132 tc.xuntagged(xlist("Inbox"), ustatus("Inbox"))
134 tc.last(tc.client.ListFull(false, "Inbox"))
135 tc.xuntagged(xlist("Inbox"), ustatus("Inbox"))
137 tc.last(tc.client.ListFull(false, "%"))
138 tc.xuntagged(xlist("Archive", Farchive), ustatus("Archive"), xlist("Drafts", Fdraft), ustatus("Drafts"), xlist("Inbox"), ustatus("Inbox"), xlist("Junk", Fjunk), ustatus("Junk"), xlist("Sent", Fsent), ustatus("Sent"), xlist("Trash", Ftrash), ustatus("Trash"))
140 tc.last(tc.client.ListFull(false, "*"))
141 tc.xuntagged(xlist("Archive", Farchive), ustatus("Archive"), xlist("Drafts", Fdraft), ustatus("Drafts"), xlist("Inbox"), ustatus("Inbox"), xlist("Junk", Fjunk), ustatus("Junk"), xlist("Sent", Fsent), ustatus("Sent"), xlist("Trash", Ftrash), ustatus("Trash"))
143 tc.last(tc.client.ListFull(false, "A*"))
144 tc.xuntagged(xlist("Archive", Farchive), ustatus("Archive"))
146 tc.last(tc.client.ListFull(false, "A*", "Junk"))
147 tc.xuntagged(xlist("Archive", Farchive), ustatus("Archive"), xlist("Junk", Fjunk), ustatus("Junk"))
149 tc.client.Create("Inbox/todo")
151 tc.last(tc.client.ListFull(false, "Inbox*"))
152 tc.xuntagged(ulist("Inbox", Fhaschildren, Fsubscribed), ustatus("Inbox"), xlist("Inbox/todo"), ustatus("Inbox/todo"))
154 tc.last(tc.client.ListFull(false, "Inbox/%"))
155 tc.xuntagged(xlist("Inbox/todo"), ustatus("Inbox/todo"))
157 tc.last(tc.client.ListFull(false, "Inbox/*"))
158 tc.xuntagged(xlist("Inbox/todo"), ustatus("Inbox/todo"))
160 // Leading full INBOX is turned into Inbox, so mailbox matches.
161 tc.last(tc.client.ListFull(false, "INBOX/*"))
162 tc.xuntagged(xlist("Inbox/todo"), ustatus("Inbox/todo"))
164 // No match because we are only touching various casings of the full "INBOX".
165 tc.last(tc.client.ListFull(false, "INBO*"))
168 tc.last(tc.client.ListFull(true, "Inbox"))
169 tc.xuntagged(xchildlist("Inbox", Fsubscribed, Fhaschildren), ustatus("Inbox"))
171 tc.client.Unsubscribe("Inbox")
172 tc.last(tc.client.ListFull(true, "Inbox"))
173 tc.xuntagged(xchildlist("Inbox", Fhaschildren), ustatus("Inbox"))
175 tc.client.Delete("Inbox/todo") // Still subscribed.
176 tc.last(tc.client.ListFull(true, "Inbox"))
177 tc.xuntagged(xchildlist("Inbox", Fhasnochildren), ustatus("Inbox"))
179 // Simple extended list without RETURN options.
180 tc.transactf("ok", `list "" ("inbox")`)
181 tc.xuntagged(ulist("Inbox"))
183 tc.transactf("ok", `list () "" ("inbox") return ()`)
184 tc.xuntagged(ulist("Inbox"))
186 tc.transactf("ok", `list "" ("inbox") return ()`)
187 tc.xuntagged(ulist("Inbox"))
189 tc.transactf("ok", `list () "" ("inbox")`)
190 tc.xuntagged(ulist("Inbox"))
192 tc.transactf("ok", `list (remote) "" ("inbox")`)
193 tc.xuntagged(ulist("Inbox"))
195 tc.transactf("ok", `list (remote) "" "/inbox"`)
198 tc.transactf("ok", `list (remote) "/inbox" ""`)
201 tc.transactf("ok", `list (remote) "inbox" ""`)
204 tc.transactf("ok", `list (remote) "inbox" "a"`)
207 tc.client.Create("inbox/a")
208 tc.transactf("ok", `list (remote) "inbox" "a"`)
209 tc.xuntagged(ulist("Inbox/a"))
211 tc.client.Subscribe("x")
212 tc.transactf("ok", `list (subscribed) "" x return (subscribed)`)
213 tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`, `\NonExistent`}, Separator: '/', Mailbox: "x"})
215 tc.transactf("bad", `list (recursivematch) "" "*"`) // Cannot have recursivematch without a base selection option like subscribed.
216 tc.transactf("bad", `list (recursivematch remote) "" "*"`) // "remote" is not a base selection option.
217 tc.transactf("bad", `list (unknown) "" "*"`) // Unknown selection options must result in BAD.
218 tc.transactf("bad", `list () "" "*" return (unknown)`) // Unknown return options must result in BAD.