108 lines
4.5 KiB
Go
108 lines
4.5 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func setupYearInReviewServiceTest(t *testing.T) (*gorm.DB, *YearInReviewService, *model.Account, *model.User, *model.Inbox, *model.Contact) {
|
|
t.Helper()
|
|
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.User{},
|
|
&model.Inbox{},
|
|
&model.Contact{},
|
|
&model.Conversation{},
|
|
&model.ReportingEvent{},
|
|
))
|
|
t.Cleanup(func() {
|
|
sqlDB, _ := db.DB()
|
|
_ = sqlDB.Close()
|
|
})
|
|
|
|
account := &model.Account{Name: "Review", Timezone: "UTC"}
|
|
require.NoError(t, db.Create(account).Error)
|
|
user := &model.User{AccountID: account.ID, Name: "Agent", Email: "agent-review@example.com", Password: "secret", Active: true}
|
|
require.NoError(t, db.Create(user).Error)
|
|
inbox := &model.Inbox{AccountID: account.ID, Name: "Web", ChannelType: "web_widget", ChannelID: 1, Enabled: true}
|
|
require.NoError(t, db.Create(inbox).Error)
|
|
contact := &model.Contact{AccountID: account.ID, Name: "Customer", Email: "customer-review@example.com"}
|
|
require.NoError(t, db.Create(contact).Error)
|
|
|
|
return db, NewYearInReviewService(db), account, user, inbox, contact
|
|
}
|
|
|
|
func TestYearInReviewBuildsAndCachesChatwootPayload(t *testing.T) {
|
|
db, svc, account, user, inbox, contact := setupYearInReviewServiceTest(t)
|
|
dayOne := time.Date(2026, time.January, 2, 10, 0, 0, 0, time.UTC)
|
|
dayTwo := time.Date(2026, time.March, 5, 12, 0, 0, 0, time.UTC)
|
|
otherYear := time.Date(2025, time.January, 2, 10, 0, 0, 0, time.UTC)
|
|
otherUserID := user.ID + 99
|
|
|
|
createReviewConversation(t, db, account.ID, inbox.ID, contact.ID, user.ID, dayOne)
|
|
createReviewConversation(t, db, account.ID, inbox.ID, contact.ID, user.ID, dayOne.Add(2*time.Hour))
|
|
createReviewConversation(t, db, account.ID, inbox.ID, contact.ID, user.ID, dayTwo)
|
|
createReviewConversation(t, db, account.ID, inbox.ID, contact.ID, user.ID, otherYear)
|
|
createReviewConversation(t, db, account.ID, inbox.ID, contact.ID, otherUserID, dayOne)
|
|
|
|
require.NoError(t, db.Create(&model.ReportingEvent{Base: model.Base{CreatedAt: dayOne}, AccountID: account.ID, Name: model.MetricNameFirstResponse, UserID: &user.ID, Value: 120.9}).Error)
|
|
require.NoError(t, db.Create(&model.ReportingEvent{Base: model.Base{CreatedAt: dayTwo}, AccountID: account.ID, Name: model.MetricNameFirstResponse, UserID: &user.ID, Value: 240.1}).Error)
|
|
require.NoError(t, db.Create(&model.ReportingEvent{Base: model.Base{CreatedAt: otherYear}, AccountID: account.ID, Name: model.MetricNameFirstResponse, UserID: &user.ID, Value: 999}).Error)
|
|
|
|
data, err := svc.Show(context.Background(), account.ID, user.ID, 2026)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, data)
|
|
assert.Equal(t, 2026, data.Year)
|
|
assert.Equal(t, int64(3), data.TotalConversations)
|
|
require.NotNil(t, data.BusiestDay)
|
|
assert.Equal(t, "Jan 02", data.BusiestDay.Date)
|
|
assert.Equal(t, int64(2), data.BusiestDay.Count)
|
|
assert.Equal(t, int64(180), data.SupportPersonality.AvgResponseTimeSeconds)
|
|
|
|
var refreshed model.User
|
|
require.NoError(t, db.First(&refreshed, user.ID).Error)
|
|
var uiSettings map[string]any
|
|
require.NoError(t, json.Unmarshal(refreshed.UISettings, &uiSettings))
|
|
assert.Contains(t, uiSettings, "year_in_review_1_2026")
|
|
|
|
createReviewConversation(t, db, account.ID, inbox.ID, contact.ID, user.ID, dayTwo.Add(time.Hour))
|
|
cached, err := svc.Show(context.Background(), account.ID, user.ID, 2026)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(3), cached.TotalConversations)
|
|
}
|
|
|
|
func TestYearInReviewReturnsEmptyPersonalityWithoutEvents(t *testing.T) {
|
|
_, svc, account, user, _, _ := setupYearInReviewServiceTest(t)
|
|
|
|
data, err := svc.Show(context.Background(), account.ID, user.ID, 2026)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(0), data.TotalConversations)
|
|
assert.Nil(t, data.BusiestDay)
|
|
assert.Equal(t, int64(0), data.SupportPersonality.AvgResponseTimeSeconds)
|
|
}
|
|
|
|
func createReviewConversation(t *testing.T, db *gorm.DB, accountID, inboxID, contactID, assigneeID uint, createdAt time.Time) {
|
|
t.Helper()
|
|
conversation := &model.Conversation{
|
|
Base: model.Base{CreatedAt: createdAt},
|
|
AccountID: accountID,
|
|
InboxID: inboxID,
|
|
ContactID: contactID,
|
|
AssigneeID: &assigneeID,
|
|
Status: string(model.ConversationStatusOpen),
|
|
ChannelType: "web_widget",
|
|
Channel: "web_widget",
|
|
}
|
|
require.NoError(t, db.Create(conversation).Error)
|
|
}
|