优化
This commit is contained in:
@@ -24,6 +24,10 @@ class FinanceContractTest {
|
||||
assertTrue(service.contains("status='PROCESSING'") && service.contains("stableNo"));
|
||||
assertTrue(service.contains("request_hash") && service.contains("result_resource_id") && service.contains("Idempotency-Key已用于其他请求"));
|
||||
assertTrue(service.contains("status IN ('ISSUED','PARTIALLY_PAID','PAID')"));
|
||||
String controller = Files.readString(Path.of("src/main/java/com/baiyue/finance/controller/PlatformFinanceController.java"));
|
||||
assertTrue(controller.contains("/vouchers") && controller.contains("MultipartFile"));
|
||||
assertTrue(controller.contains("costSnapshotClient.container") && controller.contains("createCost(request.customerId(), user.userId(), internal, volumes, key)"));
|
||||
assertTrue(service.contains("validateVoucherFiles(tenantId, request.voucherFileIds())"));
|
||||
String unified = Files.readString(Path.of("../deploy/sql/头程数据库统一增量-MySQL8.sql"));
|
||||
assertTrue(unified.contains("CREATE DATABASE IF NOT EXISTS baiyue_finance"));
|
||||
assertTrue(unified.contains("assert_finance_permissions"));
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.baiyue.finance;
|
||||
|
||||
import com.baiyue.finance.service.FinanceService;
|
||||
import com.baiyue.finance.client.FinanceFileClient;
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -14,6 +16,7 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
class FinanceServiceValidationTest {
|
||||
@Test
|
||||
@@ -28,7 +31,12 @@ class FinanceServiceValidationTest {
|
||||
assertEquals(new BigDecimal("50.000000"), allocations.get(2).amount());
|
||||
assertEquals(new BigDecimal("100.000000"), allocations.stream().map(FinanceService.CostAllocation::amount)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
assertEquals(true, allocations.get(2).roundingAdjustment());
|
||||
assertEquals(false, allocations.get(2).roundingAdjustment());
|
||||
var tail = FinanceService.allocateContainerCost(new BigDecimal("100.00"), List.of(
|
||||
new FinanceService.ContainerOrderVolume(21L, 201L, 7L, 9L, BigDecimal.ONE),
|
||||
new FinanceService.ContainerOrderVolume(22L, 202L, 7L, 9L, BigDecimal.ONE),
|
||||
new FinanceService.ContainerOrderVolume(23L, 203L, 7L, 9L, BigDecimal.ONE)));
|
||||
assertEquals(true, tail.get(2).roundingAdjustment());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -62,4 +70,49 @@ class FinanceServiceValidationTest {
|
||||
List.of(new FinanceService.ReceiptAllocation(10L, BigDecimal.ONE), new FinanceService.ReceiptAllocation(10L, BigDecimal.ONE)));
|
||||
assertThrows(RuntimeException.class, () -> service.createReceipt(1L, 2L, request, "k3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsVoucherFromAnotherCustomer() {
|
||||
JdbcTemplate jdbc = mock(JdbcTemplate.class);
|
||||
FinanceFileClient files = mock(FinanceFileClient.class);
|
||||
when(files.metadata(anyString(), eq(9L), eq(9L), eq(77L))).thenReturn(ApiResponse.success(
|
||||
new FinanceFileClient.Metadata(77L, 10L, "FINANCE_VOUCHER", "9", "v.jpg", "sha", "image/jpeg", 10L)));
|
||||
FinanceService service = new FinanceService(jdbc, new ObjectMapper());
|
||||
ReflectionTestUtils.setField(service, "fileClient", files);
|
||||
var request = new FinanceService.ReceiptRequest("R-3", 1L, null, "BANK_TRANSFER", null, List.of("77"), null,
|
||||
List.of(new FinanceService.ReceiptAllocation(10L, BigDecimal.ONE)));
|
||||
assertThrows(RuntimeException.class, () -> service.createReceipt(9L, 2L, request, "k4"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsSingleOrderWhenOrderNotOwnedByCustomer() {
|
||||
JdbcTemplate jdbc = mock(JdbcTemplate.class);
|
||||
when(jdbc.queryForObject(startsWith("SELECT COUNT(*) FROM fin_fee_source"), eq(Number.class), any(), any())).thenReturn(0);
|
||||
FinanceService service = new FinanceService(jdbc, new ObjectMapper());
|
||||
var request = new FinanceService.CostRequest("C-2", "SINGLE_ORDER", 99L, null, null, null, null, "MANUAL", "货拉拉", BigDecimal.ONE, List.of("1"), null);
|
||||
assertThrows(RuntimeException.class, () -> service.createCost(9L, 2L, request, "k5"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsBillRevisionHistoryOnlyForOwningCustomer() {
|
||||
JdbcTemplate jdbc = mock(JdbcTemplate.class);
|
||||
when(jdbc.queryForObject(startsWith("SELECT COUNT(*) FROM fin_bill"), eq(Number.class), eq(50L), eq(9L)))
|
||||
.thenReturn(1);
|
||||
var rows = List.<java.util.Map<String, Object>>of(java.util.Map.of("version", 2));
|
||||
when(jdbc.queryForList(startsWith("SELECT id,bill_id,version"), eq(9L), eq(50L))).thenReturn(rows);
|
||||
FinanceService service = new FinanceService(jdbc, new ObjectMapper());
|
||||
|
||||
assertEquals(rows, service.billRevisions(9L, 50L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsBillRevisionHistoryFromAnotherCustomer() {
|
||||
JdbcTemplate jdbc = mock(JdbcTemplate.class);
|
||||
when(jdbc.queryForObject(startsWith("SELECT COUNT(*) FROM fin_bill"), eq(Number.class), eq(50L), eq(9L)))
|
||||
.thenReturn(0);
|
||||
FinanceService service = new FinanceService(jdbc, new ObjectMapper());
|
||||
|
||||
assertThrows(RuntimeException.class, () -> service.billRevisions(9L, 50L));
|
||||
verify(jdbc, never()).queryForList(startsWith("SELECT id,bill_id,version"), (Object[]) any());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.baiyue.finance;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.finance.client.FinanceFileClient;
|
||||
import com.baiyue.finance.client.FirstlegCostSnapshotClient;
|
||||
import com.baiyue.finance.controller.PlatformFinanceController;
|
||||
import com.baiyue.finance.service.FinanceService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class PlatformFinanceControllerBehaviorTest {
|
||||
@Mock FinanceService service;
|
||||
@Mock FinanceFileClient fileClient;
|
||||
@Mock FirstlegCostSnapshotClient snapshotClient;
|
||||
private PlatformFinanceController controller;
|
||||
private final AuthenticatedUser user = new AuthenticatedUser(
|
||||
7L, null, null, null, "finance", "ADMIN", "WEB", Set.of());
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
controller = new PlatformFinanceController(service, fileClient, snapshotClient);
|
||||
ReflectionTestUtils.setField(controller, "fileToken", "internal-token");
|
||||
}
|
||||
|
||||
@Test
|
||||
void containerCostUsesFirstlegSnapshotInsteadOfBrowserData() {
|
||||
var request = new PlatformFinanceController.CostRequest(
|
||||
10L, "CONTAINER_SHARED", null, 88L, "清关费", new BigDecimal("300.00"),
|
||||
"CNY", List.of("91"), "整柜成本");
|
||||
var snapshot = new FirstlegCostSnapshotClient.ContainerSnapshot(88L, 10L, List.of(
|
||||
new FirstlegCostSnapshotClient.OrderVolume(101L, 1001L, new BigDecimal("1.25")),
|
||||
new FirstlegCostSnapshotClient.OrderVolume(102L, 1002L, new BigDecimal("2.75"))));
|
||||
when(snapshotClient.container("internal-token", 10L, 88L)).thenReturn(ApiResponse.success(snapshot));
|
||||
when(service.createCost(eq(10L), eq(7L), any(), any(), eq("cost-key"))).thenReturn(Map.of("id", 1L));
|
||||
|
||||
controller.cost(user, "cost-key", request);
|
||||
|
||||
verify(snapshotClient).container("internal-token", 10L, 88L);
|
||||
verify(service).createCost(eq(10L), eq(7L), any(), eq(List.of(
|
||||
new FinanceService.ContainerOrderVolume(101L, 1001L, 88L, 10L, new BigDecimal("1.25")),
|
||||
new FinanceService.ContainerOrderVolume(102L, 1002L, 88L, 10L, new BigDecimal("2.75")))), eq("cost-key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void containerCostRejectsEmptyFirstlegSnapshot() {
|
||||
var request = new PlatformFinanceController.CostRequest(
|
||||
10L, "CONTAINER_SHARED", null, 88L, "拖车费", BigDecimal.TEN,
|
||||
"CNY", List.of("91"), null);
|
||||
when(snapshotClient.container("internal-token", 10L, 88L)).thenReturn(ApiResponse.success(
|
||||
new FirstlegCostSnapshotClient.ContainerSnapshot(88L, 10L, List.of())));
|
||||
|
||||
assertThatThrownBy(() -> controller.cost(user, "cost-key", request))
|
||||
.hasMessageContaining("未返回有效柜内订单体积快照");
|
||||
verify(service, never()).createCost(any(Long.class), any(Long.class), any(), any(), any());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user