diff --git a/go.mod b/go.mod index 4291717..8041b34 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/gorilla/sessions v1.1.3 github.com/gorilla/websocket v1.4.0 github.com/jhillyerd/enmime v0.2.1 + github.com/jhillyerd/goldiff v0.1.0 github.com/kelseyhightower/envconfig v1.3.0 github.com/microcosm-cc/bluemonday v1.0.1 github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index 7b3fe17..55a81b2 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ github.com/jaytaylor/html2text v0.0.0-20180606194806-57d518f124b0 h1:xqgexXAGQgY github.com/jaytaylor/html2text v0.0.0-20180606194806-57d518f124b0/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= github.com/jhillyerd/enmime v0.2.1 h1:YodBfMH3jmrZn68Gg4ZoZH1ECDsdh8BLW9+DjoFce6o= github.com/jhillyerd/enmime v0.2.1/go.mod h1:0gWUCFBL87cvx6/MSSGNBHJ6r+fMArqltDFwHxC10P4= +github.com/jhillyerd/goldiff v0.1.0 h1:7JzKPKVwAg1GzrbnsToYzq3Y5+S7dXM4hgEYiOzaf4A= +github.com/jhillyerd/goldiff v0.1.0/go.mod h1:WeDal6DTqhbMhNkf5REzWCIvKl3JWs0Q9omZ/huIWAs= github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM= github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4= diff --git a/pkg/test/integration_test.go b/pkg/test/integration_test.go new file mode 100644 index 0000000..3dbca28 --- /dev/null +++ b/pkg/test/integration_test.go @@ -0,0 +1,173 @@ +package test + +import ( + "bytes" + "context" + "fmt" + "io/ioutil" + smtpclient "net/smtp" + "os" + "path/filepath" + "testing" + "time" + + "github.com/jhillyerd/goldiff" + "github.com/jhillyerd/inbucket/pkg/config" + "github.com/jhillyerd/inbucket/pkg/message" + "github.com/jhillyerd/inbucket/pkg/msghub" + "github.com/jhillyerd/inbucket/pkg/policy" + "github.com/jhillyerd/inbucket/pkg/rest" + "github.com/jhillyerd/inbucket/pkg/rest/client" + "github.com/jhillyerd/inbucket/pkg/server/smtp" + "github.com/jhillyerd/inbucket/pkg/server/web" + "github.com/jhillyerd/inbucket/pkg/storage" + "github.com/jhillyerd/inbucket/pkg/storage/mem" + "github.com/jhillyerd/inbucket/pkg/webui" +) + +const ( + restBaseURL = "http://127.0.0.1:9000/" + smtpHost = "127.0.0.1:2500" +) + +func TestSuite(t *testing.T) { + stopServer, err := startServer() + if err != nil { + t.Fatal(err) + } + _ = stopServer + // defer stopServer() + + testCases := []struct { + name string + test func(*testing.T) + }{ + {"basic", testBasic}, + {"fullname", testFullname}, + } + for _, tc := range testCases { + t.Run(tc.name, tc.test) + } +} + +func testBasic(t *testing.T) { + client, err := client.New(restBaseURL) + if err != nil { + t.Fatal(err) + } + from := "fromuser@inbucket.org" + to := []string{"recipient@inbucket.org"} + input := readTestData("basic.txt") + + // Send mail + err = smtpclient.SendMail(smtpHost, nil, from, to, input) + if err != nil { + t.Fatal(err) + } + + // Confirm receipt + msg, err := client.GetMessage("recipient", "latest") + if err != nil { + t.Fatal(err) + } + if msg == nil { + t.Errorf("Got nil message, wanted non-nil message.") + } + + // Compare to golden. + got := formatMessage(msg) + goldiff.File(t, got, "testdata", "basic.golden") +} + +func testFullname(t *testing.T) { + client, err := client.New(restBaseURL) + if err != nil { + t.Fatal(err) + } + from := "fromuser@inbucket.org" + to := []string{"recipient@inbucket.org"} + input := readTestData("fullname.txt") + + // Send mail + err = smtpclient.SendMail(smtpHost, nil, from, to, input) + if err != nil { + t.Fatal(err) + } + + // Confirm receipt + msg, err := client.GetMessage("recipient", "latest") + if err != nil { + t.Fatal(err) + } + if msg == nil { + t.Errorf("Got nil message, wanted non-nil message.") + } + + // Compare to golden. + got := formatMessage(msg) + goldiff.File(t, got, "testdata", "fullname.golden") +} + +func formatMessage(m *client.Message) []byte { + b := &bytes.Buffer{} + fmt.Fprintf(b, "Mailbox: %v\n", m.Mailbox) + fmt.Fprintf(b, "From: %v\n", m.From) + fmt.Fprintf(b, "To: %v\n", m.To) + fmt.Fprintf(b, "Subject: %v\n", m.Subject) + fmt.Fprintf(b, "Size: %v\n", m.Size) + fmt.Fprintf(b, "\nBODY TEXT:\n%v\n", m.Body.Text) + fmt.Fprintf(b, "\nBODY HTML:\n%v\n", m.Body.HTML) + return b.Bytes() +} + +func startServer() (func(), error) { + // TODO Refactor inbucket/main.go so we don't need to repeat all this here. + storage.Constructors["memory"] = mem.New + os.Clearenv() + conf, err := config.Process() + if err != nil { + return nil, err + } + rootCtx, rootCancel := context.WithCancel(context.Background()) + shutdownChan := make(chan bool) + store, err := storage.FromConfig(conf.Storage) + if err != nil { + rootCancel() + return nil, err + } + msgHub := msghub.New(rootCtx, conf.Web.MonitorHistory) + addrPolicy := &policy.Addressing{Config: conf} + mmanager := &message.StoreManager{AddrPolicy: addrPolicy, Store: store, Hub: msgHub} + // Start HTTP server. + web.Initialize(conf, shutdownChan, mmanager, msgHub) + rest.SetupRoutes(web.Router.PathPrefix("/api/").Subrouter()) + webui.SetupRoutes(web.Router) + go web.Start(rootCtx) + // Start SMTP server. + smtpServer := smtp.NewServer(conf.SMTP, shutdownChan, mmanager, addrPolicy) + go smtpServer.Start(rootCtx) + + // TODO Implmement an elegant way to determine server readiness. + time.Sleep(500 * time.Millisecond) + + return func() { + // Shut everything down. + close(shutdownChan) + rootCancel() + smtpServer.Drain() + }, nil +} + +func readTestData(path ...string) []byte { + // Prefix path with testdata. + p := append([]string{"testdata"}, path...) + f, err := os.Open(filepath.Join(p...)) + if err != nil { + panic(err) + } + data, err := ioutil.ReadAll(f) + if err != nil { + panic(err) + } + return data +} diff --git a/pkg/test/testdata/basic.golden b/pkg/test/testdata/basic.golden new file mode 100644 index 0000000..014c93f --- /dev/null +++ b/pkg/test/testdata/basic.golden @@ -0,0 +1,12 @@ +Mailbox: recipient +From: +To: [] +Subject: basic subject +Size: 217 + +BODY TEXT: +Basic message. + + +BODY HTML: + diff --git a/pkg/test/testdata/basic.txt b/pkg/test/testdata/basic.txt new file mode 100644 index 0000000..1087c28 --- /dev/null +++ b/pkg/test/testdata/basic.txt @@ -0,0 +1,5 @@ +From: fromuser@inbucket.org +To: recipient@inbucket.org +Subject: basic subject + +Basic message. diff --git a/pkg/test/testdata/fullname.golden b/pkg/test/testdata/fullname.golden new file mode 100644 index 0000000..e42108f --- /dev/null +++ b/pkg/test/testdata/fullname.golden @@ -0,0 +1,12 @@ +Mailbox: recipient +From: "From User" +To: ["Rec I. Pient" ] +Subject: basic subject +Size: 246 + +BODY TEXT: +Basic message. + + +BODY HTML: + diff --git a/pkg/test/testdata/fullname.txt b/pkg/test/testdata/fullname.txt new file mode 100644 index 0000000..c595d8c --- /dev/null +++ b/pkg/test/testdata/fullname.txt @@ -0,0 +1,5 @@ +From: From User +To: "Rec I. Pient" +Subject: basic subject + +Basic message.