194 lines
4.8 KiB
Go
194 lines
4.8 KiB
Go
package leveldb
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/require"
|
|
"m8sh.su/x/m8sh/database"
|
|
)
|
|
|
|
func TestUsers_Create(t *testing.T) {
|
|
db, cleanup := openDB(t)
|
|
defer cleanup()
|
|
|
|
users := db.Users()
|
|
|
|
user := database.User{
|
|
Name: "masha@d1.com",
|
|
DisplayName: "Masha",
|
|
Bio: "test bio",
|
|
PublicKey: []byte("pubkey"),
|
|
Avatar: uuid.New(),
|
|
}
|
|
|
|
t.Run("create new user", func(t *testing.T) {
|
|
err := users.Create(user)
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("create duplicate returns ErrAlreadyExists", func(t *testing.T) {
|
|
err := users.Create(user)
|
|
require.ErrorIs(t, err, database.ErrAlreadyExists)
|
|
})
|
|
|
|
t.Run("create with empty name", func(t *testing.T) {
|
|
err := users.Create(database.User{Name: ""})
|
|
require.NoError(t, err)
|
|
})
|
|
}
|
|
|
|
func TestUsers_Get(t *testing.T) {
|
|
db, cleanup := openDB(t)
|
|
defer cleanup()
|
|
|
|
users := db.Users()
|
|
|
|
user := database.User{
|
|
Name: "masha@d1.com",
|
|
DisplayName: "Masha",
|
|
Bio: "test bio",
|
|
PublicKey: []byte("pubkey"),
|
|
Avatar: uuid.New(),
|
|
}
|
|
require.NoError(t, users.Create(user))
|
|
|
|
t.Run("get existing user", func(t *testing.T) {
|
|
got, err := users.Get("masha@d1.com")
|
|
require.NoError(t, err)
|
|
require.Equal(t, user.Name, got.Name)
|
|
require.Equal(t, user.DisplayName, got.DisplayName)
|
|
require.Equal(t, user.Bio, got.Bio)
|
|
require.Equal(t, user.PublicKey, got.PublicKey)
|
|
require.Equal(t, user.Avatar, got.Avatar)
|
|
})
|
|
|
|
t.Run("get non-existing user returns ErrNotFound", func(t *testing.T) {
|
|
_, err := users.Get("nonexistent@d1.com")
|
|
require.ErrorIs(t, err, database.ErrNotFound)
|
|
})
|
|
|
|
t.Run("get user with subscribers count", func(t *testing.T) {
|
|
// Write a valid total key for this user.
|
|
totalKey := key("masha@d1.com", prefixSubsTotal)
|
|
var buf [8]byte
|
|
binary.LittleEndian.PutUint64(buf[:], 42)
|
|
require.NoError(t, db.db.Put(totalKey, buf[:], nil))
|
|
|
|
got, err := users.Get("masha@d1.com")
|
|
require.NoError(t, err)
|
|
require.Equal(t, uint64(42), got.Subscribers)
|
|
})
|
|
|
|
t.Run("get user ignores corrupted total key", func(t *testing.T) {
|
|
// Write garbage as the total key.
|
|
totalKey := key("corrupted@d1.com", prefixSubsTotal)
|
|
require.NoError(t, db.db.Put(totalKey, []byte("not-a-number"), nil))
|
|
|
|
// Create the user.
|
|
require.NoError(t, users.Create(database.User{Name: "corrupted@d1.com"}))
|
|
|
|
// Get should still succeed, Subscribers will be 0 because binary.Uint64 on short data reads whatever it can.
|
|
got, err := users.Get("corrupted@d1.com")
|
|
require.NoError(t, err)
|
|
// 8 bytes not guaranteed, but it won't panic—just reads garbage as uint64.
|
|
_ = got.Subscribers
|
|
})
|
|
}
|
|
|
|
func TestUsers_Update(t *testing.T) {
|
|
db, cleanup := openDB(t)
|
|
defer cleanup()
|
|
|
|
users := db.Users()
|
|
|
|
user := database.User{
|
|
Name: "masha@d1.com",
|
|
DisplayName: "Masha",
|
|
}
|
|
require.NoError(t, users.Create(user))
|
|
|
|
t.Run("update existing user", func(t *testing.T) {
|
|
user.DisplayName = "Masha Updated"
|
|
user.Bio = "new bio"
|
|
|
|
err := users.Update("masha@d1.com", user)
|
|
require.NoError(t, err)
|
|
|
|
got, err := users.Get("masha@d1.com")
|
|
require.NoError(t, err)
|
|
require.Equal(t, "masha@d1.com", got.Name)
|
|
require.Equal(t, "Masha Updated", got.DisplayName)
|
|
require.Equal(t, "new bio", got.Bio)
|
|
})
|
|
|
|
t.Run("update non-existing user returns ErrNotFound", func(t *testing.T) {
|
|
err := users.Update("nonexistent@d1.com", user)
|
|
require.ErrorIs(t, err, database.ErrNotFound)
|
|
})
|
|
}
|
|
|
|
func TestUsers_Delete(t *testing.T) {
|
|
db, cleanup := openDB(t)
|
|
defer cleanup()
|
|
|
|
users := db.Users()
|
|
|
|
user := database.User{
|
|
Name: "masha@d1.com",
|
|
}
|
|
require.NoError(t, users.Create(user))
|
|
|
|
t.Run("delete existing user", func(t *testing.T) {
|
|
err := users.Delete("masha@d1.com")
|
|
require.NoError(t, err)
|
|
|
|
require.False(t, users.CheckExists("masha@d1.com"))
|
|
|
|
_, err = users.Get("masha@d1.com")
|
|
require.ErrorIs(t, err, database.ErrNotFound)
|
|
})
|
|
|
|
t.Run("delete non-existing user returns ErrNotFound", func(t *testing.T) {
|
|
err := users.Delete("nonexistent@d1.com")
|
|
require.ErrorIs(t, err, database.ErrNotFound)
|
|
})
|
|
}
|
|
|
|
func TestUsers_CheckExists(t *testing.T) {
|
|
db, cleanup := openDB(t)
|
|
defer cleanup()
|
|
|
|
users := db.Users()
|
|
|
|
user := database.User{
|
|
Name: "masha@d1.com",
|
|
}
|
|
require.NoError(t, users.Create(user))
|
|
|
|
t.Run("existing user returns true", func(t *testing.T) {
|
|
require.True(t, users.CheckExists("masha@d1.com"))
|
|
})
|
|
|
|
t.Run("non-existing user returns false", func(t *testing.T) {
|
|
require.False(t, users.CheckExists("nonexistent@d1.com"))
|
|
})
|
|
}
|
|
|
|
func TestUsers_AfterCloseReturnsError(t *testing.T) {
|
|
path := t.TempDir() + "/db"
|
|
db, err := New(path)
|
|
require.NoError(t, err)
|
|
|
|
users := db.Users()
|
|
require.NoError(t, users.Create(database.User{Name: "masha@d1.com"}))
|
|
|
|
require.NoError(t, db.Close())
|
|
|
|
_, err = users.Get("masha@d1.com")
|
|
require.Error(t, err)
|
|
|
|
require.False(t, users.CheckExists("masha@d1.com"))
|
|
}
|