init push
This commit is contained in:
581
internal/service/mission_service_test.go
Normal file
581
internal/service/mission_service_test.go
Normal file
@@ -0,0 +1,581 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
afterflightinspection "wucher/internal/domain/after_flight_inspection"
|
||||
basedomain "wucher/internal/domain/base"
|
||||
flightdomain "wucher/internal/domain/flight"
|
||||
flightdata "wucher/internal/domain/flight_data"
|
||||
"wucher/internal/domain/mission"
|
||||
reserveac "wucher/internal/domain/reserve_ac"
|
||||
takeoverdomain "wucher/internal/domain/takeover"
|
||||
"wucher/internal/shared/pkg/util"
|
||||
)
|
||||
|
||||
type missionRepoMock struct {
|
||||
createFn func(context.Context, *mission.Mission) error
|
||||
findCategoryByCodeFn func(context.Context, string) (*mission.MissionCategory, error)
|
||||
updateFlightDataIDByIDFn func(context.Context, []byte, []byte, []byte) error
|
||||
deleteByIDFn func(context.Context, []byte, []byte) error
|
||||
deleteByFlightIDFn func(ctx context.Context, flightID []byte, deletedBy []byte) error
|
||||
maxCodeSeqFn func() (int, error)
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) WithTransaction(ctx context.Context, fn func(context.Context) error) error {
|
||||
return fn(ctx)
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) Create(ctx context.Context, row *mission.Mission) error {
|
||||
if m.createFn != nil {
|
||||
return m.createFn(ctx, row)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) CreateCategory(context.Context, *mission.MissionCategory) error { return nil }
|
||||
|
||||
func (m *missionRepoMock) CreatePlaceholder(context.Context, *flightdata.FlightData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) UpdateFlightDataIDByID(ctx context.Context, missionID, flightDataID, updatedBy []byte) error {
|
||||
if m.updateFlightDataIDByIDFn != nil {
|
||||
return m.updateFlightDataIDByIDFn(ctx, missionID, flightDataID, updatedBy)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) UpdateByID(context.Context, []byte, string, []byte, []byte, string, []byte) error {
|
||||
return nil
|
||||
}
|
||||
func (m *missionRepoMock) AttachFile(context.Context, []byte, []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) DetachFile(context.Context, []byte, []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) DeleteByID(ctx context.Context, missionID []byte, deletedBy []byte) error {
|
||||
if m.deleteByIDFn != nil {
|
||||
return m.deleteByIDFn(ctx, missionID, deletedBy)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) DeleteByFlightID(ctx context.Context, flightID []byte, deletedBy []byte) error {
|
||||
if m.deleteByFlightIDFn != nil {
|
||||
return m.deleteByFlightIDFn(ctx, flightID, deletedBy)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) ListByFlightID(context.Context, []byte) ([]mission.Mission, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *missionRepoMock) ListByFlightIDs(context.Context, [][]byte) ([]mission.Mission, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) GetByID(context.Context, []byte) (*mission.Mission, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) GetByFlightID(context.Context, []byte) (*mission.Mission, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) List(context.Context, string, string, []byte, string, int, int) ([]mission.Mission, int64, error) {
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) ListDatatable(context.Context, mission.ListFilter, int, int) ([]mission.Mission, int64, int64, error) {
|
||||
return nil, 0, 0, nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) ListCategoriesWithSubCategories(context.Context) ([]mission.MissionCategory, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) FindCategoryByCode(ctx context.Context, code string) (*mission.MissionCategory, error) {
|
||||
if m.findCategoryByCodeFn != nil {
|
||||
return m.findCategoryByCodeFn(ctx, code)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) SubCategoryBelongsToCategory(context.Context, []byte, []byte) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (m *missionRepoMock) MaxCodeSeqByPrefix(context.Context, string) (int, error) {
|
||||
if m.maxCodeSeqFn != nil {
|
||||
return m.maxCodeSeqFn()
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
type flightDataSvcMockForMission struct {
|
||||
createPlaceholderFn func(context.Context, *flightdata.FlightData) error
|
||||
}
|
||||
|
||||
type afterFlightInspectionSvcMockForMission struct {
|
||||
getByFlightInspectionIDFn func(context.Context, []byte) (*afterflightinspection.AfterFlightInspection, error)
|
||||
}
|
||||
|
||||
type flightSvcMockForMission struct {
|
||||
getByIDFn func(context.Context, []byte) (*flightdomain.Flight, error)
|
||||
}
|
||||
|
||||
func (m *flightSvcMockForMission) Create(context.Context, *flightdomain.Flight) error { return nil }
|
||||
func (m *flightSvcMockForMission) Update(context.Context, *flightdomain.Flight) error { return nil }
|
||||
func (m *flightSvcMockForMission) Delete(context.Context, []byte, []byte) error { return nil }
|
||||
func (m *flightSvcMockForMission) GetByID(ctx context.Context, id []byte) (*flightdomain.Flight, error) {
|
||||
if m.getByIDFn != nil {
|
||||
return m.getByIDFn(ctx, id)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
func (m *flightSvcMockForMission) ListByUserID(context.Context, []byte, int, int) ([]flightdomain.Flight, int64, error) {
|
||||
return nil, 0, nil
|
||||
}
|
||||
func (m *flightSvcMockForMission) ListByCreatedBy(context.Context, []byte, string, string, string, int, int) ([]flightdomain.Flight, int64, error) {
|
||||
return nil, 0, nil
|
||||
}
|
||||
func (m *flightSvcMockForMission) GetByReserveAcID(context.Context, []byte) (*flightdomain.Flight, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *flightSvcMockForMission) ListByReserveAcID(context.Context, []byte) ([]flightdomain.Flight, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *flightSvcMockForMission) GetByTakeoverAcID(context.Context, []byte) (*flightdomain.Flight, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *flightSvcMockForMission) ListByTakeoverAcIDs(context.Context, [][]byte) ([]flightdomain.Flight, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *flightSvcMockForMission) GetByDutyRosterID(context.Context, []byte) (*flightdomain.Flight, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *flightSvcMockForMission) ListByDutyRosterIDs(context.Context, [][]byte) ([]flightdomain.Flight, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *flightSvcMockForMission) List(context.Context, string, string, string, int, int) ([]flightdomain.Flight, int64, error) {
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
||||
func (m *flightDataSvcMockForMission) Create(context.Context, *flightdata.FlightData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *flightDataSvcMockForMission) CreatePlaceholder(ctx context.Context, row *flightdata.FlightData) error {
|
||||
if m.createPlaceholderFn != nil {
|
||||
return m.createPlaceholderFn(ctx, row)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *flightDataSvcMockForMission) Update(context.Context, *flightdata.FlightData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *flightDataSvcMockForMission) Delete(context.Context, []byte, []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *flightDataSvcMockForMission) GetByID(context.Context, []byte) (*flightdata.FlightData, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *flightDataSvcMockForMission) GetByFlightID(context.Context, []byte) (*flightdata.FlightData, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *flightDataSvcMockForMission) GetByMissionID(context.Context, []byte) (*flightdata.FlightData, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *flightDataSvcMockForMission) ListByMissionID(context.Context, []byte) ([]flightdata.FlightData, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *flightDataSvcMockForMission) List(context.Context, string, []byte, []byte, int, int) ([]flightdata.FlightData, int64, error) {
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
||||
func (m *flightDataSvcMockForMission) GetSPODetailsByFlightDataID(context.Context, []byte) (*flightdata.SPODetails, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *flightDataSvcMockForMission) UpsertSPODetails(context.Context, []byte, *flightdata.SPOUpsertData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *afterFlightInspectionSvcMockForMission) Upsert(context.Context, []byte, *afterflightinspection.UpsertRequest) (*afterflightinspection.AfterFlightInspection, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *afterFlightInspectionSvcMockForMission) GetByFlightInspectionID(ctx context.Context, id []byte) (*afterflightinspection.AfterFlightInspection, error) {
|
||||
if m.getByFlightInspectionIDFn != nil {
|
||||
return m.getByFlightInspectionIDFn(ctx, id)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *afterFlightInspectionSvcMockForMission) DeleteByFlightInspectionID(context.Context, []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestMissionServiceCreateDoesNotAutoCreateFlightData(t *testing.T) {
|
||||
var createdPlaceholder *flightdata.FlightData
|
||||
var updatedFlightDataID bool
|
||||
flightID := []byte("flight-id-123456")
|
||||
date := time.Date(2026, 6, 15, 0, 0, 0, 0, time.UTC)
|
||||
baseRow := &basedomain.Base{
|
||||
ID: []byte("base-id-12345678"),
|
||||
BaseName: "Zurich",
|
||||
Latitude: 47.3769,
|
||||
Longitude: 8.5417,
|
||||
UTC: "Europe/Zurich",
|
||||
OperationalShiftTimes: []basedomain.BaseOperationalShiftTime{{
|
||||
DateStart: &date,
|
||||
DateEnd: &date,
|
||||
StartTimeType: basedomain.ShiftTimeTypeFixed,
|
||||
EndTimeType: basedomain.ShiftTimeTypeFixed,
|
||||
ShiftStart: "09:00:00",
|
||||
ShiftEnd: "17:00:00",
|
||||
}},
|
||||
}
|
||||
|
||||
svc := NewMissionService(
|
||||
&missionRepoMock{
|
||||
findCategoryByCodeFn: func(context.Context, string) (*mission.MissionCategory, error) {
|
||||
return &mission.MissionCategory{ID: []byte("category-id-1234"), CodeType: "SPO", TypeName: "SPO"}, nil
|
||||
},
|
||||
updateFlightDataIDByIDFn: func(context.Context, []byte, []byte, []byte) error {
|
||||
updatedFlightDataID = true
|
||||
return nil
|
||||
},
|
||||
maxCodeSeqFn: func() (int, error) { return 4, nil },
|
||||
createFn: func(_ context.Context, row *mission.Mission) error {
|
||||
if row.StartTime == "" || row.EndTime == "" {
|
||||
t.Fatalf("expected resolved mission times on create, got start=%q end=%q", row.StartTime, row.EndTime)
|
||||
}
|
||||
if !strings.HasPrefix(row.Code, "SPO-") || !strings.HasSuffix(row.Code, "-5") {
|
||||
t.Fatalf("expected generated code SPO-<yy>-5, got %q", row.Code)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
&flightSvcMockForMission{
|
||||
getByIDFn: func(context.Context, []byte) (*flightdomain.Flight, error) {
|
||||
return &flightdomain.Flight{
|
||||
ID: flightID,
|
||||
Date: date,
|
||||
Takeover: &takeoverdomain.TakeoverAc{
|
||||
Base: baseRow,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
&flightDataSvcMockForMission{
|
||||
createPlaceholderFn: func(_ context.Context, row *flightdata.FlightData) error {
|
||||
row.ID = []byte("flight-data-id-123")
|
||||
createdPlaceholder = row
|
||||
return nil
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
row := &mission.Mission{
|
||||
FlightID: flightID,
|
||||
Type: "spo",
|
||||
CreatedBy: []byte("creator-id-12345"),
|
||||
UpdatedBy: []byte("creator-id-12345"),
|
||||
}
|
||||
|
||||
if err := svc.Create(context.Background(), row); err != nil {
|
||||
t.Fatalf("Create returned error: %v", err)
|
||||
}
|
||||
// Mission create must NOT auto-create any flight data anymore.
|
||||
if createdPlaceholder != nil {
|
||||
t.Fatal("expected no placeholder flight data to be created on mission create")
|
||||
}
|
||||
if updatedFlightDataID {
|
||||
t.Fatal("expected mission flight_data_id not to be touched")
|
||||
}
|
||||
if len(row.FlightDataID) != 0 {
|
||||
t.Fatalf("expected mission flight_data_id to stay empty, got %x", row.FlightDataID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissionServiceCreateBlockedWhenAfterFlightInspectionExists(t *testing.T) {
|
||||
flightID := []byte("flight-id-123456")
|
||||
inspectionID := []byte("inspection-id-12")
|
||||
date := time.Date(2026, 6, 15, 0, 0, 0, 0, time.UTC)
|
||||
baseRow := &basedomain.Base{
|
||||
ID: []byte("base-id-12345678"),
|
||||
BaseName: "Zurich",
|
||||
Latitude: 47.3769,
|
||||
Longitude: 8.5417,
|
||||
UTC: "Europe/Zurich",
|
||||
OperationalShiftTimes: []basedomain.BaseOperationalShiftTime{{
|
||||
DateStart: &date,
|
||||
DateEnd: &date,
|
||||
StartTimeType: basedomain.ShiftTimeTypeFixed,
|
||||
EndTimeType: basedomain.ShiftTimeTypeFixed,
|
||||
ShiftStart: "09:00:00",
|
||||
ShiftEnd: "17:00:00",
|
||||
}},
|
||||
}
|
||||
repo := &missionRepoMock{
|
||||
findCategoryByCodeFn: func(context.Context, string) (*mission.MissionCategory, error) {
|
||||
return &mission.MissionCategory{ID: []byte("category-id-1234"), CodeType: "SPO", TypeName: "SPO"}, nil
|
||||
},
|
||||
createFn: func(context.Context, *mission.Mission) error {
|
||||
t.Fatal("mission create should not be called when after flight inspection exists")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
svc := NewMissionService(
|
||||
repo,
|
||||
&flightSvcMockForMission{
|
||||
getByIDFn: func(context.Context, []byte) (*flightdomain.Flight, error) {
|
||||
return &flightdomain.Flight{
|
||||
ID: flightID,
|
||||
Date: date,
|
||||
Takeover: &takeoverdomain.TakeoverAc{
|
||||
Base: baseRow,
|
||||
ReserveAc: &reserveac.ReserveAc{InspectionID: inspectionID},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
&afterFlightInspectionSvcMockForMission{
|
||||
getByFlightInspectionIDFn: func(context.Context, []byte) (*afterflightinspection.AfterFlightInspection, error) {
|
||||
return &afterflightinspection.AfterFlightInspection{ID: []byte("after-flight-123")}, nil
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
err := svc.Create(context.Background(), &mission.Mission{
|
||||
FlightID: flightID,
|
||||
Type: "SPO",
|
||||
CreatedBy: []byte("creator-12345678"),
|
||||
UpdatedBy: []byte("creator-12345678"),
|
||||
})
|
||||
if !errors.Is(err, mission.ErrLockedAfterFlightInspection) {
|
||||
t.Fatalf("expected after-flight inspection lock error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissionServiceCreateResolvesMissionTimes(t *testing.T) {
|
||||
flightID := []byte("flight-id-123456")
|
||||
date := time.Date(2026, 6, 15, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
startType string
|
||||
endType string
|
||||
startClock string
|
||||
endClock string
|
||||
useDefaultShift bool
|
||||
defaultStart string
|
||||
defaultEnd string
|
||||
wantStart string
|
||||
wantEnd string
|
||||
}{
|
||||
{
|
||||
name: "fixed",
|
||||
startType: basedomain.ShiftTimeTypeFixed,
|
||||
endType: basedomain.ShiftTimeTypeFixed,
|
||||
startClock: "06:00:00",
|
||||
endClock: "21:00:00",
|
||||
wantStart: "06:00",
|
||||
wantEnd: "21:00",
|
||||
},
|
||||
{
|
||||
name: "bmct and ecet",
|
||||
startType: basedomain.ShiftTimeTypeBMCT,
|
||||
endType: basedomain.ShiftTimeTypeECET,
|
||||
wantStart: "04:49",
|
||||
wantEnd: "22:05",
|
||||
},
|
||||
{
|
||||
name: "mixed fixed start",
|
||||
startType: basedomain.ShiftTimeTypeFixed,
|
||||
endType: basedomain.ShiftTimeTypeECET,
|
||||
startClock: "23:59:00",
|
||||
wantStart: "23:59",
|
||||
wantEnd: "22:05",
|
||||
},
|
||||
{
|
||||
name: "mixed fixed end",
|
||||
startType: basedomain.ShiftTimeTypeBMCT,
|
||||
endType: basedomain.ShiftTimeTypeFixed,
|
||||
endClock: "23:59:00",
|
||||
wantStart: "04:49",
|
||||
wantEnd: "23:59",
|
||||
},
|
||||
{
|
||||
name: "fallback to default shift when operational schedule missing",
|
||||
useDefaultShift: true,
|
||||
wantStart: "06:00",
|
||||
wantEnd: "21:00",
|
||||
},
|
||||
{
|
||||
name: "fallback accepts datetime default shifts",
|
||||
useDefaultShift: true,
|
||||
defaultStart: "2000-01-01 06:00:00",
|
||||
defaultEnd: "2000-01-01 21:00:00",
|
||||
wantStart: "06:00",
|
||||
wantEnd: "21:00",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
baseRow := &basedomain.Base{
|
||||
ID: []byte("base-id-12345678"),
|
||||
BaseName: "Zurich",
|
||||
Latitude: 47.3769,
|
||||
Longitude: 8.5417,
|
||||
UTC: "Europe/Zurich",
|
||||
DefaultShiftStart: "06:00:00",
|
||||
DefaultShiftEnd: "21:00:00",
|
||||
}
|
||||
if tc.defaultStart != "" {
|
||||
baseRow.DefaultShiftStart = tc.defaultStart
|
||||
}
|
||||
if tc.defaultEnd != "" {
|
||||
baseRow.DefaultShiftEnd = tc.defaultEnd
|
||||
}
|
||||
if !tc.useDefaultShift {
|
||||
baseRow.OperationalShiftTimes = []basedomain.BaseOperationalShiftTime{{
|
||||
DateStart: &date,
|
||||
DateEnd: &date,
|
||||
StartTimeType: tc.startType,
|
||||
EndTimeType: tc.endType,
|
||||
ShiftStart: tc.startClock,
|
||||
ShiftEnd: tc.endClock,
|
||||
}}
|
||||
}
|
||||
|
||||
var gotStart, gotEnd string
|
||||
svc := NewMissionService(
|
||||
&missionRepoMock{
|
||||
findCategoryByCodeFn: func(context.Context, string) (*mission.MissionCategory, error) {
|
||||
return &mission.MissionCategory{ID: []byte("category-id-1234"), CodeType: "SPO", TypeName: "SPO"}, nil
|
||||
},
|
||||
createFn: func(_ context.Context, row *mission.Mission) error {
|
||||
gotStart = row.StartTime
|
||||
gotEnd = row.EndTime
|
||||
return nil
|
||||
},
|
||||
},
|
||||
&flightSvcMockForMission{
|
||||
getByIDFn: func(context.Context, []byte) (*flightdomain.Flight, error) {
|
||||
return &flightdomain.Flight{
|
||||
ID: flightID,
|
||||
Date: date,
|
||||
Takeover: &takeoverdomain.TakeoverAc{
|
||||
Base: baseRow,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
row := &mission.Mission{FlightID: flightID, Type: "SPO"}
|
||||
if err := svc.Create(context.Background(), row); err != nil {
|
||||
t.Fatalf("Create returned error: %v", err)
|
||||
}
|
||||
if gotStart != tc.wantStart || gotEnd != tc.wantEnd {
|
||||
t.Fatalf("unexpected resolved times: got %s/%s want %s/%s", gotStart, gotEnd, tc.wantStart, tc.wantEnd)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissionServiceDeleteByFlightIDRequiresFlightID(t *testing.T) {
|
||||
svc := NewMissionService(&missionRepoMock{})
|
||||
|
||||
err := svc.DeleteByFlightID(context.Background(), nil, nil)
|
||||
if !errors.Is(err, mission.ErrFlightIDRequired) {
|
||||
t.Fatalf("expected ErrFlightIDRequired, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissionServiceDeleteByFlightIDDelegatesToRepo(t *testing.T) {
|
||||
wantFlightID := []byte("1234567890123456")
|
||||
wantDeletedBy := []byte("6543210987654321")
|
||||
called := false
|
||||
|
||||
svc := NewMissionService(&missionRepoMock{
|
||||
deleteByFlightIDFn: func(_ context.Context, flightID []byte, deletedBy []byte) error {
|
||||
called = true
|
||||
if string(flightID) != string(wantFlightID) {
|
||||
t.Fatalf("unexpected flightID: %x", flightID)
|
||||
}
|
||||
if string(deletedBy) != string(wantDeletedBy) {
|
||||
t.Fatalf("unexpected deletedBy: %x", deletedBy)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
if err := svc.DeleteByFlightID(context.Background(), wantFlightID, wantDeletedBy); err != nil {
|
||||
t.Fatalf("DeleteByFlightID returned error: %v", err)
|
||||
}
|
||||
if !called {
|
||||
t.Fatal("expected repository DeleteByFlightID to be called")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeMissionClockValueAcceptsDatetime(t *testing.T) {
|
||||
got := util.NormalizeClockValue("2000-01-01 08:00:00")
|
||||
if got != "08:00" {
|
||||
t.Fatalf("expected 08:00, got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissionServiceDeleteByIDRequiresMissionID(t *testing.T) {
|
||||
svc := NewMissionService(&missionRepoMock{})
|
||||
|
||||
err := svc.DeleteByID(context.Background(), nil, nil)
|
||||
if !errors.Is(err, mission.ErrMissionIDRequired) {
|
||||
t.Fatalf("expected ErrMissionIDRequired, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissionServiceDeleteByIDDelegatesToRepo(t *testing.T) {
|
||||
wantMissionID := []byte("1234567890123456")
|
||||
wantDeletedBy := []byte("6543210987654321")
|
||||
called := false
|
||||
|
||||
svc := NewMissionService(&missionRepoMock{
|
||||
deleteByIDFn: func(_ context.Context, missionID []byte, deletedBy []byte) error {
|
||||
called = true
|
||||
if string(missionID) != string(wantMissionID) {
|
||||
t.Fatalf("unexpected missionID: %x", missionID)
|
||||
}
|
||||
if string(deletedBy) != string(wantDeletedBy) {
|
||||
t.Fatalf("unexpected deletedBy: %x", deletedBy)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
if err := svc.DeleteByID(context.Background(), wantMissionID, wantDeletedBy); err != nil {
|
||||
t.Fatalf("DeleteByID returned error: %v", err)
|
||||
}
|
||||
if !called {
|
||||
t.Fatal("expected repository DeleteByID to be called")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user