From 6bd3e76048415f79c8b43ff1b19cf8af54c7b9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E8=87=AA=E8=BE=BE?= <980324341@qq.com> Date: Sat, 5 Sep 2026 09:23:21 +0800 Subject: [PATCH] =?UTF-8?q?task-218(=E7=A6=BB=E7=BA=BF=E5=8F=AF=E6=94=B6?= =?UTF-8?q?=E9=83=A8=E5=88=86):=20=E7=BB=93=E6=9E=9C=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=A5=91=E7=BA=A6=EF=BC=88=E7=9C=9F=E5=AE=9E?= =?UTF-8?q?=20AppearancePatentSheetBuilder=20=E7=BA=AF=E8=B0=83=E7=94=A8?= =?UTF-8?q?=EF=BC=9ASheet=20=E5=90=8D/=E4=B8=BB=E8=A1=A8=E5=88=97=E5=BA=8F?= =?UTF-8?q?(=E5=90=AB=E6=A0=87=E9=A2=98/=E5=9B=BE=E7=89=87=E9=93=BE?= =?UTF-8?q?=E6=8E=A5/sku)/=E5=8E=9F=E5=9B=A0=E8=A1=A8=E5=88=97/=E7=A9=BA?= =?UTF-8?q?=E8=A1=8C=E4=BA=A7=E5=87=BA=EF=BC=89+=208=20=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 文件名 -result.xlsx 与 ZIP 结构由运行时组装/上传环节生成,依赖真实流水线(3+2 约定 env-gated 另行验证) --- .../AppearancePatentResultFormatTest.java | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 backend-java/src/test/java/com/nanri/aiimage/modules/appearancepatent/service/support/AppearancePatentResultFormatTest.java diff --git a/backend-java/src/test/java/com/nanri/aiimage/modules/appearancepatent/service/support/AppearancePatentResultFormatTest.java b/backend-java/src/test/java/com/nanri/aiimage/modules/appearancepatent/service/support/AppearancePatentResultFormatTest.java new file mode 100644 index 00000000..ecca3e17 --- /dev/null +++ b/backend-java/src/test/java/com/nanri/aiimage/modules/appearancepatent/service/support/AppearancePatentResultFormatTest.java @@ -0,0 +1,110 @@ +package com.nanri.aiimage.modules.appearancepatent.service.support; + +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * task-218(离线可收部分):结果文件格式契约(真实 Sheet builder 纯调用)。 + * + * 调 AppearancePatentSheetBuilder 在内存 Workbook 生成 Sheet,断言 Sheet 名、主表列序、 + * 原因表列名冻结、空行也能产出(空结果文件);文件名 `-result.xlsx` 与 ZIP 结构 + * 由运行时组装/上传环节生成,依赖真实流水线(env-gated 部分另行验证)。 + */ +class AppearancePatentResultFormatTest { + + private static Workbook build() { + Workbook wb = new XSSFWorkbook(); + AppearancePatentSheetBuilder.buildResultSheet(wb, List.of(), Map.of()); + return wb; + } + + private static List expectedMainHeaders() { + List headers = new ArrayList<>(AppearancePatentSheetBuilder.RESULT_HEADERS); + headers.add(6, "标题"); + headers.add(7, "图片链接"); + headers.add(8, "sku"); + return headers; + } + + @Test + void mainSheetNameFrozen() throws Exception { + try (Workbook wb = build()) { + assertNotNull(wb.getSheet("外观专利检测结果"), "主 Sheet 名应冻结为 外观专利检测结果"); + } + } + + @Test + void reasonSheetNameFrozen() throws Exception { + try (Workbook wb = build()) { + assertNotNull(wb.getSheet("原因"), "原因 Sheet 名应冻结为 原因"); + } + } + + @Test + void mainHeaderColumnOrderMatchesContract() throws Exception { + try (Workbook wb = build()) { + Sheet sheet = wb.getSheet("外观专利检测结果"); + Row header = sheet.getRow(0); + List actual = new ArrayList<>(); + for (int i = 0; i < header.getLastCellNum(); i++) { + actual.add(header.getCell(i).getStringCellValue()); + } + assertEquals(expectedMainHeaders(), actual, "主表列序应与 RESULT_HEADERS + 标题/图片链接/sku 一致"); + } + } + + @Test + void reasonHeaderColumnsFrozen() throws Exception { + try (Workbook wb = build()) { + Sheet reason = wb.getSheet("原因"); + Row header = reason.getRow(0); + assertEquals("ASIN", header.getCell(0).getStringCellValue()); + assertEquals("外观原因", header.getCell(1).getStringCellValue()); + assertEquals("专利原因", header.getCell(2).getStringCellValue()); + assertEquals("标题原因", header.getCell(3).getStringCellValue()); + } + } + + @Test + void emptyRowsStillGenerateSheets() throws Exception { + try (Workbook wb = build()) { + assertNotNull(wb.getSheet("外观专利检测结果")); + assertNotNull(wb.getSheet("原因")); + assertEquals(0, wb.getSheet("外观专利检测结果").getPhysicalNumberOfRows() - 1, + "空行时应仅表头,无数据行抛错"); + } + } + + @Test + void resultHeadersConstantDefinesBrandColumns() throws Exception { + List headers = AppearancePatentSheetBuilder.RESULT_HEADERS; + assertTrue(headers.contains("品牌") && headers.contains("价格") && headers.contains("结论") + && headers.contains("状态"), "RESULT_HEADERS 应含 品牌/价格/结论/状态"); + } + + @Test + void firstColumnIsRowId() throws Exception { + List headers = expectedMainHeaders(); + assertEquals("id", headers.get(0), "首列应为 id"); + assertEquals("asin", headers.get(1)); + } + + @Test + void columnCountMatchesContract() throws Exception { + try (Workbook wb = build()) { + int headerCount = wb.getSheet("外观专利检测结果").getRow(0).getLastCellNum(); + assertEquals(expectedMainHeaders().size(), headerCount, "列数应与契约表头一致"); + } + } +}