Merge remote-tracking branch 'origin/test' into dev

This commit is contained in:
2026-09-03 19:09:04 +08:00
4 changed files with 169 additions and 69 deletions
@@ -4,7 +4,9 @@ import com.baiyue.common.core.api.ApiResponse;
import com.baiyue.common.core.api.PageResult;
import com.baiyue.order.client.MerchantPricingCatalogClient;
import com.baiyue.order.client.MerchantWarehouseCatalogClient;
import com.baiyue.order.client.TenantEligibilityClient;
import com.baiyue.order.dto.CustomerAddressDtos;
import com.baiyue.order.dto.MerchantBatchDraftDtos;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.jupiter.api.BeforeEach;
@@ -17,6 +19,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -28,6 +31,7 @@ class MerchantBatchImportServiceTest {
private final CustomerAddressService addresses = mock(CustomerAddressService.class);
private final MerchantWarehouseCatalogClient warehouses = mock(MerchantWarehouseCatalogClient.class);
private final MerchantPricingCatalogClient pricing = mock(MerchantPricingCatalogClient.class);
private final TenantEligibilityClient tenantDirectory = mock(TenantEligibilityClient.class);
private MerchantBatchImportService service;
@BeforeEach
@@ -36,6 +40,8 @@ class MerchantBatchImportServiceTest {
ReflectionTestUtils.setField(service, "addresses", addresses);
ReflectionTestUtils.setField(service, "warehouses", warehouses);
ReflectionTestUtils.setField(service, "pricing", pricing);
ReflectionTestUtils.setField(service, "tenantDirectory", tenantDirectory);
ReflectionTestUtils.setField(service, "token", "internal-token");
ReflectionTestUtils.setField(service, "json", new ObjectMapper().findAndRegisterModules());
when(addresses.list(88L, "PICKUP")).thenReturn(List.of(address(11L, "工厂", "PICKUP")));
when(addresses.list(88L, "PRIVATE_DESTINATION")).thenReturn(List.of(address(12L, "美国门店", "PRIVATE_DESTINATION")));
@@ -46,6 +52,9 @@ class MerchantBatchImportServiceTest {
.thenReturn(ApiResponse.success(new PageResult<>(List.of(domestic, fba, overseas), 1, 200, 3, 1)));
when(pricing.channels("Bearer test", 21L)).thenReturn(ApiResponse.success(List.of(
new MerchantPricingCatalogClient.Channel("US-SEA", "美森海运"))));
var customer = new TenantEligibilityClient.CustomerSummary(88L, "C00088", "权威测试企业", "ACTIVE", "张三", "13800000000");
when(tenantDirectory.customerSummary("internal-token", 1, 1, 88L))
.thenReturn(ApiResponse.success(new PageResult<>(List.of(customer), 1, 1, 1, 1)));
}
@Test
@@ -54,19 +63,26 @@ class MerchantBatchImportServiceTest {
try (var workbook = new XSSFWorkbook(new ByteArrayInputStream(content))) {
var sheet = workbook.getSheet("订单导入");
assertThat(sheet.getRow(0).getCell(0).getStringCellValue()).isEqualTo("订单基础");
assertThat(sheet.getRow(0).getCell(6).getStringCellValue()).isEqualTo("目的地与仓库");
assertThat(sheet.getRow(1).getCell(0).getStringCellValue()).isEqualTo("客户行号 *");
assertThat(sheet.getRow(1).getCell(6).getStringCellValue()).isEqualTo("目的类型 *");
assertThat(sheet.getRow(1).getCell(7).getStringCellValue()).isEqualTo("FBA目的仓");
assertThat(sheet.getRow(1).getCell(8).getStringCellValue()).isEqualTo("海外仓目的仓");
assertThat(sheet.getRow(1).getLastCellNum()).isEqualTo((short) 34);
assertThat(rowValues(sheet.getRow(1))).doesNotContain("目的国家代码", "目的仓库名称", "亚马逊仓库代码");
assertThat(sheet.getRow(0).getCell(5).getStringCellValue()).isEqualTo("目的地与预约");
assertThat(sheet.getRow(0).getCell(10).getStringCellValue()).isEqualTo("货物与包装");
assertThat(sheet.getRow(0).getCell(22).getStringCellValue()).isEqualTo("报关与计价");
assertThat(sheet.getRow(0).getCell(26).getStringCellValue()).isEqualTo("FBA业务信息");
assertThat(sheet.getRow(0).getCell(29).getStringCellValue()).isEqualTo("联系人/备注");
assertThat(sheet.getRow(1).getCell(0).getStringCellValue()).isEqualTo("运输方式 *");
assertThat(sheet.getRow(1).getCell(5).getStringCellValue()).isEqualTo("目的类型 *");
assertThat(sheet.getRow(1).getCell(6).getStringCellValue()).isEqualTo("FBA目的仓");
assertThat(sheet.getRow(1).getCell(7).getStringCellValue()).isEqualTo("海外仓目的仓");
assertThat(sheet.getRow(1).getLastCellNum()).isEqualTo((short) 31);
assertThat(rowValues(sheet.getRow(1))).doesNotContain("客户行号", "客户名称(企业名称)", "贸易术语",
"目的国家代码", "目的仓库名称", "亚马逊仓库代码");
assertThat(sheet.getRow(2).getCell(0).getStringCellValue()).isEmpty();
assertThat(sheet.getRow(51).getCell(0).getStringCellValue()).isEmpty();
assertThat(sheet.getRow(2).getCell(4).getCellStyle().getDataFormatString()).isEqualTo("yyyy-mm-dd");
assertThat(sheet.getRow(2).getCell(11).getCellStyle().getDataFormatString()).isEqualTo("yyyy-mm-dd hh:mm:ss");
assertThat(sheet.getRow(2).getCell(1).getCellStyle().getDataFormatString()).isEqualTo("yyyy-mm-dd");
assertThat(sheet.getRow(2).getCell(9).getCellStyle().getDataFormatString()).isEqualTo("yyyy-mm-dd hh:mm:ss");
assertThat(sheet.getPaneInformation().isFreezePane()).isTrue();
assertThat(sheet.getMergedRegions()).hasSize(6);
assertThat(Set.of(groupColor(sheet, 0), groupColor(sheet, 5), groupColor(sheet, 10),
groupColor(sheet, 22), groupColor(sheet, 26), groupColor(sheet, 29))).hasSize(6);
assertThat(sheet.getCTWorksheet().isSetAutoFilter()).isTrue();
assertThat(sheet.getRow(1).getCell(0).getCellComment()).isNotNull();
assertThat(sheet.getDataValidations()).hasSizeGreaterThanOrEqualTo(10);
@@ -82,20 +98,22 @@ class MerchantBatchImportServiceTest {
byte[] content = service.template(88L, "Bearer test");
try (var workbook = new XSSFWorkbook(new ByteArrayInputStream(content)); var out = new ByteArrayOutputStream()) {
var row = workbook.getSheet("订单导入").getRow(2);
row.createCell(0).setCellValue("第1行"); row.createCell(1).setCellValue("测试客户");
row.createCell(2).setCellValue("海运"); row.getCell(4).setCellValue(LocalDate.of(2026, 9, 20));
row.createCell(6).setCellValue("亚马逊FBA"); row.createCell(7).setCellValue("ATL6");
row.createCell(10).setCellValue("平台上门提货");
row.getCell(11).setCellValue(LocalDateTime.of(2026, 9, 10, 14, 30, 0));
row.createCell(12).setCellValue("工厂|张三|深圳|科技园1号");
row.createCell(13).setCellValue("义乌收货仓|CN-YW"); row.createCell(14).setCellValue("美森海运|US-SEA");
row.createCell(15).setCellValue("买单报关"); row.createCell(16).setCellValue("不包税");
row.createCell(22).setCellValue("蓝牙音箱"); row.createCell(23).setCellValue("纸箱");
row.createCell(24).setCellValue("1"); row.createCell(25).setCellValue("1.2"); row.createCell(26).setCellValue("0.1");
row.createCell(28).setCellValue("否"); row.createCell(29).setCellValue("是");
row.createCell(0).setCellValue("海运"); row.getCell(1).setCellValue(LocalDate.of(2026, 9, 20));
row.createCell(2).setCellValue("平台上门提货");
row.createCell(3).setCellValue("义乌收货仓|CN-YW"); row.createCell(4).setCellValue("美森海运|US-SEA");
row.createCell(5).setCellValue("亚马逊FBA"); row.createCell(6).setCellValue("ATL6");
row.getCell(9).setCellValue(LocalDateTime.of(2026, 9, 10, 14, 30, 0));
row.createCell(10).setCellValue("蓝牙音箱"); row.createCell(11).setCellValue("纸箱");
row.createCell(12).setCellValue("1"); row.createCell(13).setCellValue("1.2"); row.createCell(14).setCellValue("0.1");
row.createCell(16).setCellValue("否"); row.createCell(17).setCellValue("是");
row.createCell(22).setCellValue("买单报关"); row.createCell(23).setCellValue("不包税");
row.createCell(29).setCellValue("工厂|张三|深圳|科技园1号");
workbook.write(out);
var item = service.parse(88L, "Bearer test", out.toByteArray()).get(0);
assertThat(item.parseError()).isNull();
assertThat(item.clientRowId()).isEqualTo("excel-row-3");
assertThat(item.draft().customerName()).isEqualTo("权威测试企业");
assertThat(item.draft().tradeTerm()).isEqualTo("FOB");
assertThat(item.draft().transportMode()).isEqualTo("SEA");
assertThat(item.draft().pickupMethod()).isEqualTo("PICKUP");
assertThat(item.draft().senderAddressId()).isEqualTo(11L);
@@ -110,6 +128,7 @@ class MerchantBatchImportServiceTest {
assertThat(item.draft().requestedPickupAt()).isEqualTo(LocalDateTime.of(2026, 9, 10, 14, 30, 0));
assertThat(item.draft().cargoes().get(0).packageType()).isEqualTo("CARTON");
assertThat(item.draft().cargoes().get(0).dangerousGoods()).isTrue();
verify(tenantDirectory).customerSummary("internal-token", 1, 1, 88L);
}
}
@@ -118,8 +137,8 @@ class MerchantBatchImportServiceTest {
byte[] content = service.template(88L, "Bearer test");
try (var workbook = new XSSFWorkbook(new ByteArrayInputStream(content)); var out = new ByteArrayOutputStream()) {
var row = workbook.getSheet("订单导入").getRow(2);
row.createCell(0).setCellValue("第1行"); row.createCell(6).setCellValue("亚马逊FBA");
row.createCell(8).setCellValue("洛杉矶海外仓|US-LAX");
row.createCell(5).setCellValue("亚马逊FBA");
row.createCell(7).setCellValue("洛杉矶海外仓|US-LAX");
workbook.write(out);
var item = service.parse(88L, "Bearer test", out.toByteArray()).get(0);
assertThat(item.draft()).isNull();
@@ -127,6 +146,19 @@ class MerchantBatchImportServiceTest {
}
}
@Test
void errorReportShowsOnlyActualExcelRowAndErrors() throws Exception {
var failure = MerchantBatchDraftDtos.Result.failure(0, "excel-row-7", "VALIDATION_FAILED", "字段不正确");
var response = new MerchantBatchDraftDtos.Response(1, 0, 1, List.of(failure));
org.springframework.web.multipart.MultipartFile file = ReflectionTestUtils.invokeMethod(service, "errorReport", response);
try (var workbook = new XSSFWorkbook(file.getInputStream())) {
var sheet = workbook.getSheet("错误报告");
assertThat(rowValues(sheet.getRow(0))).containsExactly("Excel行号", "错误代码", "错误说明");
assertThat(sheet.getRow(1).getCell(0).getNumericCellValue()).isEqualTo(7);
assertThat(sheet.getRow(1).getLastCellNum()).isEqualTo((short) 3);
}
}
@Test
void templateReadsEveryActiveWarehousePageWithoutApplyingBusinessLimit() throws Exception {
List<MerchantWarehouseCatalogClient.Warehouse> firstPage = new ArrayList<>();
@@ -179,6 +211,10 @@ class MerchantBatchImportServiceTest {
return values;
}
private static short groupColor(org.apache.poi.xssf.usermodel.XSSFSheet sheet, int column) {
return sheet.getRow(0).getCell(column).getCellStyle().getFillForegroundColor();
}
private static CustomerAddressDtos.Response address(long id, String name, String type) {
return new CustomerAddressDtos.Response(id, type, name, "测试公司", "张三", "13800000000", null,
"CN", "广东", "深圳", "南山", "科技园1号", "518000", true);