diff --git a/config/config.go b/config/config.go index 60eeea8..c9a2d7c 100644 --- a/config/config.go +++ b/config/config.go @@ -233,14 +233,9 @@ func VerifyConfig() error { return err } - TenantID = tools.Normalize(TenantID) + TenantID = DBTenantID(TenantID) if TenantID != "" { logger.Log().Infof("[db] using tenant \"%s\"", TenantID) - re := regexp.MustCompile(`[^a-zA-Z0-9\_]`) - TenantID = re.ReplaceAllString(TenantID, "_") - if !strings.HasSuffix(TenantID, "_") { - TenantID = TenantID + "_" - } } re := regexp.MustCompile(`.*:\d+$`) @@ -632,3 +627,17 @@ func isValidURL(s string) bool { return strings.HasPrefix(u.Scheme, "http") } + +// DBTenantID converts a tenant ID to a DB-friendly value if set +func DBTenantID(s string) string { + s = tools.Normalize(s) + if s != "" { + re := regexp.MustCompile(`[^a-zA-Z0-9\_]`) + s = re.ReplaceAllString(s, "_") + if !strings.HasSuffix(s, "_") { + s = s + "_" + } + } + + return s +} diff --git a/internal/storage/messages_test.go b/internal/storage/messages_test.go index 95f3525..8e9c6e2 100644 --- a/internal/storage/messages_test.go +++ b/internal/storage/messages_test.go @@ -3,10 +3,12 @@ package storage import ( "testing" "time" + + "github.com/axllent/mailpit/config" ) func TestTextEmailInserts(t *testing.T) { - setup() + setup("") defer Close() t.Log("Testing text email storage") @@ -38,113 +40,140 @@ func TestTextEmailInserts(t *testing.T) { } func TestMimeEmailInserts(t *testing.T) { - setup() - defer Close() + for _, tenantID := range []string{"", "MyServer 3", "host.example.com"} { + tenantID = config.DBTenantID(tenantID) - t.Log("Testing mime email storage") + setup(tenantID) - start := time.Now() + if tenantID == "" { + t.Log("Testing mime email storage") + } else { + t.Logf("Testing mime email storage (tenant %s)", tenantID) + } + + start := time.Now() + + for i := 0; i < testRuns; i++ { + if _, err := Store(&testMimeEmail); err != nil { + t.Log("error ", err) + t.Fail() + } + } + + assertEqual(t, CountTotal(), float64(testRuns), "Incorrect number of mime emails stored") + + t.Logf("Inserted %d text emails in %s", testRuns, time.Since(start)) + + delStart := time.Now() + if err := DeleteAllMessages(); err != nil { + t.Log("error ", err) + t.Fail() + } + + assertEqual(t, CountTotal(), float64(0), "incorrect number of mime emails deleted") + + t.Logf("Deleted %d mime emails in %s", testRuns, time.Since(delStart)) + + Close() + } +} + +func TestRetrieveMimeEmail(t *testing.T) { + for _, tenantID := range []string{"", "MyServer 3", "host.example.com"} { + tenantID = config.DBTenantID(tenantID) + + setup(tenantID) + + if tenantID == "" { + t.Log("Testing mime email retrieval") + } else { + t.Logf("Testing mime email retrieval (tenant %s)", tenantID) + } + + id, err := Store(&testMimeEmail) + if err != nil { + t.Log("error ", err) + t.Fail() + } + + msg, err := GetMessage(id) + if err != nil { + t.Log("error ", err) + t.Fail() + } + + assertEqual(t, msg.From.Name, "Sender Smith", "\"From\" name does not match") + assertEqual(t, msg.From.Address, "sender2@example.com", "\"From\" address does not match") + assertEqual(t, msg.Subject, "inline + attachment", "subject does not match") + assertEqual(t, len(msg.To), 1, "incorrect number of recipients") + assertEqual(t, msg.To[0].Name, "Recipient Ross", "\"To\" name does not match") + assertEqual(t, msg.To[0].Address, "recipient2@example.com", "\"To\" address does not match") + assertEqual(t, len(msg.Attachments), 1, "incorrect number of attachments") + assertEqual(t, msg.Attachments[0].FileName, "Sample PDF.pdf", "attachment filename does not match") + assertEqual(t, len(msg.Inline), 1, "incorrect number of inline attachments") + assertEqual(t, msg.Inline[0].FileName, "inline-image.jpg", "inline attachment filename does not match") + + attachmentData, err := GetAttachmentPart(id, msg.Attachments[0].PartID) + if err != nil { + t.Log("error ", err) + t.Fail() + } + assertEqual(t, float64(len(attachmentData.Content)), msg.Attachments[0].Size, "attachment size does not match") + + inlineData, err := GetAttachmentPart(id, msg.Inline[0].PartID) + if err != nil { + t.Log("error ", err) + t.Fail() + } + assertEqual(t, float64(len(inlineData.Content)), msg.Inline[0].Size, "inline attachment size does not match") + + Close() + } +} + +func TestMessageSummary(t *testing.T) { + for _, tenantID := range []string{"", "MyServer 3", "host.example.com"} { + tenantID = config.DBTenantID(tenantID) + + setup(tenantID) + + if tenantID == "" { + t.Log("Testing message summary") + } else { + t.Logf("Testing message summary (tenant %s)", tenantID) + } - for i := 0; i < testRuns; i++ { if _, err := Store(&testMimeEmail); err != nil { t.Log("error ", err) t.Fail() } + + summaries, err := List(0, 0, 1) + if err != nil { + t.Log("error ", err) + t.Fail() + } + + assertEqual(t, len(summaries), 1, "Expected 1 result") + + msg := summaries[0] + + assertEqual(t, msg.From.Name, "Sender Smith", "\"From\" name does not match") + assertEqual(t, msg.From.Address, "sender2@example.com", "\"From\" address does not match") + assertEqual(t, msg.Subject, "inline + attachment", "subject does not match") + assertEqual(t, len(msg.To), 1, "incorrect number of recipients") + assertEqual(t, msg.To[0].Name, "Recipient Ross", "\"To\" name does not match") + assertEqual(t, msg.To[0].Address, "recipient2@example.com", "\"To\" address does not match") + assertEqual(t, msg.Snippet, "Message with inline image and attachment:", "\"Snippet\" does does not match") + assertEqual(t, msg.Attachments, 1, "Expected 1 attachment") + assertEqual(t, msg.MessageID, "33af2ac1-c33d-9738-35e3-a6daf90bbd89@gmail.com", "\"MessageID\" does not match") + + Close() } - - assertEqual(t, CountTotal(), float64(testRuns), "Incorrect number of mime emails stored") - - t.Logf("Inserted %d text emails in %s", testRuns, time.Since(start)) - - delStart := time.Now() - if err := DeleteAllMessages(); err != nil { - t.Log("error ", err) - t.Fail() - } - - assertEqual(t, CountTotal(), float64(0), "incorrect number of mime emails deleted") - - t.Logf("Deleted %d mime emails in %s", testRuns, time.Since(delStart)) -} - -func TestRetrieveMimeEmail(t *testing.T) { - setup() - defer Close() - - t.Log("Testing mime email retrieval") - - id, err := Store(&testMimeEmail) - if err != nil { - t.Log("error ", err) - t.Fail() - } - - msg, err := GetMessage(id) - if err != nil { - t.Log("error ", err) - t.Fail() - } - - assertEqual(t, msg.From.Name, "Sender Smith", "\"From\" name does not match") - assertEqual(t, msg.From.Address, "sender2@example.com", "\"From\" address does not match") - assertEqual(t, msg.Subject, "inline + attachment", "subject does not match") - assertEqual(t, len(msg.To), 1, "incorrect number of recipients") - assertEqual(t, msg.To[0].Name, "Recipient Ross", "\"To\" name does not match") - assertEqual(t, msg.To[0].Address, "recipient2@example.com", "\"To\" address does not match") - assertEqual(t, len(msg.Attachments), 1, "incorrect number of attachments") - assertEqual(t, msg.Attachments[0].FileName, "Sample PDF.pdf", "attachment filename does not match") - assertEqual(t, len(msg.Inline), 1, "incorrect number of inline attachments") - assertEqual(t, msg.Inline[0].FileName, "inline-image.jpg", "inline attachment filename does not match") - - attachmentData, err := GetAttachmentPart(id, msg.Attachments[0].PartID) - if err != nil { - t.Log("error ", err) - t.Fail() - } - assertEqual(t, float64(len(attachmentData.Content)), msg.Attachments[0].Size, "attachment size does not match") - - inlineData, err := GetAttachmentPart(id, msg.Inline[0].PartID) - if err != nil { - t.Log("error ", err) - t.Fail() - } - assertEqual(t, float64(len(inlineData.Content)), msg.Inline[0].Size, "inline attachment size does not match") -} - -func TestMessageSummary(t *testing.T) { - setup() - defer Close() - - t.Log("Testing message summary") - - if _, err := Store(&testMimeEmail); err != nil { - t.Log("error ", err) - t.Fail() - } - - summaries, err := List(0, 0, 1) - if err != nil { - t.Log("error ", err) - t.Fail() - } - - assertEqual(t, len(summaries), 1, "Expected 1 result") - - msg := summaries[0] - - assertEqual(t, msg.From.Name, "Sender Smith", "\"From\" name does not match") - assertEqual(t, msg.From.Address, "sender2@example.com", "\"From\" address does not match") - assertEqual(t, msg.Subject, "inline + attachment", "subject does not match") - assertEqual(t, len(msg.To), 1, "incorrect number of recipients") - assertEqual(t, msg.To[0].Name, "Recipient Ross", "\"To\" name does not match") - assertEqual(t, msg.To[0].Address, "recipient2@example.com", "\"To\" address does not match") - assertEqual(t, msg.Snippet, "Message with inline image and attachment:", "\"Snippet\" does does not match") - assertEqual(t, msg.Attachments, 1, "Expected 1 attachment") - assertEqual(t, msg.MessageID, "33af2ac1-c33d-9738-35e3-a6daf90bbd89@gmail.com", "\"MessageID\" does not match") } func BenchmarkImportText(b *testing.B) { - setup() + setup("") defer Close() for i := 0; i < b.N; i++ { @@ -156,7 +185,7 @@ func BenchmarkImportText(b *testing.B) { } func BenchmarkImportMime(b *testing.B) { - setup() + setup("") defer Close() for i := 0; i < b.N; i++ { diff --git a/internal/storage/search_test.go b/internal/storage/search_test.go index 74065a9..100786a 100644 --- a/internal/storage/search_test.go +++ b/internal/storage/search_test.go @@ -6,133 +6,154 @@ import ( "math/rand" "testing" + "github.com/axllent/mailpit/config" "github.com/jhillyerd/enmime" ) func TestSearch(t *testing.T) { - setup() - defer Close() + for _, tenantID := range []string{"", "MyServer 3", "host.example.com"} { + tenantID = config.DBTenantID(tenantID) - t.Log("Testing search") - for i := 0; i < testRuns; i++ { - msg := enmime.Builder(). - From(fmt.Sprintf("From %d", i), fmt.Sprintf("from-%d@example.com", i)). - CC(fmt.Sprintf("CC %d", i), fmt.Sprintf("cc-%d@example.com", i)). - CC(fmt.Sprintf("CC2 %d", i), fmt.Sprintf("cc2-%d@example.com", i)). - Subject(fmt.Sprintf("Subject line %d end", i)). - Text([]byte(fmt.Sprintf("This is the email body %d .", i))). - To(fmt.Sprintf("To %d", i), fmt.Sprintf("to-%d@example.com", i)). - To(fmt.Sprintf("To2 %d", i), fmt.Sprintf("to2-%d@example.com", i)). - ReplyTo(fmt.Sprintf("Reply To %d", i), fmt.Sprintf("reply-to-%d@example.com", i)) + setup(tenantID) - env, err := msg.Build() + if tenantID == "" { + t.Log("Testing search") + } else { + t.Logf("Testing search (tenant %s)", tenantID) + } + + for i := 0; i < testRuns; i++ { + msg := enmime.Builder(). + From(fmt.Sprintf("From %d", i), fmt.Sprintf("from-%d@example.com", i)). + CC(fmt.Sprintf("CC %d", i), fmt.Sprintf("cc-%d@example.com", i)). + CC(fmt.Sprintf("CC2 %d", i), fmt.Sprintf("cc2-%d@example.com", i)). + Subject(fmt.Sprintf("Subject line %d end", i)). + Text([]byte(fmt.Sprintf("This is the email body %d .", i))). + To(fmt.Sprintf("To %d", i), fmt.Sprintf("to-%d@example.com", i)). + To(fmt.Sprintf("To2 %d", i), fmt.Sprintf("to2-%d@example.com", i)). + ReplyTo(fmt.Sprintf("Reply To %d", i), fmt.Sprintf("reply-to-%d@example.com", i)) + + env, err := msg.Build() + if err != nil { + t.Log("error ", err) + t.Fail() + } + + buf := new(bytes.Buffer) + + if err := env.Encode(buf); err != nil { + t.Log("error ", err) + t.Fail() + } + + bufBytes := buf.Bytes() + + if _, err := Store(&bufBytes); err != nil { + t.Log("error ", err) + t.Fail() + } + } + + for i := 1; i < 51; i++ { + // search a random something that will return a single result + uniqueSearches := []string{ + fmt.Sprintf("from-%d@example.com", i), + fmt.Sprintf("from:from-%d@example.com", i), + fmt.Sprintf("to-%d@example.com", i), + fmt.Sprintf("to:to-%d@example.com", i), + fmt.Sprintf("to2-%d@example.com", i), + fmt.Sprintf("to:to2-%d@example.com", i), + fmt.Sprintf("cc-%d@example.com", i), + fmt.Sprintf("cc:cc-%d@example.com", i), + fmt.Sprintf("cc2-%d@example.com", i), + fmt.Sprintf("cc:cc2-%d@example.com", i), + fmt.Sprintf("reply-to-%d@example.com", i), + fmt.Sprintf("reply-to:\"reply-to-%d@example.com\"", i), + fmt.Sprintf("\"Subject line %d end\"", i), + fmt.Sprintf("subject:\"Subject line %d end\"", i), + fmt.Sprintf("\"the email body %d jdsauk dwqmdqw\"", i), + } + searchIdx := rand.Intn(len(uniqueSearches)) + + search := uniqueSearches[searchIdx] + + summaries, _, err := Search(search, "", 0, 0, 100) + if err != nil { + t.Log("error ", err) + t.Fail() + } + + assertEqual(t, len(summaries), 1, "search result expected") + + assertEqual(t, summaries[0].From.Name, fmt.Sprintf("From %d", i), "\"From\" name does not match") + assertEqual(t, summaries[0].From.Address, fmt.Sprintf("from-%d@example.com", i), "\"From\" address does not match") + assertEqual(t, summaries[0].To[0].Name, fmt.Sprintf("To %d", i), "\"To\" name does not match") + assertEqual(t, summaries[0].To[0].Address, fmt.Sprintf("to-%d@example.com", i), "\"To\" address does not match") + assertEqual(t, summaries[0].Subject, fmt.Sprintf("Subject line %d end", i), "\"Subject\" does not match") + } + + // search something that will return 200 results + summaries, _, err := Search("This is the email body", "", 0, 0, testRuns) if err != nil { t.Log("error ", err) t.Fail() } + assertEqual(t, len(summaries), testRuns, "search results expected") - buf := new(bytes.Buffer) - - if err := env.Encode(buf); err != nil { - t.Log("error ", err) - t.Fail() - } - - bufBytes := buf.Bytes() - - if _, err := Store(&bufBytes); err != nil { - t.Log("error ", err) - t.Fail() - } + Close() } - - for i := 1; i < 51; i++ { - // search a random something that will return a single result - uniqueSearches := []string{ - fmt.Sprintf("from-%d@example.com", i), - fmt.Sprintf("from:from-%d@example.com", i), - fmt.Sprintf("to-%d@example.com", i), - fmt.Sprintf("to:to-%d@example.com", i), - fmt.Sprintf("to2-%d@example.com", i), - fmt.Sprintf("to:to2-%d@example.com", i), - fmt.Sprintf("cc-%d@example.com", i), - fmt.Sprintf("cc:cc-%d@example.com", i), - fmt.Sprintf("cc2-%d@example.com", i), - fmt.Sprintf("cc:cc2-%d@example.com", i), - fmt.Sprintf("reply-to-%d@example.com", i), - fmt.Sprintf("reply-to:\"reply-to-%d@example.com\"", i), - fmt.Sprintf("\"Subject line %d end\"", i), - fmt.Sprintf("subject:\"Subject line %d end\"", i), - fmt.Sprintf("\"the email body %d jdsauk dwqmdqw\"", i), - } - searchIdx := rand.Intn(len(uniqueSearches)) - - search := uniqueSearches[searchIdx] - - summaries, _, err := Search(search, "", 0, 0, 100) - if err != nil { - t.Log("error ", err) - t.Fail() - } - - assertEqual(t, len(summaries), 1, "search result expected") - - assertEqual(t, summaries[0].From.Name, fmt.Sprintf("From %d", i), "\"From\" name does not match") - assertEqual(t, summaries[0].From.Address, fmt.Sprintf("from-%d@example.com", i), "\"From\" address does not match") - assertEqual(t, summaries[0].To[0].Name, fmt.Sprintf("To %d", i), "\"To\" name does not match") - assertEqual(t, summaries[0].To[0].Address, fmt.Sprintf("to-%d@example.com", i), "\"To\" address does not match") - assertEqual(t, summaries[0].Subject, fmt.Sprintf("Subject line %d end", i), "\"Subject\" does not match") - } - - // search something that will return 200 results - summaries, _, err := Search("This is the email body", "", 0, 0, testRuns) - if err != nil { - t.Log("error ", err) - t.Fail() - } - assertEqual(t, len(summaries), testRuns, "search results expected") } func TestSearchDelete100(t *testing.T) { - setup() - defer Close() + for _, tenantID := range []string{"", "MyServer 3", "host.example.com"} { + tenantID = config.DBTenantID(tenantID) - t.Log("Testing search delete of 100 messages") - for i := 0; i < 100; i++ { - if _, err := Store(&testTextEmail); err != nil { + setup(tenantID) + + if tenantID == "" { + t.Log("Testing search delete of 100 messages") + } else { + t.Logf("Testing search delete of 100 messages (tenant %s)", tenantID) + } + + for i := 0; i < 100; i++ { + if _, err := Store(&testTextEmail); err != nil { + t.Log("error ", err) + t.Fail() + } + if _, err := Store(&testMimeEmail); err != nil { + t.Log("error ", err) + t.Fail() + } + } + + _, total, err := Search("from:sender@example.com", "", 0, 0, 100) + if err != nil { t.Log("error ", err) t.Fail() } - if _, err := Store(&testMimeEmail); err != nil { + + assertEqual(t, total, 100, "100 search results expected") + + if err := DeleteSearch("from:sender@example.com", ""); err != nil { t.Log("error ", err) t.Fail() } + + _, total, err = Search("from:sender@example.com", "", 0, 0, 100) + if err != nil { + t.Log("error ", err) + t.Fail() + } + + assertEqual(t, total, 0, "0 search results expected") + + Close() } - - _, total, err := Search("from:sender@example.com", "", 0, 0, 100) - if err != nil { - t.Log("error ", err) - t.Fail() - } - - assertEqual(t, total, 100, "100 search results expected") - - if err := DeleteSearch("from:sender@example.com", ""); err != nil { - t.Log("error ", err) - t.Fail() - } - - _, total, err = Search("from:sender@example.com", "", 0, 0, 100) - if err != nil { - t.Log("error ", err) - t.Fail() - } - - assertEqual(t, total, 0, "0 search results expected") } func TestSearchDelete1100(t *testing.T) { - setup() + setup("") defer Close() t.Log("Testing search delete of 1100 messages") diff --git a/internal/storage/tags_test.go b/internal/storage/tags_test.go index f9ae285..98548e5 100644 --- a/internal/storage/tags_test.go +++ b/internal/storage/tags_test.go @@ -4,127 +4,140 @@ import ( "fmt" "strings" "testing" + + "github.com/axllent/mailpit/config" ) func TestTags(t *testing.T) { - setup() - defer Close() - t.Log("Testing tags") + for _, tenantID := range []string{"", "MyServer 3", "host.example.com"} { + tenantID = config.DBTenantID(tenantID) - ids := []string{} + setup(tenantID) - for i := 0; i < 10; i++ { + if tenantID == "" { + t.Log("Testing tags") + } else { + t.Logf("Testing tags (tenant %s)", tenantID) + } + + ids := []string{} + + for i := 0; i < 10; i++ { + id, err := Store(&testMimeEmail) + if err != nil { + t.Log("error ", err) + t.Fail() + } + ids = append(ids, id) + } + + for i := 0; i < 10; i++ { + if _, err := SetMessageTags(ids[i], []string{fmt.Sprintf("Tag-%d", i)}); err != nil { + t.Log("error ", err) + t.Fail() + } + } + + for i := 0; i < 10; i++ { + message, err := GetMessage(ids[i]) + if err != nil { + t.Log("error ", err) + t.Fail() + } + + if len(message.Tags) != 1 || message.Tags[0] != fmt.Sprintf("Tag-%d", i) { + t.Fatal("Message tags do not match") + } + } + + if err := DeleteAllMessages(); err != nil { + t.Log("error ", err) + t.Fail() + } + + // test 20 tags id, err := Store(&testMimeEmail) if err != nil { t.Log("error ", err) t.Fail() } - ids = append(ids, id) - } - - for i := 0; i < 10; i++ { - if _, err := SetMessageTags(ids[i], []string{fmt.Sprintf("Tag-%d", i)}); err != nil { + newTags := []string{} + for i := 0; i < 20; i++ { + // pad number with 0 to ensure they are returned alphabetically + newTags = append(newTags, fmt.Sprintf("AnotherTag %02d", i)) + } + if _, err := SetMessageTags(id, newTags); err != nil { t.Log("error ", err) t.Fail() } - } + returnedTags := getMessageTags(id) + assertEqual(t, strings.Join(newTags, "|"), strings.Join(returnedTags, "|"), "Message tags do not match") - for i := 0; i < 10; i++ { - message, err := GetMessage(ids[i]) + // remove first tag + if err := deleteMessageTag(id, newTags[0]); err != nil { + t.Log("error ", err) + t.Fail() + } + returnedTags = getMessageTags(id) + assertEqual(t, strings.Join(newTags[1:], "|"), strings.Join(returnedTags, "|"), "Message tags do not match after deleting 1") + + // remove all tags + if err := DeleteAllMessageTags(id); err != nil { + t.Log("error ", err) + t.Fail() + } + returnedTags = getMessageTags(id) + assertEqual(t, "", strings.Join(returnedTags, "|"), "Message tags should be empty") + + // apply the same tag twice + if _, err := SetMessageTags(id, []string{"Duplicate Tag", "Duplicate Tag"}); err != nil { + t.Log("error ", err) + t.Fail() + } + returnedTags = getMessageTags(id) + assertEqual(t, "Duplicate Tag", strings.Join(returnedTags, "|"), "Message tags should be duplicated") + if err := DeleteAllMessageTags(id); err != nil { + t.Log("error ", err) + t.Fail() + } + + // apply tag with invalid characters + if _, err := SetMessageTags(id, []string{"Dirty! \"Tag\""}); err != nil { + t.Log("error ", err) + t.Fail() + } + returnedTags = getMessageTags(id) + assertEqual(t, "Dirty Tag", strings.Join(returnedTags, "|"), "Dirty message tag did not clean as expected") + if err := DeleteAllMessageTags(id); err != nil { + t.Log("error ", err) + t.Fail() + } + + // Check deleted message tags also prune the tags database + allTags := GetAllTags() + assertEqual(t, "", strings.Join(allTags, "|"), "Tags did not delete as expected") + + if err := DeleteAllMessages(); err != nil { + t.Log("error ", err) + t.Fail() + } + + // test 20 tags + id, err = Store(&testTagEmail) if err != nil { t.Log("error ", err) t.Fail() } - if len(message.Tags) != 1 || message.Tags[0] != fmt.Sprintf("Tag-%d", i) { - t.Fatal("Message tags do not match") + returnedTags = getMessageTags(id) + assertEqual(t, "BccTag|CcTag|FromFag|ToTag|X-tag1|X-tag2", strings.Join(returnedTags, "|"), "Tags not detected correctly") + if err := DeleteAllMessageTags(id); err != nil { + t.Log("error ", err) + t.Fail() } + + Close() } - if err := DeleteAllMessages(); err != nil { - t.Log("error ", err) - t.Fail() - } - - // test 20 tags - id, err := Store(&testMimeEmail) - if err != nil { - t.Log("error ", err) - t.Fail() - } - newTags := []string{} - for i := 0; i < 20; i++ { - // pad number with 0 to ensure they are returned alphabetically - newTags = append(newTags, fmt.Sprintf("AnotherTag %02d", i)) - } - if _, err := SetMessageTags(id, newTags); err != nil { - t.Log("error ", err) - t.Fail() - } - returnedTags := getMessageTags(id) - assertEqual(t, strings.Join(newTags, "|"), strings.Join(returnedTags, "|"), "Message tags do not match") - - // remove first tag - if err := deleteMessageTag(id, newTags[0]); err != nil { - t.Log("error ", err) - t.Fail() - } - returnedTags = getMessageTags(id) - assertEqual(t, strings.Join(newTags[1:], "|"), strings.Join(returnedTags, "|"), "Message tags do not match after deleting 1") - - // remove all tags - if err := DeleteAllMessageTags(id); err != nil { - t.Log("error ", err) - t.Fail() - } - returnedTags = getMessageTags(id) - assertEqual(t, "", strings.Join(returnedTags, "|"), "Message tags should be empty") - - // apply the same tag twice - if _, err := SetMessageTags(id, []string{"Duplicate Tag", "Duplicate Tag"}); err != nil { - t.Log("error ", err) - t.Fail() - } - returnedTags = getMessageTags(id) - assertEqual(t, "Duplicate Tag", strings.Join(returnedTags, "|"), "Message tags should be duplicated") - if err := DeleteAllMessageTags(id); err != nil { - t.Log("error ", err) - t.Fail() - } - - // apply tag with invalid characters - if _, err := SetMessageTags(id, []string{"Dirty! \"Tag\""}); err != nil { - t.Log("error ", err) - t.Fail() - } - returnedTags = getMessageTags(id) - assertEqual(t, "Dirty Tag", strings.Join(returnedTags, "|"), "Dirty message tag did not clean as expected") - if err := DeleteAllMessageTags(id); err != nil { - t.Log("error ", err) - t.Fail() - } - - // Check deleted message tags also prune the tags database - allTags := GetAllTags() - assertEqual(t, "", strings.Join(allTags, "|"), "Tags did not delete as expected") - - if err := DeleteAllMessages(); err != nil { - t.Log("error ", err) - t.Fail() - } - - // test 20 tags - id, err = Store(&testTagEmail) - if err != nil { - t.Log("error ", err) - t.Fail() - } - - returnedTags = getMessageTags(id) - assertEqual(t, "BccTag|CcTag|FromFag|ToTag|X-tag1|X-tag2", strings.Join(returnedTags, "|"), "Tags not detected correctly") - if err := DeleteAllMessageTags(id); err != nil { - t.Log("error ", err) - t.Fail() - } } diff --git a/internal/storage/testing.go b/internal/storage/testing.go index a8d3f12..7526793 100644 --- a/internal/storage/testing.go +++ b/internal/storage/testing.go @@ -16,10 +16,11 @@ var ( testRuns = 100 ) -func setup() { +func setup(tenantID string) { logger.NoLogging = true config.MaxMessages = 0 config.Database = os.Getenv("MP_DATABASE") + config.TenantID = config.DBTenantID(tenantID) if err := InitDB(); err != nil { panic(err)