package jnpf.dmsService; import jnpf.base.UserInfo; import jnpf.dmsEntity.compare.DmsCompareRequest; import jnpf.dmsEntity.compare.DmsCompareTicket; import jnpf.dmsEntity.permission.entity.DmsFileVersionEntity; import jnpf.dmsEntity.permission.enums.DmsPermissionAction; import jnpf.dmsEntity.permission.enums.DmsResourceType; import jnpf.dmsEntity.preview.form.DmsFilePreviewTicketRequest; import jnpf.dmsEntity.preview.vo.DmsFilePreviewTicketVO; import jnpf.dmsMapper.DmsFileVersionMapper; import jnpf.dmsPermission.DmsCurrentIdentity; import jnpf.exception.DataException; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import java.util.Date; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; class DmsFileCompareServiceTest { private final UUID document = UUID.randomUUID(); private final DmsFileVersionEntity current = version(3); private final DmsFileVersionEntity historical = version(1); @Test void acceptsOlderVersionOfTheSameDocument() { assertDoesNotThrow(() -> DmsFileCompareService.validatePair(request(), current, historical)); } @Test void rejectsCrossDocumentOrNonHistoricalInput() { historical.setDocumentId(UUID.randomUUID()); assertThrows(DataException.class, () -> DmsFileCompareService.validatePair(request(), current, historical)); historical.setDocumentId(document); historical.setVersionNo(4L); assertThrows(DataException.class, () -> DmsFileCompareService.validatePair(request(), current, historical)); assertThrows(DataException.class, () -> DmsFileCompareService.validatePair(request(), current, current)); } @Test void rejectsStaleCurrentAndUnsupportedFiles() { assertThrows(DataException.class, () -> DmsFileCompareService.validatePair(request(), version(4), historical)); historical.setFileName("scan.pdf"); assertThrows(DataException.class, () -> DmsFileCompareService.validatePair(request(), current, historical)); } @Test void authorizesBothSourcesBeforeIssuingBoundPair() { DmsCurrentIdentity identity = mock(DmsCurrentIdentity.class); DmsPermissionDecisionService permissions = mock(DmsPermissionDecisionService.class); DmsFileVersionMapper versions = mock(DmsFileVersionMapper.class); DmsFilePreviewService previews = mock(DmsFilePreviewService.class); DmsCompareTicketIssuer issuer = mock(DmsCompareTicketIssuer.class); UserInfo user = new UserInfo(); user.setUserId("u1"); when(identity.requireUser()).thenReturn(user); when(identity.tenantId(user)).thenReturn("t1"); when(versions.selectCurrentEffective("t1", document)).thenReturn(current); when(versions.selectReadableByTenantAndId("t1", historical.getId())).thenReturn(historical); when(previews.createTicket(any())).thenAnswer(invocation -> { DmsFilePreviewTicketRequest r = invocation.getArgument(0); DmsFilePreviewTicketVO source = new DmsFilePreviewTicketVO(); source.setFileVersionId(r.getResourceId()); source.setExpiresAt(new Date(System.currentTimeMillis() + 300_000)); return source; }); when(issuer.issue(any(), anyLong())).thenReturn("pair-ticket"); DmsFileCompareService service = new DmsFileCompareService(identity, permissions, versions, previews, issuer); assertEquals("pair-ticket", service.createTicket(request())); verify(permissions).requireAllowed(DmsResourceType.FILE_VERSION, current.getId(), DmsPermissionAction.READ); verify(permissions).requireAllowed(DmsResourceType.FILE_VERSION, historical.getId(), DmsPermissionAction.READ); ArgumentCaptor pair = ArgumentCaptor.forClass(DmsCompareTicket.class); verify(issuer).issue(pair.capture(), anyLong()); assertEquals(historical.getId(), pair.getValue().getHistorical().getFileVersionId()); assertEquals(current.getId(), pair.getValue().getCurrent().getFileVersionId()); assertEquals("t1", pair.getValue().getTenantId()); assertEquals("u1", pair.getValue().getUserId()); reset(previews, issuer); doThrow(new DataException("denied")).when(permissions).requireAllowed(DmsResourceType.FILE_VERSION, historical.getId(), DmsPermissionAction.READ); assertThrows(DataException.class, () -> service.createTicket(request())); verifyNoInteractions(previews, issuer); } private DmsCompareRequest request() { DmsCompareRequest r = new DmsCompareRequest(); r.setDocumentId(document); r.setCurrentVersionId(current.getId()); r.setHistoricalVersionId(historical.getId()); r.setOperationId(UUID.randomUUID()); return r; } private DmsFileVersionEntity version(long number) { DmsFileVersionEntity v = new DmsFileVersionEntity(); v.setId(UUID.randomUUID()); v.setDocumentId(document); v.setVersionNo(number); v.setFileName("procedure.docx"); return v; } }