File: recent_test.go

package info (click to toggle)
golang-github-protonmail-gluon 0.17.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 16,020 kB
  • sloc: sh: 55; makefile: 5
file content (184 lines) | stat: -rw-r--r-- 7,093 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
package tests

import (
	"testing"
)

func TestRecentSelect(t *testing.T) {
	runManyToOneTestWithAuth(t, defaultServerOptions(t), []int{1, 2, 3}, func(c map[int]*testConnection, _ *testSession) {
		// Client 1 appends a new message to INBOX.
		c[1].doAppend(`INBOX`, buildRFC5322TestLiteral(`To: 1@pm.me`)).expect("OK")

		// Client 2 is the first to be notified of the new message; it appears as recent to client 2.
		c[2].C("A006 select INBOX")
		c[2].Se(`* 1 EXISTS`, `* 1 RECENT`).OK("A006")

		// Client 3 is the second to be notified of the new message; it does not appear as recent to client 3.
		c[3].C("A006 select INBOX")
		c[3].Se(`* 1 EXISTS`, `* 0 RECENT`).OK("A006")
	})
}

func TestRecentStatus(t *testing.T) {
	runManyToOneTestWithAuth(t, defaultServerOptions(t), []int{1, 2, 3}, func(c map[int]*testConnection, _ *testSession) {
		// Client 1 appends a new message to INBOX.
		c[1].doAppend("INBOX", buildRFC5322TestLiteral(`To: 1@pm.me`)).expect("OK")

		// Client 2 is the first to be notified of the new message; it appears as recent to client 2.
		// Calling STATUS must not change the value of RECENT.
		c[2].C("A006 STATUS INBOX (RECENT)")
		c[2].S(`* STATUS "INBOX" (RECENT 1)`).OK("A006")

		// Client 3 is the second to be notified of the new message; it still appears as recent to client 3.
		c[3].C("A006 STATUS INBOX (RECENT)")
		c[3].S(`* STATUS "INBOX" (RECENT 1)`).OK("A006")
	})
}

func TestRecentFetch(t *testing.T) {
	runManyToOneTestWithAuth(t, defaultServerOptions(t), []int{1, 2, 3}, func(c map[int]*testConnection, _ *testSession) {
		// Client 1 appends a new message to INBOX.
		c[1].doAppend(`INBOX`, buildRFC5322TestLiteral(`To: 1@pm.me`)).expect("OK")

		// Client 2 is the first to be notified of the new message; it appears as recent to client 2.
		c[2].C("A006 select INBOX")
		c[2].Se(`* 1 EXISTS`, `* 1 RECENT`).OK("A006")

		// Client 2 fetches the message; it is still recent to client 2.
		c[2].C("A006 fetch 1 (UID FLAGS)")
		c[2].Se(`* 1 FETCH (UID 1 FLAGS (\Recent))`).OK("A006")

		// Client 2 fetches the message again; it is still recent to client 2.
		c[2].C("A006 fetch 1 (UID FLAGS)")
		c[2].Se(`* 1 FETCH (UID 1 FLAGS (\Recent))`).OK("A006")

		// Client 3 is the second to be notified of the new message; it no longer appears as recent to client 3.
		c[3].C("A006 select INBOX")
		c[3].Se(`* 1 EXISTS`, `* 0 RECENT`).OK("A006")

		// Client 3 fetches the message; it is not recent to client 3.
		c[3].C("A006 fetch 1 (UID FLAGS)")
		c[3].Se(`* 1 FETCH (UID 1 FLAGS ())`).OK("A006")
	})
}

func TestRecentAppend(t *testing.T) {
	runManyToOneTestWithAuth(t, defaultServerOptions(t), []int{1, 2, 3}, func(c map[int]*testConnection, _ *testSession) {
		// Client 1 appends a new message to INBOX.
		c[1].doAppend(`INBOX`, buildRFC5322TestLiteral(`To: 1@pm.me`)).expect("OK")

		// Client 2 is the first to be notified of the new message; it appears as recent to client 2.
		c[2].C("A006 select INBOX")
		c[2].Se(`* 1 EXISTS`, `* 1 RECENT`).OK("A006")

		// Client 2 then appends a second message to the mailbox while selected.
		// As it was the first client to perform the operation, it sees the message as recent.
		c[2].doAppend(`INBOX`, buildRFC5322TestLiteral(`To: 2@pm.me`)).expect("OK")
		c[2].C("A006 fetch 2 (UID FLAGS)")
		c[2].Se(`* 2 FETCH (UID 2 FLAGS (\Recent))`).OK("A006")
	})
}

