package parking import ( "strings" "testing" "time" "github.com/glebarez/sqlite" "gorm.io/gorm" "wails-app/internal/dao" "wails-app/internal/global" common "wails-app/internal/model/common" ) // newInferTestDB 每个用例独立的内存库,避免相互污染。 func newInferTestDB(t *testing.T) { t.Helper() db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) if err != nil { t.Fatalf("打开内存数据库失败: %v", err) } if err := db.AutoMigrate(&dao.VehicleRecord{}); err != nil { t.Fatalf("迁移表失败: %v", err) } oldDB := global.GVA_DB global.GVA_DB = db oldMinutes := global.GVA_CONFIG.System.InoutMinStayMinutes global.GVA_CONFIG.System.InoutMinStayMinutes = 1 t.Cleanup(func() { global.GVA_DB = oldDB global.GVA_CONFIG.System.InoutMinStayMinutes = oldMinutes }) } func TestInferInoutDirection_NoSessionMeansEntry(t *testing.T) { newInferTestDB(t) svc := &PassageService{} dir, err := svc.inferInoutDirection(common.PassageRequest{RFIDTag: "E280001"}) if err != nil { t.Fatalf("无会话应推断为进场,却返回错误: %v", err) } if dir != "in" { t.Fatalf("期望方向 in,实际 %s", dir) } } func TestInferInoutDirection_ActiveSessionPastMinStayMeansExit(t *testing.T) { newInferTestDB(t) rec := dao.VehicleRecord{ PlateNumber: "湘A11111", RFIDTag: "E280001", EntryTime: time.Now().Add(-5 * time.Minute), } if err := global.GVA_DB.Create(&rec).Error; err != nil { t.Fatalf("造会话数据失败: %v", err) } svc := &PassageService{} dir, err := svc.inferInoutDirection(common.PassageRequest{RFIDTag: "E280001"}) if err != nil { t.Fatalf("停留已满最小值应推断为出场,却返回错误: %v", err) } if dir != "out" { t.Fatalf("期望方向 out,实际 %s", dir) } } func TestInferInoutDirection_DuplicateReadWithinMinStayIgnored(t *testing.T) { newInferTestDB(t) rec := dao.VehicleRecord{ PlateNumber: "湘A22222", RFIDTag: "E280002", EntryTime: time.Now().Add(-30 * time.Second), } if err := global.GVA_DB.Create(&rec).Error; err != nil { t.Fatalf("造会话数据失败: %v", err) } svc := &PassageService{} _, err := svc.inferInoutDirection(common.PassageRequest{RFIDTag: "E280002"}) if err == nil || !strings.Contains(err.Error(), "重复读卡忽略") { t.Fatalf("最小停留内重复读卡应被忽略,实际: %v", err) } } func TestInferInoutDirection_AmbiguousSessionsFailSafe(t *testing.T) { newInferTestDB(t) now := time.Now().Add(-10 * time.Minute) for _, rec := range []dao.VehicleRecord{ {PlateNumber: "湘A33333", RFIDTag: "E280003", EntryTime: now}, {PlateNumber: "湘A33334", RFIDTag: "E280003", EntryTime: now}, } { if err := global.GVA_DB.Create(&rec).Error; err != nil { t.Fatalf("造会话数据失败: %v", err) } } svc := &PassageService{} _, err := svc.inferInoutDirection(common.PassageRequest{RFIDTag: "E280003"}) if err == nil || !strings.Contains(err.Error(), "方向推断失败") { t.Fatalf("同卡多会话应保错退出,实际: %v", err) } }