package postgres import ( "testing" "time" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "m8sh.su/d/jules/database" ) func setupTestUser(t *testing.T, db *DB) *database.User { u := &database.User{ ID: uuid.New(), Language: "en", Timezone: "UTC", PreferredChat: "telegram", LLMCount: 0, SearchCount: 0, NotificationCount: 0, CountUpdatedAt: time.Now().Truncate(24 * time.Hour), BindCode: uuid.New(), ContactCode: uuid.New(), Role: "free", } err := db.users.Create(t.Context(), u) require.NoError(t, err) return u } func TestUsers_Create(t *testing.T) { db := setupTestDB(t) user := setupTestUser(t, db) assert.NotEqual(t, uuid.Nil, user.ID) assert.NotEqual(t, uuid.Nil, user.BindCode) assert.NotEqual(t, uuid.Nil, user.ContactCode) assert.Equal(t, "telegram", user.PreferredChat) assert.Equal(t, "en", user.Language) assert.Equal(t, "UTC", user.Timezone) assert.Equal(t, 0, user.LLMCount) assert.Equal(t, 0, user.SearchCount) assert.Equal(t, 0, user.NotificationCount) assert.Equal(t, "free", user.Role) } func TestUsers_Get(t *testing.T) { db := setupTestDB(t) user := setupTestUser(t, db) t.Run("by id", func(t *testing.T) { fetched, err := db.users.Get(t.Context(), user.ID, database.UserLookupByID) require.NoError(t, err) assert.Equal(t, user.ID, fetched.ID) }) t.Run("by bind code", func(t *testing.T) { fetched, err := db.users.Get(t.Context(), user.BindCode, database.UserLookupByBindCode) require.NoError(t, err) assert.Equal(t, user.ID, fetched.ID) assert.Equal(t, user.BindCode, fetched.BindCode) }) t.Run("by contact code", func(t *testing.T) { fetched, err := db.users.Get(t.Context(), user.ContactCode, database.UserLookupByContactCode) require.NoError(t, err) assert.Equal(t, user.ID, fetched.ID) assert.Equal(t, user.ContactCode, fetched.ContactCode) }) t.Run("by invalid type", func(t *testing.T) { vv := database.UserLookupByContactCode vv = 6 _, err := db.users.Get(t.Context(), user.ContactCode, vv) require.Error(t, err) assert.Contains(t, err.Error(), "invalid lookup type") }) t.Run("not found", func(t *testing.T) { _, err := db.users.Get(t.Context(), uuid.New(), database.UserLookupByID) assert.ErrorIs(t, err, database.ErrNotFound) }) } func TestUsers_Update(t *testing.T) { db := setupTestDB(t) user := setupTestUser(t, db) t.Run("success", func(t *testing.T) { user.PreferredChat = "whatsapp" user.Language = "ru" user.Timezone = "Europe/Moscow" user.LLMCount = 10 user.SearchCount = 20 user.NotificationCount = 30 user.Role = "premium" user.BindCode = uuid.New() user.ContactCode = uuid.New() err := db.users.Update(t.Context(), user) require.NoError(t, err) fetched, err := db.users.Get(t.Context(), user.ID, database.UserLookupByID) require.NoError(t, err) assert.Equal(t, "whatsapp", fetched.PreferredChat) assert.Equal(t, "ru", fetched.Language) assert.Equal(t, "Europe/Moscow", fetched.Timezone) assert.Equal(t, 10, fetched.LLMCount) assert.Equal(t, 20, fetched.SearchCount) assert.Equal(t, 30, fetched.NotificationCount) assert.Equal(t, "premium", fetched.Role) assert.Equal(t, user.BindCode, fetched.BindCode) assert.Equal(t, user.ContactCode, fetched.ContactCode) }) t.Run("not found", func(t *testing.T) { ghost := &database.User{ID: uuid.New()} err := db.users.Update(t.Context(), ghost) assert.ErrorIs(t, err, database.ErrNotFound) }) } func TestUsers_Delete(t *testing.T) { db := setupTestDB(t) t.Run("success", func(t *testing.T) { user := setupTestUser(t, db) err := db.users.Delete(t.Context(), user.ID) require.NoError(t, err) _, err = db.users.Get(t.Context(), user.ID, database.UserLookupByID) assert.ErrorIs(t, err, database.ErrNotFound) }) t.Run("not found", func(t *testing.T) { err := db.users.Delete(t.Context(), uuid.New()) assert.ErrorIs(t, err, database.ErrNotFound) }) } func TestUsers_Get_DatabaseError(t *testing.T) { db := setupTestDB(t) db.Close() _, err := db.users.Get(t.Context(), uuid.New(), database.UserLookupByID) assert.Error(t, err) assert.NotErrorIs(t, err, database.ErrNotFound) } func TestUsers_Update_DatabaseError(t *testing.T) { db := setupTestDB(t) user := setupTestUser(t, db) db.Close() err := db.users.Update(t.Context(), user) assert.Error(t, err) assert.NotErrorIs(t, err, database.ErrNotFound) } func TestUsers_Delete_DatabaseError(t *testing.T) { db := setupTestDB(t) user := setupTestUser(t, db) db.Close() err := db.users.Delete(t.Context(), user.ID) assert.Error(t, err) assert.NotErrorIs(t, err, database.ErrNotFound) }