1package imapserver
2
3import (
4 "testing"
5
6 "github.com/mjl-/mox/imapclient"
7)
8
9func TestMove(t *testing.T) {
10 testMove(t, false)
11}
12
13func TestMoveUIDOnly(t *testing.T) {
14 testMove(t, true)
15}
16
17func testMove(t *testing.T, uidonly bool) {
18 defer mockUIDValidity()()
19 tc := start(t, uidonly)
20 defer tc.close()
21
22 tc2 := startNoSwitchboard(t, uidonly)
23 defer tc2.closeNoWait()
24
25 tc3 := startNoSwitchboard(t, uidonly)
26 defer tc3.closeNoWait()
27
28 tc.login("mjl@mox.example", password0)
29 tc.client.Select("inbox")
30
31 tc2.login("mjl@mox.example", password0)
32 tc2.client.Select("Trash")
33
34 tc3.login("mjl@mox.example", password0)
35 tc3.client.Select("inbox")
36
37 tc.transactf("bad", "move") // Missing params.
38 tc.transactf("bad", "move 1") // Missing params.
39 tc.transactf("bad", "move 1 inbox ") // Leftover.
40
41 // Seqs 1,2 and UIDs 3,4.
42 tc.client.Append("inbox", makeAppend(exampleMsg))
43 tc.client.Append("inbox", makeAppend(exampleMsg))
44 tc.client.UIDStoreFlagsSet("1:2", true, `\Deleted`)
45 tc.client.Expunge()
46 tc.client.Append("inbox", makeAppend(exampleMsg))
47 tc.client.Append("inbox", makeAppend(exampleMsg))
48
49 if uidonly {
50 tc.transactf("ok", "uid move 1:* Trash")
51 } else {
52 tc.client.Unselect()
53 tc.client.Examine("inbox")
54 tc.transactf("no", "move 1 Trash") // Opened readonly.
55 tc.client.Unselect()
56 tc.client.Select("inbox")
57
58 tc.transactf("no", "move 1 nonexistent")
59 tc.xcodeWord("TRYCREATE")
60
61 tc.transactf("no", "move 1 expungebox")
62 tc.xcodeWord("TRYCREATE")
63
64 tc.transactf("no", "move 1 inbox") // Cannot move to same mailbox.
65
66 tc2.transactf("ok", "noop") // Drain.
67 tc3.transactf("ok", "noop") // Drain.
68
69 tc.transactf("ok", "move 1:* Trash")
70 tc.xuntagged(
71 imapclient.UntaggedResult{Status: "OK", Code: imapclient.CodeCopyUID{DestUIDValidity: 1, From: []imapclient.NumRange{{First: 3, Last: uint32ptr(4)}}, To: []imapclient.NumRange{{First: 1, Last: uint32ptr(2)}}}, Text: "moved"},
72 imapclient.UntaggedExpunge(1),
73 imapclient.UntaggedExpunge(1),
74 )
75 tc2.transactf("ok", "noop")
76 tc2.xuntagged(
77 imapclient.UntaggedExists(2),
78 tc.untaggedFetch(1, 1, imapclient.FetchFlags(nil)),
79 tc.untaggedFetch(2, 2, imapclient.FetchFlags(nil)),
80 )
81 tc3.transactf("ok", "noop")
82 tc3.xuntagged(imapclient.UntaggedExpunge(1), imapclient.UntaggedExpunge(1))
83 }
84
85 // UIDs 5,6
86 tc.client.Append("inbox", makeAppend(exampleMsg))
87 tc.client.Append("inbox", makeAppend(exampleMsg))
88 tc2.transactf("ok", "noop") // Drain.
89 tc3.transactf("ok", "noop") // Drain.
90
91 tc.transactf("no", "uid move 1:4 Trash") // No match.
92 tc.transactf("ok", "uid move 6:5 Trash")
93 if uidonly {
94 tc.xuntagged(
95 imapclient.UntaggedResult{Status: "OK", Code: imapclient.CodeCopyUID{DestUIDValidity: 1, From: []imapclient.NumRange{{First: 5, Last: uint32ptr(6)}}, To: []imapclient.NumRange{{First: 3, Last: uint32ptr(4)}}}, Text: "moved"},
96 imapclient.UntaggedVanished{UIDs: xparseNumSet("5:6")},
97 )
98 } else {
99 tc.xuntagged(
100 imapclient.UntaggedResult{Status: "OK", Code: imapclient.CodeCopyUID{DestUIDValidity: 1, From: []imapclient.NumRange{{First: 5, Last: uint32ptr(6)}}, To: []imapclient.NumRange{{First: 3, Last: uint32ptr(4)}}}, Text: "moved"},
101 imapclient.UntaggedExpunge(1),
102 imapclient.UntaggedExpunge(1),
103 )
104 }
105 tc2.transactf("ok", "noop")
106 tc2.xuntagged(
107 imapclient.UntaggedExists(4),
108 tc2.untaggedFetch(3, 3, imapclient.FetchFlags(nil)),
109 tc2.untaggedFetch(4, 4, imapclient.FetchFlags(nil)),
110 )
111 tc3.transactf("ok", "noop")
112 if uidonly {
113 tc3.xuntagged(imapclient.UntaggedVanished{UIDs: xparseNumSet("5:6")})
114 } else {
115 tc3.xuntagged(imapclient.UntaggedExpunge(1), imapclient.UntaggedExpunge(1))
116 }
117}
118