1package imapserver
2
3import (
4 "strings"
5 "testing"
6
7 "github.com/mjl-/mox/imapclient"
8)
9
10func TestStore(t *testing.T) {
11 tc := start(t)
12 defer tc.close()
13
14 tc.client.Login("mjl@mox.example", password0)
15 tc.client.Enable("imap4rev2")
16
17 tc.client.Append("inbox", nil, nil, []byte(exampleMsg))
18 tc.client.Select("inbox")
19
20 uid1 := imapclient.FetchUID(1)
21 noflags := imapclient.FetchFlags(nil)
22
23 tc.transactf("ok", "store 1 flags.silent ()")
24 tc.xuntagged()
25
26 tc.transactf("ok", `store 1 flags ()`)
27 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, noflags}})
28 tc.transactf("ok", `fetch 1 flags`)
29 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, noflags}})
30
31 tc.transactf("ok", `store 1 flags.silent (\Seen)`)
32 tc.xuntagged()
33 tc.transactf("ok", `fetch 1 flags`)
34 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, imapclient.FetchFlags{`\Seen`}}})
35
36 tc.transactf("ok", `store 1 flags ($Junk)`)
37 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, imapclient.FetchFlags{`$Junk`}}})
38 tc.transactf("ok", `fetch 1 flags`)
39 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, imapclient.FetchFlags{`$Junk`}}})
40
41 tc.transactf("ok", `store 1 +flags ()`)
42 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, imapclient.FetchFlags{`$Junk`}}})
43 tc.transactf("ok", `store 1 +flags (\Deleted)`)
44 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, imapclient.FetchFlags{`\Deleted`, `$Junk`}}})
45 tc.transactf("ok", `fetch 1 flags`)
46 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, imapclient.FetchFlags{`\Deleted`, `$Junk`}}})
47
48 tc.transactf("ok", `store 1 -flags \Deleted $Junk`)
49 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, noflags}})
50 tc.transactf("ok", `fetch 1 flags`)
51 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, noflags}})
52
53 tc.transactf("bad", "store 2 flags ()") // ../rfc/9051:7018
54
55 tc.transactf("ok", "uid store 1 flags ()")
56 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, noflags}})
57
58 tc.transactf("ok", "store 1 flags (new)") // New flag.
59 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, imapclient.FetchFlags{"new"}}})
60 tc.transactf("ok", "store 1 flags (new new a b c)") // Duplicates are ignored.
61 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, imapclient.FetchFlags{"a", "b", "c", "new"}}})
62 tc.transactf("ok", "store 1 +flags (new new c d e)")
63 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, imapclient.FetchFlags{"a", "b", "c", "d", "e", "new"}}})
64 tc.transactf("ok", "store 1 -flags (new new e a c)")
65 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, imapclient.FetchFlags{"b", "d"}}})
66 tc.transactf("ok", "store 1 flags ($Forwarded Different)")
67 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, imapclient.FetchFlags{"$Forwarded", "different"}}})
68
69 tc.transactf("bad", "store") // Need numset, flags and args.
70 tc.transactf("bad", "store 1") // Need flags.
71 tc.transactf("bad", "store 1 +") // Need flags.
72 tc.transactf("bad", "store 1 -") // Need flags.
73 tc.transactf("bad", "store 1 flags ") // Need flags.
74 tc.transactf("bad", "store 1 flags ") // Need flags.
75
76 tc.client.Unselect()
77 tc.transactf("ok", "examine inbox") // Open read-only.
78
79 // Flags are added to mailbox, not removed.
80 flags := strings.Split(`\Seen \Answered \Flagged \Deleted \Draft $Forwarded $Junk $NotJunk $Phishing $MDNSent a b c d different e new`, " ")
81 tc.xuntaggedOpt(false, imapclient.UntaggedFlags(flags))
82
83 tc.transactf("no", `store 1 flags ()`) // No permission to set flags.
84}
85