Files
m8sh/database/leveldb/emails_test.go
T
2026-06-06 19:20:38 +03:00

263 lines
6.0 KiB
Go

package leveldb
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"m8sh.su/x/m8sh/database"
)
func TestEmail_Put(t *testing.T) {
db, cleanup := openDB(t)
defer cleanup()
email := db.Email()
user := "masha@d1.com"
letter := database.Letter{
From: "alice@d1.com",
To: user,
Subject: "Hello",
Body: []byte("hello world"),
Date: time.Now(),
}
t.Run("put incoming letter", func(t *testing.T) {
err := email.Put(user, letter)
require.NoError(t, err)
})
t.Run("put outgoing letter", func(t *testing.T) {
outgoing := database.Letter{
From: user,
To: "bob@d2.io",
Subject: "Reply",
Body: []byte("thanks"),
Date: time.Now(),
}
err := email.Put(user, outgoing)
require.NoError(t, err)
})
t.Run("put letter with empty body", func(t *testing.T) {
empty := database.Letter{
From: "alice@d1.com",
To: user,
Date: time.Now(),
}
err := email.Put(user, empty)
require.NoError(t, err)
})
t.Run("put letter with attachments", func(t *testing.T) {
withAtt := database.Letter{
From: "alice@d1.com",
To: user,
Subject: "Files",
Body: []byte("check these"),
Date: time.Now(),
Attachments: []database.Attachment{
{Filename: "doc.pdf", Size: 1024, MimeType: "application/pdf"},
},
}
err := email.Put(user, withAtt)
require.NoError(t, err)
})
}
func TestEmail_Get(t *testing.T) {
db, cleanup := openDB(t)
defer cleanup()
email := db.Email()
user := "masha@d1.com"
now := time.Now()
letter := database.Letter{
From: "alice@d1.com",
To: user,
Subject: "Test",
Body: []byte("test body"),
Date: now,
}
err := email.Put(user, letter)
require.NoError(t, err)
t.Run("get existing letter", func(t *testing.T) {
got, err := email.Get(user, "alice@d1.com", now)
require.NoError(t, err)
require.Equal(t, letter.From, got.From)
require.Equal(t, letter.To, got.To)
require.Equal(t, letter.Subject, got.Subject)
require.Equal(t, letter.Body, got.Body)
})
t.Run("get non-existing letter", func(t *testing.T) {
_, err := email.Get(user, "nonexistent@d5.io", now)
require.ErrorIs(t, err, database.ErrNotFound)
})
t.Run("get letter empty body", func(t *testing.T) {
emptyTime := time.Now()
err := email.Put(user, database.Letter{
From: "bob@d2.io",
To: user,
Date: emptyTime,
})
require.NoError(t, err)
got, err := email.Get(user, "bob@d2.io", emptyTime)
require.NoError(t, err)
require.Empty(t, got.Body)
})
}
func TestEmail_List(t *testing.T) {
db, cleanup := openDB(t)
defer cleanup()
email := db.Email()
user := "masha@d1.com"
for i := 0; i < 5; i++ {
err := email.Put(user, database.Letter{
From: "sender@d.com",
To: user,
Subject: "Subject",
Body: []byte("body"),
Date: time.Now().Add(-time.Duration(i) * time.Second),
})
require.NoError(t, err)
}
t.Run("list all", func(t *testing.T) {
list, err := email.List(user, 10, time.Time{})
require.NoError(t, err)
require.Len(t, list, 5)
})
t.Run("list with limit", func(t *testing.T) {
list, err := email.List(user, 2, time.Time{})
require.NoError(t, err)
require.Len(t, list, 2)
})
t.Run("list before time", func(t *testing.T) {
pivot := time.Now().Add(-2 * time.Second)
list, err := email.List(user, 10, pivot)
require.NoError(t, err)
for _, l := range list {
require.True(t, l.Date.Before(pivot))
}
})
t.Run("list empty user", func(t *testing.T) {
list, err := email.List("unknown@d1.com", 10, time.Time{})
require.NoError(t, err)
require.Empty(t, list)
})
}
func TestEmail_MarkSeen(t *testing.T) {
db, cleanup := openDB(t)
defer cleanup()
email := db.Email()
user := "masha@d1.com"
now := time.Now()
err := email.Put(user, database.Letter{
From: "sender@d.com",
To: user,
Subject: "Unread",
Body: []byte("body"),
Date: now,
})
require.NoError(t, err)
t.Run("mark seen", func(t *testing.T) {
err := email.MarkSeen(user, "sender@d.com", now)
require.NoError(t, err)
got, err := email.Get(user, "sender@d.com", now)
require.NoError(t, err)
require.True(t, got.Seen)
})
t.Run("mark seen twice is idempotent", func(t *testing.T) {
err := email.MarkSeen(user, "sender@d.com", now)
require.NoError(t, err)
})
t.Run("mark seen non-existing returns ErrNotFound", func(t *testing.T) {
err := email.MarkSeen(user, "nonexistent@d5.io", now)
require.ErrorIs(t, err, database.ErrNotFound)
})
}
func TestEmail_Delete(t *testing.T) {
db, cleanup := openDB(t)
defer cleanup()
email := db.Email()
user := "masha@d1.com"
now := time.Now()
err := email.Put(user, database.Letter{
From: "sender@d.com",
To: user,
Subject: "Delete me",
Body: []byte("body"),
Date: now,
})
require.NoError(t, err)
t.Run("delete existing", func(t *testing.T) {
err := email.Delete(user, "sender@d.com", now)
require.NoError(t, err)
_, err = email.Get(user, "sender@d.com", now)
require.ErrorIs(t, err, database.ErrNotFound)
})
t.Run("delete non-existing returns ErrNotFound", func(t *testing.T) {
err := email.Delete(user, "nonexistent@d5.io", now)
require.ErrorIs(t, err, database.ErrNotFound)
})
t.Run("delete twice returns ErrNotFound", func(t *testing.T) {
err := email.Delete(user, "sender@d.com", now)
require.ErrorIs(t, err, database.ErrNotFound)
})
}
func TestEmail_AfterCloseReturnsError(t *testing.T) {
path := t.TempDir() + "/db"
db, err := New(path)
require.NoError(t, err)
email := db.Email()
now := time.Now()
err = email.Put("masha@d1.com", database.Letter{
From: "alice@d1.com",
To: "masha@d1.com",
Date: now,
})
require.NoError(t, err)
require.NoError(t, db.Close())
require.NotPanics(t, func() {
email.Get("masha@d1.com", "alice@d1.com", now)
email.List("masha@d1.com", 10, time.Time{})
email.MarkSeen("masha@d1.com", "alice@d1.com", now)
email.Delete("masha@d1.com", "alice@d1.com", now)
email.Put("masha@d1.com", database.Letter{
From: "bob@d2.io",
To: "masha@d1.com",
Date: time.Now(),
})
})
}