package v1 import ( "context" "encoding/json" "net/http/httptest" "testing" "time" "github.com/gin-gonic/gin" "github.com/gochat/gochat/internal/model" "github.com/gochat/gochat/internal/repository" "github.com/gochat/gochat/internal/service" "github.com/stretchr/testify/require" "gorm.io/datatypes" "gorm.io/driver/sqlite" "gorm.io/gorm" ) func TestChatwoot415SerializerFields(t *testing.T) { account := &model.Account{Base: model.Base{ID: 1}, CustomAttributes: datatypes.JSON(`{"billing_currency":"brl","help_center_generation_id":"gen-1"}`)} accountPayload := serializeAccount(account) custom := accountPayload["custom_attributes"].(map[string]any) require.Equal(t, "brl", custom["billing_currency"]) require.Equal(t, "gen-1", custom["help_center_generation_id"]) category := &model.Category{Base: model.Base{ID: 2}, AccountID: 1, Name: "FAQ", Slug: "faq", Locale: "en", Icon: "book", IconColor: "#123456"} require.Equal(t, "#123456", categoryPayload(category, "en")["icon_color"]) article := &model.Article{CategoryID: &category.ID, Category: category} require.Equal(t, "#123456", articleCategoryPayload(article)["icon_color"]) ctx, _ := gin.CreateTestContext(httptest.NewRecorder()) ctx.Request = httptest.NewRequest("GET", "/", nil) team := &model.Team{Base: model.Base{ID: 3}, AccountID: 1, Name: "Support", Icon: "users", IconColor: "#abcdef"} teamPayload := serializeTeamForAccount(ctx, nil, team) require.Equal(t, "users", teamPayload["icon"]) require.Equal(t, "#abcdef", teamPayload["icon_color"]) portal := &model.Portal{Base: model.Base{ID: 4}, AccountID: 1, Name: "Help", Slug: "help", Locale: "en", PortalConfiguration: json.RawMessage(`{"locale_translations":{"en":{"header":"Help"}}}`)} portalConfigPayload := portalPayload(portal, "en", 0)["config"].(gin.H) require.Equal(t, "Help", portalConfigPayload["locale_translations"].(map[string]any)["en"].(map[string]any)["header"]) inbox := &model.Inbox{Base: model.Base{ID: 5}, AccountID: 1, Name: "Voice", ChannelType: "whatsapp", ChannelConfig: `{"voice_enabled":true,"inbound_calls_enabled":false}`} require.Equal(t, false, serializeInbox(inbox, nil, true)["inbound_calls_enabled"]) frt, nrt, rt := time.Now(), time.Now().Add(time.Minute), time.Now().Add(2*time.Minute) applied := &model.AppliedSLA{FRTTargetAt: &frt, NRTTargetAt: &nrt, RTTargetAt: &rt} slaPayload := serializeAppliedSlaReportApplied(applied) require.Equal(t, frt.Unix(), slaPayload["sla_frt_due_at"]) require.Equal(t, nrt.Unix(), slaPayload["sla_nrt_due_at"]) require.Equal(t, rt.Unix(), slaPayload["sla_rt_due_at"]) } func TestChatwoot415AssignmentPolicyFieldRoundTrip(t *testing.T) { db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=private"), &gorm.Config{}) require.NoError(t, err) require.NoError(t, db.AutoMigrate(&model.Account{}, &model.Inbox{}, &model.AssignmentPolicy{}, &model.InboxAssignmentPolicy{})) account := &model.Account{Name: "Account"} require.NoError(t, db.Create(account).Error) hours := 24 svc := service.NewAssignmentPolicyService(repository.NewAssignmentPolicyRepo(db), repository.NewInboxAssignmentPolicyRepo(db), nil) policy, err := svc.CreateAccountPolicy(context.Background(), account.ID, service.CreatePolicyRequest{Name: "Fresh", ExcludeOlderThanHours: &hours}) require.NoError(t, err) payload, err := svc.SerializePolicy(context.Background(), policy) require.NoError(t, err) require.Equal(t, &hours, policy.ExcludeOlderThanHours) require.Equal(t, &hours, payload["exclude_older_than_hours"]) } func TestChatwoot415CaptainMessageSenderSerializer(t *testing.T) { db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=private"), &gorm.Config{}) require.NoError(t, err) require.NoError(t, db.AutoMigrate(&model.Account{}, &model.CaptainAssistant{}, &model.Conversation{}, &model.Message{}, &model.Attachment{}, &model.Call{})) account := &model.Account{Name: "Account"} require.NoError(t, db.Create(account).Error) assistant := &model.CaptainAssistant{AccountID: account.ID, Name: "Fin", Description: "AI assistant", Config: json.RawMessage(`{}`)} require.NoError(t, db.Create(assistant).Error) message := &model.Message{AccountID: account.ID, SenderID: &assistant.ID, SenderType: "Captain::Assistant", Content: "Answer", MessageType: "outgoing"} payload := serializeMessage(context.Background(), db, message, nil) require.Equal(t, "captain_assistant", payload.Sender["type"]) require.Equal(t, "Fin", payload.Sender["name"]) require.Equal(t, "AI assistant", payload.Sender["description"]) }