package parking import ( "fmt" "testing" "time" "github.com/glebarez/sqlite" "github.com/stretchr/testify/require" "gorm.io/gorm" "wails-app/internal/dao" "wails-app/internal/global" "wails-app/internal/model/parking/request" ) func setupParkingLotTest(t *testing.T) *parkingLotService { t.Helper() dsn := fmt.Sprintf("file:parking-lot-%d?mode=memory&cache=shared", time.Now().UnixNano()) db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{}) require.NoError(t, err) sqlDB, err := db.DB() require.NoError(t, err) t.Cleanup(func() { _ = sqlDB.Close() if global.GVA_DB == db { global.GVA_DB = nil } }) global.GVA_DB = db require.NoError(t, db.AutoMigrate(&dao.ParkingLot{}, &dao.VehicleRecord{})) return NewParkingLotService() } func TestCreateParkingLotPersistsFullAdmissionPolicies(t *testing.T) { svc := setupParkingLotTest(t) require.NoError(t, svc.CreateParkingLot(request.ParkingLotCreate{ LotCode: "LOT-A", LotName: "A区", Capacity: 20, AllowTemporaryWhenFull: false, AllowMonthlyWhenFull: true, AllowVIPWhenFull: false, })) var lot dao.ParkingLot require.NoError(t, global.GVA_DB.Where("lot_code = ?", "LOT-A").First(&lot).Error) require.Zero(t, lot.Occupied) require.Equal(t, 20, lot.Available) require.False(t, lot.AllowTemporaryWhenFull) require.True(t, lot.AllowMonthlyWhenFull) require.False(t, lot.AllowVIPWhenFull) } func TestUpdateParkingLotUsesActiveSessionsForAvailability(t *testing.T) { svc := setupParkingLotTest(t) lot := &dao.ParkingLot{LotCode: "LOT-B", LotName: "B区", Capacity: 2, Available: 2} require.NoError(t, global.GVA_DB.Create(lot).Error) require.NoError(t, global.GVA_DB.Create(&dao.VehicleRecord{ PlateNumber: "IN-PARK", ParkingLotID: lot.ID, EntryTime: time.Now(), PaymentStatus: "unpaid", }).Error) err := svc.UpdateParkingLot(request.ParkingLotUpdate{ ID: lot.ID, LotCode: lot.LotCode, LotName: lot.LotName, Capacity: 0, }) require.EqualError(t, err, "停车场容量不能小于当前在场车辆数") require.NoError(t, svc.UpdateParkingLot(request.ParkingLotUpdate{ ID: lot.ID, LotCode: lot.LotCode, LotName: lot.LotName, Capacity: 3, AllowTemporaryWhenFull: true, AllowMonthlyWhenFull: false, AllowVIPWhenFull: true, })) require.NoError(t, global.GVA_DB.First(&lot, lot.ID).Error) require.Equal(t, 1, lot.Occupied) require.Equal(t, 2, lot.Available) require.True(t, lot.AllowTemporaryWhenFull) require.False(t, lot.AllowMonthlyWhenFull) require.True(t, lot.AllowVIPWhenFull) } func TestDeleteParkingLotRejectsActiveSessions(t *testing.T) { svc := setupParkingLotTest(t) lot := &dao.ParkingLot{LotCode: "LOT-C", LotName: "C区", Capacity: 10, Available: 9, Occupied: 1} require.NoError(t, global.GVA_DB.Create(lot).Error) require.NoError(t, global.GVA_DB.Create(&dao.VehicleRecord{ PlateNumber: "ACTIVE-CAR", ParkingLotID: lot.ID, EntryTime: time.Now(), PaymentStatus: "unpaid", }).Error) require.EqualError(t, svc.DeleteParkingLot(lot.ID), "停车场仍有在场车辆,不能删除") require.NoError(t, global.GVA_DB.First(&dao.ParkingLot{}, lot.ID).Error) } func TestDeleteParkingLotWithoutActiveSessions(t *testing.T) { svc := setupParkingLotTest(t) lot := &dao.ParkingLot{LotCode: "LOT-D", LotName: "D区", Capacity: 10, Available: 10} require.NoError(t, global.GVA_DB.Create(lot).Error) require.NoError(t, svc.DeleteParkingLot(lot.ID)) var count int64 require.NoError(t, global.GVA_DB.Model(&dao.ParkingLot{}).Where("id = ?", lot.ID).Count(&count).Error) require.Zero(t, count) }