Files
mgm-daylight-mcrm-api-mobile/src/test/java/com/mgm/mcrm/PublicEndpointsMigrationTest.java
T
2026-09-15 17:04:06 +08:00

130 lines
7.8 KiB
Java

package com.mgm.mcrm;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.mgm.mcrm.appsetting.controllers.CfgSettingController;
import com.mgm.mcrm.appsetting.dtos.CfgSettingQueryRequest;
import com.mgm.mcrm.appsetting.models.CfgSettings;
import com.mgm.mcrm.appsetting.models.SysSetting;
import com.mgm.mcrm.appsetting.services.SettingService;
import com.mgm.mcrm.appsetting.services.SysSettingService;
import com.mgm.mcrm.authorization.services.UserTokenService;
import com.mgm.mcrm.common.config.WebFilterConfig;
import com.mgm.mcrm.logging.controllers.SysLogAppController;
import com.mgm.mcrm.logging.dtos.AppLogDto;
import com.mgm.mcrm.logging.models.SysLogApp;
import com.mgm.mcrm.logging.services.SysLogAppService;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
class PublicEndpointsMigrationTest {
@Test void publicConfigurationRejectsOtherKeysBeforeQuery() throws Exception {
var service = mock(SettingService.class);
var controller = new CfgSettingController();
ReflectionTestUtils.setField(controller, "settingService", service);
for (String key : new String[]{null, "", "MACAU_IP", "macau_string", "MACAU_STRING "}) {
var query = new CfgSettingQueryRequest(); query.setKeyName(key);
var result = controller.getPublicSettingByKey(new MockHttpServletRequest(), query).getBody();
assertFalse(result.isSuccess()); assertEquals("SETTING_KEY_NOT_ALLOWED", result.getCode());
}
assertFalse(controller.getPublicSettingByKey(new MockHttpServletRequest(), null).getBody().isSuccess());
verifyNoInteractions(service);
var setting = new CfgSettings();
when(service.getSettingByKey("MACAU_STRING")).thenReturn(setting);
var query = new CfgSettingQueryRequest(); query.setKeyName("MACAU_STRING");
assertSame(setting, controller.getPublicSettingByKey(new MockHttpServletRequest(), query).getBody().getData());
verify(service).getSettingByKey("MACAU_STRING");
}
@Test void publicLoginSettingsOnlyFetchTwoAllowedKeysAndAllowMissingSettings() {
var service = mock(SysSettingService.class);
var controller = new CfgSettingController();
ReflectionTestUtils.setField(controller, "sysSettingService", service);
var sso = new SysSetting(); var tpd = new SysSetting();
when(service.getSysSettingByKey("APP_MOCK_SSO")).thenReturn(sso);
when(service.getSysSettingByKey("APP_MOCK_TPD")).thenReturn(tpd);
assertEquals(java.util.List.of(sso, tpd), controller.getPublicLoginSettings(new MockHttpServletRequest()).getBody().getData());
verify(service).getSysSettingByKey("APP_MOCK_SSO");
verify(service).getSysSettingByKey("APP_MOCK_TPD");
verifyNoMoreInteractions(service);
when(service.getSysSettingByKey("APP_MOCK_TPD")).thenReturn(null);
assertEquals(1, controller.getPublicLoginSettings(new MockHttpServletRequest()).getBody().getData().size());
}
@Test void filterAllowsOnlyNewPublicRoutesAndKeepsRefreshProtected() throws Exception {
var config = new WebFilterConfig();
var tokens = mock(UserTokenService.class);
ReflectionTestUtils.setField(config, "secretKey", "test-only-key");
ReflectionTestUtils.setField(config, "userTokenService", tokens);
var filter = config.jwtAuthFilter().getFilter();
for (String route : new String[]{"/system/write_public_log", "/system/sys_setting/get_public_login_settings", "/web/setting/get_public_setting_by_key"}) {
var reached = new AtomicBoolean();
filter.doFilter(new MockHttpServletRequest("POST", "/api" + route), new MockHttpServletResponse(),
(req, res) -> reached.set(true));
assertTrue(reached.get(), route);
}
for (String route : new String[]{"/system/write_log", "/system/sys_setting/get_list", "/web/setting/get_setting_by_key", "/app/booking/mock_cancel", "/app/refresh_token"}) {
var reached = new AtomicBoolean(); var response = new MockHttpServletResponse();
filter.doFilter(new MockHttpServletRequest("POST", "/api" + route), response, (req, res) -> reached.set(true));
assertFalse(reached.get(), route); assertEquals(401, response.getStatus(), route);
}
}
private SysLogAppController logs(SysLogAppService service) {
var controller = new SysLogAppController();
ReflectionTestUtils.setField(controller, "logService", service);
when(service.save(any(SysLogApp.class))).thenAnswer(call -> call.getArgument(0));
return controller;
}
@Test void anonymousIdentityCannotBeSpoofedAndNullBodiesAreSafe() {
var service = mock(SysLogAppService.class); var controller = logs(service);
var dto = new AppLogDto(); dto.setLoginId("admin");
var result = controller.writePublicAppLog(new MockHttpServletRequest(), dto).getBody().getData();
assertEquals("ANONYMOUS", result.getLoginId()); assertNull(result.getLogDesc());
assertNull(result.getRequestBody()); assertNull(result.getResponseBody()); assertEquals(0, result.getTagSuccess());
assertEquals(400, controller.writePublicAppLog(new MockHttpServletRequest(), null).getStatusCode().value());
verify(service, times(1)).save(any(SysLogApp.class));
}
@Test void authenticatedLogUsesTokenIdentityAndRequiresIdentity() {
var service = mock(SysLogAppService.class); var controller = logs(service);
var dto = new AppLogDto(); dto.setLoginId("forged-user");
var request = new MockHttpServletRequest();
assertEquals(401, controller.writeAppLog(request, dto).getStatusCode().value());
verify(service, never()).save(any());
// Controller identity test; JWT admission is covered separately by the filter test.
request.addHeader("Authorization", "Bearer " + JWT.create().withSubject("80001")
.withClaim("login_id", "actual-user").sign(Algorithm.HMAC256("test-only-key")));
assertEquals("actual-user", controller.writeAppLog(request, dto).getBody().getData().getLoginId());
}
@Test void logsLimitInputAndEscapeText() {
var controller = logs(mock(SysLogAppService.class));
var dto = new AppLogDto(); dto.setEventCode("e".repeat(101)); dto.setTransId("t".repeat(101));
dto.setLogDesc("x".repeat(999) + "<ignored"); dto.setRequestBody("r".repeat(4001)); dto.setResponseBody("<script>&");
var log = controller.writePublicAppLog(new MockHttpServletRequest(), dto).getBody().getData();
assertEquals(100, log.getEventCode().length()); assertEquals(100, log.getTransId().length());
assertEquals("x".repeat(999) + "&lt;", log.getLogDesc());
assertEquals(4000, log.getRequestBody().length()); assertEquals("&lt;script&gt;&amp;", log.getResponseBody());
}
@Test void httpRejectsMissingAndMalformedLogBodiesWithoutSaving() throws Exception {
var service = mock(SysLogAppService.class); var mvc = MockMvcBuilders.standaloneSetup(logs(service)).build();
mvc.perform(post("/api/system/write_public_log")).andExpect(status().isBadRequest());
mvc.perform(post("/api/system/write_public_log").contentType("application/json")
.content("{\"tagSuccess\":\"not-a-number\"}")).andExpect(status().isBadRequest());
verify(service, never()).save(any());
}
}