1/*2Maddy Mail Server - Composable all-in-one email server.3Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors45This program is free software: you can redistribute it and/or modify6it under the terms of the GNU General Public License as published by7the Free Software Foundation, either version 3 of the License, or8(at your option) any later version.910This program is distributed in the hope that it will be useful,11but WITHOUT ANY WARRANTY; without even the implied warranty of12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13GNU General Public License for more details.1415You should have received a copy of the GNU General Public License16along with this program. If not, see <https://www.gnu.org/licenses/>.17*/1819package smtp2021import (22 "reflect"23 "testing"24 "time"2526 "github.com/emersion/go-message/textproto"27 "github.com/emersion/go-smtp"28 "github.com/foxcpp/maddy/framework/module"29)3031func init() {32 msgIDField = func() (string, error) {33 return "A", nil34 }3536 now = func() time.Time {37 return time.Unix(0, 0)38 }39}4041func TestSubmissionPrepare(t *testing.T) {42 test := func(hdrMap, expectedMap map[string][]string) {43 t.Helper()4445 hdr := textproto.Header{}46 for k, v := range hdrMap {47 for _, field := range v {48 hdr.Add(k, field)49 }50 }5152 endp := testEndpoint(t, "submission", &module.Dummy{}, &module.Dummy{}, nil, nil)53 defer func() {54 // Synchronize the endpoint initialization.55 // Otherwise Close will race with Serve called by setupListeners.56 cl, _ := smtp.Dial("127.0.0.1:" + testPort)57 cl.Close()5859 endp.Close()60 }()6162 session, err := endp.NewSession(nil)63 if err != nil {64 t.Fatal(err)65 }6667 err = session.(*Session).submissionPrepare(&module.MsgMetadata{}, &hdr)68 if expectedMap == nil {69 if err == nil {70 t.Error("Expected an error, got none")71 }72 t.Log(err)73 return74 }75 if expectedMap != nil && err != nil {76 t.Error("Unexpected error:", err)77 return78 }7980 resMap := make(map[string][]string)81 for field := hdr.Fields(); field.Next(); {82 resMap[field.Key()] = append(resMap[field.Key()], field.Value())83 }8485 if !reflect.DeepEqual(expectedMap, resMap) {86 t.Errorf("wrong header result\nwant %#+v\ngot %#+v", expectedMap, resMap)87 }88 }8990 // No From field.91 test(map[string][]string{}, nil)9293 // Malformed From field.94 test(map[string][]string{95 "From": {"<hello@example.org>, \"\""},96 }, nil)97 test(map[string][]string{98 "From": {" adasda"},99 }, nil)100101 // Malformed Reply-To.102 test(map[string][]string{103 "From": {"<hello@example.org>"},104 "Reply-To": {"<hello@example.org>, \"\""},105 }, nil)106107 // Malformed CC.108 test(map[string][]string{109 "From": {"<hello@example.org>"},110 "Reply-To": {"<hello@example.org>"},111 "Cc": {"<hello@example.org>, \"\""},112 }, nil)113114 // Malformed Sender.115 test(map[string][]string{116 "From": {"<hello@example.org>"},117 "Reply-To": {"<hello@example.org>"},118 "Cc": {"<hello@example.org>"},119 "Sender": {"<hello@example.org> asd"},120 }, nil)121122 // Multiple From + no Sender.123 test(map[string][]string{124 "From": {"<hello@example.org>, <hello2@example.org>"},125 }, nil)126127 // Multiple From + valid Sender.128 test(map[string][]string{129 "From": {"<hello@example.org>, <hello2@example.org>"},130 "Sender": {"<hello@example.org>"},131 "Date": {"Fri, 22 Nov 2019 20:51:31 +0800"},132 "Message-Id": {"<foobar@example.org>"},133 }, map[string][]string{134 "From": {"<hello@example.org>, <hello2@example.org>"},135 "Sender": {"<hello@example.org>"},136 "Date": {"Fri, 22 Nov 2019 20:51:31 +0800"},137 "Message-Id": {"<foobar@example.org>"},138 })139140 // Add missing Message-Id.141 test(map[string][]string{142 "From": {"<hello@example.org>"},143 "Date": {"Fri, 22 Nov 2019 20:51:31 +0800"},144 }, map[string][]string{145 "From": {"<hello@example.org>"},146 "Date": {"Fri, 22 Nov 2019 20:51:31 +0800"},147 "Message-Id": {"<A@mx.example.com>"},148 })149150 // Malformed Date.151 test(map[string][]string{152 "From": {"<hello@example.org>"},153 "Date": {"not a date"},154 }, nil)155156 // Add missing Date.157 test(map[string][]string{158 "From": {"<hello@example.org>"},159 "Message-Id": {"<A@mx.example.org>"},160 }, map[string][]string{161 "From": {"<hello@example.org>"},162 "Message-Id": {"<A@mx.example.org>"},163 "Date": {"Thu, 1 Jan 1970 00:00:00 +0000"},164 })165}