225 lines
6.5 KiB
Go
225 lines
6.5 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"
|
|
)
|
|
|
|
func setupSlackIntegrationServiceTestDB(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{},
|
|
&model.IntegrationApp{},
|
|
), "failed to auto-migrate models")
|
|
|
|
t.Cleanup(func() {
|
|
sqlDB, _ := db.DB()
|
|
sqlDB.Close()
|
|
})
|
|
|
|
return db
|
|
}
|
|
|
|
func setupSlackIntegrationService(t *testing.T) (*SlackIntegrationService, *gorm.DB) {
|
|
t.Helper()
|
|
db := setupSlackIntegrationServiceTestDB(t)
|
|
hookRepo := repository.NewIntegrationHookRepo(db)
|
|
svc := NewSlackIntegrationService(hookRepo)
|
|
return svc, db
|
|
}
|
|
|
|
func seedSlackAccount(db *gorm.DB, t *testing.T) uint {
|
|
t.Helper()
|
|
account := &model.Account{Name: "Test Slack Account"}
|
|
require.NoError(t, db.Create(account).Error, "failed to seed account")
|
|
return account.ID
|
|
}
|
|
|
|
// ========================================
|
|
// SlackIntegrationService — Create tests
|
|
// ========================================
|
|
|
|
func TestSlackIntegrationService_Create(t *testing.T) {
|
|
svc, db := setupSlackIntegrationService(t)
|
|
accountID := seedSlackAccount(db, t)
|
|
|
|
req := CreateSlackRequest{
|
|
ChannelID: "C12345678",
|
|
ChannelName: "general",
|
|
SlackToken: "xoxb-test-token",
|
|
}
|
|
|
|
hook, err := svc.Create(context.Background(), accountID, req)
|
|
assert.NoError(t, err)
|
|
assert.NotZero(t, hook.ID)
|
|
assert.Equal(t, model.HookTypeSlack, hook.HookType)
|
|
assert.Equal(t, model.HookStatusActive, hook.Status)
|
|
assert.Equal(t, accountID, hook.AccountID)
|
|
assert.NotNil(t, hook.Settings)
|
|
}
|
|
|
|
func TestSlackIntegrationService_Create_SettingsStored(t *testing.T) {
|
|
svc, db := setupSlackIntegrationService(t)
|
|
accountID := seedSlackAccount(db, t)
|
|
|
|
req := CreateSlackRequest{
|
|
ChannelID: "C99999999",
|
|
ChannelName: "notifications",
|
|
SlackToken: "xoxb-special-token",
|
|
}
|
|
|
|
hook, err := svc.Create(context.Background(), accountID, req)
|
|
require.NoError(t, err)
|
|
|
|
// Verify that the settings JSON contains the Slack fields
|
|
var settings model.SlackSettings
|
|
err = json.Unmarshal(hook.Settings, &settings)
|
|
require.NoError(t, err, "failed to unmarshal settings JSON")
|
|
|
|
assert.Equal(t, "C99999999", settings.ChannelID)
|
|
assert.Equal(t, "notifications", settings.ChannelName)
|
|
assert.Equal(t, "xoxb-special-token", settings.SlackToken)
|
|
}
|
|
|
|
// ========================================
|
|
// SlackIntegrationService — Update tests
|
|
// ========================================
|
|
|
|
func TestSlackIntegrationService_Update(t *testing.T) {
|
|
svc, db := setupSlackIntegrationService(t)
|
|
accountID := seedSlackAccount(db, t)
|
|
|
|
// Create first
|
|
createReq := CreateSlackRequest{
|
|
ChannelID: "C10000001",
|
|
ChannelName: "old-channel",
|
|
SlackToken: "xoxb-old-token",
|
|
}
|
|
_, err := svc.Create(context.Background(), accountID, createReq)
|
|
require.NoError(t, err)
|
|
|
|
// Update
|
|
updateReq := UpdateSlackRequest{
|
|
ChannelID: "C20000002",
|
|
ChannelName: "new-channel",
|
|
SlackToken: "xoxb-new-token",
|
|
}
|
|
|
|
updated, err := svc.Update(context.Background(), accountID, updateReq)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify updated settings
|
|
var settings model.SlackSettings
|
|
err = json.Unmarshal(updated.Settings, &settings)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "C20000002", settings.ChannelID)
|
|
assert.Equal(t, "new-channel", settings.ChannelName)
|
|
assert.Equal(t, "xoxb-new-token", settings.SlackToken)
|
|
}
|
|
|
|
func TestSlackIntegrationService_Update_NotFound(t *testing.T) {
|
|
svc, db := setupSlackIntegrationService(t)
|
|
accountID := seedSlackAccount(db, t)
|
|
|
|
// No Slack hook created for this account — update should fail
|
|
updateReq := UpdateSlackRequest{
|
|
ChannelID: "C00000000",
|
|
}
|
|
|
|
updated, err := svc.Update(context.Background(), accountID, updateReq)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, updated)
|
|
assert.Contains(t, err.Error(), "not found")
|
|
}
|
|
|
|
// ========================================
|
|
// SlackIntegrationService — Delete tests
|
|
// ========================================
|
|
|
|
func TestSlackIntegrationService_Delete(t *testing.T) {
|
|
svc, db := setupSlackIntegrationService(t)
|
|
accountID := seedSlackAccount(db, t)
|
|
|
|
// Create first
|
|
createReq := CreateSlackRequest{
|
|
ChannelID: "C30000003",
|
|
ChannelName: "delete-me",
|
|
SlackToken: "xoxb-delete-token",
|
|
}
|
|
_, err := svc.Create(context.Background(), accountID, createReq)
|
|
require.NoError(t, err)
|
|
|
|
// Delete
|
|
err = svc.Delete(context.Background(), accountID)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify it's gone — no Slack hooks should remain for this account
|
|
hookRepo := repository.NewIntegrationHookRepo(db)
|
|
hooks, err := hookRepo.FindByAccountAndType(context.Background(), accountID, model.HookTypeSlack)
|
|
assert.NoError(t, err)
|
|
assert.Empty(t, hooks)
|
|
}
|
|
|
|
func TestSlackIntegrationService_Delete_NotFound(t *testing.T) {
|
|
svc, db := setupSlackIntegrationService(t)
|
|
accountID := seedSlackAccount(db, t)
|
|
|
|
// No Slack hook exists for this account — delete should fail
|
|
err := svc.Delete(context.Background(), accountID)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "not found")
|
|
}
|
|
|
|
// ========================================
|
|
// SlackIntegrationService — ListAllChannels tests
|
|
// ========================================
|
|
|
|
func TestSlackIntegrationService_ListAllChannels(t *testing.T) {
|
|
svc, db := setupSlackIntegrationService(t)
|
|
accountID := seedSlackAccount(db, t)
|
|
|
|
// Create a Slack integration first
|
|
createReq := CreateSlackRequest{
|
|
ChannelID: "C40000004",
|
|
ChannelName: "list-channels",
|
|
SlackToken: "xoxb-list-token",
|
|
}
|
|
_, err := svc.Create(context.Background(), accountID, createReq)
|
|
require.NoError(t, err)
|
|
|
|
channels, err := svc.ListAllChannels(context.Background(), accountID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, channels, 1)
|
|
|
|
// The placeholder response contains the configured channel
|
|
assert.Equal(t, "C40000004", channels[0]["id"])
|
|
assert.Equal(t, "list-channels", channels[0]["name"])
|
|
}
|
|
|
|
func TestSlackIntegrationService_ListAllChannels_NotFound(t *testing.T) {
|
|
svc, db := setupSlackIntegrationService(t)
|
|
accountID := seedSlackAccount(db, t)
|
|
|
|
// No Slack integration exists for this account
|
|
channels, err := svc.ListAllChannels(context.Background(), accountID)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, channels)
|
|
assert.Contains(t, err.Error(), "not found")
|
|
} |