This commit is contained in:
2026-08-25 15:08:34 +08:00
parent e815abcbd7
commit 44198866d9
64 changed files with 1382 additions and 360 deletions
@@ -21,6 +21,7 @@ class BaiyueFirstlegApplicationContractTest {
.contains("com.baiyue.firstleg.portschedule.mapper")
.contains("com.baiyue.firstleg.customs.mapper")
.contains("com.baiyue.firstleg.customerstatistics.adapter.out.persistence")
.contains("com.baiyue.firstleg.pricebookquery.adapter.out.persistence")
.doesNotContain("com.baiyue.firstleg.customerstatistics.mapper");
}
@@ -6,7 +6,7 @@ import com.baiyue.firstleg.domain.PriceModel;
import com.baiyue.firstleg.domain.PricingTaxMode;
import com.baiyue.firstleg.domain.PricingDestinationType;
import com.baiyue.firstleg.dto.PriceBookDtos;
import com.baiyue.firstleg.mapper.PriceBookQueryMapper;
import com.baiyue.firstleg.pricebookquery.adapter.out.persistence.PriceBookQueryMapper;
import org.apache.ibatis.annotations.Select;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -9,8 +9,8 @@ import com.baiyue.firstleg.oceanbooking.entity.OceanBookingContainerRequirementE
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingEntity;
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingOperationEntity;
import com.baiyue.firstleg.oceanbooking.repository.OceanBookingRepository;
import com.baiyue.firstleg.repository.PriceBookQueryRepository;
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
import com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase;
import com.baiyue.firstleg.service.WarehouseSupplierSnapshotService;
import com.baiyue.firstleg.service.FirstlegDocumentNumberGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -33,7 +33,7 @@ import static org.mockito.Mockito.*;
class OceanBookingServiceTest {
@Mock private OceanBookingRepository repository;
@Mock private PriceBookQueryRepository priceBooks;
@Mock private PriceBookQueryUseCase priceBooks;
@Mock private WarehouseSupplierSnapshotService suppliers;
@Mock private WarehouseMasterDataClient warehouses;
@Mock private FirstlegDocumentNumberGenerator documentNumbers;
@@ -0,0 +1,67 @@
package com.baiyue.firstleg.pricebookquery;
import com.baiyue.firstleg.pricebookquery.application.port.out.PriceBookQueryReader;
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.core.importer.ImportOption;
import org.junit.jupiter.api.Test;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.resideInAPackage;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.resideOutsideOfPackage;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
class PriceBookQueryArchitectureTest {
private static final String FIRSTLEG = "com.baiyue.firstleg..";
private static final String SLICE = "com.baiyue.firstleg.pricebookquery..";
private static final String APPLICATION = "com.baiyue.firstleg.pricebookquery.application..";
private static final String INPUT_PORT = "com.baiyue.firstleg.pricebookquery.application.port.in..";
private static final String OUTPUT_PORT = "com.baiyue.firstleg.pricebookquery.application.port.out..";
private static final String MODEL = "com.baiyue.firstleg.pricebookquery.application.model..";
private static final String PERSISTENCE = "com.baiyue.firstleg.pricebookquery.adapter.out.persistence..";
private static final JavaClasses PRODUCTION_CLASSES = new ClassFileImporter()
.withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)
.withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_JARS)
.importPackages("com.baiyue.firstleg");
@Test
void applicationStaysFreeOfWebAndPersistenceFrameworks() {
noClasses().that().resideInAPackage(APPLICATION)
.should().dependOnClassesThat().resideInAnyPackage(
"org.springframework.web..",
"org.apache.ibatis..",
"com.baomidou.mybatisplus..")
.check(PRODUCTION_CLASSES);
}
@Test
void applicationOnlyDependsOnItsOwnSliceWithinFirstleg() {
classes().that().resideInAPackage(APPLICATION)
.should().onlyDependOnClassesThat(
resideOutsideOfPackage(FIRSTLEG).or(resideInAPackage(APPLICATION)))
.check(PRODUCTION_CLASSES);
}
@Test
void persistenceAdapterCollaboratesThroughTheOutputPortAndModel() {
classes().that().resideInAPackage(PERSISTENCE)
.should().onlyDependOnClassesThat(
resideOutsideOfPackage(SLICE)
.or(resideInAPackage(PERSISTENCE))
.or(resideInAPackage(OUTPUT_PORT))
.or(resideInAPackage(MODEL)))
.andShould().beAssignableTo(PriceBookQueryReader.class)
.check(PRODUCTION_CLASSES);
}
@Test
void consumersOnlySeeTheInputPortAndReadModel() {
noClasses().that().resideOutsideOfPackage(SLICE)
.should().dependOnClassesThat(
resideInAPackage(SLICE)
.and(resideOutsideOfPackage(INPUT_PORT))
.and(resideOutsideOfPackage(MODEL)))
.check(PRODUCTION_CLASSES);
}
}
@@ -0,0 +1,46 @@
package com.baiyue.firstleg.pricebookquery;
import com.baiyue.firstleg.pricebookquery.application.PriceBookQueryService;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelPrefixRow;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
import com.baiyue.firstleg.pricebookquery.application.port.out.PriceBookQueryReader;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class PriceBookQueryServiceTest {
@Mock private PriceBookQueryReader reader;
@InjectMocks private PriceBookQueryService service;
@Test
void delegatesStableReadOperationsToTheOutputPort() {
ChannelPrefixRow prefix = new ChannelPrefixRow("SEA", "IN", "OUT");
when(reader.findActiveVersionId()).thenReturn(9L);
when(reader.findChannelPrefix("SEA")).thenReturn(prefix);
assertThat(service.activeVersionId()).isEqualTo(9L);
assertThat(service.channelPrefix("SEA")).isSameAs(prefix);
verify(reader).findActiveVersionId();
verify(reader).findChannelPrefix("SEA");
}
@Test
void keepsChannelAvailabilityAsApplicationLogic() {
ChannelRow channel = new ChannelRow();
channel.setChannelCode("SEA");
when(reader.findChannels(9L, 3L)).thenReturn(List.of(channel));
assertThat(service.channelAvailable(9L, 3L, "SEA")).isTrue();
assertThat(service.channelAvailable(9L, 3L, "AIR")).isFalse();
verify(reader, org.mockito.Mockito.times(2)).findChannels(9L, 3L);
}
}
@@ -1,7 +1,7 @@
package com.baiyue.firstleg.pricing;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
@@ -1,7 +1,7 @@
package com.baiyue.firstleg.pricing;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
@@ -17,8 +17,8 @@ import com.baiyue.firstleg.mapper.ContainerTransportHistoryMapper;
import com.baiyue.firstleg.repository.ContainerRepository;
import com.baiyue.firstleg.repository.LoadingPickRepository;
import com.baiyue.firstleg.repository.SmartLoadingRepository;
import com.baiyue.firstleg.repository.PriceBookQueryRepository;
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
import com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase;
import com.baiyue.firstleg.oceanbooking.repository.OceanBookingRepository;
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingEntity;
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingContainerAllocationEntity;
@@ -51,7 +51,7 @@ class ContainerServiceTest {
@MockBean private SmartLoadingRepository smartLoadingRepository;
@MockBean private LoadingPickRepository loadingPickRepository;
@MockBean private LoadingPickService loadingPickService;
@MockBean private PriceBookQueryRepository priceBooks;
@MockBean private PriceBookQueryUseCase priceBooks;
@MockBean private OceanBookingRepository oceanBookings;
@MockBean private WarehouseSupplierSnapshotService suppliers;
@MockBean private FirstlegDocumentNumberGenerator documentNumbers;
@@ -4,7 +4,7 @@ import com.baiyue.firstleg.domain.CustomerDimensionBoxType;
import com.baiyue.firstleg.entity.CustomerDimensionConfigEntity;
import com.baiyue.firstleg.pricing.FbaWarehouseRateEstimator;
import com.baiyue.firstleg.repository.CustomerDimensionConfigRepository;
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
@@ -11,7 +11,7 @@ import com.baiyue.firstleg.entity.InboundPricingEntity;
import com.baiyue.firstleg.entity.InboundPricingIdempotencyEntity;
import com.baiyue.firstleg.pricing.ActivePriceBookEstimator;
import com.baiyue.firstleg.repository.FbaPricingRepository;
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -13,11 +13,11 @@ import com.baiyue.firstleg.pricing.FbaWarehouseRateEstimator;
import com.baiyue.firstleg.pricing.PriceBookWarehouseRegionResolver;
import com.baiyue.firstleg.pricing.PriceRegionResolver;
import com.baiyue.firstleg.pricing.RegionWeightTierEstimator;
import com.baiyue.firstleg.repository.PriceBookQueryRepository;
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelTaxModeRow;
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelPrefixRow;
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelTaxModeRow;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelPrefixRow;
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
import com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
@@ -38,7 +38,7 @@ import static org.mockito.Mockito.when;
PriceBookWarehouseRegionResolver.class})
@TestPropertySource(properties = "baiyue.security.internal-service-token=internal-token")
class MerchantPriceBookServiceTest {
@MockBean private PriceBookQueryRepository repository;
@MockBean private PriceBookQueryUseCase repository;
@MockBean private PriceBookWarehouseClient warehouses;
@Resource private MerchantPriceBookService service;