1package imapserver
2
3import (
4 "testing"
5
6 "github.com/mjl-/mox/imapclient"
7)
8
9func TestCreate(t *testing.T) {
10 testCreate(t, false)
11}
12
13func TestCreateUIDOnly(t *testing.T) {
14 testCreate(t, true)
15}
16
17func testCreate(t *testing.T, uidonly bool) {
18 tc := start(t, uidonly)
19 defer tc.close()
20
21 tc2 := startNoSwitchboard(t, uidonly)
22 defer tc2.closeNoWait()
23
24 tc.login("mjl@mox.example", password0)
25 tc2.login("mjl@mox.example", password0)
26
27 tc.transactf("no", "create inbox") // Already exists and not allowed. ../rfc/9051:1913
28 tc.transactf("no", "create Inbox") // Idem.
29
30 // Don't allow names that can cause trouble when exporting to directories.
31 tc.transactf("no", "create .")
32 tc.transactf("no", "create ..")
33 tc.transactf("no", "create legit/..")
34 tc.transactf("ok", "create ...") // No special meaning.
35
36 // ../rfc/9051:1937
37 tc.transactf("ok", "create inbox/a/c")
38 tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a"}, imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a/c"})
39
40 tc2.transactf("ok", "noop")
41 tc2.xuntagged(
42 imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "..."},
43 imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a"},
44 imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a/c"},
45 )
46
47 tc.transactf("no", "create inbox/a/c") // Exists.
48
49 tc.transactf("ok", "create inbox/a/x")
50 tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a/x"})
51
52 tc2.transactf("ok", "noop")
53 tc2.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a/x"})
54
55 // ../rfc/9051:1934
56 tc.transactf("ok", "create mailbox/")
57 tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "mailbox"})
58
59 // OldName is only set for IMAP4rev2 or NOTIFY.
60 tc.client.Enable(imapclient.CapIMAP4rev2)
61 tc.transactf("ok", "create mailbox2/")
62 tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "mailbox2", OldName: "mailbox2/"})
63
64 tc2.transactf("ok", "noop")
65 tc2.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "mailbox"}, imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "mailbox2"})
66
67 // If we are already subscribed, create should still work, and we still want to see the subscribed flag.
68 tc.transactf("ok", "subscribe newbox")
69 tc2.transactf("ok", "noop")
70 tc2.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`, `\NonExistent`}, Separator: '/', Mailbox: "newbox"})
71
72 tc.transactf("ok", "create newbox")
73 tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "newbox"})
74 tc2.transactf("ok", "noop")
75 tc2.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "newbox"})
76
77 // todo: test create+delete+create of a name results in a higher uidvalidity.
78
79 tc.transactf("no", "create /bad/root")
80 tc.transactf("no", "create bad//root") // Cannot have internal duplicate slashes.
81 tc.transactf("no", `create ""`) // Refuse empty mailbox name.
82 // We are not allowing special characters.
83 tc.transactf("bad", `create "\n"`)
84 tc.transactf("bad", `create "\x7f"`)
85 tc.transactf("bad", `create "\x9f"`)
86 tc.transactf("bad", `create "\u2028"`)
87 tc.transactf("bad", `create "\u2029"`)
88 tc.transactf("ok", `create "%%"`)
89 tc.transactf("ok", `create "*"`)
90 tc.transactf("no", `create "#"`) // Leading hash not allowed.
91 tc.transactf("ok", `create "test#"`)
92
93 // Create with flags.
94 tc.transactf("no", `create "newwithflags" (use (\unknown))`)
95 tc.transactf("no", `create "newwithflags" (use (\all))`)
96 tc.transactf("ok", `create "newwithflags" (use (\archive))`)
97 tc.transactf("ok", "noop")
98 tc.xuntagged()
99 tc.transactf("ok", `create "newwithflags2" (use (\archive) use (\drafts \sent))`)
100
101 // UTF-7 checks are only for IMAP4 before rev2 and without UTF8=ACCEPT.
102 tc.transactf("ok", `create "&"`) // Interpreted as UTF-8, no UTF-7.
103 tc2.transactf("bad", `create "&"`) // Bad UTF-7.
104 tc2.transactf("ok", `create "&Jjo-"`) // ☺, valid UTF-7.
105
106 tc.transactf("ok", "create expungebox") // Existed in past.
107 tc.transactf("ok", "delete expungebox") // Gone again.
108}
109