167 lines
9.0 KiB
Java
167 lines
9.0 KiB
Java
package com.baiyue.lastleg.merchant;
|
|
|
|
import com.baiyue.common.security.AuthenticatedUser;
|
|
import com.baiyue.lastleg.controller.MerchantLastlegOrderController;
|
|
import com.baiyue.lastleg.inboundplan.controller.MerchantInboundPlanController;
|
|
import com.baiyue.lastleg.inboundplan.dto.InboundPlanRequests;
|
|
import com.baiyue.lastleg.inboundplan.service.InboundPlanService;
|
|
import com.baiyue.lastleg.discard.controller.MerchantCargoDiscardController;
|
|
import com.baiyue.lastleg.looseboard.controller.MerchantLocalLooseboardController;
|
|
import com.baiyue.lastleg.looseboard.dto.LocalLooseboardRequests;
|
|
import com.baiyue.lastleg.looseboard.service.LocalLooseboardService;
|
|
import com.baiyue.lastleg.procurement.controller.MerchantOverseasProcurementController;
|
|
import com.baiyue.lastleg.relabel.controller.MerchantRelabelApplicationController;
|
|
import com.baiyue.lastleg.returnreceipt.controller.MerchantReturnOrderController;
|
|
import com.baiyue.lastleg.security.OverseasPermissions;
|
|
import com.baiyue.lastleg.transfer.controller.MerchantWarehouseTransferController;
|
|
import com.baiyue.lastleg.trucking.controller.MerchantUsTruckOrderController;
|
|
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.security.access.prepost.PreAuthorize;
|
|
import org.springframework.test.util.ReflectionTestUtils;
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
import org.springframework.web.server.ResponseStatusException;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
import static org.mockito.Mockito.verify;
|
|
|
|
@ExtendWith(MockitoExtension.class)
|
|
class MerchantOverseasCustomerApiContractTest {
|
|
@Mock LocalLooseboardService looseboardService;
|
|
@Mock InboundPlanService inboundPlanService;
|
|
private MerchantLocalLooseboardController looseboard;
|
|
private MerchantInboundPlanController inbound;
|
|
|
|
@BeforeEach
|
|
void setUp() {
|
|
looseboard = new MerchantLocalLooseboardController();
|
|
inbound = new MerchantInboundPlanController();
|
|
ReflectionTestUtils.setField(looseboard, "service", looseboardService);
|
|
ReflectionTestUtils.setField(inbound, "service", inboundPlanService);
|
|
}
|
|
|
|
@Test
|
|
void merchantControllersUseFrozenPathsAndOperationPermissions() {
|
|
assertPath(MerchantOverseasProcurementController.class, "/api/merchant/v1/last-leg/overseas-procurements");
|
|
assertPermissions(MerchantOverseasProcurementController.class, Map.of(
|
|
"create", OverseasPermissions.MERCHANT_PROCUREMENT_CREATE,
|
|
"page", OverseasPermissions.MERCHANT_PROCUREMENT_LIST,
|
|
"detail", OverseasPermissions.MERCHANT_PROCUREMENT_LIST));
|
|
assertPath(MerchantUsTruckOrderController.class, "/api/merchant/v1/last-leg/us-truck-orders");
|
|
assertPermissions(MerchantUsTruckOrderController.class, Map.of(
|
|
"create", OverseasPermissions.MERCHANT_TRUCKING_CREATE,
|
|
"page", OverseasPermissions.MERCHANT_TRUCKING_LIST,
|
|
"detail", OverseasPermissions.MERCHANT_TRUCKING_LIST,
|
|
"update", OverseasPermissions.MERCHANT_TRUCKING_EDIT));
|
|
assertPath(MerchantLocalLooseboardController.class, "/api/merchant/v1/last-leg/local-looseboard-orders");
|
|
assertPermissions(MerchantLocalLooseboardController.class, Map.of(
|
|
"create", OverseasPermissions.MERCHANT_LOOSEBOARD_CREATE,
|
|
"page", OverseasPermissions.MERCHANT_LOOSEBOARD_LIST,
|
|
"detail", OverseasPermissions.MERCHANT_LOOSEBOARD_LIST,
|
|
"update", OverseasPermissions.MERCHANT_LOOSEBOARD_EDIT));
|
|
assertController(MerchantInboundPlanController.class,
|
|
"/api/merchant/v1/last-leg/inbound-plans", OverseasPermissions.MERCHANT_INBOUND_LIST);
|
|
assertController(MerchantLastlegOrderController.class,
|
|
"/api/merchant/v1/last-leg/orders", OverseasPermissions.MERCHANT_LAST_MILE_ORDER_LIST);
|
|
|
|
assertPermissions(MerchantWarehouseTransferController.class, Map.of(
|
|
"create", OverseasPermissions.MERCHANT_TRANSFER_CREATE,
|
|
"page", OverseasPermissions.MERCHANT_TRANSFER_LIST,
|
|
"detail", OverseasPermissions.MERCHANT_TRANSFER_LIST,
|
|
"confirmMeasurement", OverseasPermissions.MERCHANT_TRANSFER_CONFIRM));
|
|
assertPermissions(MerchantCargoDiscardController.class, Map.of(
|
|
"candidates", OverseasPermissions.MERCHANT_DISCARD_LIST,
|
|
"create", OverseasPermissions.MERCHANT_DISCARD_CREATE,
|
|
"page", OverseasPermissions.MERCHANT_DISCARD_LIST,
|
|
"detail", OverseasPermissions.MERCHANT_DISCARD_LIST,
|
|
"cancel", OverseasPermissions.MERCHANT_DISCARD_CANCEL));
|
|
assertPermissions(MerchantReturnOrderController.class, Map.of(
|
|
"create", OverseasPermissions.MERCHANT_RETURN_ORDER_CREATE,
|
|
"page", OverseasPermissions.MERCHANT_RETURN_ORDER_LIST,
|
|
"detail", OverseasPermissions.MERCHANT_RETURN_ORDER_LIST,
|
|
"downloadPhoto", OverseasPermissions.MERCHANT_RETURN_ORDER_LIST,
|
|
"relabelCandidates", OverseasPermissions.MERCHANT_RETURN_ORDER_RELABEL,
|
|
"createRelabel", OverseasPermissions.MERCHANT_RETURN_ORDER_RELABEL));
|
|
assertPermissions(MerchantRelabelApplicationController.class, Map.of(
|
|
"candidates", OverseasPermissions.MERCHANT_RELABEL_LIST,
|
|
"historicalOrders", OverseasPermissions.MERCHANT_RELABEL_LIST,
|
|
"create", OverseasPermissions.MERCHANT_RELABEL_CREATE,
|
|
"page", OverseasPermissions.MERCHANT_RELABEL_LIST,
|
|
"detail", OverseasPermissions.MERCHANT_RELABEL_LIST,
|
|
"uploadShippingLabel", OverseasPermissions.MERCHANT_RELABEL_FILES,
|
|
"uploadFile", OverseasPermissions.MERCHANT_RELABEL_FILES,
|
|
"downloadShippingLabel", OverseasPermissions.MERCHANT_RELABEL_LIST,
|
|
"downloadCompletionPhoto", OverseasPermissions.MERCHANT_RELABEL_LIST,
|
|
"confirmCompletion", OverseasPermissions.MERCHANT_RELABEL_CONFIRM));
|
|
}
|
|
|
|
@Test
|
|
void looseboardAndInboundQueriesUseAuthenticatedCustomerScope() {
|
|
AuthenticatedUser merchant = user(101L, "MERCHANT");
|
|
LocalLooseboardRequests.MerchantQuery looseboardQuery = new LocalLooseboardRequests.MerchantQuery(1, 20,
|
|
null, null, null, null, null);
|
|
InboundPlanRequests.Query inboundQuery = new InboundPlanRequests.Query(1, 20, null, null, null, null,
|
|
null, null, null, null, null, null, null, null);
|
|
|
|
looseboard.page(merchant, looseboardQuery);
|
|
inbound.page(merchant, inboundQuery);
|
|
|
|
verify(looseboardService).page("101", looseboardQuery);
|
|
verify(inboundPlanService).page("101", inboundQuery);
|
|
}
|
|
|
|
@Test
|
|
void merchantQueryDtosDoNotAcceptCustomerScope() {
|
|
for (Class<?> type : Set.of(LocalLooseboardRequests.MerchantQuery.class,
|
|
com.baiyue.lastleg.procurement.dto.OverseasProcurementRequests.MerchantQuery.class,
|
|
com.baiyue.lastleg.trucking.dto.UsTruckOrderRequests.MerchantQuery.class,
|
|
InboundPlanRequests.Query.class)) {
|
|
assertThat(Arrays.stream(type.getRecordComponents()).map(component -> component.getName()))
|
|
.doesNotContain("customerId", "warehouseId", "operatorId");
|
|
}
|
|
}
|
|
|
|
@Test
|
|
void merchantEndpointsRejectPlatformIdentityBeforeCallingServices() {
|
|
AuthenticatedUser platform = user(0L, "PLATFORM");
|
|
assertThatThrownBy(() -> looseboard.detail(platform, "LB-1"))
|
|
.isInstanceOf(ResponseStatusException.class).hasMessageContaining("403");
|
|
assertThatThrownBy(() -> inbound.detail(platform, "IP-1"))
|
|
.isInstanceOf(ResponseStatusException.class).hasMessageContaining("403");
|
|
}
|
|
|
|
private static void assertController(Class<?> type, String path, String permission) {
|
|
assertPath(type, path);
|
|
assertThat(type.getAnnotation(PreAuthorize.class).value())
|
|
.isEqualTo("hasAuthority('" + permission + "')");
|
|
}
|
|
|
|
private static void assertPath(Class<?> type, String path) {
|
|
assertThat(type.getAnnotation(RequestMapping.class).value()).containsExactly(path);
|
|
}
|
|
|
|
private static void assertPermissions(Class<?> type, Map<String, String> permissions) {
|
|
for (var entry : permissions.entrySet()) {
|
|
var method = Arrays.stream(type.getDeclaredMethods())
|
|
.filter(candidate -> candidate.getName().equals(entry.getKey()))
|
|
.findFirst().orElseThrow();
|
|
assertThat(method.getAnnotation(PreAuthorize.class))
|
|
.as(type.getSimpleName() + "." + entry.getKey()).isNotNull();
|
|
assertThat(method.getAnnotation(PreAuthorize.class).value())
|
|
.isEqualTo("hasAuthority('" + entry.getValue() + "')");
|
|
}
|
|
}
|
|
|
|
private static AuthenticatedUser user(long customerId, String appCode) {
|
|
return new AuthenticatedUser(7L, customerId, customerId, 8L, "operator", appCode, "WEB", Set.of());
|
|
}
|
|
}
|