init push
This commit is contained in:
587
internal/repository/mysql/helicopter_repo_test.go
Normal file
587
internal/repository/mysql/helicopter_repo_test.go
Normal file
@@ -0,0 +1,587 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
|
||||
afterflightinspection "wucher/internal/domain/after_flight_inspection"
|
||||
filemanager "wucher/internal/domain/file_manager"
|
||||
"wucher/internal/domain/helicopter"
|
||||
"wucher/internal/shared/pkg/uuidv7"
|
||||
)
|
||||
|
||||
func intPtr(v int) *int {
|
||||
return &v
|
||||
}
|
||||
|
||||
func openHelicopterTestDB(t *testing.T) *gorm.DB {
|
||||
t.Helper()
|
||||
dsn := fmt.Sprintf("file:helicopter_test_%d?mode=memory&cache=shared", time.Now().UnixNano())
|
||||
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{
|
||||
NowFunc: func() time.Time { return time.Now().UTC() },
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("open sqlite: %v", err)
|
||||
}
|
||||
if err := db.AutoMigrate(&filemanager.Folder{}, &filemanager.File{}, &filemanager.Attachment{}, &helicopter.Helicopter{}); err != nil {
|
||||
t.Fatalf("auto migrate: %v", err)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
func TestNewHelicopterRepository(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
if repo == nil || repo.db == nil {
|
||||
t.Fatalf("expected repository initialized")
|
||||
}
|
||||
if repo.hasUsersTable {
|
||||
t.Fatalf("expected users table cache to be false in base helicopter test db")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelicopterRepositoryCachesUsersTablePresence(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
if err := db.Exec(`CREATE TABLE users (
|
||||
id BLOB PRIMARY KEY,
|
||||
first_name TEXT,
|
||||
last_name TEXT,
|
||||
username TEXT,
|
||||
email TEXT
|
||||
)`).Error; err != nil {
|
||||
t.Fatalf("create users table: %v", err)
|
||||
}
|
||||
|
||||
repo := NewHelicopterRepository(db)
|
||||
if !repo.hasUsersTable {
|
||||
t.Fatalf("expected users table cache to be true")
|
||||
}
|
||||
|
||||
creatorID := uuidv7.MustBytes()
|
||||
updaterID := uuidv7.MustBytes()
|
||||
if err := db.Table("users").Create([]map[string]any{
|
||||
{
|
||||
"id": creatorID,
|
||||
"first_name": "Ada",
|
||||
"last_name": "Lovelace",
|
||||
"username": "ada",
|
||||
"email": "ada@example.com",
|
||||
},
|
||||
{
|
||||
"id": updaterID,
|
||||
"first_name": "Grace",
|
||||
"last_name": "Hopper",
|
||||
"username": "grace",
|
||||
"email": "grace@example.com",
|
||||
},
|
||||
}).Error; err != nil {
|
||||
t.Fatalf("seed users: %v", err)
|
||||
}
|
||||
|
||||
row := &helicopter.Helicopter{
|
||||
Designation: "H145",
|
||||
Identifier: "PK-AUDIT",
|
||||
Type: "Twin",
|
||||
CreatedBy: creatorID,
|
||||
UpdatedBy: updaterID,
|
||||
}
|
||||
if err := repo.Create(context.Background(), row); err != nil {
|
||||
t.Fatalf("seed helicopter: %v", err)
|
||||
}
|
||||
|
||||
got, err := repo.GetByID(context.Background(), row.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("get helicopter: %v", err)
|
||||
}
|
||||
if got == nil {
|
||||
t.Fatalf("expected helicopter row")
|
||||
}
|
||||
if got.CreatedByName != "Ada Lovelace" {
|
||||
t.Fatalf("unexpected created_by_name: %q", got.CreatedByName)
|
||||
}
|
||||
if got.UpdatedByName != "Grace Hopper" {
|
||||
t.Fatalf("unexpected updated_by_name: %q", got.UpdatedByName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelicopterRepositoryCreate(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
row := &helicopter.Helicopter{Designation: "H145", Identifier: "PK-ABC", Type: "Twin"}
|
||||
|
||||
if err := repo.Create(context.Background(), row); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if len(row.ID) == 0 {
|
||||
t.Fatalf("expected id set")
|
||||
}
|
||||
inactive := &helicopter.Helicopter{Designation: "Inactive", Identifier: "PK-INACTIVE", Type: "Single", IsActive: false}
|
||||
if err := repo.Create(context.Background(), inactive); err != nil {
|
||||
t.Fatalf("create inactive: %v", err)
|
||||
}
|
||||
gotInactive, err := repo.GetByID(context.Background(), inactive.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("get inactive: %v", err)
|
||||
}
|
||||
if gotInactive == nil || gotInactive.IsActive {
|
||||
t.Fatalf("expected inactive helicopter persisted as false")
|
||||
}
|
||||
|
||||
sqlDB, _ := db.DB()
|
||||
_ = sqlDB.Close()
|
||||
if err := repo.Create(context.Background(), &helicopter.Helicopter{Designation: "AfterClose", Identifier: "PK-CLOSE", Type: "Twin"}); err == nil {
|
||||
t.Fatalf("expected error on closed DB")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelicopterRepositoryUpdate(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
row := &helicopter.Helicopter{Designation: "Old", Identifier: "PK-OLD", Type: "Single"}
|
||||
if err := repo.Create(context.Background(), row); err != nil {
|
||||
t.Fatalf("seed create: %v", err)
|
||||
}
|
||||
|
||||
row.Designation = "New"
|
||||
row.Type = "Twin"
|
||||
if err := repo.Update(context.Background(), row); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
loaded, err := repo.GetByID(context.Background(), row.ID)
|
||||
if err != nil || loaded == nil || loaded.Designation != "New" || loaded.Type != "Twin" {
|
||||
t.Fatalf("expected updated row")
|
||||
}
|
||||
|
||||
sqlDB, _ := db.DB()
|
||||
_ = sqlDB.Close()
|
||||
if err := repo.Update(context.Background(), row); err == nil {
|
||||
t.Fatalf("expected error on closed DB")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelicopterRepositoryUpdate_ReplacesFotoAttachmentID(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
now := time.Now().UTC()
|
||||
|
||||
folder := &filemanager.Folder{
|
||||
ID: uuidv7.MustBytes(),
|
||||
Name: "photos",
|
||||
NameNormalized: "photos",
|
||||
Depth: 0,
|
||||
PathCache: "/photos",
|
||||
NameSlot: "live",
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
if err := db.Create(folder).Error; err != nil {
|
||||
t.Fatalf("create folder: %v", err)
|
||||
}
|
||||
|
||||
makeFile := func(name, key string) *filemanager.File {
|
||||
return &filemanager.File{
|
||||
ID: uuidv7.MustBytes(),
|
||||
FolderID: folder.ID,
|
||||
Name: name,
|
||||
NameNormalized: strings.ToLower(name),
|
||||
Extension: "webp",
|
||||
SizeBytes: 1234,
|
||||
MimeType: "image/webp",
|
||||
Bucket: "bucket",
|
||||
ObjectKey: key,
|
||||
Status: filemanager.FileStatusReady,
|
||||
NameSlot: "live",
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
}
|
||||
oldFile := makeFile("old.webp", "objects/old.webp")
|
||||
newFile := makeFile("new.webp", "objects/new.webp")
|
||||
if err := db.Create(oldFile).Error; err != nil {
|
||||
t.Fatalf("create old file: %v", err)
|
||||
}
|
||||
if err := db.Create(newFile).Error; err != nil {
|
||||
t.Fatalf("create new file: %v", err)
|
||||
}
|
||||
|
||||
oldAttachment := &filemanager.Attachment{
|
||||
ID: uuidv7.MustBytes(),
|
||||
FileID: oldFile.ID,
|
||||
RefType: "helicopter_photo",
|
||||
RefID: "helicopter-1",
|
||||
IsPrimary: true,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
newAttachment := &filemanager.Attachment{
|
||||
ID: uuidv7.MustBytes(),
|
||||
FileID: newFile.ID,
|
||||
RefType: "helicopter_photo",
|
||||
RefID: "helicopter-1",
|
||||
IsPrimary: true,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
if err := db.Create(oldAttachment).Error; err != nil {
|
||||
t.Fatalf("create old attachment: %v", err)
|
||||
}
|
||||
if err := db.Create(newAttachment).Error; err != nil {
|
||||
t.Fatalf("create new attachment: %v", err)
|
||||
}
|
||||
|
||||
row := &helicopter.Helicopter{
|
||||
ID: uuidv7.MustBytes(),
|
||||
Designation: "Old",
|
||||
Identifier: "PK-OLD-ATT",
|
||||
Type: "Single",
|
||||
FotoAttachmentID: oldAttachment.ID,
|
||||
FotoAttachment: oldAttachment,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
if err := repo.Create(context.Background(), row); err != nil {
|
||||
t.Fatalf("seed create helicopter: %v", err)
|
||||
}
|
||||
|
||||
row.FotoAttachmentID = newAttachment.ID
|
||||
row.FotoAttachment = oldAttachment
|
||||
if err := repo.Update(context.Background(), row); err != nil {
|
||||
t.Fatalf("update helicopter: %v", err)
|
||||
}
|
||||
|
||||
loaded, err := repo.GetByID(context.Background(), row.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("get by id after update: %v", err)
|
||||
}
|
||||
if loaded == nil {
|
||||
t.Fatalf("expected updated row")
|
||||
}
|
||||
if string(loaded.FotoAttachmentID) != string(newAttachment.ID) {
|
||||
t.Fatalf("expected foto_attachment_id replaced")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelicopterRepositoryDelete(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
row := &helicopter.Helicopter{Designation: "DeleteMe", Identifier: "PK-DEL", Type: "Twin"}
|
||||
if err := repo.Create(context.Background(), row); err != nil {
|
||||
t.Fatalf("seed create: %v", err)
|
||||
}
|
||||
|
||||
if err := repo.Delete(context.Background(), row.ID); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
got, err := repo.GetByID(context.Background(), row.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("get by id after delete: %v", err)
|
||||
}
|
||||
if got != nil {
|
||||
t.Fatalf("expected row deleted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelicopterRepositoryGetByID(t *testing.T) {
|
||||
t.Run("found", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
row := &helicopter.Helicopter{Designation: "Found", Identifier: "PK-FND", Type: "Twin"}
|
||||
if err := repo.Create(context.Background(), row); err != nil {
|
||||
t.Fatalf("seed create: %v", err)
|
||||
}
|
||||
|
||||
got, err := repo.GetByID(context.Background(), row.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if got == nil || got.Identifier != "PK-FND" {
|
||||
t.Fatalf("expected row found")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("not found", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
got, err := repo.GetByID(context.Background(), uuidv7.MustBytes())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if got != nil {
|
||||
t.Fatalf("expected nil for not found")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("db error", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
sqlDB, _ := db.DB()
|
||||
_ = sqlDB.Close()
|
||||
|
||||
if _, err := repo.GetByID(context.Background(), uuidv7.MustBytes()); err == nil {
|
||||
t.Fatalf("expected error on closed DB")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestHelicopterRepositoryList(t *testing.T) {
|
||||
t.Run("success without limit", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "H145", Identifier: "PK-A", Type: "Twin"})
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "H125", Identifier: "PK-B", Type: "Single"})
|
||||
|
||||
rows, total, err := repo.List(context.Background(), "", nil, "", 0, 0, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if total != 2 || len(rows) != 2 {
|
||||
t.Fatalf("expected 2 rows, total=%d len=%d", total, len(rows))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("success with filter sort and limit", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "Main", Identifier: "PK-MAIN", Type: "Twin"})
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "Backup", Identifier: "PK-BACK", Type: "Single"})
|
||||
|
||||
rows, total, err := repo.List(context.Background(), "MAIN", nil, "identifier DESC", 1, 0, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if total != 1 || len(rows) != 1 || rows[0].Identifier != "PK-MAIN" {
|
||||
t.Fatalf("unexpected list result")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("default order active sortkey first and inactive last", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "Gamma", Identifier: "PK-G", Type: "Twin", IsActive: true})
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "Beta", Identifier: "PK-B0", Type: "Twin", SortKey: intPtr(0), IsActive: true})
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "Charlie", Identifier: "PK-C", Type: "Twin", SortKey: intPtr(2), IsActive: true})
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "Alpha", Identifier: "PK-A1", Type: "Twin", IsActive: true})
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "Alpha", Identifier: "PK-A2", Type: "Twin", SortKey: intPtr(1), IsActive: true})
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "Zulu", Identifier: "PK-Z", Type: "Twin", IsActive: false})
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "Bravo", Identifier: "PK-B", Type: "Twin", IsActive: false, SortKey: intPtr(9)})
|
||||
|
||||
rows, total, err := repo.List(context.Background(), "", nil, "", 0, 0, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if total != 7 || len(rows) != 7 {
|
||||
t.Fatalf("unexpected total/len total=%d len=%d", total, len(rows))
|
||||
}
|
||||
|
||||
gotOrder := []string{
|
||||
rows[0].Designation + "|" + rows[0].Identifier,
|
||||
rows[1].Designation + "|" + rows[1].Identifier,
|
||||
rows[2].Designation + "|" + rows[2].Identifier,
|
||||
rows[3].Designation + "|" + rows[3].Identifier,
|
||||
rows[4].Designation + "|" + rows[4].Identifier,
|
||||
rows[5].Designation + "|" + rows[5].Identifier,
|
||||
rows[6].Designation + "|" + rows[6].Identifier,
|
||||
}
|
||||
wantOrder := []string{
|
||||
"Beta|PK-B0",
|
||||
"Alpha|PK-A2",
|
||||
"Charlie|PK-C",
|
||||
"Alpha|PK-A1",
|
||||
"Gamma|PK-G",
|
||||
"Bravo|PK-B",
|
||||
"Zulu|PK-Z",
|
||||
}
|
||||
for i := range wantOrder {
|
||||
if gotOrder[i] != wantOrder[i] {
|
||||
t.Fatalf("unexpected default order: got=%v want=%v", gotOrder, wantOrder)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("status filter", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
|
||||
// Minimal schema for the booked/available EXISTS subquery.
|
||||
if err := db.Exec(`CREATE TABLE reserve_acs (id BLOB PRIMARY KEY, helicopter_id BLOB, inspection_id BLOB, deleted_at DATETIME)`).Error; err != nil {
|
||||
t.Fatalf("create reserve_acs: %v", err)
|
||||
}
|
||||
if err := db.Exec(`CREATE TABLE takeover_acs (id BLOB PRIMARY KEY, reserve_ac_id BLOB, deleted_at DATETIME)`).Error; err != nil {
|
||||
t.Fatalf("create takeover_acs: %v", err)
|
||||
}
|
||||
if err := db.Exec(`CREATE TABLE flights (id BLOB PRIMARY KEY, reserve_ac_id BLOB, takeover_ac_id BLOB, deleted_at DATETIME)`).Error; err != nil {
|
||||
t.Fatalf("create flights: %v", err)
|
||||
}
|
||||
if err := db.AutoMigrate(&afterflightinspection.AfterFlightInspection{}); err != nil {
|
||||
t.Fatalf("auto migrate after flight inspection: %v", err)
|
||||
}
|
||||
|
||||
aog := &helicopter.Helicopter{Designation: "AOG", Identifier: "PK-AOG", Type: "Twin", AirOnGround: true}
|
||||
booked := &helicopter.Helicopter{Designation: "Booked", Identifier: "PK-BKD", Type: "Twin"}
|
||||
closed := &helicopter.Helicopter{Designation: "Closed", Identifier: "PK-CLS", Type: "Twin"}
|
||||
available := &helicopter.Helicopter{Designation: "Avail", Identifier: "PK-AVL", Type: "Twin"}
|
||||
for _, h := range []*helicopter.Helicopter{aog, booked, closed, available} {
|
||||
if err := repo.Create(context.Background(), h); err != nil {
|
||||
t.Fatalf("create helicopter: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Give "booked" an active (non-deleted) flight assignment.
|
||||
raID := uuidv7.MustBytes()
|
||||
takeoverID := uuidv7.MustBytes()
|
||||
if err := db.Table("reserve_acs").Create(map[string]any{"id": raID, "helicopter_id": booked.ID}).Error; err != nil {
|
||||
t.Fatalf("insert reserve_ac: %v", err)
|
||||
}
|
||||
if err := db.Table("takeover_acs").Create(map[string]any{"id": takeoverID, "reserve_ac_id": raID}).Error; err != nil {
|
||||
t.Fatalf("insert takeover_ac: %v", err)
|
||||
}
|
||||
if err := db.Table("flights").Create(map[string]any{"id": uuidv7.MustBytes(), "takeover_ac_id": takeoverID}).Error; err != nil {
|
||||
t.Fatalf("insert flight: %v", err)
|
||||
}
|
||||
closedRAID := uuidv7.MustBytes()
|
||||
closedTakeoverID := uuidv7.MustBytes()
|
||||
closedInspectionID := uuidv7.MustBytes()
|
||||
if err := db.Table("reserve_acs").Create(map[string]any{"id": closedRAID, "helicopter_id": closed.ID, "inspection_id": closedInspectionID}).Error; err != nil {
|
||||
t.Fatalf("insert closed reserve_ac: %v", err)
|
||||
}
|
||||
if err := db.Table("takeover_acs").Create(map[string]any{"id": closedTakeoverID, "reserve_ac_id": closedRAID}).Error; err != nil {
|
||||
t.Fatalf("insert closed takeover_ac: %v", err)
|
||||
}
|
||||
if err := db.Table("flights").Create(map[string]any{"id": uuidv7.MustBytes(), "takeover_ac_id": closedTakeoverID}).Error; err != nil {
|
||||
t.Fatalf("insert closed flight: %v", err)
|
||||
}
|
||||
if err := db.Create(&afterflightinspection.AfterFlightInspection{FlightInspectionID: closedInspectionID, CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC()}).Error; err != nil {
|
||||
t.Fatalf("insert after flight inspection: %v", err)
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
statuses []string
|
||||
groundedIDs [][]byte
|
||||
want []string
|
||||
}{
|
||||
{name: "aog only", statuses: []string{"aog"}, want: []string{"PK-AOG"}},
|
||||
{name: "booked only", statuses: []string{"booked"}, want: []string{"PK-BKD"}},
|
||||
{name: "available only", statuses: []string{"available"}, want: []string{"PK-AVL", "PK-CLS"}},
|
||||
{name: "available and booked", statuses: []string{"available", "booked"}, want: []string{"PK-AVL", "PK-BKD", "PK-CLS"}},
|
||||
{name: "mcf matches nothing", statuses: []string{"mcf"}, want: []string{}},
|
||||
{name: "no filter returns all", statuses: nil, want: []string{"PK-AOG", "PK-AVL", "PK-BKD", "PK-CLS"}},
|
||||
{name: "complaint-grounded excluded from available", statuses: []string{"available"}, groundedIDs: [][]byte{available.ID}, want: []string{"PK-CLS"}},
|
||||
{name: "complaint-grounded appears as aog", statuses: []string{"aog"}, groundedIDs: [][]byte{available.ID}, want: []string{"PK-AOG", "PK-AVL"}},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
rows, total, err := repo.List(context.Background(), "", tc.statuses, "identifier ASC", 0, 0, tc.groundedIDs)
|
||||
if err != nil {
|
||||
t.Fatalf("list: %v", err)
|
||||
}
|
||||
if int(total) != len(tc.want) || len(rows) != len(tc.want) {
|
||||
t.Fatalf("count mismatch: total=%d len=%d want=%d", total, len(rows), len(tc.want))
|
||||
}
|
||||
got := make([]string, len(rows))
|
||||
for i := range rows {
|
||||
got[i] = rows[i].Identifier
|
||||
}
|
||||
for i := range tc.want {
|
||||
if got[i] != tc.want[i] {
|
||||
t.Fatalf("unexpected rows: got=%v want=%v", got, tc.want)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("count error", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
if err := db.Migrator().DropTable(&helicopter.Helicopter{}); err != nil {
|
||||
t.Fatalf("drop table: %v", err)
|
||||
}
|
||||
|
||||
if _, _, err := repo.List(context.Background(), "", nil, "", 10, 0, nil); err == nil {
|
||||
t.Fatalf("expected count error")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("find error", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
_ = repo.Create(context.Background(), &helicopter.Helicopter{Designation: "Main", Identifier: "PK-ERR", Type: "Twin"})
|
||||
|
||||
if _, _, err := repo.List(context.Background(), "", nil, "designation ASC, )", 10, 0, nil); err == nil {
|
||||
t.Fatalf("expected find error from invalid sort")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestHelicopterRepositoryNextReportNumber(t *testing.T) {
|
||||
t.Run("success", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
row := &helicopter.Helicopter{
|
||||
Designation: "H145",
|
||||
Identifier: " PK-ABC ",
|
||||
Type: "Twin",
|
||||
ReportSequence: 7,
|
||||
}
|
||||
if err := repo.Create(context.Background(), row); err != nil {
|
||||
t.Fatalf("seed create: %v", err)
|
||||
}
|
||||
|
||||
reportNumber, sequence, err := repo.NextReportNumber(context.Background(), row.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if reportNumber != "PK-ABC-0008" || sequence != 8 {
|
||||
t.Fatalf("unexpected report number/sequence: %q %d", reportNumber, sequence)
|
||||
}
|
||||
loaded, err := repo.GetByID(context.Background(), row.ID)
|
||||
if err != nil || loaded == nil || loaded.ReportSequence != 8 {
|
||||
t.Fatalf("expected report_sequence updated")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("identifier empty", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
row := &helicopter.Helicopter{
|
||||
Designation: "H145",
|
||||
Identifier: " ",
|
||||
Type: "Twin",
|
||||
}
|
||||
if err := repo.Create(context.Background(), row); err != nil {
|
||||
t.Fatalf("seed create: %v", err)
|
||||
}
|
||||
|
||||
if _, _, err := repo.NextReportNumber(context.Background(), row.ID); err == nil {
|
||||
t.Fatalf("expected identifier empty error")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("not found", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
if _, _, err := repo.NextReportNumber(context.Background(), uuidv7.MustBytes()); err == nil {
|
||||
t.Fatalf("expected not found error")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("db error", func(t *testing.T) {
|
||||
db := openHelicopterTestDB(t)
|
||||
repo := NewHelicopterRepository(db)
|
||||
sqlDB, _ := db.DB()
|
||||
_ = sqlDB.Close()
|
||||
|
||||
if _, _, err := repo.NextReportNumber(context.Background(), uuidv7.MustBytes()); err == nil {
|
||||
t.Fatalf("expected error on closed DB")
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user