package jnpf.fileStorage; import cn.dev33.satoken.same.SaSameUtil; import jnpf.base.ActionResult; import jnpf.controller.UtilsController; import jnpf.controller.WorkflowFileController; import jnpf.exception.DataException; import jnpf.model.fileaccess.WorkflowFileGrant; import jnpf.model.fileaccess.WorkflowFileRequest; import org.junit.Before; import org.junit.Test; import org.mockito.MockedStatic; import java.util.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; public class WorkflowFileControllerTest { private WorkflowFileTicketService access; private UtilsController files; private WorkflowFileController controller; private WorkflowFileRequest request; private WorkflowFileGrant grant; @Before public void setup() { jnpf.util.context.SpringContext.setApplicationContext(mock(org.springframework.context.ApplicationContext.class)); access = mock(WorkflowFileTicketService.class); files = mock(UtilsController.class); controller = new WorkflowFileController(access, files); request = new WorkflowFileRequest(); request.setFileId("A"); grant = new WorkflowFileGrant(); grant.setContext(request); grant.setFile(new LinkedHashMap<>(Map.of("fileId", "A", "name", "a.docx", "url", "/api/file/Image/annex/A"))); when(access.authorizePreview(request)).thenReturn(grant); when(access.authorizeDownloads(any())).thenReturn(List.of(grant)); } @Test public void singleDownloadDelegatesWithAuthorizedFile() throws Exception { when(files.downloadUrl("annex", "A")).thenReturn(ActionResult.success((Object) Map.of("url", "/native-download"))); Map result = controller.download(List.of(request)).getData(); assertEquals("a.docx", result.get("downloadName")); assertEquals("/native-download", ((Map) result.get("downloadVo")).get("url")); org.mockito.InOrder order = inOrder(access, files); order.verify(access).authorizeDownloads(List.of(request)); order.verify(files).downloadUrl("annex", "A"); } @Test public void batchDelegatesOnlyAfterAllAuthorization() throws Exception { WorkflowFileRequest second = new WorkflowFileRequest(); second.setFileId("B"); WorkflowFileGrant other = new WorkflowFileGrant(); other.setContext(second); other.setFile(Map.of("name", "b.docx")); when(access.authorizeDownloads(any())).thenReturn(List.of(grant, other)); when(files.packDownloadUrl(eq("annex"), any())).thenReturn(ActionResult.success(Map.of("downloadVo", Map.of("url", "/native-zip"), "downloadName", "files.zip"))); assertEquals("files.zip", controller.download(List.of(request, second)).getData().get("downloadName")); verify(files).packDownloadUrl("annex", List.of(Map.of("fileId", "A", "fileName", "a.docx"), Map.of("fileId", "B", "fileName", "b.docx"))); verify(files, never()).downloadUrl(any(), any()); } @Test public void denialDoesNotCallOriginalFileExecution() throws Exception { when(access.authorizeDownloads(any())).thenThrow(new DataException("denied")); when(access.authorizePreview(any())).thenThrow(new DataException("denied")); try { controller.download(List.of(request)); fail(); } catch (DataException expected) { } try { controller.preview(request, "platform"); fail(); } catch (DataException expected) { } verifyNoInteractions(files); } @Test public void nativeFailureIsNotConvertedToSuccessfulDownload() throws Exception { when(files.downloadUrl(any(), any())).thenReturn(ActionResult.fail("missing")); try { controller.download(List.of(request)); fail(); } catch (DataException expected) { } } @Test public void imageUsesOriginalImageAddressWithoutReencoding() { grant.getFile().put("name", "a.png"); Map result = controller.preview(request, "office").getData(); assertEquals("image", result.get("kind")); assertEquals("/api/file/Image/annex/A", result.get("url")); verify(access, never()).previewTicket(any()); verifyNoInteractions(files); } @Test public void officeTicketOnlyBindsConfiguration() { when(access.previewTicket(grant)).thenReturn("config-ticket"); Map result = controller.preview(request, "office").getData(); assertEquals("config-ticket", result.get("ticket")); assertFalse(result.containsKey("url")); verifyNoInteractions(files); } @Test public void platformPreviewDelegatesWithCanonicalFileMetadata() { when(files.preview(any())).thenReturn(ActionResult.success("", "http://preview/native")); Map result = controller.preview(request, "platform").getData(); assertEquals("platform", result.get("kind")); assertEquals("http://preview/native", result.get("url")); verify(files).preview(argThat(p -> "A".equals(p.getFileName()) && "/api/file/Image/annex/A".equals(p.getFileDownloadUrl()))); verify(access, never()).previewTicket(any()); } @Test public void configAccessIsInternalAndStillRevalidates() { when(access.previewAccess("ticket")).thenReturn(grant); try (MockedStatic internal = mockStatic(SaSameUtil.class, withSettings().mockMaker(org.mockito.MockMakers.INLINE))) { assertSame(grant, controller.previewAccess("ticket").getData()); internal.verify(SaSameUtil::checkCurrentRequestToken); verify(access).previewAccess("ticket"); } } }