|  | 
| 15 | 15 |  */ | 
| 16 | 16 | package com.vaadin.flow.component.html; | 
| 17 | 17 | 
 | 
|  | 18 | +import java.io.ByteArrayOutputStream; | 
|  | 19 | +import java.io.OutputStream; | 
| 18 | 20 | import java.util.Optional; | 
| 19 | 21 | 
 | 
| 20 | 22 | import org.junit.Assert; | 
| 21 | 23 | import org.junit.Test; | 
|  | 24 | +import org.mockito.ArgumentCaptor; | 
| 22 | 25 | import org.mockito.Mockito; | 
| 23 | 26 | 
 | 
| 24 | 27 | import com.vaadin.flow.dom.Element; | 
|  | 28 | +import com.vaadin.flow.server.VaadinRequest; | 
|  | 29 | +import com.vaadin.flow.server.VaadinResponse; | 
|  | 30 | +import com.vaadin.flow.server.VaadinService; | 
|  | 31 | +import com.vaadin.flow.server.VaadinSession; | 
|  | 32 | +import com.vaadin.flow.server.streams.DownloadEvent; | 
| 25 | 33 | import com.vaadin.flow.server.streams.DownloadHandler; | 
| 26 | 34 | import com.vaadin.flow.server.streams.DownloadResponse; | 
| 27 | 35 | import com.vaadin.flow.server.streams.InputStreamDownloadHandler; | 
| @@ -71,4 +79,110 @@ public Element getElement() { | 
| 71 | 79 |         new TestImage(handler, "test.png"); | 
| 72 | 80 |         Assert.assertTrue(handler.isInline()); | 
| 73 | 81 |     } | 
|  | 82 | + | 
|  | 83 | +    /** | 
|  | 84 | +     * Helper method to capture and invoke a DownloadHandler, returning the | 
|  | 85 | +     * captured content type. | 
|  | 86 | +     */ | 
|  | 87 | +    private String captureAndInvokeDownloadHandler(Element element) | 
|  | 88 | +            throws Exception { | 
|  | 89 | +        ArgumentCaptor<DownloadHandler> handlerCaptor = ArgumentCaptor | 
|  | 90 | +                .forClass(DownloadHandler.class); | 
|  | 91 | +        Mockito.verify(element).setAttribute(Mockito.eq("src"), | 
|  | 92 | +                handlerCaptor.capture()); | 
|  | 93 | + | 
|  | 94 | +        DownloadHandler handler = handlerCaptor.getValue(); | 
|  | 95 | +        Assert.assertTrue("Handler should be InputStreamDownloadHandler", | 
|  | 96 | +                handler instanceof InputStreamDownloadHandler); | 
|  | 97 | + | 
|  | 98 | +        // Create mock event and response to capture content type | 
|  | 99 | +        VaadinRequest request = Mockito.mock(VaadinRequest.class); | 
|  | 100 | +        VaadinResponse response = Mockito.mock(VaadinResponse.class); | 
|  | 101 | +        VaadinSession session = Mockito.mock(VaadinSession.class); | 
|  | 102 | +        VaadinService service = Mockito.mock(VaadinService.class); | 
|  | 103 | +        OutputStream outputStream = new ByteArrayOutputStream(); | 
|  | 104 | +        Mockito.when(response.getOutputStream()).thenReturn(outputStream); | 
|  | 105 | +        Mockito.when(response.getService()).thenReturn(service); | 
|  | 106 | +        Mockito.when(service.getMimeType(Mockito.anyString())) | 
|  | 107 | +                .thenReturn("application/octet-stream"); | 
|  | 108 | + | 
|  | 109 | +        DownloadEvent event = new DownloadEvent(request, response, session, | 
|  | 110 | +                element); | 
|  | 111 | +        handler.handleDownloadRequest(event); | 
|  | 112 | + | 
|  | 113 | +        ArgumentCaptor<String> contentTypeCaptor = ArgumentCaptor | 
|  | 114 | +                .forClass(String.class); | 
|  | 115 | +        Mockito.verify(response).setContentType(contentTypeCaptor.capture()); | 
|  | 116 | +        return contentTypeCaptor.getValue(); | 
|  | 117 | +    } | 
|  | 118 | + | 
|  | 119 | +    @Test | 
|  | 120 | +    public void byteArrayConstructor_typicalUseCase() throws Exception { | 
|  | 121 | +        Element element = Mockito.mock(Element.class); | 
|  | 122 | +        byte[] imageData = new byte[] { 1, 2, 3, 4, 5 }; | 
|  | 123 | + | 
|  | 124 | +        class TestImage extends Image { | 
|  | 125 | +            public TestImage(byte[] content, String name) { | 
|  | 126 | +                super(content, name); | 
|  | 127 | +            } | 
|  | 128 | + | 
|  | 129 | +            @Override | 
|  | 130 | +            public Element getElement() { | 
|  | 131 | +                return element; | 
|  | 132 | +            } | 
|  | 133 | +        } | 
|  | 134 | + | 
|  | 135 | +        new TestImage(imageData, "test.png"); | 
|  | 136 | +        Mockito.verify(element).setAttribute("alt", "test.png"); | 
|  | 137 | + | 
|  | 138 | +        String contentType = captureAndInvokeDownloadHandler(element); | 
|  | 139 | +        Assert.assertEquals("image/png", contentType); | 
|  | 140 | +    } | 
|  | 141 | + | 
|  | 142 | +    @Test | 
|  | 143 | +    public void byteArrayConstructor_withExplicitMimeType() throws Exception { | 
|  | 144 | +        Element element = Mockito.mock(Element.class); | 
|  | 145 | +        byte[] imageData = new byte[] { 1, 2, 3, 4, 5 }; | 
|  | 146 | + | 
|  | 147 | +        class TestImage extends Image { | 
|  | 148 | +            public TestImage(byte[] content, String name, String mimeType) { | 
|  | 149 | +                super(content, name, mimeType); | 
|  | 150 | +            } | 
|  | 151 | + | 
|  | 152 | +            @Override | 
|  | 153 | +            public Element getElement() { | 
|  | 154 | +                return element; | 
|  | 155 | +            } | 
|  | 156 | +        } | 
|  | 157 | + | 
|  | 158 | +        new TestImage(imageData, "test.webp", "image/webp"); | 
|  | 159 | +        Mockito.verify(element).setAttribute("alt", "test.webp"); | 
|  | 160 | + | 
|  | 161 | +        String contentType = captureAndInvokeDownloadHandler(element); | 
|  | 162 | +        Assert.assertEquals("image/webp", contentType); | 
|  | 163 | +    } | 
|  | 164 | + | 
|  | 165 | +    @Test | 
|  | 166 | +    public void byteArrayConstructor_withNullMimeType() throws Exception { | 
|  | 167 | +        Element element = Mockito.mock(Element.class); | 
|  | 168 | +        byte[] imageData = new byte[] { 1, 2, 3, 4, 5 }; | 
|  | 169 | + | 
|  | 170 | +        class TestImage extends Image { | 
|  | 171 | +            public TestImage(byte[] content, String name, String mimeType) { | 
|  | 172 | +                super(content, name, mimeType); | 
|  | 173 | +            } | 
|  | 174 | + | 
|  | 175 | +            @Override | 
|  | 176 | +            public Element getElement() { | 
|  | 177 | +                return element; | 
|  | 178 | +            } | 
|  | 179 | +        } | 
|  | 180 | + | 
|  | 181 | +        new TestImage(imageData, "test.img", null); | 
|  | 182 | +        Mockito.verify(element).setAttribute("alt", "test.img"); | 
|  | 183 | + | 
|  | 184 | +        String contentType = captureAndInvokeDownloadHandler(element); | 
|  | 185 | +        // When MIME type is null, it falls back to the service's getMimeType | 
|  | 186 | +        Assert.assertEquals("application/octet-stream", contentType); | 
|  | 187 | +    } | 
| 74 | 188 | } | 
0 commit comments