582 lines
18 KiB
Go
582 lines
18 KiB
Go
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")
|
|
}
|
|
}
|