169 lines
5.2 KiB
Go
169 lines
5.2 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
afterflightinspection "wucher/internal/domain/after_flight_inspection"
|
|
)
|
|
|
|
type afterFlightInspectionRepoStub struct {
|
|
exists bool
|
|
caps *afterflightinspection.HelicopterCapabilities
|
|
existing *afterflightinspection.AfterFlightInspection
|
|
upserted *afterflightinspection.AfterFlightInspection
|
|
upsertErr error
|
|
existsErr error
|
|
capErr error
|
|
flightChecked int
|
|
}
|
|
|
|
func (r *afterFlightInspectionRepoStub) Upsert(_ context.Context, row *afterflightinspection.AfterFlightInspection) error {
|
|
r.upserted = row
|
|
return r.upsertErr
|
|
}
|
|
|
|
func (r *afterFlightInspectionRepoStub) GetByFlightInspectionID(context.Context, []byte) (*afterflightinspection.AfterFlightInspection, error) {
|
|
return r.existing, nil
|
|
}
|
|
|
|
func (r *afterFlightInspectionRepoStub) DeleteByFlightInspectionID(context.Context, []byte) error {
|
|
return nil
|
|
}
|
|
|
|
func (r *afterFlightInspectionRepoStub) FlightInspectionExists(context.Context, []byte) (bool, error) {
|
|
if r.existsErr != nil {
|
|
return false, r.existsErr
|
|
}
|
|
return r.exists, nil
|
|
}
|
|
|
|
func (r *afterFlightInspectionRepoStub) GetHelicopterCapabilities(context.Context, []byte) (*afterflightinspection.HelicopterCapabilities, error) {
|
|
if r.capErr != nil {
|
|
return nil, r.capErr
|
|
}
|
|
r.flightChecked++
|
|
return r.caps, nil
|
|
}
|
|
|
|
func TestAfterFlightInspectionServiceValidateRequestRequiresCapabilityChecks(t *testing.T) {
|
|
svc := NewAfterFlightInspectionService(&afterFlightInspectionRepoStub{})
|
|
|
|
nr1 := "checked"
|
|
nr2 := "checked"
|
|
lh := "checked"
|
|
rh := "checked"
|
|
mgb := "checked"
|
|
igb := "checked"
|
|
tgb := "checked"
|
|
req := &afterflightinspection.UpsertRequest{
|
|
OilEngineNR1Checked: &nr1,
|
|
OilEngineNR2Checked: &nr2,
|
|
HydraulicLHChecked: &lh,
|
|
HydraulicRHChecked: &rh,
|
|
OilTransmissionMGBChecked: &mgb,
|
|
OilTransmissionIGBChecked: &igb,
|
|
OilTransmissionTGBChecked: &tgb,
|
|
}
|
|
caps := &afterflightinspection.HelicopterCapabilities{
|
|
NR1: true, NR2: true, LH: true, RH: true, MGB: true, IGB: true, TGB: true,
|
|
}
|
|
if err := svc.validateRequest(req, caps); err != nil {
|
|
t.Fatalf("expected request to be valid, got %v", err)
|
|
}
|
|
|
|
req.OilEngineNR2Checked = nil
|
|
if err := svc.validateRequest(req, caps); err == nil {
|
|
t.Fatal("expected missing required nr2 check to be rejected")
|
|
}
|
|
}
|
|
|
|
func TestAfterFlightInspectionServiceUpsertUpdatesExistingRow(t *testing.T) {
|
|
existingID := make([]byte, 16)
|
|
for i := range existingID {
|
|
existingID[i] = byte(i + 1)
|
|
}
|
|
createdBy := []byte("creator123456789")
|
|
createdAt := time.Date(2026, 1, 1, 8, 0, 0, 0, time.UTC)
|
|
|
|
repo := &afterFlightInspectionRepoStub{
|
|
exists: true,
|
|
caps: &afterflightinspection.HelicopterCapabilities{NR1: true},
|
|
existing: &afterflightinspection.AfterFlightInspection{
|
|
ID: existingID,
|
|
CreatedAt: createdAt,
|
|
CreatedBy: createdBy,
|
|
},
|
|
}
|
|
svc := NewAfterFlightInspectionService(repo)
|
|
|
|
flightInspectionID := make([]byte, 16)
|
|
for i := range flightInspectionID {
|
|
flightInspectionID[i] = byte(100 + i)
|
|
}
|
|
nr1 := "400"
|
|
row, err := svc.Upsert(context.Background(), flightInspectionID, &afterflightinspection.UpsertRequest{
|
|
OilEngineNR1Checked: &nr1,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Upsert returned error: %v", err)
|
|
}
|
|
|
|
// The saved row must reuse the existing identity so GORM performs an UPDATE
|
|
// instead of inserting a duplicate flight_inspection_id (the original bug).
|
|
if string(repo.upserted.ID) != string(existingID) {
|
|
t.Fatalf("expected upsert to reuse existing ID %x, got %x", existingID, repo.upserted.ID)
|
|
}
|
|
if !repo.upserted.CreatedAt.Equal(createdAt) {
|
|
t.Fatalf("expected created_at to be preserved, got %v", repo.upserted.CreatedAt)
|
|
}
|
|
if string(repo.upserted.CreatedBy) != string(createdBy) {
|
|
t.Fatalf("expected created_by to be preserved, got %x", repo.upserted.CreatedBy)
|
|
}
|
|
if row == nil || string(row.ID) != string(existingID) {
|
|
t.Fatal("expected returned row to carry existing ID")
|
|
}
|
|
}
|
|
|
|
func TestAfterFlightInspectionServiceUpsertInsertsWhenAbsent(t *testing.T) {
|
|
repo := &afterFlightInspectionRepoStub{
|
|
exists: true,
|
|
caps: &afterflightinspection.HelicopterCapabilities{NR1: true},
|
|
}
|
|
svc := NewAfterFlightInspectionService(repo)
|
|
|
|
flightInspectionID := make([]byte, 16)
|
|
for i := range flightInspectionID {
|
|
flightInspectionID[i] = byte(50 + i)
|
|
}
|
|
nr1 := "400"
|
|
if _, err := svc.Upsert(context.Background(), flightInspectionID, &afterflightinspection.UpsertRequest{
|
|
OilEngineNR1Checked: &nr1,
|
|
}); err != nil {
|
|
t.Fatalf("Upsert returned error: %v", err)
|
|
}
|
|
|
|
// No existing row: a new INSERT (empty ID, BeforeCreate mints a UUID).
|
|
if len(repo.upserted.ID) != 0 {
|
|
t.Fatalf("expected empty ID for new row, got %x", repo.upserted.ID)
|
|
}
|
|
if string(repo.upserted.FlightInspectionID) != string(flightInspectionID) {
|
|
t.Fatal("expected flight_inspection_id to be set")
|
|
}
|
|
}
|
|
|
|
func TestAfterFlightInspectionServiceValidateRequestRejectsUnsupportedChecks(t *testing.T) {
|
|
svc := NewAfterFlightInspectionService(&afterFlightInspectionRepoStub{})
|
|
|
|
yes := "checked"
|
|
req := &afterflightinspection.UpsertRequest{
|
|
OilEngineNR1Checked: &yes,
|
|
}
|
|
caps := &afterflightinspection.HelicopterCapabilities{}
|
|
|
|
if err := svc.validateRequest(req, caps); err == nil {
|
|
t.Fatal("expected unsupported nr1 check to be rejected")
|
|
}
|
|
}
|