93 lines
2.7 KiB
Go
93 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"calllinesystem/server/internal/model"
|
|
|
|
"gorm.io/driver/postgres"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type inertConnPool struct{}
|
|
|
|
func (inertConnPool) PrepareContext(context.Context, string) (*sql.Stmt, error) {
|
|
return nil, errors.New("unexpected prepare")
|
|
}
|
|
|
|
func (inertConnPool) ExecContext(context.Context, string, ...any) (sql.Result, error) {
|
|
return nil, errors.New("unexpected exec")
|
|
}
|
|
|
|
func (inertConnPool) QueryContext(context.Context, string, ...any) (*sql.Rows, error) {
|
|
return nil, errors.New("unexpected query")
|
|
}
|
|
|
|
func (inertConnPool) QueryRowContext(context.Context, string, ...any) *sql.Row {
|
|
return &sql.Row{}
|
|
}
|
|
|
|
func TestResetProjectRejectsArchivedProjectBeforeAnyMutation(t *testing.T) {
|
|
db, err := gorm.Open(postgres.New(postgres.Config{Conn: inertConnPool{}}), &gorm.Config{
|
|
DisableAutomaticPing: true,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
archivedAt := time.Date(2026, 8, 13, 8, 0, 0, 0, time.UTC)
|
|
existing := model.Project{
|
|
ID: "11111111-1111-4111-8111-111111111111",
|
|
Code: "DEMO",
|
|
Name: "archived project",
|
|
Status: model.ProjectEnded,
|
|
ArchivedAt: &archivedAt,
|
|
}
|
|
if err := db.Callback().Query().Replace("gorm:query", func(tx *gorm.DB) {
|
|
project, ok := tx.Statement.Dest.(*model.Project)
|
|
if !ok {
|
|
t.Fatalf("query destination = %T, want *model.Project", tx.Statement.Dest)
|
|
}
|
|
*project = existing
|
|
tx.RowsAffected = 1
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
mutationCount := 0
|
|
recordMutation := func(tx *gorm.DB) {
|
|
mutationCount++
|
|
tx.AddError(errors.New("unexpected mutation"))
|
|
}
|
|
if err := db.Callback().Raw().Replace("gorm:raw", recordMutation); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := db.Callback().Update().Replace("gorm:update", recordMutation); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := db.Callback().Create().Replace("gorm:create", recordMutation); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := db.Callback().Delete().Replace("gorm:delete", recordMutation); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
project, err := resetProject(db, projectSeed{
|
|
Code: "demo", Name: "replacement", Status: model.ProjectRunning,
|
|
}, time.Date(2026, 8, 13, 9, 0, 0, 0, time.UTC))
|
|
if err == nil || !strings.Contains(strings.ToLower(err.Error()), "archived") {
|
|
t.Fatalf("resetProject error = %v, want explicit archived-project error", err)
|
|
}
|
|
if mutationCount != 0 {
|
|
t.Fatalf("resetProject performed %d mutations after loading an archived project, want 0", mutationCount)
|
|
}
|
|
if project.ID != existing.ID || project.Name != existing.Name || project.Status != existing.Status || project.ArchivedAt != existing.ArchivedAt {
|
|
t.Fatalf("returned project was modified: %#v", project)
|
|
}
|
|
}
|