- Replace UUID with ULID for app ID generation (lexicographically sortable) - Remove container_id column from apps table (migration 002) - Add upaas.id Docker label to identify containers by app ID - Implement FindContainerByAppID in Docker client to query by label - Update handlers and deploy service to use label-based container lookup - Show system-managed upaas.id label in UI with editing disabled Container association is now determined dynamically via Docker label rather than stored in the database, making the system more resilient to container recreation or external changes.
802 lines
18 KiB
Go
802 lines
18 KiB
Go
package models_test
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/fx"
|
|
|
|
"git.eeqj.de/sneak/upaas/internal/config"
|
|
"git.eeqj.de/sneak/upaas/internal/database"
|
|
"git.eeqj.de/sneak/upaas/internal/globals"
|
|
"git.eeqj.de/sneak/upaas/internal/logger"
|
|
"git.eeqj.de/sneak/upaas/internal/models"
|
|
)
|
|
|
|
// Test constants to satisfy goconst linter.
|
|
const (
|
|
testHash = "hash"
|
|
testBranch = "main"
|
|
testValue = "value"
|
|
testEventType = "push"
|
|
)
|
|
|
|
func setupTestDB(t *testing.T) (*database.Database, func()) {
|
|
t.Helper()
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
globals.SetAppname("upaas-test")
|
|
globals.SetVersion("test")
|
|
|
|
globalVars, err := globals.New(fx.Lifecycle(nil))
|
|
require.NoError(t, err)
|
|
|
|
logr, err := logger.New(fx.Lifecycle(nil), logger.Params{
|
|
Globals: globalVars,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
cfg := &config.Config{
|
|
Port: 8080,
|
|
DataDir: tmpDir,
|
|
SessionSecret: "test-secret-key-at-least-32-chars",
|
|
}
|
|
|
|
testDB, err := database.New(fx.Lifecycle(nil), database.Params{
|
|
Logger: logr,
|
|
Config: cfg,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// t.TempDir() automatically cleans up after test
|
|
cleanup := func() {}
|
|
|
|
return testDB, cleanup
|
|
}
|
|
|
|
// User Tests.
|
|
|
|
func TestUserCreateAndFind(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
user := models.NewUser(testDB)
|
|
user.Username = "testuser"
|
|
user.PasswordHash = "hashed_password"
|
|
|
|
err := user.Save(context.Background())
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, user.ID)
|
|
assert.NotZero(t, user.CreatedAt)
|
|
|
|
found, err := models.FindUser(context.Background(), testDB, user.ID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, found)
|
|
assert.Equal(t, "testuser", found.Username)
|
|
}
|
|
|
|
func TestUserUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
user := models.NewUser(testDB)
|
|
user.Username = "original"
|
|
user.PasswordHash = "hash1"
|
|
|
|
err := user.Save(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
user.Username = "updated"
|
|
user.PasswordHash = "hash2"
|
|
|
|
err = user.Save(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
found, err := models.FindUser(context.Background(), testDB, user.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "updated", found.Username)
|
|
assert.Equal(t, "hash2", found.PasswordHash)
|
|
}
|
|
|
|
func TestUserDelete(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
user := models.NewUser(testDB)
|
|
user.Username = "todelete"
|
|
user.PasswordHash = testHash
|
|
|
|
err := user.Save(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
err = user.Delete(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
found, err := models.FindUser(context.Background(), testDB, user.ID)
|
|
require.NoError(t, err)
|
|
assert.Nil(t, found)
|
|
}
|
|
|
|
func TestUserFindByUsername(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
user := models.NewUser(testDB)
|
|
user.Username = "findme"
|
|
user.PasswordHash = testHash
|
|
|
|
err := user.Save(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
found, err := models.FindUserByUsername(
|
|
context.Background(), testDB, "findme",
|
|
)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, found)
|
|
assert.Equal(t, user.ID, found.ID)
|
|
}
|
|
|
|
func TestUserFindByUsernameNotFound(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
found, err := models.FindUserByUsername(
|
|
context.Background(), testDB, "nonexistent",
|
|
)
|
|
require.NoError(t, err)
|
|
assert.Nil(t, found)
|
|
}
|
|
|
|
func TestUserExists(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("returns false when no users", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
exists, err := models.UserExists(context.Background(), testDB)
|
|
require.NoError(t, err)
|
|
assert.False(t, exists)
|
|
})
|
|
|
|
t.Run("returns true when user exists", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
user := models.NewUser(testDB)
|
|
user.Username = "admin"
|
|
user.PasswordHash = testHash
|
|
|
|
err := user.Save(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
exists, err := models.UserExists(context.Background(), testDB)
|
|
require.NoError(t, err)
|
|
assert.True(t, exists)
|
|
})
|
|
}
|
|
|
|
// App Tests.
|
|
|
|
func TestAppCreateAndFind(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
assert.NotZero(t, app.CreatedAt)
|
|
|
|
found, err := models.FindApp(context.Background(), testDB, app.ID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, found)
|
|
assert.Equal(t, "test-app", found.Name)
|
|
assert.Equal(t, models.AppStatusPending, found.Status)
|
|
}
|
|
|
|
func TestAppUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
app.Name = "updated"
|
|
app.Status = models.AppStatusRunning
|
|
app.ImageID = sql.NullString{String: "image123", Valid: true}
|
|
|
|
err := app.Save(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
found, err := models.FindApp(context.Background(), testDB, app.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "updated", found.Name)
|
|
assert.Equal(t, models.AppStatusRunning, found.Status)
|
|
assert.Equal(t, "image123", found.ImageID.String)
|
|
}
|
|
|
|
func TestAppDelete(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
err := app.Delete(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
found, err := models.FindApp(context.Background(), testDB, app.ID)
|
|
require.NoError(t, err)
|
|
assert.Nil(t, found)
|
|
}
|
|
|
|
func TestAppFindByWebhookSecret(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
found, err := models.FindAppByWebhookSecret(
|
|
context.Background(), testDB, app.WebhookSecret,
|
|
)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, found)
|
|
assert.Equal(t, app.ID, found.ID)
|
|
}
|
|
|
|
func TestAllApps(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("returns empty list when no apps", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
apps, err := models.AllApps(context.Background(), testDB)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, apps)
|
|
})
|
|
|
|
t.Run("returns apps ordered by name", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
names := []string{"zebra", "alpha", "mike"}
|
|
|
|
for idx, name := range names {
|
|
app := models.NewApp(testDB)
|
|
app.ID = name + "-id"
|
|
app.Name = name
|
|
app.RepoURL = "git@example.com:user/" + name + ".git"
|
|
app.Branch = testBranch
|
|
app.DockerfilePath = "Dockerfile"
|
|
app.WebhookSecret = "secret-" + strconv.Itoa(idx)
|
|
app.SSHPrivateKey = "private"
|
|
app.SSHPublicKey = "public"
|
|
|
|
err := app.Save(context.Background())
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
apps, err := models.AllApps(context.Background(), testDB)
|
|
require.NoError(t, err)
|
|
require.Len(t, apps, 3)
|
|
|
|
assert.Equal(t, "alpha", apps[0].Name)
|
|
assert.Equal(t, "mike", apps[1].Name)
|
|
assert.Equal(t, "zebra", apps[2].Name)
|
|
})
|
|
}
|
|
|
|
// EnvVar Tests.
|
|
|
|
func TestEnvVarCRUD(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("creates and finds env vars", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
// Create app first.
|
|
app := createTestApp(t, testDB)
|
|
|
|
envVar := models.NewEnvVar(testDB)
|
|
envVar.AppID = app.ID
|
|
envVar.Key = "DATABASE_URL"
|
|
envVar.Value = "postgres://localhost/db"
|
|
|
|
err := envVar.Save(context.Background())
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, envVar.ID)
|
|
|
|
envVars, err := models.FindEnvVarsByAppID(
|
|
context.Background(), testDB, app.ID,
|
|
)
|
|
require.NoError(t, err)
|
|
require.Len(t, envVars, 1)
|
|
assert.Equal(t, "DATABASE_URL", envVars[0].Key)
|
|
})
|
|
|
|
t.Run("deletes env var", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
envVar := models.NewEnvVar(testDB)
|
|
envVar.AppID = app.ID
|
|
envVar.Key = "TO_DELETE"
|
|
envVar.Value = testValue
|
|
|
|
err := envVar.Save(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
err = envVar.Delete(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
envVars, err := models.FindEnvVarsByAppID(
|
|
context.Background(), testDB, app.ID,
|
|
)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, envVars)
|
|
})
|
|
}
|
|
|
|
// Label Tests.
|
|
|
|
func TestLabelCRUD(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("creates and finds labels", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
label := models.NewLabel(testDB)
|
|
label.AppID = app.ID
|
|
label.Key = "traefik.enable"
|
|
label.Value = "true"
|
|
|
|
err := label.Save(context.Background())
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, label.ID)
|
|
|
|
labels, err := models.FindLabelsByAppID(
|
|
context.Background(), testDB, app.ID,
|
|
)
|
|
require.NoError(t, err)
|
|
require.Len(t, labels, 1)
|
|
assert.Equal(t, "traefik.enable", labels[0].Key)
|
|
})
|
|
}
|
|
|
|
// Volume Tests.
|
|
|
|
func TestVolumeCRUD(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("creates and finds volumes", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
volume := models.NewVolume(testDB)
|
|
volume.AppID = app.ID
|
|
volume.HostPath = "/data/app"
|
|
volume.ContainerPath = "/app/data"
|
|
volume.ReadOnly = true
|
|
|
|
err := volume.Save(context.Background())
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, volume.ID)
|
|
|
|
volumes, err := models.FindVolumesByAppID(
|
|
context.Background(), testDB, app.ID,
|
|
)
|
|
require.NoError(t, err)
|
|
require.Len(t, volumes, 1)
|
|
assert.Equal(t, "/data/app", volumes[0].HostPath)
|
|
assert.True(t, volumes[0].ReadOnly)
|
|
})
|
|
}
|
|
|
|
// WebhookEvent Tests.
|
|
|
|
func TestWebhookEventCRUD(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("creates and finds webhook events", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
event := models.NewWebhookEvent(testDB)
|
|
event.AppID = app.ID
|
|
event.EventType = testEventType
|
|
event.Branch = testBranch
|
|
event.CommitSHA = sql.NullString{String: "abc123", Valid: true}
|
|
event.Matched = true
|
|
|
|
err := event.Save(context.Background())
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, event.ID)
|
|
|
|
events, err := models.FindWebhookEventsByAppID(
|
|
context.Background(), testDB, app.ID, 10,
|
|
)
|
|
require.NoError(t, err)
|
|
require.Len(t, events, 1)
|
|
assert.Equal(t, "push", events[0].EventType)
|
|
assert.True(t, events[0].Matched)
|
|
})
|
|
}
|
|
|
|
// Deployment Tests.
|
|
|
|
func TestDeploymentCreateAndFind(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
deployment := models.NewDeployment(testDB)
|
|
deployment.AppID = app.ID
|
|
deployment.CommitSHA = sql.NullString{String: "abc123def456", Valid: true}
|
|
deployment.Status = models.DeploymentStatusBuilding
|
|
|
|
err := deployment.Save(context.Background())
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, deployment.ID)
|
|
assert.NotZero(t, deployment.StartedAt)
|
|
|
|
found, err := models.FindDeployment(context.Background(), testDB, deployment.ID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, found)
|
|
assert.Equal(t, models.DeploymentStatusBuilding, found.Status)
|
|
}
|
|
|
|
func TestDeploymentAppendLog(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
deployment := models.NewDeployment(testDB)
|
|
deployment.AppID = app.ID
|
|
deployment.Status = models.DeploymentStatusBuilding
|
|
|
|
err := deployment.Save(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
err = deployment.AppendLog(context.Background(), "Building image...")
|
|
require.NoError(t, err)
|
|
|
|
err = deployment.AppendLog(context.Background(), "Image built successfully")
|
|
require.NoError(t, err)
|
|
|
|
found, err := models.FindDeployment(context.Background(), testDB, deployment.ID)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, found.Logs.String, "Building image...")
|
|
assert.Contains(t, found.Logs.String, "Image built successfully")
|
|
}
|
|
|
|
func TestDeploymentMarkFinished(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
deployment := models.NewDeployment(testDB)
|
|
deployment.AppID = app.ID
|
|
deployment.Status = models.DeploymentStatusBuilding
|
|
|
|
err := deployment.Save(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
err = deployment.MarkFinished(context.Background(), models.DeploymentStatusSuccess)
|
|
require.NoError(t, err)
|
|
|
|
found, err := models.FindDeployment(context.Background(), testDB, deployment.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, models.DeploymentStatusSuccess, found.Status)
|
|
assert.True(t, found.FinishedAt.Valid)
|
|
}
|
|
|
|
func TestDeploymentFindByAppID(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
for idx := range 5 {
|
|
deploy := models.NewDeployment(testDB)
|
|
deploy.AppID = app.ID
|
|
deploy.Status = models.DeploymentStatusSuccess
|
|
deploy.CommitSHA = sql.NullString{
|
|
String: "commit" + strconv.Itoa(idx),
|
|
Valid: true,
|
|
}
|
|
|
|
err := deploy.Save(context.Background())
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
deployments, err := models.FindDeploymentsByAppID(context.Background(), testDB, app.ID, 3)
|
|
require.NoError(t, err)
|
|
assert.Len(t, deployments, 3)
|
|
}
|
|
|
|
func TestDeploymentFindLatest(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
for idx := range 3 {
|
|
deploy := models.NewDeployment(testDB)
|
|
deploy.AppID = app.ID
|
|
deploy.CommitSHA = sql.NullString{
|
|
String: "commit" + strconv.Itoa(idx),
|
|
Valid: true,
|
|
}
|
|
deploy.Status = models.DeploymentStatusSuccess
|
|
|
|
err := deploy.Save(context.Background())
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
latest, err := models.LatestDeploymentForApp(context.Background(), testDB, app.ID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, latest)
|
|
assert.Equal(t, "commit2", latest.CommitSHA.String)
|
|
}
|
|
|
|
// App Helper Methods Tests.
|
|
|
|
func TestAppGetEnvVars(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
env1 := models.NewEnvVar(testDB)
|
|
env1.AppID = app.ID
|
|
env1.Key = "KEY1"
|
|
env1.Value = "value1"
|
|
_ = env1.Save(context.Background())
|
|
|
|
env2 := models.NewEnvVar(testDB)
|
|
env2.AppID = app.ID
|
|
env2.Key = "KEY2"
|
|
env2.Value = "value2"
|
|
_ = env2.Save(context.Background())
|
|
|
|
envVars, err := app.GetEnvVars(context.Background())
|
|
require.NoError(t, err)
|
|
assert.Len(t, envVars, 2)
|
|
}
|
|
|
|
func TestAppGetLabels(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
label := models.NewLabel(testDB)
|
|
label.AppID = app.ID
|
|
label.Key = "label.key"
|
|
label.Value = "label.value"
|
|
_ = label.Save(context.Background())
|
|
|
|
labels, err := app.GetLabels(context.Background())
|
|
require.NoError(t, err)
|
|
assert.Len(t, labels, 1)
|
|
}
|
|
|
|
func TestAppGetVolumes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
vol := models.NewVolume(testDB)
|
|
vol.AppID = app.ID
|
|
vol.HostPath = "/host"
|
|
vol.ContainerPath = "/container"
|
|
_ = vol.Save(context.Background())
|
|
|
|
volumes, err := app.GetVolumes(context.Background())
|
|
require.NoError(t, err)
|
|
assert.Len(t, volumes, 1)
|
|
}
|
|
|
|
func TestAppGetDeployments(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
deploy := models.NewDeployment(testDB)
|
|
deploy.AppID = app.ID
|
|
deploy.Status = models.DeploymentStatusSuccess
|
|
_ = deploy.Save(context.Background())
|
|
|
|
deployments, err := app.GetDeployments(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
assert.Len(t, deployments, 1)
|
|
}
|
|
|
|
func TestAppGetWebhookEvents(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
event := models.NewWebhookEvent(testDB)
|
|
event.AppID = app.ID
|
|
event.EventType = testEventType
|
|
event.Branch = testBranch
|
|
event.Matched = true
|
|
_ = event.Save(context.Background())
|
|
|
|
events, err := app.GetWebhookEvents(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
assert.Len(t, events, 1)
|
|
}
|
|
|
|
// Cascade Delete Tests.
|
|
|
|
//nolint:funlen // Test function with many assertions - acceptable for integration tests
|
|
func TestCascadeDelete(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("deleting app cascades to related records", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testDB, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
app := createTestApp(t, testDB)
|
|
|
|
// Create related records.
|
|
env := models.NewEnvVar(testDB)
|
|
env.AppID = app.ID
|
|
env.Key = "KEY"
|
|
env.Value = "value"
|
|
_ = env.Save(context.Background())
|
|
|
|
label := models.NewLabel(testDB)
|
|
label.AppID = app.ID
|
|
label.Key = "key"
|
|
label.Value = "value"
|
|
_ = label.Save(context.Background())
|
|
|
|
vol := models.NewVolume(testDB)
|
|
vol.AppID = app.ID
|
|
vol.HostPath = "/host"
|
|
vol.ContainerPath = "/container"
|
|
_ = vol.Save(context.Background())
|
|
|
|
event := models.NewWebhookEvent(testDB)
|
|
event.AppID = app.ID
|
|
event.EventType = testEventType
|
|
event.Branch = testBranch
|
|
event.Matched = true
|
|
_ = event.Save(context.Background())
|
|
|
|
deploy := models.NewDeployment(testDB)
|
|
deploy.AppID = app.ID
|
|
deploy.Status = models.DeploymentStatusSuccess
|
|
_ = deploy.Save(context.Background())
|
|
|
|
// Delete app.
|
|
err := app.Delete(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
// Verify cascades.
|
|
envVars, _ := models.FindEnvVarsByAppID(
|
|
context.Background(), testDB, app.ID,
|
|
)
|
|
assert.Empty(t, envVars)
|
|
|
|
labels, _ := models.FindLabelsByAppID(
|
|
context.Background(), testDB, app.ID,
|
|
)
|
|
assert.Empty(t, labels)
|
|
|
|
volumes, _ := models.FindVolumesByAppID(
|
|
context.Background(), testDB, app.ID,
|
|
)
|
|
assert.Empty(t, volumes)
|
|
|
|
events, _ := models.FindWebhookEventsByAppID(
|
|
context.Background(), testDB, app.ID, 10,
|
|
)
|
|
assert.Empty(t, events)
|
|
|
|
deployments, _ := models.FindDeploymentsByAppID(
|
|
context.Background(), testDB, app.ID, 10,
|
|
)
|
|
assert.Empty(t, deployments)
|
|
})
|
|
}
|
|
|
|
// Helper function to create a test app.
|
|
func createTestApp(t *testing.T, testDB *database.Database) *models.App {
|
|
t.Helper()
|
|
|
|
app := models.NewApp(testDB)
|
|
app.ID = "test-app-" + t.Name()
|
|
app.Name = "test-app"
|
|
app.RepoURL = "git@example.com:user/repo.git"
|
|
app.Branch = testBranch
|
|
app.DockerfilePath = "Dockerfile"
|
|
app.WebhookSecret = "secret-" + t.Name()
|
|
app.SSHPrivateKey = "private"
|
|
app.SSHPublicKey = "public"
|
|
|
|
err := app.Save(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
return app
|
|
}
|