func TestRecentStore(t *testing.T) {
	runManyToOneTestWithAuth(t, defaultServerOptions(t), []int{1, 2}, func(c map[int]*testConnection, s *testSession) {
		mbox, done := c[1].doCreateTempDir()
		defer func() {
			s.flush("user")
			done()
		}()

		// Create a message in mbox.
		c[1].doAppend(mbox, buildRFC5322TestLiteral(`To: 1@pm.me`)).expect(`OK`)

		// Select in the mailbox.
		c[1].Cf(`A002 SELECT %v`, mbox).OK(`A002`)

		// Set the message as deleted.
		c[1].C(`A004 STORE 1 +FLAGS (\Deleted)`)
		c[1].S(`* 1 FETCH (FLAGS (\Deleted \Recent))`)
		c[1].OK(`A004`)

		// The message still has the recent flag when fetching.
		c[1].C("A006 FETCH 1 (UID FLAGS)")
		c[1].Se(`* 1 FETCH (UID 1 FLAGS (\Deleted \Recent))`)
		c[1].OK("A006")

		// Select in the mailbox.
		c[2].Cf(`A002 SELECT %v`, mbox).OK(`A002`)

		// The message does not have the recent flag when fetching because this client wasn't first notified.
		c[2].C("A006 FETCH 1 (UID FLAGS)")
		c[2].Se(`* 1 FETCH (UID 1 FLAGS (\Deleted))`)
		c[2].OK("A006")
	})
}

func TestRecentExists(t *testing.T) {
	runManyToOneTestWithAuth(t, defaultServerOptions(t), []int{1, 2, 3}, func(c map[int]*testConnection, _ *testSession) {
		// Client 1 and B both select INBOX.
		c[1].C("A006 select INBOX").OK("A006")
		c[2].C("A006 select INBOX").OK("A006")

		// Client 3 appends a new message to INBOX.
		c[3].doAppend(`INBOX`, buildRFC5322TestLiteral(`To: 1@pm.me`)).expect("OK")

		// Client 1 is notified of the new message. No recent is sent as client 2 still has the mailbox selected.
		c[1].C("A007 NOOP")
		c[1].S("* 1 EXISTS").OK("A007")

		// Client 2 is notified of the new message second; it does not appear as recent to client 2.
		c[2].C("A007 NOOP")
		c[2].S("* 1 EXISTS").OK("A007")
	})
}

func TestRecentIDLEExists(t *testing.T) {
	runManyToOneTestWithAuth(t, defaultServerOptions(t), []int{1, 2}, func(c map[int]*testConnection, _ *testSession) {
		// Client 1 selects INBOX and IDLEs.
		c[1].C("A006 select INBOX").OK("A006")
		c[1].C("A007 IDLE")
		c[1].S("+ Ready")

		// Client 2 appends two new messages to INBOX.
		c[2].doAppend(`INBOX`, buildRFC5322TestLiteral(`To: 1@pm.me`)).expect("OK")
		c[2].doAppend(`INBOX`, buildRFC5322TestLiteral(`To: 2@pm.me`)).expect("OK")

		// Client 1 receives EXISTS and RECENT updates.
		c[1].S(`* 2 EXISTS`, `* 2 RECENT`)
		c[1].C("DONE")
		c[1].OK(`A007`)
	})
}

func TestRecentIDLEExpunge(t *testing.T) {
	runManyToOneTestWithAuth(t, defaultServerOptions(t), []int{1, 2}, func(c map[int]*testConnection, _ *testSession) {
		// Client 1 creates a second mailbox and begins to IDLE inside it.
		c[1].C("A002 CREATE folder").OK("A002")
		c[1].C("A006 select folder").OK("A006")
		c[1].C("A007 IDLE")
		c[1].S("+ Ready")

		// Client 2 appends two new messages to INBOX.
		c[2].doAppend(`INBOX`, buildRFC5322TestLiteral(`To: 1@pm.me`)).expect("OK")
		c[2].doAppend(`INBOX`, buildRFC5322TestLiteral(`To: 1@pm.me`)).expect("OK")

		// Client 2 moves those two messages to the other folder.
		c[2].C("A006 select INBOX").OK("A006")
		c[2].C("A006 move 1:* folder").OK("A006")

		// Client 1 receives EXISTS. Since Client 2 still has the mailbox selected, recent updates are not sent.
		c[1].S(`* 2 EXISTS`)

		// Client 2 moves those two messages back to INBOX.
		// In doing so, it sees the messages in the folder; they are no longer recent.
		c[2].C("A006 select folder").OK("A006")
		c[2].C("A006 move 1:* INBOX").OK("A006")

		// Client 1 receives EXPUNGE updates for those messages.
		// It receives no RECENT updates because client 2 already saw them.
		// The order of expunge results cannot be guaranteed (MOVE is handled in random order).
		c[1].Sx(`\* \d EXPUNGE`, `\* \d EXPUNGE`)
		c[1].C("DONE")
		c[1].OK(`A007`)
	})
}