package imapserver import ( "testing" "github.com/mjl-/mox/imapclient" ) func TestAppend(t *testing.T) { defer mockUIDValidity()() tc := start(t) // note: with switchboard because this connection stays alive unlike tc2. defer tc.close() tc2 := startNoSwitchboard(t) // note: without switchboard because this connection will break during tests. defer tc2.close() tc3 := startNoSwitchboard(t) defer tc3.close() tc2.client.Login("mjl@mox.example", password0) tc2.client.Select("inbox") tc.client.Login("mjl@mox.example", password0) tc.client.Select("inbox") tc3.client.Login("mjl@mox.example", password0) tc2.transactf("bad", "append") // Missing params. tc2.transactf("bad", `append inbox`) // Missing message. tc2.transactf("bad", `append inbox "test"`) // Message must be literal. // Syntax error for line ending in literal causes connection abort. tc2.transactf("bad", "append inbox (\\Badflag) {1+}\r\nx") // Unknown flag. tc2 = startNoSwitchboard(t) defer tc2.close() tc2.client.Login("mjl@mox.example", password0) tc2.client.Select("inbox") tc2.transactf("bad", "append inbox () \"bad time\" {1+}\r\nx") // Bad time. tc2 = startNoSwitchboard(t) defer tc2.close() tc2.client.Login("mjl@mox.example", password0) tc2.client.Select("inbox") tc2.transactf("no", "append nobox (\\Seen) \" 1-Jan-2022 10:10:00 +0100\" {1}") tc2.xcode("TRYCREATE") tc2.transactf("ok", "append inbox (\\Seen Label1 $label2) \" 1-Jan-2022 10:10:00 +0100\" {1+}\r\nx") tc2.xuntagged(imapclient.UntaggedExists(1)) tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UID: 1}) tc.transactf("ok", "noop") uid1 := imapclient.FetchUID(1) flags := imapclient.FetchFlags{`\Seen`, "$label2", "label1"} tc.xuntagged(imapclient.UntaggedExists(1), imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, flags}}) tc3.transactf("ok", "noop") tc3.xuntagged() // Inbox is not selected, nothing to report. tc2.transactf("ok", "append inbox (\\Seen) \" 1-Jan-2022 10:10:00 +0100\" UTF8 ({47+}\r\ncontent-type: just completely invalid;;\r\n\r\ntest)") tc2.xuntagged(imapclient.UntaggedExists(2)) tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UID: 2}) tc2.transactf("ok", "append inbox (\\Seen) \" 1-Jan-2022 10:10:00 +0100\" UTF8 ({31+}\r\ncontent-type: text/plain;\n\ntest)") tc2.xuntagged(imapclient.UntaggedExists(3)) tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UID: 3}) // Messages that we cannot parse are marked as application/octet-stream. Perhaps // the imap client knows how to deal with them. tc2.transactf("ok", "uid fetch 2 body") uid2 := imapclient.FetchUID(2) xbs := imapclient.FetchBodystructure{ RespAttr: "BODY", Body: imapclient.BodyTypeBasic{ MediaType: "APPLICATION", MediaSubtype: "OCTET-STREAM", BodyFields: imapclient.BodyFields{ Octets: 4, }, }, } tc2.xuntagged(imapclient.UntaggedFetch{Seq: 2, Attrs: []imapclient.FetchAttr{uid2, xbs}}) tclimit := startArgs(t, false, false, true, true, "limit") defer tclimit.close() tclimit.client.Login("limit@mox.example", password0) tclimit.client.Select("inbox") // First message of 1 byte is within limits. tclimit.transactf("ok", "append inbox (\\Seen Label1 $label2) \" 1-Jan-2022 10:10:00 +0100\" {1+}\r\nx") tclimit.xuntagged(imapclient.UntaggedExists(1)) // Second message would take account past limit. tclimit.transactf("no", "append inbox (\\Seen Label1 $label2) \" 1-Jan-2022 10:10:00 +0100\" {1+}\r\nx") tclimit.xcode("OVERQUOTA") }