250 lines
7.0 KiB
Go
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")
|
|
} |