暂存提交
This commit is contained in:
+61
@@ -0,0 +1,61 @@
|
||||
package com.baiyue.warehouse.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class PlatformMasterDataControllerContractTest {
|
||||
@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");
|
||||
assertMethod(PlatformPartnerController.class, "update", PutMapping.class, "platform:counterparty:edit");
|
||||
assertMethod(PlatformPartnerController.class, "changeStatus", PatchMapping.class, "platform:counterparty:status");
|
||||
}
|
||||
|
||||
@Test
|
||||
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");
|
||||
assertMethod(PlatformExpressCompanyController.class, "update", PutMapping.class, "platform:express:edit");
|
||||
assertMethod(PlatformExpressCompanyController.class, "changeStatus", PatchMapping.class, "platform:express:status");
|
||||
}
|
||||
|
||||
private static void assertContract(Class<?> controller, String authority, String path) throws Exception {
|
||||
RequestMapping mapping = controller.getAnnotation(RequestMapping.class);
|
||||
assertThat(mapping.value()).containsExactly(path);
|
||||
|
||||
Method page = controller.getDeclaredMethod("page",
|
||||
com.baiyue.common.security.AuthenticatedUser.class,
|
||||
long.class,
|
||||
controller == PlatformPartnerController.class
|
||||
? com.baiyue.warehouse.dto.MasterDataQueries.PartnerPageQuery.class
|
||||
: com.baiyue.warehouse.dto.MasterDataQueries.ExpressCompanyPageQuery.class);
|
||||
assertThat(page.getAnnotation(GetMapping.class)).isNotNull();
|
||||
assertThat(page.getAnnotation(PreAuthorize.class).value()).contains(authority);
|
||||
assertThat(page.getAnnotation(Operation.class).summary()).contains("分页查询");
|
||||
}
|
||||
|
||||
private static void assertMethod(Class<?> controller, String methodName,
|
||||
Class<? extends java.lang.annotation.Annotation> mapping,
|
||||
String authority) {
|
||||
Method method = java.util.Arrays.stream(controller.getDeclaredMethods())
|
||||
.filter(candidate -> candidate.getName().equals(methodName))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
assertThat(method.getAnnotation(mapping)).isNotNull();
|
||||
assertThat(method.getAnnotation(PreAuthorize.class).value()).contains(authority);
|
||||
assertThat(method.getAnnotation(Operation.class).summary()).isNotBlank();
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.baiyue.warehouse.repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baiyue.warehouse.dto.MasterDataQueries.ExpressCompanyPageQuery;
|
||||
import com.baiyue.warehouse.entity.ExpressCompanyEntity;
|
||||
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.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class ExpressCompanyRepositoryTest {
|
||||
@BeforeAll
|
||||
static void 初始化实体字段缓存() {
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new Configuration(), "test"), ExpressCompanyEntity.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void 平台分页强制租户并支持筛选() {
|
||||
ExpressCompanyMapper mapper = mock(ExpressCompanyMapper.class);
|
||||
when(mapper.selectPage(any(Page.class), any())).thenAnswer(invocation -> invocation.getArgument(0));
|
||||
|
||||
new ExpressCompanyRepository(mapper).page(10001L,
|
||||
new ExpressCompanyPageQuery(1, 20, "顺丰", "ACTIVE"));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ArgumentCaptor<LambdaQueryWrapper<ExpressCompanyEntity>> wrapper =
|
||||
ArgumentCaptor.forClass(LambdaQueryWrapper.class);
|
||||
verify(mapper).selectPage(any(Page.class), wrapper.capture());
|
||||
wrapper.getValue().getSqlSegment();
|
||||
assertThat(wrapper.getValue().getParamNameValuePairs().values())
|
||||
.contains(10001L, "ACTIVE", "%顺丰%");
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package com.baiyue.warehouse.repository;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class WarehouseSchemaContractTest {
|
||||
@Test
|
||||
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");
|
||||
assertColumns(sql, "wh_warehouse_address", "warehouse_id", "address_type", "country_code", "state_province",
|
||||
"city", "district", "postal_code", "address_line1", "address_line2", "latitude", "longitude");
|
||||
assertColumns(sql, "wh_service_capability", "warehouse_id", "capability_code", "capability_name", "enabled",
|
||||
"cutoff_time", "description");
|
||||
assertBaseColumns(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
void 往来单位表包含实体全部持久化字段() throws IOException {
|
||||
String sql = read("warehouse-partner.sql");
|
||||
assertColumns(sql, "wh_partner", "partner_code", "partner_name", "partner_type", "contact_name",
|
||||
"contact_phone", "contact_email", "country_code", "province", "city", "district", "address_line",
|
||||
"postal_code", "status");
|
||||
assertBaseColumns(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
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");
|
||||
assertBaseColumns(sql);
|
||||
}
|
||||
|
||||
private static String read(String file) throws IOException {
|
||||
return Files.readString(Path.of("src/main/resources/db", file));
|
||||
}
|
||||
|
||||
private static void assertColumns(String sql, String table, String... columns) {
|
||||
assertThat(sql).contains("CREATE TABLE IF NOT EXISTS " + table);
|
||||
for (String column : columns) {
|
||||
assertThat(sql).contains(column + " ");
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertBaseColumns(String sql) {
|
||||
assertColumns(sql, tableName(sql), "tenant_id", "created_by", "created_at", "updated_by", "updated_at",
|
||||
"deleted", "version");
|
||||
}
|
||||
|
||||
private static String tableName(String sql) {
|
||||
int start = sql.indexOf("CREATE TABLE IF NOT EXISTS ") + "CREATE TABLE IF NOT EXISTS ".length();
|
||||
int end = sql.indexOf(' ', start);
|
||||
return sql.substring(start, end);
|
||||
}
|
||||
}
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
package com.baiyue.warehouse.service;
|
||||
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.warehouse.dto.MasterDataQueries.ExpressCompanySaveRequest;
|
||||
import com.baiyue.warehouse.dto.MasterDataQueries.PartnerSaveRequest;
|
||||
import com.baiyue.warehouse.entity.ExpressCompanyEntity;
|
||||
import com.baiyue.warehouse.entity.PartnerEntity;
|
||||
import com.baiyue.warehouse.repository.ExpressCompanyRepository;
|
||||
import com.baiyue.warehouse.repository.PartnerRepository;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class PlatformMasterDataManagementServiceTest {
|
||||
@Test
|
||||
void 往来单位详情强制租户隔离() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
PlatformPartnerQueryService service = new PlatformPartnerQueryService(repository);
|
||||
|
||||
assertThatThrownBy(() -> service.detail(10002L, 1L)).isInstanceOf(BizException.class);
|
||||
verify(repository).findOwned(10002L, 1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void 往来单位编码在租户内必须唯一() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
when(repository.existsCode(10001L, "CUS-001", null)).thenReturn(true);
|
||||
PlatformPartnerQueryService service = new PlatformPartnerQueryService(repository);
|
||||
|
||||
assertThatThrownBy(() -> service.create(10001L, partnerRequest()))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("编码");
|
||||
verify(repository, never()).insert(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void 往来单位并发重复编码统一返回业务冲突() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
doThrow(new DataIntegrityViolationException("duplicate")).when(repository).insert(any());
|
||||
PlatformPartnerQueryService service = new PlatformPartnerQueryService(repository);
|
||||
|
||||
assertThatThrownBy(() -> service.create(10001L, partnerRequest()))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("编码");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 往来单位新增写入租户和请求字段() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
doAnswer(invocation -> {
|
||||
PartnerEntity entity = invocation.getArgument(0);
|
||||
entity.setId(18L);
|
||||
return null;
|
||||
}).when(repository).insert(any());
|
||||
PlatformPartnerQueryService service = new PlatformPartnerQueryService(repository);
|
||||
|
||||
assertThat(service.create(10001L, partnerRequest())).isEqualTo(18L);
|
||||
|
||||
org.mockito.ArgumentCaptor<PartnerEntity> entity = org.mockito.ArgumentCaptor.forClass(PartnerEntity.class);
|
||||
verify(repository).insert(entity.capture());
|
||||
assertThat(entity.getValue().getTenantId()).isEqualTo(10001L);
|
||||
assertThat(entity.getValue().getPartnerCode()).isEqualTo("CUS-001");
|
||||
assertThat(entity.getValue().getPartnerName()).isEqualTo("示例客户");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 往来单位编辑保留归属并更新字段() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
PartnerEntity entity = new PartnerEntity();
|
||||
entity.setId(19L);
|
||||
entity.setTenantId(10001L);
|
||||
when(repository.findOwned(10001L, 19L)).thenReturn(entity);
|
||||
PlatformPartnerQueryService service = new PlatformPartnerQueryService(repository);
|
||||
|
||||
service.update(10001L, 19L, partnerRequest());
|
||||
|
||||
assertThat(entity.getTenantId()).isEqualTo(10001L);
|
||||
assertThat(entity.getPartnerName()).isEqualTo("示例客户");
|
||||
verify(repository).save(entity);
|
||||
}
|
||||
|
||||
@Test
|
||||
void 往来单位停用保留主数据() {
|
||||
PartnerRepository repository = mock(PartnerRepository.class);
|
||||
PartnerEntity entity = new PartnerEntity();
|
||||
entity.setId(8L);
|
||||
entity.setTenantId(10001L);
|
||||
entity.setStatus("ACTIVE");
|
||||
when(repository.findOwned(10001L, 8L)).thenReturn(entity);
|
||||
PlatformPartnerQueryService service = new PlatformPartnerQueryService(repository);
|
||||
|
||||
service.changeStatus(10001L, 8L, "INACTIVE");
|
||||
|
||||
assertThat(entity.getStatus()).isEqualTo("INACTIVE");
|
||||
verify(repository).save(entity);
|
||||
}
|
||||
|
||||
@Test
|
||||
void 快递公司详情强制租户隔离() {
|
||||
ExpressCompanyRepository repository = mock(ExpressCompanyRepository.class);
|
||||
ExpressCompanyQueryService service = new ExpressCompanyQueryService(repository);
|
||||
|
||||
assertThatThrownBy(() -> service.detail(10002L, 1L)).isInstanceOf(BizException.class);
|
||||
verify(repository).findOwned(10002L, 1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void 快递公司编码在租户内必须唯一() {
|
||||
ExpressCompanyRepository repository = mock(ExpressCompanyRepository.class);
|
||||
when(repository.existsCode(10001L, "SF", null)).thenReturn(true);
|
||||
ExpressCompanyQueryService service = new ExpressCompanyQueryService(repository);
|
||||
|
||||
assertThatThrownBy(() -> service.create(10001L, expressRequest()))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("编码");
|
||||
verify(repository, never()).insert(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void 快递公司并发重复编码统一返回业务冲突() {
|
||||
ExpressCompanyRepository repository = mock(ExpressCompanyRepository.class);
|
||||
doThrow(new DataIntegrityViolationException("duplicate")).when(repository).insert(any());
|
||||
ExpressCompanyQueryService service = new ExpressCompanyQueryService(repository);
|
||||
|
||||
assertThatThrownBy(() -> service.create(10001L, expressRequest()))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("编码");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 快递公司新增写入租户和请求字段() {
|
||||
ExpressCompanyRepository repository = mock(ExpressCompanyRepository.class);
|
||||
doAnswer(invocation -> {
|
||||
ExpressCompanyEntity entity = invocation.getArgument(0);
|
||||
entity.setId(28L);
|
||||
return null;
|
||||
}).when(repository).insert(any());
|
||||
ExpressCompanyQueryService service = new ExpressCompanyQueryService(repository);
|
||||
|
||||
assertThat(service.create(10001L, expressRequest())).isEqualTo(28L);
|
||||
|
||||
org.mockito.ArgumentCaptor<ExpressCompanyEntity> entity =
|
||||
org.mockito.ArgumentCaptor.forClass(ExpressCompanyEntity.class);
|
||||
verify(repository).insert(entity.capture());
|
||||
assertThat(entity.getValue().getTenantId()).isEqualTo(10001L);
|
||||
assertThat(entity.getValue().getCompanyCode()).isEqualTo("SF");
|
||||
assertThat(entity.getValue().getCompanyName()).isEqualTo("顺丰速运");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 快递公司编辑保留归属并更新字段() {
|
||||
ExpressCompanyRepository repository = mock(ExpressCompanyRepository.class);
|
||||
ExpressCompanyEntity entity = new ExpressCompanyEntity();
|
||||
entity.setId(29L);
|
||||
entity.setTenantId(10001L);
|
||||
when(repository.findOwned(10001L, 29L)).thenReturn(entity);
|
||||
ExpressCompanyQueryService service = new ExpressCompanyQueryService(repository);
|
||||
|
||||
service.update(10001L, 29L, expressRequest());
|
||||
|
||||
assertThat(entity.getTenantId()).isEqualTo(10001L);
|
||||
assertThat(entity.getCompanyName()).isEqualTo("顺丰速运");
|
||||
verify(repository).save(entity);
|
||||
}
|
||||
|
||||
@Test
|
||||
void 快递公司停用保留主数据() {
|
||||
ExpressCompanyRepository repository = mock(ExpressCompanyRepository.class);
|
||||
ExpressCompanyEntity entity = new ExpressCompanyEntity();
|
||||
entity.setId(9L);
|
||||
entity.setTenantId(10001L);
|
||||
entity.setStatus("ACTIVE");
|
||||
when(repository.findOwned(10001L, 9L)).thenReturn(entity);
|
||||
ExpressCompanyQueryService service = new ExpressCompanyQueryService(repository);
|
||||
|
||||
service.changeStatus(10001L, 9L, "INACTIVE");
|
||||
|
||||
assertThat(entity.getStatus()).isEqualTo("INACTIVE");
|
||||
verify(repository).save(entity);
|
||||
}
|
||||
|
||||
private static PartnerSaveRequest partnerRequest() {
|
||||
return new PartnerSaveRequest("CUS-001", "示例客户", "CUSTOMER", "张三", "13800138000",
|
||||
"test@example.com", "CN", "广东省", "深圳市", "南山区", "示例地址", "518000", "ACTIVE");
|
||||
}
|
||||
|
||||
private static ExpressCompanySaveRequest expressRequest() {
|
||||
return new ExpressCompanySaveRequest("SF", "顺丰速运", "95338", "https://www.sf-express.com",
|
||||
"https://example.com/{trackingNo}", "ACTIVE", null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user