| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- package printer
- import (
- "fmt"
- "strings"
- "testing"
- "time"
- "github.com/gin-gonic/gin"
- "github.com/glebarez/sqlite"
- "github.com/stretchr/testify/require"
- "gorm.io/gorm"
- "wails-app/internal/dao"
- "wails-app/internal/global"
- commonModel "wails-app/internal/model/common"
- )
- type fakeTicketMachinePassage struct {
- req commonModel.PassageRequest
- result *commonModel.PassageResult
- err error
- }
- func (f *fakeTicketMachinePassage) HandlePassage(req commonModel.PassageRequest) (*commonModel.PassageResult, error) {
- f.req = req
- return f.result, f.err
- }
- type fakeTicketMachinePrinter struct {
- printerID uint
- lotName string
- channelCode string
- plateNo string
- ticketID uint
- ticketNo string
- err error
- }
- func (f *fakeTicketMachinePrinter) PrintTicket(printerID uint, lotName, channelCode, plateNo string, ticketID uint, ticketNo string) error {
- f.printerID = printerID
- f.lotName = lotName
- f.channelCode = channelCode
- f.plateNo = plateNo
- f.ticketID = ticketID
- f.ticketNo = ticketNo
- return f.err
- }
- func setupTicketMachineTest(t *testing.T) (*dao.ParkingLot, *dao.Channel) {
- t.Helper()
- dsn := fmt.Sprintf("file:ticket-machine-%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.Channel{}, &dao.UHFReader{}))
- lot := &dao.ParkingLot{LotCode: "LOT-TICKET", LotName: "票机停车场", Capacity: 50, Available: 50}
- require.NoError(t, db.Create(lot).Error)
- channel := &dao.Channel{
- ChannelCode: "TICKET-IN", ChannelName: "票机入口", Direction: "in",
- AllowTemporary: true, ParkingLotID: lot.ID,
- }
- require.NoError(t, db.Create(channel).Error)
- return lot, channel
- }
- func createTicketMachineDevice(t *testing.T, channelID uint, code string) *dao.UHFReader {
- t.Helper()
- device := &dao.UHFReader{
- DeviceCode: code, DeviceName: code + "名称", DeviceType: "gate",
- ConnectType: "tcp", IsActive: true, ChannelID: channelID,
- }
- require.NoError(t, global.GVA_DB.Create(device).Error)
- return device
- }
- func TestProcessTicketMachineButtonUsesUnifiedPassageAndReturnedTicket(t *testing.T) {
- lot, channel := setupTicketMachineTest(t)
- device := createTicketMachineDevice(t, channel.ID, "GATE-TICKET-01")
- passage := &fakeTicketMachinePassage{result: &commonModel.PassageResult{
- Success: true, Direction: "in", PlateNumber: "TKT-RESULT",
- SessionID: 41, TicketID: 73, TicketNo: "ticket-no-73", EntryTime: 123456,
- BusinessCompleted: true, GateOpened: true, GateStatus: "opened",
- }}
- printer := &fakeTicketMachinePrinter{}
- result, err := processTicketMachineButton(buttonReq{
- PrinterID: 9, ChannelCode: channel.ChannelCode,
- }, passage, printer)
- require.NoError(t, err)
- require.True(t, result.AnonymousVehicle)
- require.Equal(t, lot.ID, result.ParkingLotID)
- require.Equal(t, channel.ChannelCode, result.ChannelCode)
- require.Equal(t, device.DeviceCode, result.DeviceCode)
- require.EqualValues(t, 41, result.SessionID)
- require.EqualValues(t, 73, result.TicketID)
- require.Equal(t, "ticket-no-73", result.TicketNo)
- require.Equal(t, "printed", result.PrintStatus)
- require.Equal(t, device.DeviceCode, passage.req.DeviceCode)
- require.Equal(t, "in", passage.req.Direction)
- require.Equal(t, "ticket_machine", passage.req.TriggerSource)
- require.True(t, strings.HasPrefix(passage.req.PlateNumber, "TKT"))
- require.Len(t, passage.req.PlateNumber, 19)
- require.EqualValues(t, 9, printer.printerID)
- require.Equal(t, lot.LotName, printer.lotName)
- require.Equal(t, channel.ChannelCode, printer.channelCode)
- require.Empty(t, printer.plateNo)
- require.EqualValues(t, 73, printer.ticketID)
- require.Equal(t, "ticket-no-73", printer.ticketNo)
- }
- func TestProcessTicketMachineButtonRequiresDeviceWhenChannelHasMultiple(t *testing.T) {
- _, channel := setupTicketMachineTest(t)
- createTicketMachineDevice(t, channel.ID, "GATE-A")
- createTicketMachineDevice(t, channel.ID, "GATE-B")
- result, err := processTicketMachineButton(buttonReq{
- PrinterID: 1, ChannelCode: channel.ChannelCode,
- }, &fakeTicketMachinePassage{}, &fakeTicketMachinePrinter{})
- require.Nil(t, result)
- require.EqualError(t, err, "票机通道绑定了多个启用设备,必须指定 device_code")
- }
- func TestProcessTicketMachineButtonKeepsBusinessResultWhenPrintFails(t *testing.T) {
- _, channel := setupTicketMachineTest(t)
- createTicketMachineDevice(t, channel.ID, "GATE-PRINT")
- passage := &fakeTicketMachinePassage{result: &commonModel.PassageResult{
- SessionID: 8, TicketID: 9, TicketNo: "ticket-9", PlateNumber: "TEST-PLATE",
- EntryTime: 100, BusinessCompleted: true, GateStatus: "opened",
- }}
- printer := &fakeTicketMachinePrinter{err: fmt.Errorf("paper out")}
- result, err := processTicketMachineButton(buttonReq{
- PrinterID: 1, ChannelCode: channel.ChannelCode, PlateNo: "TEST-PLATE",
- }, passage, printer)
- require.ErrorContains(t, err, "打印失败")
- require.EqualValues(t, 8, result.SessionID)
- require.EqualValues(t, 9, result.TicketID)
- require.Equal(t, "completed", result.BusinessStatus)
- require.Equal(t, "failed", result.PrintStatus)
- }
- func TestPrinterDebugRoutesAreDisabledByDefault(t *testing.T) {
- gin.SetMode(gin.TestMode)
- router := gin.New()
- group := router.Group("")
- SetupPrinterRouter(group)
- SetupPrinterDebugRoutes(group, false)
- routes := router.Routes()
- require.Len(t, routes, 1)
- require.Equal(t, "POST", routes[0].Method)
- require.Equal(t, "/ticket-machine/button", routes[0].Path)
- }
- func TestPrinterDebugRoutesUseSafeMethodsWhenEnabled(t *testing.T) {
- gin.SetMode(gin.TestMode)
- router := gin.New()
- SetupPrinterDebugRoutes(router.Group(""), true)
- methods := map[string]string{}
- for _, route := range router.Routes() {
- methods[route.Path] = route.Method
- }
- require.Equal(t, "POST", methods["/ticket-machine/test"])
- require.Equal(t, "POST", methods["/ticket-machine/debug"])
- require.Equal(t, "GET", methods["/ticket-machine/usb-list"])
- }
|