Merge branch 'test' of http://8.163.30.128:10082/java-project/baiyue-firstleg into oy-test
This commit is contained in:
+1
@@ -59,6 +59,7 @@ public class PlatformExpressCompanyController {
|
||||
@Operation(summary = "分页查询快递公司", description = "按目标租户、关键字和状态分页查询快递公司")
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "查询条件无效"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "需要登录"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "需要平台快递公司查询权限")
|
||||
})
|
||||
|
||||
@@ -86,6 +86,7 @@ public class PlatformPartnerController {
|
||||
@Operation(summary = "分页查询往来单位", description = "按目标租户、关键字、类型和状态分页查询往来单位")
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "查询条件无效"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "需要登录"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "需要平台往来单位查询权限")
|
||||
})
|
||||
|
||||
+20
-5
@@ -16,6 +16,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -48,9 +49,12 @@ public class PlatformWarehouseController {
|
||||
)
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "Created successfully / 创建成功"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "Platform access required / 需要平台端权限"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "Invalid request / 请求参数无效"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "Platform warehouse create permission required (platform:warehouse:create) / 需要平台仓库新增权限"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "409", description = "Warehouse code already exists / 仓库编码已存在")
|
||||
})
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAuthority('platform:warehouse:create')")
|
||||
public ApiResponse<Long> create(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Valid @RequestBody WarehouseRequests.SaveRequest request) {
|
||||
requirePlatform(user);
|
||||
@@ -64,9 +68,13 @@ public class PlatformWarehouseController {
|
||||
)
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "Updated successfully / 更新成功"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "Platform access or tenant validation failed / 平台权限或租户校验失败"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "Invalid request / 请求参数无效"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "Platform warehouse edit permission required (platform:warehouse:edit), or tenant validation failed / 需要平台仓库编辑权限,或租户校验失败"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "Warehouse not found / 仓库不存在"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "409", description = "Warehouse code already exists / 仓库编码已存在")
|
||||
})
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("hasAuthority('platform:warehouse:edit')")
|
||||
public ApiResponse<Void> update(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Parameter(description = "Target tenant ID / 目标租户 ID", example = "10001", required = true)
|
||||
@@ -86,9 +94,11 @@ public class PlatformWarehouseController {
|
||||
)
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "Query succeeded / 查询成功"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "Platform access required / 需要平台端权限")
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "Invalid query / 查询参数无效"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "Platform warehouse list permission required (platform:warehouse:list) / 需要平台仓库查询权限")
|
||||
})
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAuthority('platform:warehouse:list')")
|
||||
public ApiResponse<PageResult<WarehouseEntity>> page(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Parameter(description = "Target tenant ID / 目标租户 ID", example = "10001", required = true)
|
||||
@@ -105,9 +115,11 @@ public class PlatformWarehouseController {
|
||||
)
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "Query succeeded / 查询成功"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "Platform access required / 需要平台端权限"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "Platform warehouse list permission required (platform:warehouse:list) / 需要平台仓库查询权限"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "Warehouse not found / 仓库不存在")
|
||||
})
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAuthority('platform:warehouse:list')")
|
||||
public ApiResponse<WarehouseDetailResponse> detail(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Parameter(description = "Target tenant ID / 目标租户 ID", example = "10001", required = true)
|
||||
@@ -125,9 +137,12 @@ public class PlatformWarehouseController {
|
||||
)
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "Status changed / 状态变更成功"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "Platform access required / 需要平台端权限"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "Invalid status / 状态无效"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "Platform warehouse status permission required (platform:warehouse:status) / 需要平台仓库启停权限"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "Warehouse not found / 仓库不存在")
|
||||
})
|
||||
@PatchMapping("/{id}/status")
|
||||
@PreAuthorize("hasAuthority('platform:warehouse:status')")
|
||||
public ApiResponse<Void> status(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Parameter(description = "Target tenant ID / 目标租户 ID", example = "10001", required = true)
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
/** 仓储数据库不可用或结构漂移时返回可识别的业务码,并保留完整链路日志。 */
|
||||
/** 仓储数据库不可用或结构漂移时返回可识别的 503,并保留完整链路日志。 */
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
@RestControllerAdvice(basePackages = "com.baiyue.warehouse.controller")
|
||||
public class WarehouseDataAccessExceptionHandler {
|
||||
@@ -25,7 +25,7 @@ public class WarehouseDataAccessExceptionHandler {
|
||||
String traceId = CorrelationContext.traceId(request);
|
||||
log.error("Warehouse data access failure requestId={} traceId={}", requestId, traceId, exception);
|
||||
ResultCode code = ResultCode.SERVICE_UNAVAILABLE;
|
||||
return ResponseEntity.ok(ApiResponse.failure(code,
|
||||
return ResponseEntity.status(code.httpStatus()).body(ApiResponse.failure(code,
|
||||
"仓储数据库暂不可用,请检查数据源和数据库迁移", requestId, traceId));
|
||||
}
|
||||
}
|
||||
|
||||
+36
-7
@@ -1,7 +1,7 @@
|
||||
package com.baiyue.warehouse.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -14,11 +14,21 @@ import java.lang.reflect.Method;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DisplayName("平台主数据控制器契约")
|
||||
class PlatformMasterDataControllerContractTest {
|
||||
@Test
|
||||
@DisplayName("往来单位分页路径权限和接口说明完整")
|
||||
void shouldDeclareCompletePartnerListContract() throws Exception {
|
||||
void 仓库平台接口按读取新增编辑和启停权限隔离() {
|
||||
RequestMapping mapping = PlatformWarehouseController.class.getAnnotation(RequestMapping.class);
|
||||
assertThat(mapping.value()).containsExactly("/api/platform/v1/warehouse-admin");
|
||||
|
||||
assertWarehouseMethod("page", GetMapping.class, "platform:warehouse:list");
|
||||
assertWarehouseMethod("detail", GetMapping.class, "platform:warehouse:list");
|
||||
assertWarehouseMethod("create", PostMapping.class, "platform:warehouse:create");
|
||||
assertWarehouseMethod("update", PutMapping.class, "platform:warehouse:edit");
|
||||
assertWarehouseMethod("status", PatchMapping.class, "platform:warehouse:status");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 往来单位分页路径权限和接口说明完整() throws Exception {
|
||||
assertContract(PlatformPartnerController.class, "platform:counterparty:list", "/api/platform/v1/partners");
|
||||
assertMethod(PlatformPartnerController.class, "detail", GetMapping.class, "platform:counterparty:list");
|
||||
assertMethod(PlatformPartnerController.class, "create", PostMapping.class, "platform:counterparty:create");
|
||||
@@ -29,8 +39,7 @@ class PlatformMasterDataControllerContractTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("快递公司分页路径权限和接口说明完整")
|
||||
void shouldDeclareCompleteExpressCompanyListContract() throws Exception {
|
||||
void 快递公司分页路径权限和接口说明完整() throws Exception {
|
||||
assertContract(PlatformExpressCompanyController.class, "platform:express:list", "/api/platform/v1/express-companies");
|
||||
assertMethod(PlatformExpressCompanyController.class, "detail", GetMapping.class, "platform:express:list");
|
||||
assertMethod(PlatformExpressCompanyController.class, "create", PostMapping.class, "platform:express:create");
|
||||
@@ -63,7 +72,27 @@ class PlatformMasterDataControllerContractTest {
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
assertThat(method.getAnnotation(mapping)).isNotNull();
|
||||
assertThat(method.getAnnotation(PreAuthorize.class).value()).contains(authority);
|
||||
PreAuthorize preAuthorize = method.getAnnotation(PreAuthorize.class);
|
||||
assertThat(preAuthorize).isNotNull();
|
||||
assertThat(preAuthorize.value()).isEqualTo("hasAuthority('" + authority + "')");
|
||||
assertThat(method.getAnnotation(Operation.class).summary()).isNotBlank();
|
||||
}
|
||||
|
||||
private static void assertWarehouseMethod(String methodName,
|
||||
Class<? extends java.lang.annotation.Annotation> mapping,
|
||||
String authority) {
|
||||
assertMethod(PlatformWarehouseController.class, methodName, mapping, authority);
|
||||
Method method = java.util.Arrays.stream(PlatformWarehouseController.class.getDeclaredMethods())
|
||||
.filter(candidate -> candidate.getName().equals(methodName))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
ApiResponses responses = method.getAnnotation(ApiResponses.class);
|
||||
assertThat(responses).isNotNull();
|
||||
assertThat(java.util.Arrays.stream(responses.value())
|
||||
.filter(response -> "403".equals(response.responseCode()))
|
||||
.map(io.swagger.v3.oas.annotations.responses.ApiResponse::description))
|
||||
.singleElement()
|
||||
.asString()
|
||||
.contains(authority);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -2,7 +2,6 @@ package com.baiyue.warehouse.controller;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
|
||||
@@ -10,11 +9,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@DisplayName("仓库数据访问异常处理器")
|
||||
class WarehouseDataAccessExceptionHandlerTest {
|
||||
@Test
|
||||
@DisplayName("数据源故障统一返回HTTP 200与S0503业务码并保留请求标识")
|
||||
void shouldReturnServiceUnavailableAndPreserveRequestIdsForDataSourceFailure() {
|
||||
void 数据源故障统一返回503并保留请求标识() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
when(request.getAttribute("requestId")).thenReturn("request-1");
|
||||
when(request.getAttribute("traceId")).thenReturn("trace-1");
|
||||
@@ -22,7 +19,7 @@ class WarehouseDataAccessExceptionHandlerTest {
|
||||
var response = new WarehouseDataAccessExceptionHandler().handle(
|
||||
new DataAccessResourceFailureException("database unavailable"), request);
|
||||
|
||||
assertThat(response.getStatusCode().value()).isEqualTo(200);
|
||||
assertThat(response.getStatusCode().value()).isEqualTo(503);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().code()).isEqualTo(ResultCode.SERVICE_UNAVAILABLE.code());
|
||||
assertThat(response.getBody().message()).contains("数据库");
|
||||
|
||||
+1
-4
@@ -1,18 +1,15 @@
|
||||
package com.baiyue.warehouse.controller;
|
||||
|
||||
import com.baiyue.warehouse.service.WarehouseSchemaReadinessService;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@DisplayName("仓库健康检查控制器")
|
||||
class WarehouseHealthControllerTest {
|
||||
@Test
|
||||
@DisplayName("表结构漂移时状态接口返回503")
|
||||
void shouldReturnServiceUnavailableWhenSchemaDrifts() {
|
||||
void 表结构漂移时状态接口返回503() {
|
||||
WarehouseSchemaReadinessService service = mock(WarehouseSchemaReadinessService.class);
|
||||
when(service.readiness()).thenReturn(
|
||||
new WarehouseSchemaReadinessService.Readiness(false, "DEGRADED", "需要执行迁移"));
|
||||
|
||||
+2
-5
@@ -9,7 +9,6 @@ import com.baiyue.warehouse.mapper.ExpressCompanyMapper;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.apache.ibatis.session.Configuration;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
@@ -19,16 +18,14 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@DisplayName("快递公司仓储")
|
||||
class ExpressCompanyRepositoryTest {
|
||||
@BeforeAll
|
||||
static void initializeEntityFieldCache() {
|
||||
static void 初始化实体字段缓存() {
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new Configuration(), "test"), ExpressCompanyEntity.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("平台分页强制租户并支持筛选")
|
||||
void shouldEnforceTenantAndSupportFilteringForPlatformPage() {
|
||||
void 平台分页强制租户并支持筛选() {
|
||||
ExpressCompanyMapper mapper = mock(ExpressCompanyMapper.class);
|
||||
when(mapper.selectPage(any(Page.class), any())).thenAnswer(invocation -> invocation.getArgument(0));
|
||||
|
||||
|
||||
@@ -17,14 +17,11 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@DisplayName("往来单位仓储")
|
||||
class PartnerRepositoryTest {
|
||||
@BeforeAll static void initializeEntityFieldCache() {
|
||||
@BeforeAll static void 初始化实体字段缓存() {
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new Configuration(), "test"), PartnerEntity.class);
|
||||
}
|
||||
@Test
|
||||
@DisplayName("候选查询强制租户和启用状态")
|
||||
void shouldEnforceTenantAndActiveStatusForCandidateQuery() {
|
||||
@Test void 候选查询强制租户和启用状态() {
|
||||
PartnerMapper mapper=mock(PartnerMapper.class); when(mapper.selectList(any())).thenReturn(List.of());
|
||||
when(mapper.selectPartnerIdsByType(10001,"SHIPPER")).thenReturn(List.of(1L));
|
||||
new PartnerRepository(mapper).activeCandidates(10001,"示例","SHIPPER");
|
||||
@@ -49,9 +46,7 @@ class PartnerRepositoryTest {
|
||||
wrapper.getValue().getSqlSegment();
|
||||
assertThat(wrapper.getValue().getParamNameValuePairs().values()).contains(10001L,"ACTIVE",1L,2L);
|
||||
}
|
||||
@Test
|
||||
@DisplayName("详情查询强制租户和启用状态")
|
||||
void shouldEnforceTenantAndActiveStatusForDetailQuery() {
|
||||
@Test void 详情查询强制租户和启用状态() {
|
||||
PartnerMapper mapper=mock(PartnerMapper.class); when(mapper.selectOne(any())).thenReturn(null);
|
||||
new PartnerRepository(mapper).findActive(10002,9);
|
||||
@SuppressWarnings("unchecked") ArgumentCaptor<LambdaQueryWrapper<PartnerEntity>> c=ArgumentCaptor.forClass(LambdaQueryWrapper.class);
|
||||
@@ -59,9 +54,7 @@ class PartnerRepositoryTest {
|
||||
assertThat(c.getValue().getParamNameValuePairs().values()).contains(10002L,9L,"ACTIVE");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("平台分页强制租户并支持筛选")
|
||||
void shouldEnforceTenantAndSupportFilteringForPlatformPage() {
|
||||
@Test void 平台分页强制租户并支持筛选() {
|
||||
PartnerMapper mapper=mock(PartnerMapper.class);
|
||||
when(mapper.selectPartnerIdsByType(10001L, "CUSTOMER")).thenReturn(List.of(9L));
|
||||
when(mapper.selectPage(any(Page.class), any())).thenAnswer(invocation -> invocation.getArgument(0));
|
||||
|
||||
+4
-10
@@ -1,6 +1,5 @@
|
||||
package com.baiyue.warehouse.repository;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -9,11 +8,9 @@ import java.nio.file.Path;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DisplayName("仓库数据库结构契约")
|
||||
class WarehouseSchemaContractTest {
|
||||
@Test
|
||||
@DisplayName("仓库三张表包含实体全部持久化字段")
|
||||
void shouldContainAllPersistentFieldsInWarehouseTables() throws IOException {
|
||||
void 仓库三张表包含实体全部持久化字段() throws IOException {
|
||||
String sql = read("warehouse.sql");
|
||||
assertColumns(sql, "wh_warehouse", "warehouse_code", "warehouse_name", "warehouse_type", "country_code",
|
||||
"timezone", "contact_name", "contact_phone", "contact_email", "status", "remark");
|
||||
@@ -25,8 +22,7 @@ class WarehouseSchemaContractTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("往来单位表包含实体全部持久化字段")
|
||||
void shouldContainAllPersistentFieldsInPartnerTable() throws IOException {
|
||||
void 往来单位表包含实体全部持久化字段() throws IOException {
|
||||
String sql = read("warehouse-partner.sql");
|
||||
assertColumns(sql, "wh_partner", "data_scope_id", "partner_code", "partner_name", "partner_type", "contact_name",
|
||||
"contact_phone", "contact_email", "country_code", "province", "city", "district", "address_line",
|
||||
@@ -37,8 +33,7 @@ class WarehouseSchemaContractTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("快递公司表包含实体全部持久化字段")
|
||||
void shouldContainAllPersistentFieldsInExpressCompanyTable() throws IOException {
|
||||
void 快递公司表包含实体全部持久化字段() throws IOException {
|
||||
String sql = read("warehouse-express-company.sql");
|
||||
assertColumns(sql, "wh_express_company", "company_code", "company_name", "service_phone", "website",
|
||||
"tracking_url_template", "status", "remark");
|
||||
@@ -46,8 +41,7 @@ class WarehouseSchemaContractTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("既有库增量迁移覆盖全部仓储实体表和列表索引")
|
||||
void shouldCoverAllWarehouseTablesAndListIndexesInIncrementalMigration() throws IOException {
|
||||
void 既有库增量迁移覆盖全部仓储实体表和列表索引() throws IOException {
|
||||
String sql = read("phase1-warehouse-schema-migration.sql");
|
||||
assertThat(sql).contains("FROM information_schema.columns")
|
||||
.contains("CREATE PROCEDURE add_column_if_missing")
|
||||
|
||||
@@ -26,7 +26,7 @@ class PartnerQueryServiceTest {
|
||||
.isEqualTo(ResultCode.NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test void inactivePartnerReturnsConflict() {
|
||||
@Test void 停用往来单位返回409() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
PartnerEntity partner = new PartnerEntity();
|
||||
partner.setId(7L); partner.setTenantId(10001L); partner.setStatus("INACTIVE");
|
||||
@@ -38,7 +38,7 @@ class PartnerQueryServiceTest {
|
||||
.isEqualTo(ResultCode.CONFLICT);
|
||||
}
|
||||
|
||||
@Test void activePartnerIsReturned() {
|
||||
@Test void 启用往来单位正常返回() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
PartnerEntity partner = new PartnerEntity();
|
||||
partner.setId(7L); partner.setTenantId(10001L); partner.setStatus("ACTIVE");
|
||||
|
||||
+11
-23
@@ -21,11 +21,9 @@ import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@DisplayName("平台主数据维护服务")
|
||||
class PlatformMasterDataManagementServiceTest {
|
||||
@Test
|
||||
@DisplayName("往来单位详情强制租户隔离")
|
||||
void shouldEnforceTenantIsolationForPartnerDetail() {
|
||||
void 往来单位详情强制租户隔离() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
PlatformPartnerQueryService service = new PlatformPartnerQueryService(repository);
|
||||
|
||||
@@ -34,8 +32,7 @@ class PlatformMasterDataManagementServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("往来单位编码在租户内必须唯一")
|
||||
void shouldRequireUniquePartnerCodeWithinTenant() {
|
||||
void 往来单位编码在租户内必须唯一() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
when(repository.existsCode(10001L, "CUS-001", null)).thenReturn(true);
|
||||
PlatformPartnerQueryService service = new PlatformPartnerQueryService(repository);
|
||||
@@ -46,8 +43,7 @@ class PlatformMasterDataManagementServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("往来单位并发重复编码统一返回业务冲突")
|
||||
void shouldReturnBusinessConflictForConcurrentDuplicatePartnerCode() {
|
||||
void 往来单位并发重复编码统一返回业务冲突() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
doThrow(new DataIntegrityViolationException("duplicate")).when(repository).insert(any());
|
||||
PlatformPartnerQueryService service = new PlatformPartnerQueryService(repository);
|
||||
@@ -57,8 +53,7 @@ class PlatformMasterDataManagementServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("往来单位新增写入租户和请求字段")
|
||||
void shouldPersistTenantAndRequestFieldsWhenCreatingPartner() {
|
||||
void 往来单位新增写入租户和请求字段() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
doAnswer(invocation -> {
|
||||
PartnerEntity entity = invocation.getArgument(0);
|
||||
@@ -80,8 +75,7 @@ class PlatformMasterDataManagementServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("往来单位编辑保留归属并更新字段")
|
||||
void shouldPreserveOwnershipAndUpdateFieldsWhenEditingPartner() {
|
||||
void 往来单位编辑保留归属并更新字段() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
PartnerEntity entity = new PartnerEntity();
|
||||
entity.setId(19L);
|
||||
@@ -97,8 +91,7 @@ class PlatformMasterDataManagementServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("往来单位停用保留主数据")
|
||||
void shouldPreservePartnerMasterDataWhenDeactivating() {
|
||||
void 往来单位停用保留主数据() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
PartnerEntity entity = new PartnerEntity();
|
||||
entity.setId(8L);
|
||||
@@ -114,8 +107,7 @@ class PlatformMasterDataManagementServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("快递公司详情强制租户隔离")
|
||||
void shouldEnforceTenantIsolationForExpressCompanyDetail() {
|
||||
void 快递公司详情强制租户隔离() {
|
||||
ExpressCompanyRepository repository = mock(ExpressCompanyRepository.class);
|
||||
ExpressCompanyQueryService service = new ExpressCompanyQueryService(repository);
|
||||
|
||||
@@ -124,8 +116,7 @@ class PlatformMasterDataManagementServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("快递公司编码在租户内必须唯一")
|
||||
void shouldRequireUniqueExpressCompanyCodeWithinTenant() {
|
||||
void 快递公司编码在租户内必须唯一() {
|
||||
ExpressCompanyRepository repository = mock(ExpressCompanyRepository.class);
|
||||
when(repository.existsCode(10001L, "SF", null)).thenReturn(true);
|
||||
ExpressCompanyQueryService service = new ExpressCompanyQueryService(repository);
|
||||
@@ -159,8 +150,7 @@ class PlatformMasterDataManagementServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("快递公司新增写入租户和请求字段")
|
||||
void shouldPersistTenantAndRequestFieldsWhenCreatingExpressCompany() {
|
||||
void 快递公司新增写入租户和请求字段() {
|
||||
ExpressCompanyRepository repository = mock(ExpressCompanyRepository.class);
|
||||
doAnswer(invocation -> {
|
||||
ExpressCompanyEntity entity = invocation.getArgument(0);
|
||||
@@ -180,8 +170,7 @@ class PlatformMasterDataManagementServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("快递公司编辑保留归属并更新字段")
|
||||
void shouldPreserveOwnershipAndUpdateFieldsWhenEditingExpressCompany() {
|
||||
void 快递公司编辑保留归属并更新字段() {
|
||||
ExpressCompanyRepository repository = mock(ExpressCompanyRepository.class);
|
||||
ExpressCompanyEntity entity = new ExpressCompanyEntity();
|
||||
entity.setId(29L);
|
||||
@@ -197,8 +186,7 @@ class PlatformMasterDataManagementServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("快递公司停用保留主数据")
|
||||
void shouldPreserveExpressCompanyMasterDataWhenDeactivating() {
|
||||
void 快递公司停用保留主数据() {
|
||||
ExpressCompanyRepository repository = mock(ExpressCompanyRepository.class);
|
||||
ExpressCompanyEntity entity = new ExpressCompanyEntity();
|
||||
entity.setId(9L);
|
||||
|
||||
+3
-8
@@ -4,17 +4,14 @@ import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.warehouse.entity.WarehouseEntity;
|
||||
import com.baiyue.warehouse.repository.WarehouseRepository;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@DisplayName("仓库应用服务")
|
||||
class WarehouseApplicationServiceTest {
|
||||
@Test
|
||||
@DisplayName("商户详情只返回启用且属于租户的仓库")
|
||||
void shouldReturnOnlyActiveTenantOwnedWarehouseForMerchantDetail() {
|
||||
void 商户详情只返回启用且属于租户的仓库() {
|
||||
WarehouseRepository repository=mock(WarehouseRepository.class);
|
||||
WarehouseEntity warehouse=new WarehouseEntity(); warehouse.setId(1L); warehouse.setTenantId(10001L); warehouse.setStatus("ACTIVE");
|
||||
when(repository.findOwned(10001,1)).thenReturn(warehouse);
|
||||
@@ -25,16 +22,14 @@ class WarehouseApplicationServiceTest {
|
||||
verify(repository).findOwned(10001,1);
|
||||
}
|
||||
@Test
|
||||
@DisplayName("跨租户或不存在仓库返回 404")
|
||||
void shouldTreatMissingOrCrossTenantWarehouseAsNotFound() {
|
||||
void 跨租户或不存在仓库返回404() {
|
||||
WarehouseRepository repository=mock(WarehouseRepository.class);
|
||||
WarehouseApplicationService service=new WarehouseApplicationService(); ReflectionTestUtils.setField(service,"repository",repository);
|
||||
assertThatThrownBy(() -> service.activeDetail(10002,1)).isInstanceOf(BizException.class)
|
||||
.extracting(exception -> ((BizException) exception).getResultCode()).isEqualTo(ResultCode.NOT_FOUND);
|
||||
}
|
||||
@Test
|
||||
@DisplayName("停用仓库返回 409")
|
||||
void shouldTreatInactiveWarehouseAsConflict() {
|
||||
void 停用仓库返回409() {
|
||||
WarehouseRepository repository=mock(WarehouseRepository.class);
|
||||
WarehouseEntity warehouse=new WarehouseEntity(); warehouse.setId(1L); warehouse.setTenantId(10001L); warehouse.setStatus("INACTIVE");
|
||||
when(repository.findOwned(10001,1)).thenReturn(warehouse);
|
||||
|
||||
+2
-6
@@ -1,6 +1,5 @@
|
||||
package com.baiyue.warehouse.service;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
@@ -13,11 +12,9 @@ import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@DisplayName("仓库表结构就绪检查服务")
|
||||
class WarehouseSchemaReadinessServiceTest {
|
||||
@Test
|
||||
@DisplayName("全部表字段可查询时返回就绪")
|
||||
void shouldReportUpWhenAllTablesAndColumnsAreQueryable() {
|
||||
void 全部表字段可查询时返回就绪() {
|
||||
JdbcTemplate jdbcTemplate = mock(JdbcTemplate.class);
|
||||
|
||||
var readiness = new WarehouseSchemaReadinessService(jdbcTemplate).readiness();
|
||||
@@ -28,8 +25,7 @@ class WarehouseSchemaReadinessServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("缺表或缺列时返回降级而不是伪报正常")
|
||||
void shouldReportDegradedWhenTableOrColumnIsMissing() {
|
||||
void 缺表或缺列时返回降级而不是伪报正常() {
|
||||
JdbcTemplate jdbcTemplate = mock(JdbcTemplate.class);
|
||||
doThrow(new BadSqlGrammarException("probe", "SELECT", new SQLException("missing")))
|
||||
.when(jdbcTemplate).execute(anyString());
|
||||
|
||||
Reference in New Issue
Block a user