package com.baiyue.lastleg.trucking; import com.baomidou.mybatisplus.core.MybatisConfiguration; import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; import com.baiyue.lastleg.trucking.entity.UsTruckOrder; import com.baiyue.lastleg.trucking.mapper.*; import com.baiyue.lastleg.trucking.repository.UsTruckOrderRepository; import org.junit.jupiter.api.Test; import org.mybatis.spring.SqlSessionTemplate; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; class UsTruckOrderPersistenceTest { /** 使用模块基线和真实 Mapper 验证新字段保存、回读、更新与客户隔离。 */ @Test void contactsVehicleAndLocalMinuteTimesRoundTripThroughActualMapper() throws Exception { var ds = new DriverManagerDataSource("jdbc:h2:mem:" + UUID.randomUUID() + ";MODE=MySQL;DB_CLOSE_DELAY=-1", "sa", ""); String baseline; try (var input = getClass().getResourceAsStream("/db/lastleg.sql")) { baseline = new String(input.readAllBytes(), StandardCharsets.UTF_8); } int start = baseline.indexOf("CREATE TABLE IF NOT EXISTS ll_us_truck_order ("); String ddl = baseline.substring(start, baseline.indexOf(';', start)); // H2 使用真实字段定义,去掉 MySQL 专属的索引和表选项。 ddl = ddl.replaceAll("(?m)^\\s*(?:UNIQUE KEY|KEY) [^\\n]*\\n?", ""); ddl = ddl.substring(0, ddl.indexOf(") ENGINE=")) + ")"; ddl = ddl.replaceAll(",\\s*\\)$", ")"); new JdbcTemplate(ds).execute(ddl); var config = new MybatisConfiguration(); config.setMapUnderscoreToCamelCase(true); config.addMapper(UsTruckOrderMapper.class); var factory = new MybatisSqlSessionFactoryBean(); factory.setDataSource(ds); factory.setConfiguration(config); var mapper = new SqlSessionTemplate(factory.getObject()).getMapper(UsTruckOrderMapper.class); var repository = new UsTruckOrderRepository(mapper, mock(UsTruckOrderPalletMapper.class), mock(UsTruckOrderStatusHistoryMapper.class), mock(UsTruckOrderOperationMapper.class)); var order = new UsTruckOrder(); order.setId(1L); order.setCustomerId("C-1"); order.setOrderNo("TRUCK-TEST-1"); order.setVehicleType("PALLET_15"); order.setOrigin("Los Angeles"); order.setDestination("Ontario"); order.setOriginContactName("发货人"); order.setOriginContactPhone("+1 (555) 0100"); order.setDestinationContactName("收货人"); order.setDestinationContactPhone("+1-555-0101"); order.setPickupAt(LocalDateTime.of(2026, 10, 20, 9, 30)); order.setDeliveryAt(LocalDateTime.of(2026, 10, 20, 15, 45)); order.setTotalWeightKg(BigDecimal.ZERO); order.setTotalVolumeCbm(BigDecimal.ZERO); order.setCurrency("USD"); order.setStatus("PENDING_REVIEW"); order.setIdempotencyKey("roundtrip"); order.setRequestHash("0".repeat(64)); repository.insertOrder(order); var saved = repository.findNo("C-1", order.getOrderNo()); assertEquals("PALLET_15", saved.getVehicleType()); assertEquals("发货人", saved.getOriginContactName()); assertEquals("+1 (555) 0100", saved.getOriginContactPhone()); assertEquals("收货人", saved.getDestinationContactName()); assertEquals("+1-555-0101", saved.getDestinationContactPhone()); assertEquals(order.getPickupAt(), saved.getPickupAt()); assertEquals(order.getDeliveryAt(), saved.getDeliveryAt()); assertEquals(0, saved.getPalletCount()); assertNull(repository.findNo("C-2", order.getOrderNo())); assertNull(repository.findKey("C-2", "roundtrip")); saved.setVehicleType("PALLET_30"); saved.setDestinationContactPhone("+1-555-0102"); saved.setDeliveryAt(saved.getDeliveryAt().plusMinutes(15)); repository.updateOrder(saved); var updated = repository.findKey("C-1", "roundtrip"); assertEquals("PALLET_30", updated.getVehicleType()); assertEquals("+1-555-0102", updated.getDestinationContactPhone()); assertEquals(LocalDateTime.of(2026, 10, 20, 16, 0), updated.getDeliveryAt()); } }