309 lines
9.6 KiB
Go
309 lines
9.6 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
)
|
|
|
|
// --- Helpers for CustomAttributeDefinition repo tests ---
|
|
|
|
func setupCustomAttrDefTestDB(t *testing.T) *gorm.DB {
|
|
t.Helper()
|
|
return setupTestDB(t, &model.CustomAttributeDefinition{})
|
|
}
|
|
|
|
func createCustomAttrDefTestAccount(t *testing.T, db *gorm.DB) *model.Account {
|
|
t.Helper()
|
|
account := &model.Account{Name: "Custom Attr Def Test Account"}
|
|
err := db.Create(account).Error
|
|
require.NoError(t, err, "failed to create test account")
|
|
return account
|
|
}
|
|
|
|
// ===========================================================================
|
|
// Create tests
|
|
// ===========================================================================
|
|
|
|
func TestCustomAttributeDefinitionRepo_Create(t *testing.T) {
|
|
db := setupCustomAttrDefTestDB(t)
|
|
ctx := context.Background()
|
|
repo := NewCustomAttributeDefinitionRepo(db)
|
|
|
|
account := createCustomAttrDefTestAccount(t, db)
|
|
|
|
def := &model.CustomAttributeDefinition{
|
|
AccountID: account.ID,
|
|
AttributeName: "priority",
|
|
AttributeDisplayName: "Priority",
|
|
AttributeType: "text",
|
|
AttributeModel: "conversation",
|
|
Description: "Conversation priority level",
|
|
}
|
|
|
|
err := repo.Create(ctx, def)
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, def.ID)
|
|
assert.Equal(t, account.ID, def.AccountID)
|
|
assert.Equal(t, "priority", def.AttributeName)
|
|
assert.Equal(t, "text", def.AttributeType)
|
|
assert.Equal(t, "conversation", def.AttributeModel)
|
|
}
|
|
|
|
func TestCustomAttributeDefinitionRepo_Create_DuplicateAttributeName(t *testing.T) {
|
|
db := setupCustomAttrDefTestDB(t)
|
|
ctx := context.Background()
|
|
repo := NewCustomAttributeDefinitionRepo(db)
|
|
|
|
account := createCustomAttrDefTestAccount(t, db)
|
|
|
|
def1 := &model.CustomAttributeDefinition{
|
|
AccountID: account.ID,
|
|
AttributeName: "priority",
|
|
AttributeDisplayName: "Priority",
|
|
AttributeType: "text",
|
|
AttributeModel: "conversation",
|
|
}
|
|
require.NoError(t, repo.Create(ctx, def1))
|
|
|
|
// Same attribute_name + same account + same model should fail (unique index)
|
|
def2 := &model.CustomAttributeDefinition{
|
|
AccountID: account.ID,
|
|
AttributeName: "priority",
|
|
AttributeDisplayName: "Priority Level",
|
|
AttributeType: "number",
|
|
AttributeModel: "conversation",
|
|
}
|
|
err := repo.Create(ctx, def2)
|
|
assert.Error(t, err, "duplicate attribute_name within same account+model should fail")
|
|
}
|
|
|
|
// ===========================================================================
|
|
// GetByID tests
|
|
// ===========================================================================
|
|
|
|
func TestCustomAttributeDefinitionRepo_GetByID(t *testing.T) {
|
|
db := setupCustomAttrDefTestDB(t)
|
|
ctx := context.Background()
|
|
repo := NewCustomAttributeDefinitionRepo(db)
|
|
|
|
account := createCustomAttrDefTestAccount(t, db)
|
|
|
|
def := &model.CustomAttributeDefinition{
|
|
AccountID: account.ID,
|
|
AttributeName: "status",
|
|
AttributeDisplayName: "Status",
|
|
AttributeType: "list",
|
|
AttributeModel: "contact",
|
|
}
|
|
require.NoError(t, repo.Create(ctx, def))
|
|
|
|
found, err := repo.GetByID(ctx, def.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, def.ID, found.ID)
|
|
assert.Equal(t, "status", found.AttributeName)
|
|
assert.Equal(t, "list", found.AttributeType)
|
|
}
|
|
|
|
func TestCustomAttributeDefinitionRepo_GetByID_NotFound(t *testing.T) {
|
|
db := setupCustomAttrDefTestDB(t)
|
|
ctx := context.Background()
|
|
repo := NewCustomAttributeDefinitionRepo(db)
|
|
|
|
_, err := repo.GetByID(ctx, 9999)
|
|
assert.ErrorIs(t, err, gorm.ErrRecordNotFound)
|
|
}
|
|
|
|
// ===========================================================================
|
|
// FindByAccount tests
|
|
// ===========================================================================
|
|
|
|
func TestCustomAttributeDefinitionRepo_FindByAccount(t *testing.T) {
|
|
db := setupCustomAttrDefTestDB(t)
|
|
ctx := context.Background()
|
|
repo := NewCustomAttributeDefinitionRepo(db)
|
|
|
|
account := createCustomAttrDefTestAccount(t, db)
|
|
|
|
// Create multiple definitions for the same account
|
|
for i, name := range []string{"attr_a", "attr_b", "attr_c"} {
|
|
def := &model.CustomAttributeDefinition{
|
|
AccountID: account.ID,
|
|
AttributeName: name,
|
|
AttributeDisplayName: "Attr " + name,
|
|
AttributeType: "text",
|
|
AttributeModel: "conversation",
|
|
Description: "Test desc " + string(rune('A'+i)),
|
|
}
|
|
require.NoError(t, repo.Create(ctx, def))
|
|
}
|
|
|
|
defs, total, err := repo.FindByAccount(ctx, account.ID, 0, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(3), total)
|
|
assert.Len(t, defs, 3)
|
|
}
|
|
|
|
func TestCustomAttributeDefinitionRepo_FindByAccount_Pagination(t *testing.T) {
|
|
db := setupCustomAttrDefTestDB(t)
|
|
ctx := context.Background()
|
|
repo := NewCustomAttributeDefinitionRepo(db)
|
|
|
|
account := createCustomAttrDefTestAccount(t, db)
|
|
|
|
for i := 0; i < 5; i++ {
|
|
def := &model.CustomAttributeDefinition{
|
|
AccountID: account.ID,
|
|
AttributeName: "paged_attr_" + string(rune('A'+i)),
|
|
AttributeDisplayName: "Paged Attr",
|
|
AttributeType: "text",
|
|
AttributeModel: "conversation",
|
|
}
|
|
require.NoError(t, repo.Create(ctx, def))
|
|
}
|
|
|
|
defs, total, err := repo.FindByAccount(ctx, account.ID, 0, 2)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(5), total)
|
|
assert.Len(t, defs, 2)
|
|
|
|
defs2, total2, err := repo.FindByAccount(ctx, account.ID, 2, 2)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(5), total2)
|
|
assert.Len(t, defs2, 2)
|
|
}
|
|
|
|
func TestCustomAttributeDefinitionRepo_FindByAccount_EmptyAccount(t *testing.T) {
|
|
db := setupCustomAttrDefTestDB(t)
|
|
ctx := context.Background()
|
|
repo := NewCustomAttributeDefinitionRepo(db)
|
|
|
|
defs, total, err := repo.FindByAccount(ctx, 9999, 0, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(0), total)
|
|
assert.Len(t, defs, 0)
|
|
}
|
|
|
|
// ===========================================================================
|
|
// FindByAccountAndModel tests
|
|
// ===========================================================================
|
|
|
|
func TestCustomAttributeDefinitionRepo_FindByAccountAndModel(t *testing.T) {
|
|
db := setupCustomAttrDefTestDB(t)
|
|
ctx := context.Background()
|
|
repo := NewCustomAttributeDefinitionRepo(db)
|
|
|
|
account := createCustomAttrDefTestAccount(t, db)
|
|
|
|
// Create conversation attributes
|
|
for _, name := range []string{"conv_priority", "conv_status"} {
|
|
def := &model.CustomAttributeDefinition{
|
|
AccountID: account.ID,
|
|
AttributeName: name,
|
|
AttributeDisplayName: name,
|
|
AttributeType: "text",
|
|
AttributeModel: "conversation",
|
|
}
|
|
require.NoError(t, repo.Create(ctx, def))
|
|
}
|
|
|
|
// Create contact attributes
|
|
for _, name := range []string{"contact_level", "contact_source"} {
|
|
def := &model.CustomAttributeDefinition{
|
|
AccountID: account.ID,
|
|
AttributeName: name,
|
|
AttributeDisplayName: name,
|
|
AttributeType: "text",
|
|
AttributeModel: "contact",
|
|
}
|
|
require.NoError(t, repo.Create(ctx, def))
|
|
}
|
|
|
|
convDefs, convTotal, err := repo.FindByAccountAndModel(ctx, account.ID, "conversation", 0, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(2), convTotal)
|
|
assert.Len(t, convDefs, 2)
|
|
|
|
contactDefs, contactTotal, err := repo.FindByAccountAndModel(ctx, account.ID, "contact", 0, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(2), contactTotal)
|
|
assert.Len(t, contactDefs, 2)
|
|
}
|
|
|
|
// ===========================================================================
|
|
// Update tests
|
|
// ===========================================================================
|
|
|
|
func TestCustomAttributeDefinitionRepo_Update(t *testing.T) {
|
|
db := setupCustomAttrDefTestDB(t)
|
|
ctx := context.Background()
|
|
repo := NewCustomAttributeDefinitionRepo(db)
|
|
|
|
account := createCustomAttrDefTestAccount(t, db)
|
|
|
|
def := &model.CustomAttributeDefinition{
|
|
AccountID: account.ID,
|
|
AttributeName: "priority",
|
|
AttributeDisplayName: "Priority",
|
|
AttributeType: "text",
|
|
AttributeModel: "conversation",
|
|
}
|
|
require.NoError(t, repo.Create(ctx, def))
|
|
|
|
def.AttributeDisplayName = "Priority Level"
|
|
def.Description = "Updated description"
|
|
|
|
err := repo.Update(ctx, def)
|
|
require.NoError(t, err)
|
|
|
|
found, err := repo.GetByID(ctx, def.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "Priority Level", found.AttributeDisplayName)
|
|
assert.Equal(t, "Updated description", found.Description)
|
|
}
|
|
|
|
// ===========================================================================
|
|
// Delete tests (soft delete)
|
|
// ===========================================================================
|
|
|
|
func TestCustomAttributeDefinitionRepo_Delete(t *testing.T) {
|
|
db := setupCustomAttrDefTestDB(t)
|
|
ctx := context.Background()
|
|
repo := NewCustomAttributeDefinitionRepo(db)
|
|
|
|
account := createCustomAttrDefTestAccount(t, db)
|
|
|
|
def := &model.CustomAttributeDefinition{
|
|
AccountID: account.ID,
|
|
AttributeName: "temp_attr",
|
|
AttributeDisplayName: "Temp",
|
|
AttributeType: "text",
|
|
AttributeModel: "conversation",
|
|
}
|
|
require.NoError(t, repo.Create(ctx, def))
|
|
|
|
err := repo.Delete(ctx, def.ID)
|
|
require.NoError(t, err)
|
|
|
|
// Should not be findable via GetByID (soft delete filters it)
|
|
_, err = repo.GetByID(ctx, def.ID)
|
|
assert.ErrorIs(t, err, gorm.ErrRecordNotFound)
|
|
}
|
|
|
|
func TestCustomAttributeDefinitionRepo_Delete_NotFound(t *testing.T) {
|
|
db := setupCustomAttrDefTestDB(t)
|
|
ctx := context.Background()
|
|
repo := NewCustomAttributeDefinitionRepo(db)
|
|
|
|
// Deleting a non-existent record should still succeed (GORM soft delete on zero rows)
|
|
err := repo.Delete(ctx, 9999)
|
|
// GORM Delete with a specific ID that doesn't exist may or may not error depending on version
|
|
// In practice, GORM won't return an error even if the record doesn't exist for soft delete
|
|
assert.NoError(t, err)
|
|
}
|