diff --git a/sdm/src/main/java/com/sap/cds/sdm/service/SDMServiceImpl.java b/sdm/src/main/java/com/sap/cds/sdm/service/SDMServiceImpl.java index faa3ca9b..15699f18 100644 --- a/sdm/src/main/java/com/sap/cds/sdm/service/SDMServiceImpl.java +++ b/sdm/src/main/java/com/sap/cds/sdm/service/SDMServiceImpl.java @@ -354,7 +354,7 @@ public JSONObject getObject(String objectId, SDMCredentials sdmCredentials, bool try (var response = (CloseableHttpResponse) httpClient.execute(getObjectRequest)) { if (response.getStatusLine().getStatusCode() != 200) { if (response.getStatusLine().getStatusCode() == 403) { - throw new ServiceException(SDMConstants.USER_NOT_AUTHORISED_ERROR); + throw new ServiceException(SDMUtils.getErrorMessage("USER_NOT_AUTHORISED_ERROR")); } return null; } diff --git a/sdm/src/test/java/unit/com/sap/cds/sdm/handler/applicationservice/SDMReadAttachmentsHandlerTest.java b/sdm/src/test/java/unit/com/sap/cds/sdm/handler/applicationservice/SDMReadAttachmentsHandlerTest.java index cf16d73d..a4f1ed45 100644 --- a/sdm/src/test/java/unit/com/sap/cds/sdm/handler/applicationservice/SDMReadAttachmentsHandlerTest.java +++ b/sdm/src/test/java/unit/com/sap/cds/sdm/handler/applicationservice/SDMReadAttachmentsHandlerTest.java @@ -1,11 +1,15 @@ package unit.com.sap.cds.sdm.handler.applicationservice; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import com.sap.cds.ql.Select; import com.sap.cds.ql.cqn.CqnSelect; import com.sap.cds.reflect.*; +import com.sap.cds.sdm.caching.CacheConfig; +import com.sap.cds.sdm.caching.ErrorMessageKey; import com.sap.cds.sdm.constants.SDMConstants; +import com.sap.cds.sdm.constants.SDMErrorMessages; import com.sap.cds.sdm.handler.TokenHandler; import com.sap.cds.sdm.handler.applicationservice.SDMReadAttachmentsHandler; import com.sap.cds.sdm.model.RepoValue; @@ -14,9 +18,13 @@ import com.sap.cds.sdm.utilities.SDMUtils; import com.sap.cds.services.cds.CdsReadEventContext; import com.sap.cds.services.persistence.PersistenceService; +import com.sap.cds.services.request.ParameterInfo; import com.sap.cds.services.request.UserInfo; +import com.sap.cds.services.runtime.CdsRuntime; import java.io.IOException; +import java.lang.reflect.Method; import java.util.*; +import org.ehcache.Cache; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -291,4 +299,45 @@ void testProcessBefore_SingleEntityRead_NoDelete() throws IOException { verify(context).setCqn(any(CqnSelect.class)); } } + + @Test + void testSetErrorMessagesInCache_StoresLocalizedString() throws Exception { + CdsRuntime cdsRuntime = Mockito.mock(CdsRuntime.class); + ParameterInfo paramInfo = Mockito.mock(ParameterInfo.class); + when(context.getCdsRuntime()).thenReturn(cdsRuntime); + when(context.getParameterInfo()).thenReturn(paramInfo); + when(paramInfo.getLocale()).thenReturn(Locale.GERMAN); + + // Return a German translation only for the userNotAuthorisedError key; + // all other keys return themselves (no translation found), triggering the English fallback. + String germanTranslation = + "Sie verfügen nicht über die erforderlichen Berechtigungen" + + " zum Hochladen von Anhängen. Bitte wenden Sie sich an Ihren Administrator."; + when(cdsRuntime.getLocalizedMessage( + eq("SDM.userNotAuthorisedError"), isNull(), eq(Locale.GERMAN))) + .thenReturn(germanTranslation); + when(cdsRuntime.getLocalizedMessage( + argThat(k -> k != null && !k.equals("SDM.userNotAuthorisedError")), isNull(), any())) + .thenAnswer(inv -> inv.getArgument(0)); + + CacheConfig.initializeCache(); + + // Clear any previously cached flag so the method actually runs + Cache errorMessageCache = CacheConfig.getErrorMessageCache(); + errorMessageCache.remove(new ErrorMessageKey("localizedErrorMessagesSetInCache")); + + // Invoke the private method via reflection + Method method = + SDMReadAttachmentsHandler.class.getDeclaredMethod( + "setErrorMessagesInCache", CdsReadEventContext.class); + method.setAccessible(true); + method.invoke(sdmReadAttachmentsHandler, context); + + // The cache should now hold the German translation, not the English constant + String cached = SDMUtils.getErrorMessage("USER_NOT_AUTHORISED_ERROR"); + assertEquals(germanTranslation, cached); + + // Verify the English fallback is NOT stored for this key + assertNotEquals(SDMErrorMessages.USER_NOT_AUTHORISED_ERROR, cached); + } } diff --git a/sdm/src/test/java/unit/com/sap/cds/sdm/service/SDMServiceImplTest.java b/sdm/src/test/java/unit/com/sap/cds/sdm/service/SDMServiceImplTest.java index ac569791..c3e68739 100644 --- a/sdm/src/test/java/unit/com/sap/cds/sdm/service/SDMServiceImplTest.java +++ b/sdm/src/test/java/unit/com/sap/cds/sdm/service/SDMServiceImplTest.java @@ -1512,6 +1512,26 @@ public void testGetObject_Failure() throws IOException { assertNull(objectInfo); } + @Test + public void testGetObject_403_ThrowsServiceExceptionViaUtils() throws IOException { + String objectId = "objectId403"; + SDMServiceImpl sdmServiceImpl = new SDMServiceImpl(binding, connectionPool, tokenHandler); + SDMCredentials sdmCredentials = new SDMCredentials(); + sdmCredentials.setUrl("http://example.com/"); + + when(tokenHandler.getHttpClient(any(), any(), any(), any())).thenReturn(httpClient); + when(httpClient.execute(any(HttpGet.class))).thenReturn(response); + when(response.getStatusLine()).thenReturn(statusLine); + when(statusLine.getStatusCode()).thenReturn(403); + + ServiceException exception = + assertThrows( + ServiceException.class, + () -> sdmServiceImpl.getObject(objectId, sdmCredentials, false)); + + assertEquals(SDMUtils.getErrorMessage("USER_NOT_AUTHORISED_ERROR"), exception.getMessage()); + } + @Test public void testGetObjectThrowsServiceExceptionOnIOException() throws IOException { SDMCredentials mockSdmCredentials = mock(SDMCredentials.class);