6 "github.com/mjl-/mox/imapclient"
9// todo: check that UIDValidity is indeed updated properly.
10func TestRename(t *testing.T) {
14 tc2 := startNoSwitchboard(t)
15 defer tc2.closeNoWait()
17 tc.client.Login("mjl@mox.example", password0)
18 tc2.client.Login("mjl@mox.example", password0)
20 tc.transactf("bad", "rename") // Missing parameters.
21 tc.transactf("bad", "rename x") // Missing destination.
22 tc.transactf("bad", "rename x y ") // Leftover data.
24 tc.transactf("no", "rename doesnotexist newbox") // Does not exist.
26 tc.transactf("no", "rename expungebox newbox") // No longer exists.
27 tc.xcode("NONEXISTENT")
28 tc.transactf("no", `rename "Sent" "Trash"`) // Already exists.
29 tc.xcode("ALREADYEXISTS")
31 tc.client.Create("x", nil)
32 tc.client.Subscribe("sub")
33 tc.client.Create("a/b/c", nil)
34 tc.client.Subscribe("x/y/c") // For later rename, but not affected by rename of x.
35 tc2.transactf("ok", "noop") // Drain.
37 tc.transactf("ok", "rename x z")
38 tc2.transactf("ok", "noop")
39 tc2.xuntagged(imapclient.UntaggedList{Separator: '/', Mailbox: "z"})
41 // OldName is only set for IMAP4rev2 or NOTIFY.
42 tc2.client.Enable("IMAP4rev2")
43 tc.transactf("ok", "rename z y")
44 tc2.transactf("ok", "noop")
45 tc2.xuntagged(imapclient.UntaggedList{Separator: '/', Mailbox: "y", OldName: "z"})
47 // Rename to a mailbox that only exists in database as subscribed.
48 tc.transactf("ok", "rename y sub")
49 tc2.transactf("ok", "noop")
50 tc2.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "sub", OldName: "y"})
52 // Cannot rename a child to a parent. It already exists.
53 tc.transactf("no", "rename a/b/c a/b")
54 tc.xcode("ALREADYEXISTS")
55 tc.transactf("no", "rename a/b a")
56 tc.xcode("ALREADYEXISTS")
58 tc2.transactf("ok", "noop") // Drain.
59 tc.transactf("ok", "rename a/b x/y") // This will cause new parent "x" to be created, and a/b and a/b/c to be renamed.
60 tc2.transactf("ok", "noop")
61 tc2.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "x"}, imapclient.UntaggedList{Separator: '/', Mailbox: "x/y", OldName: "a/b"}, imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "x/y/c", OldName: "a/b/c"})
63 tc.client.Create("k/l", nil)
64 tc.transactf("ok", "rename k/l k/l/m") // With "l" renamed, a new "k" will be created.
65 tc.transactf("ok", `list "" "k*" return (subscribed)`)
66 tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "k"}, imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "k/l"}, imapclient.UntaggedList{Separator: '/', Mailbox: "k/l/m"})
68 // Similar, but with missing parent not subscribed.
69 tc.transactf("ok", "rename k/l/m k/ll")
70 tc.transactf("ok", "delete k/l")
71 tc.transactf("ok", "rename k/ll k/l") // Restored to previous mailboxes now.
72 tc.client.Unsubscribe("k")
73 tc.transactf("ok", "rename k/l k/l/m") // With "l" renamed, a new "k" will be created.
74 tc.transactf("ok", `list "" "k*" return (subscribed)`)
76 imapclient.UntaggedList{Separator: '/', Mailbox: "k"},
77 imapclient.UntaggedList{Flags: []string{"\\Subscribed"}, Separator: '/', Mailbox: "k/l"},
78 imapclient.UntaggedList{Separator: '/', Mailbox: "k/l/m"},
81 tc.transactf("ok", "rename k/l/m k/l/x/y/m") // k/l/x and k/l/x/y will be created.
82 tc.transactf("ok", `list "" "k/l/x*" return (subscribed)`)
84 imapclient.UntaggedList{Separator: '/', Mailbox: "k/l/x"},
85 imapclient.UntaggedList{Separator: '/', Mailbox: "k/l/x/y"},
86 imapclient.UntaggedList{Separator: '/', Mailbox: "k/l/x/y/m"},
89 // Renaming inbox keeps inbox in existence, moves messages, and does not rename children.
90 tc.transactf("ok", "create inbox/a")
91 // To check if UIDs are renumbered properly, we add UIDs 1 and 2. Expunge 1,
92 // keeping only 2. Then rename the inbox, which should renumber UID 2 in the old
93 // inbox to UID 1 in the newly created mailbox.
94 tc.transactf("ok", "append inbox (\\deleted) {1+}\r\nx")
95 tc.transactf("ok", "append inbox (label1) {1+}\r\nx")
96 tc.transactf("ok", `select inbox`)
97 tc.transactf("ok", "expunge")
98 tc.transactf("ok", "rename inbox x/minbox")
99 tc.transactf("ok", `list "" (inbox inbox/a x/minbox)`)
101 imapclient.UntaggedList{Separator: '/', Mailbox: "Inbox"},
102 imapclient.UntaggedList{Separator: '/', Mailbox: "Inbox/a"},
103 imapclient.UntaggedList{Separator: '/', Mailbox: "x/minbox"},
105 tc.transactf("ok", `select x/minbox`)
106 tc.transactf("ok", `uid fetch 1:* flags`)
107 tc.xuntagged(imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{imapclient.FetchUID(1), imapclient.FetchFlags{"label1"}}})
109 // Renaming to new hiearchy that does not have any subscribes.
110 tc.transactf("ok", "rename x/minbox w/w")
111 tc.transactf("ok", `list "" "w*"`)
112 tc.xuntagged(imapclient.UntaggedList{Separator: '/', Mailbox: "w"}, imapclient.UntaggedList{Separator: '/', Mailbox: "w/w"})
114 tc.transactf("ok", "rename inbox misc/old/inbox")
115 tc.transactf("ok", `list "" (misc misc/old/inbox)`)
117 imapclient.UntaggedList{Separator: '/', Mailbox: "misc"},
118 imapclient.UntaggedList{Separator: '/', Mailbox: "misc/old/inbox"},
121 // todo: test create+delete+rename of/to a name results in a higher uidvalidity.