package com.ruoyi.system.mapper.flash; import com.ruoyi.system.domain.flash.FlashDeliveryOrder; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.mapping.ResultMapping; import org.apache.ibatis.session.Configuration; import org.junit.jupiter.api.Test; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Set; import java.util.stream.Collectors; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; class FlashDeliveryMapperXmlTest { @Test void stationFulfilmentLocksOrderAndPersistsExplicitTargetReset() throws Exception { String resource = "mapper/flash/FlashDeliveryOrderMapper.xml"; Configuration configuration = new Configuration(); configuration.getTypeAliasRegistry().registerAlias("FlashDeliveryOrder", FlashDeliveryOrder.class); try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource)) { new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse(); } String namespace = "com.ruoyi.system.mapper.flash.FlashDeliveryOrderMapper."; String lock = configuration.getMappedStatement(namespace + "selectByIdForUpdate") .getBoundSql(java.util.Map.of("id", 10L)).getSql().replaceAll("\\s+", " ").toLowerCase(); assertTrue(lock.endsWith("for update")); FlashDeliveryOrder order = new FlashDeliveryOrder(); order.setId(10L); order.setVersion(3); var bound = configuration.getMappedStatement(namespace + "updateFulfilment").getBoundSql(java.util.Map.of("order", order)); String sql = bound.getSql().replaceAll("\\s+", " ").toLowerCase(); assertTrue(sql.contains("current_target_stop_id = ?")); assertTrue(sql.contains("picked_up_stop_count = ?")); assertTrue(sql.contains("status = 'accepted' and version = ?")); assertTrue(sql.contains("version = version + 1")); assertTrue(bound.getParameterMappings().stream().anyMatch(p -> p.getProperty().equals("order.currentTargetStopId"))); } @Test void stationAndAdjustmentMappingsPreserveItemsAndDeclarationIdentity() throws Exception { for (String name : java.util.List.of("FlashDeliveryOrderStop", "FlashDeliveryTargetAdjustment")) { String resource = "mapper/flash/" + name + "Mapper.xml"; Configuration configuration = new Configuration(); try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource)) { new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse(); } Set properties = configuration.getResultMap("com.ruoyi.system.mapper.flash." + name + "Mapper." + name + "Result") .getResultMappings().stream().map(ResultMapping::getProperty).collect(Collectors.toSet()); if (name.equals("FlashDeliveryOrderStop")) { assertTrue(properties.containsAll(Set.of("orderId", "stopType", "stopOrder", "packageType", "quantity", "weightRange", "specification", "status", "pickedUpAt"))); } else { assertTrue(properties.containsAll(Set.of("fromStopId", "toStopId", "riderId", "clientRequestId", "orderVersion", "reason", "consentDeclared", "createTime"))); } } } @Test void waitingOrderEditsGuardOwnerStatusRiderAndVersionInOneUpdate() throws Exception { String resource = "mapper/flash/FlashDeliveryOrderMapper.xml"; Configuration configuration = new Configuration(); configuration.getTypeAliasRegistry().registerAlias("FlashDeliveryOrder", FlashDeliveryOrder.class); try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource)) { new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse(); } for (String name : java.util.List.of("updateWaitingAddress", "updateWaitingTip")) { String statement = "com.ruoyi.system.mapper.flash.FlashDeliveryOrderMapper." + name; assertTrue(configuration.hasStatement(statement), "Missing atomic update: " + name); var sql = configuration.getMappedStatement(statement) .getBoundSql(java.util.Map.of("order", new FlashDeliveryOrder(), "expectedVersion", 2)); String text = sql.getSql().replaceAll("\\s+", " ").toLowerCase(); String where = text.substring(text.indexOf("where")); assertTrue(where.contains("id = ?")); assertTrue(where.contains("user_id = ?")); assertTrue(where.contains("status = 'waiting_acceptance'")); assertTrue(where.contains("rider_id is null")); assertTrue(where.contains("version = ?")); assertTrue(text.contains("version = version + 1")); var bindings = sql.getParameterMappings().stream().map(item -> item.getProperty()).toList(); assertTrue(bindings.containsAll(java.util.List.of("order.id", "order.userId", "expectedVersion"))); if (name.equals("updateWaitingAddress")) { assertTrue(text.contains("receiver_user_id = ?")); assertTrue(bindings.containsAll(java.util.List.of("order.pickupPhone", "order.deliveryPhone", "order.pickupLongitude", "order.deliveryLatitude", "order.distanceMeters", "order.baseDeliveryFee", "order.urgentFee", "order.amount"))); } else { assertFalse(text.contains("pickup_")); assertFalse(text.contains("base_delivery_fee =")); } } } @Test void receiverLookupRequiresUniqueEligibleNormalizedPhoneCandidate() throws Exception { String resource = "mapper/infouser/InfoUserMapper.xml"; String xml; try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource)) { assertNotNull(input); xml = new String(input.readAllBytes(), StandardCharsets.UTF_8).toLowerCase(); } assertTrue(xml.contains("selectordinaryuseridsbynormalizedphone")); assertTrue(xml.contains("user_type = '0'")); assertTrue(xml.contains("status = '0'")); assertTrue(xml.contains("del_flag = '0' or del_flag is null")); assertFalse(xml.contains("regexp_replace(")); assertTrue(xml.contains("replace(phone, ' ', '')")); assertTrue(xml.contains("char(9)")); assertTrue(xml.contains("char(10)")); assertTrue(xml.contains("char(13)")); assertTrue(xml.contains("replace(replace(replace(replace(replace(replace(replace(replace(phone, " + "' ', ''), char(9), ''), char(10), ''), char(13), ''), '(', ''), ')', ''), '+', ''), " + "'-', '') = #{normalizedphone}")); assertTrue(xml.contains("limit 2")); } @Test void orderMapperMapsSnapshotsAndUsesConditionalAtomicUpdates() throws Exception { String resource = "mapper/flash/FlashDeliveryOrderMapper.xml"; Configuration configuration = new Configuration(); configuration.getTypeAliasRegistry().registerAlias("FlashDeliveryOrder", FlashDeliveryOrder.class); String xml; try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource)) { assertNotNull(input); xml = new String(input.readAllBytes(), StandardCharsets.UTF_8); } try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource)) { new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse(); } ResultMapping amount = configuration .getResultMap("com.ruoyi.system.mapper.flash.FlashDeliveryOrderMapper.FlashDeliveryOrderResult") .getResultMappings().stream().filter(item -> "amount".equals(item.getProperty())) .findFirst().orElseThrow(); assertEquals("amount", amount.getColumn()); ResultMapping weightRange = configuration .getResultMap("com.ruoyi.system.mapper.flash.FlashDeliveryOrderMapper.FlashDeliveryOrderResult") .getResultMappings().stream().filter(item -> "weightRange".equals(item.getProperty())) .findFirst().orElseThrow(); assertEquals("weight_range", weightRange.getColumn()); Set mappedProperties = configuration .getResultMap("com.ruoyi.system.mapper.flash.FlashDeliveryOrderMapper.FlashDeliveryOrderResult") .getResultMappings().stream() .map(ResultMapping::getProperty) .collect(Collectors.toSet()); assertTrue(mappedProperties.containsAll(Set.of( "receiverUserId", "deliveryType", "quantity", "weightRange", "specification", "pricingId", "pricingVersion", "pricingStartTime", "pricingEndTime", "startingDistance", "startingFare", "distance", "freight", "distanceFee", "baseDeliveryFee", "urgentRate", "minimumUrgentFee", "urgentFee", "tipAmount"))); assertFalse(mappedProperties.contains("totalWeightKg")); assertFalse(mappedProperties.contains("packageSize")); assertTrue(xml.contains("status = 'WAITING_ACCEPTANCE'")); assertTrue(xml.contains("rider_id is null")); assertTrue(xml.contains("scheduled_pickup_start_at <= #{now}")); assertTrue(xml.contains("package_type")); assertTrue(xml.contains("delivery_pin_code")); assertTrue(xml.contains("delivered_at <=")); assertTrue(xml.contains("version = version + 1")); assertTrue(xml.contains("receiver_user_id = #{userId}")); } }