From 8674dd615e5cad72194c18621100970e47d86d1f Mon Sep 17 00:00:00 2001 From: AK <116068970+aktaskaan@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:51:16 +0100 Subject: [PATCH] change CaseConcurrencyException message and add unit test (#2446) --- .../DefaultCaseDetailsRepository.java | 5 ++- .../DefaultCaseDetailsRepositoryTest.java | 43 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/main/java/uk/gov/hmcts/ccd/data/casedetails/DefaultCaseDetailsRepository.java b/src/main/java/uk/gov/hmcts/ccd/data/casedetails/DefaultCaseDetailsRepository.java index a0fb1ba026..130115ae71 100644 --- a/src/main/java/uk/gov/hmcts/ccd/data/casedetails/DefaultCaseDetailsRepository.java +++ b/src/main/java/uk/gov/hmcts/ccd/data/casedetails/DefaultCaseDetailsRepository.java @@ -77,7 +77,10 @@ public CaseDetails set(final CaseDetails caseDetails) { em.flush(); } catch (StaleObjectStateException | OptimisticLockException e) { LOG.info("Optimistic Lock Exception: Case data has been altered, UUID={}", caseDetails.getReference(), e); - throw new CaseConcurrencyException("The case data has been altered outside of this transaction."); + throw new CaseConcurrencyException(""" + Unfortunately we were unable to save your work to the case as \ + another action happened at the same time. + Please review the case and try again."""); } catch (PersistenceException e) { if (e.getCause() instanceof ConstraintViolationException && isDuplicateReference(e)) { LOG.warn("ConstraintViolationException happen for UUID={}. ConstraintName: {}", diff --git a/src/test/java/uk/gov/hmcts/ccd/data/casedetails/DefaultCaseDetailsRepositoryTest.java b/src/test/java/uk/gov/hmcts/ccd/data/casedetails/DefaultCaseDetailsRepositoryTest.java index d85155f1bf..6aa5d1389e 100644 --- a/src/test/java/uk/gov/hmcts/ccd/data/casedetails/DefaultCaseDetailsRepositoryTest.java +++ b/src/test/java/uk/gov/hmcts/ccd/data/casedetails/DefaultCaseDetailsRepositoryTest.java @@ -27,13 +27,17 @@ import uk.gov.hmcts.ccd.domain.service.common.AccessControlService; import uk.gov.hmcts.ccd.domain.service.security.AuthorisedCaseDefinitionDataService; import uk.gov.hmcts.ccd.endpoint.exceptions.BadRequestException; +import uk.gov.hmcts.ccd.endpoint.exceptions.CaseConcurrencyException; import uk.gov.hmcts.ccd.infrastructure.user.UserAuthorisation; import uk.gov.hmcts.ccd.infrastructure.user.UserAuthorisation.AccessLevel; import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.OptimisticLockException; import javax.servlet.ServletContext; import javax.servlet.ServletRequestEvent; import java.io.IOException; +import java.lang.reflect.Field; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneOffset; @@ -57,9 +61,13 @@ import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anySet; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static uk.gov.hmcts.ccd.TestFixtures.loadCaseTypeDefinition; import static uk.gov.hmcts.ccd.domain.service.common.AccessControlService.CAN_READ; @@ -125,6 +133,41 @@ public void clearDown() { listener.requestDestroyed(new ServletRequestEvent(context, request)); } + @Test + public void setShouldThrowCaseConcurrencyException() throws NoSuchFieldException, IllegalAccessException { + EntityManager emMock = mock(EntityManager.class); + CaseDetailsMapper caseDetailsMapper = mock(CaseDetailsMapper.class); + + DefaultCaseDetailsRepository defaultCaseDetailsRepository = + new DefaultCaseDetailsRepository(caseDetailsMapper, null, null, + applicationParams); + + Field emField = DefaultCaseDetailsRepository.class.getDeclaredField("em"); + emField.setAccessible(true); + emField.set(defaultCaseDetailsRepository, emMock); + + CaseDetails caseDetails = new CaseDetails(); + caseDetails.setReference(1L); + + CaseDetailsEntity caseDetailsEntity = new CaseDetailsEntity(); + caseDetailsEntity.setReference(1L); + caseDetailsEntity.setLastModified(LocalDateTime.now(ZoneOffset.UTC)); + caseDetailsEntity.setVersion(1); + + when(caseDetailsMapper.modelToEntity(caseDetails)).thenReturn(caseDetailsEntity); + when(emMock.merge(caseDetailsEntity)).thenReturn(caseDetailsEntity); + doThrow(new OptimisticLockException()).when(emMock).flush(); + + CaseConcurrencyException exception = assertThrows(CaseConcurrencyException.class, + () -> defaultCaseDetailsRepository.set(caseDetails)); + + assertThat(exception.getMessage(), is("Unfortunately we were unable to save your work to the case as " + + "another action happened at the same time.\nPlease review the case and try again.")); + + verify(emMock).merge(caseDetailsEntity); + verify(emMock).flush(); + } + @Test public void setShouldPersistCaseDetails() { CaseDetails caseDetails = new CaseDetails();