Files
gochat/internal/service/linear_notion_integration_service_test.go
T
2026-06-04 15:44:48 +08:00

250 lines
7.0 KiB
Go

package service
import (
"context"
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"github.com/gochat/gochat/internal/model"
"github.com/gochat/gochat/internal/repository"
)
// ========================================
// Shared test helpers
// ========================================
func setupLinearNotionTestDB(t *testing.T) *gorm.DB {
t.Helper()
db, err := gorm.Open(sqlite.Open("file::memory:"), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
require.NoError(t, err, "failed to open SQLite test database")
require.NoError(t, db.AutoMigrate(
&model.Account{},
&model.IntegrationHook{},
), "failed to auto-migrate models")
t.Cleanup(func() {
sqlDB, _ := db.DB()
sqlDB.Close()
})
return db
}
func seedLinearNotionAccount(db *gorm.DB, t *testing.T) uint {
t.Helper()
account := &model.Account{Name: "Test Account"}
require.NoError(t, db.Create(account).Error, "failed to seed account")
return account.ID
}
func seedLinearHook(db *gorm.DB, t *testing.T, accountID uint) uint {
t.Helper()
settings := model.LinearSettings{
TeamID: "team-1",
TeamName: "Engineering",
AccessToken: "lin_token_123",
}
settingsJSON, err := json.Marshal(settings)
require.NoError(t, err, "failed to marshal Linear settings")
hook := &model.IntegrationHook{
AccountID: accountID,
HookType: model.HookTypeLinear,
Status: model.HookStatusActive,
AccessToken: "lin_token_123",
Settings: settingsJSON,
}
require.NoError(t, db.Create(hook).Error, "failed to seed Linear hook")
return hook.ID
}
func seedNotionHook(db *gorm.DB, t *testing.T, accountID uint) uint {
t.Helper()
settings := model.NotionSettings{
DatabaseID: "db-1",
AccessToken: "notion_token_123",
}
settingsJSON, err := json.Marshal(settings)
require.NoError(t, err, "failed to marshal Notion settings")
hook := &model.IntegrationHook{
AccountID: accountID,
HookType: model.HookTypeNotion,
Status: model.HookStatusActive,
AccessToken: "notion_token_123",
Settings: settingsJSON,
}
require.NoError(t, db.Create(hook).Error, "failed to seed Notion hook")
return hook.ID
}
func setupLinearService(t *testing.T) (*LinearIntegrationService, *gorm.DB) {
t.Helper()
db := setupLinearNotionTestDB(t)
hookRepo := repository.NewIntegrationHookRepo(db)
svc := NewLinearIntegrationService(hookRepo)
return svc, db
}
func setupNotionService(t *testing.T) (*NotionIntegrationService, *gorm.DB) {
t.Helper()
db := setupLinearNotionTestDB(t)
hookRepo := repository.NewIntegrationHookRepo(db)
svc := NewNotionIntegrationService(hookRepo)
return svc, db
}
// ========================================
// LinearIntegrationService tests
// ========================================
func TestLinearIntegrationService_Delete_Success(t *testing.T) {
svc, db := setupLinearService(t)
accountID := seedLinearNotionAccount(db, t)
seedLinearHook(db, t, accountID)
err := svc.Delete(context.Background(), accountID)
assert.NoError(t, err)
// Verify the hook is gone
var count int64
db.Model(&model.IntegrationHook{}).Where("account_id = ? AND hook_type = ?", accountID, model.HookTypeLinear).Count(&count)
assert.Equal(t, int64(0), count)
}
func TestLinearIntegrationService_Delete_NotFound(t *testing.T) {
svc, db := setupLinearService(t)
accountID := seedLinearNotionAccount(db, t)
// No Linear hook seeded
err := svc.Delete(context.Background(), accountID)
assert.Error(t, err)
assert.Contains(t, err.Error(), "Linear integration not found")
}
func TestLinearIntegrationService_GetTeams_Success(t *testing.T) {
svc, db := setupLinearService(t)
accountID := seedLinearNotionAccount(db, t)
seedLinearHook(db, t, accountID)
teams, err := svc.GetTeams(context.Background(), accountID)
assert.NoError(t, err)
assert.Len(t, teams, 1)
assert.Equal(t, "team-1", teams[0]["id"])
assert.Equal(t, "Engineering", teams[0]["name"])
}
func TestLinearIntegrationService_GetTeams_NotFound(t *testing.T) {
svc, db := setupLinearService(t)
accountID := seedLinearNotionAccount(db, t)
// No Linear hook seeded
teams, err := svc.GetTeams(context.Background(), accountID)
assert.Error(t, err)
assert.Nil(t, teams)
assert.Contains(t, err.Error(), "Linear integration not found")
}
func TestLinearIntegrationService_CreateIssue_Success(t *testing.T) {
svc, db := setupLinearService(t)
accountID := seedLinearNotionAccount(db, t)
seedLinearHook(db, t, accountID)
req := CreateIssueRequest{
Title: "Bug in login flow",
Description: "Users cannot log in after password reset",
TeamID: "team-1",
}
result, err := svc.CreateIssue(context.Background(), accountID, req)
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, "Bug in login flow", result["title"])
}
func TestLinearIntegrationService_CreateIssue_NotFound(t *testing.T) {
svc, db := setupLinearService(t)
accountID := seedLinearNotionAccount(db, t)
// No Linear hook seeded
req := CreateIssueRequest{
Title: "Some issue",
TeamID: "team-1",
}
result, err := svc.CreateIssue(context.Background(), accountID, req)
assert.Error(t, err)
assert.Nil(t, result)
assert.Contains(t, err.Error(), "Linear integration not found")
}
func TestLinearIntegrationService_LinkIssue_Success(t *testing.T) {
svc, db := setupLinearService(t)
accountID := seedLinearNotionAccount(db, t)
seedLinearHook(db, t, accountID)
req := LinkIssueRequest{
IssueID: "LIN-42",
ConversationID: 10,
}
result, err := svc.LinkIssue(context.Background(), accountID, req)
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, "linked", result["status"])
assert.Equal(t, "LIN-42", result["issue_id"])
}
func TestLinearIntegrationService_LinkIssue_NotFound(t *testing.T) {
svc, db := setupLinearService(t)
accountID := seedLinearNotionAccount(db, t)
// No Linear hook seeded
req := LinkIssueRequest{
IssueID: "LIN-42",
ConversationID: 10,
}
result, err := svc.LinkIssue(context.Background(), accountID, req)
assert.Error(t, err)
assert.Nil(t, result)
assert.Contains(t, err.Error(), "Linear integration not found")
}
// ========================================
// NotionIntegrationService tests
// ========================================
func TestNotionIntegrationService_Delete_Success(t *testing.T) {
svc, db := setupNotionService(t)
accountID := seedLinearNotionAccount(db, t)
seedNotionHook(db, t, accountID)
err := svc.Delete(context.Background(), accountID)
assert.NoError(t, err)
// Verify the hook is gone
var count int64
db.Model(&model.IntegrationHook{}).Where("account_id = ? AND hook_type = ?", accountID, model.HookTypeNotion).Count(&count)
assert.Equal(t, int64(0), count)
}
func TestNotionIntegrationService_Delete_NotFound(t *testing.T) {
svc, db := setupNotionService(t)
accountID := seedLinearNotionAccount(db, t)
// No Notion hook seeded
err := svc.Delete(context.Background(), accountID)
assert.Error(t, err)
assert.Contains(t, err.Error(), "Notion integration not found")
}