Skip to content

Commit

Permalink
feat: Added logic for handling unavailable images
Browse files Browse the repository at this point in the history
Refs: #307
  • Loading branch information
pbezliapovich committed Dec 19, 2024
1 parent 9ed0b63 commit 32ce943
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,12 @@ private byte[] getResourceAsBytesImpl(String resource, List<String> unavailableW
InputStream stream = resolver.resolve(resource);
if (stream != null) {
byte[] result = StreamUtils.suckStreamThenClose(stream);
if (result.length > 0) {
if (WorkItemAttachmentUrlResolver.isWorkItemAttachmentUrl(resource) && isMediaTypeMismatch(resource, result)) {
unavailableWorkItemAttachments.add(getWorkItemIdFromAttachmentUrl(resource));
return getDefaultContent(resource);
}
return result;
if (result.length > 0 && WorkItemAttachmentUrlResolver.isWorkItemAttachmentUrl(resource) && isMediaTypeMismatch(resource, result)) {
unavailableWorkItemAttachments.add(getWorkItemIdFromAttachmentUrl(resource));
return getDefaultContent(resource);
}
return result;

}
}
}
Expand All @@ -119,8 +118,8 @@ byte[] getDefaultContent(String resource) throws IOException {
} else {
return new byte[0];
}
File sorryBear = new File(BundleHelper.getPath("com.polarion.alm.ui", defaultImagePath));
return StreamUtils.suckStreamThenClose(new FileInputStream(sorryBear));
File defaultImage = new File(BundleHelper.getPath("com.polarion.alm.ui", defaultImagePath));
return StreamUtils.suckStreamThenClose(new FileInputStream(defaultImage));
}

@VisibleForTesting
Expand Down Expand Up @@ -163,8 +162,9 @@ public byte[] processPossibleSvgImage(byte[] possibleSvgImageBytes) {
/**
* Remove GenericUrlResolver because it has no explicit timeouts declared
*/
@VisibleForTesting
@SneakyThrows
private IAttachmentUrlResolver getPolarionUrlResolverWithoutGenericUrlChildResolver() {
IAttachmentUrlResolver getPolarionUrlResolverWithoutGenericUrlChildResolver() {
IAttachmentUrlResolver attachmentUrlResolver = PolarionUrlResolver.getInstance();

if (attachmentUrlResolver instanceof ParentUrlResolver parentUrlResolver) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@

import ch.sbb.polarion.extension.generic.test_extensions.PlatformContextMockExtension;
import ch.sbb.polarion.extension.generic.test_extensions.TransactionalExecutorExtension;
import com.polarion.alm.tracker.internal.url.GenericUrlResolver;
import com.polarion.alm.tracker.internal.url.IAttachmentUrlResolver;
import com.polarion.alm.tracker.internal.url.IUrlResolver;
import com.polarion.alm.tracker.internal.url.ParentUrlResolver;
import com.polarion.alm.tracker.internal.url.PolarionUrlResolver;
import lombok.SneakyThrows;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
Expand All @@ -23,7 +26,7 @@
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;

@ExtendWith({
MockitoExtension.class,
Expand All @@ -32,7 +35,7 @@
})
class PdfExporterFileResourceProviderTest {
@Mock
PdfExporterFileResourceProvider fileResourceProviderMock;
PdfExporterFileResourceProvider resourceProviderMock;

@Mock
private IUrlResolver resolverMock;
Expand All @@ -48,7 +51,28 @@ void setUp() {
}

@Test
void getResourceAsBytesSuccess() throws IOException {
void processPossibleSvgImageTest() {
byte[] basicString = "basic".getBytes(StandardCharsets.UTF_8);
assertArrayEquals(basicString, resourceProvider.processPossibleSvgImage(basicString));
}

@Test
@SneakyThrows
void replaceImagesAsBase64EncodedTest() {
byte[] imgBytes;
try (InputStream is = this.getClass().getResourceAsStream("/test_img.png")) {
imgBytes = is != null ? is.readAllBytes() : new byte[0];
}

when(resourceProviderMock.getResourceAsBytes("http://localhost/some-path/img.png", null)).thenReturn(imgBytes);
when(resourceProviderMock.getResourceAsBase64String(any(), eq(null))).thenCallRealMethod();
String result = resourceProviderMock.getResourceAsBase64String("http://localhost/some-path/img.png", null);
assertEquals("data:image/png;base64," + Base64.getEncoder().encodeToString(imgBytes), result);
}

@Test
@SneakyThrows
void getResourceAsBytesSuccess() {
when(resolverMock.canResolve(TEST_RESOURCE)).thenReturn(true);
when(resolverMock.resolve(TEST_RESOURCE)).thenReturn(new ByteArrayInputStream(TEST_CONTENT));

Expand All @@ -60,7 +84,8 @@ void getResourceAsBytesSuccess() throws IOException {
}

@Test
void getResourceAsBytesNoResolverFound() throws IOException {
@SneakyThrows
void getResourceAsBytesNoResolverFound() {
when(resolverMock.canResolve(TEST_RESOURCE)).thenReturn(false);

List<String> unavailableAttachments = new ArrayList<>();
Expand All @@ -71,7 +96,8 @@ void getResourceAsBytesNoResolverFound() throws IOException {
}

@Test
void getResourceAsBytesResolverReturnsNull() throws IOException {
@SneakyThrows
void getResourceAsBytesResolverReturnsNull() {
when(resolverMock.canResolve(TEST_RESOURCE)).thenReturn(true);
when(resolverMock.resolve(TEST_RESOURCE)).thenReturn(null);

Expand All @@ -93,38 +119,18 @@ void getResourceAsBytesExceptionHandling() {
assertTrue(unavailableAttachments.isEmpty());
}

@Test
void processPossibleSvgImageTest() {
byte[] basicString = "basic".getBytes(StandardCharsets.UTF_8);
assertArrayEquals(basicString, resourceProvider.processPossibleSvgImage(basicString));
}

@Test
@SneakyThrows
void replaceImagesAsBase64EncodedTest() {
byte[] imgBytes;
try (InputStream is = this.getClass().getResourceAsStream("/test_img.png")) {
imgBytes = is != null ? is.readAllBytes() : new byte[0];
}

when(fileResourceProviderMock.getResourceAsBytes("http://localhost/some-path/img.png", null)).thenReturn(imgBytes);
when(fileResourceProviderMock.getResourceAsBase64String(any(), eq(null))).thenCallRealMethod();
String result = fileResourceProviderMock.getResourceAsBase64String("http://localhost/some-path/img.png", null);
assertEquals("data:image/png;base64," + Base64.getEncoder().encodeToString(imgBytes), result);
}

@Test
void isMediaTypeMismatchMatchingMimeTypes() {
String resource = "image.png";
byte[] content = new byte[0];

try (MockedStatic<MediaUtils> mockedMediaUtils = Mockito.mockStatic(MediaUtils.class)) {
try (MockedStatic<MediaUtils> mockedMediaUtils = mockStatic(MediaUtils.class)) {
mockedMediaUtils.when(() -> MediaUtils.getMimeTypeUsingTikaByContent(resource, content))
.thenReturn("image/png");
mockedMediaUtils.when(() -> MediaUtils.getMimeTypeUsingTikaByResourceName(resource, null))
.thenReturn("image/png");

boolean result = fileResourceProviderMock.isMediaTypeMismatch(resource, content);
boolean result = resourceProviderMock.isMediaTypeMismatch(resource, content);
assertFalse(result);
}
}
Expand All @@ -133,26 +139,44 @@ void isMediaTypeMismatchMatchingMimeTypes() {
@SneakyThrows
void getDefaultContentEmptyForNonImage() {
String resource = "attachment.txt";
try (MockedStatic<MediaUtils> mockedMediaUtils = Mockito.mockStatic(MediaUtils.class)) {
try (MockedStatic<MediaUtils> mockedMediaUtils = mockStatic(MediaUtils.class)) {
mockedMediaUtils.when(() -> MediaUtils.getImageFormat(resource))
.thenReturn("");

byte[] content = fileResourceProviderMock.getDefaultContent(resource);
byte[] content = resourceProviderMock.getDefaultContent(resource);
assertNull(content);
}
}

@Test
void getWorkItemIdFromAttachmentUrlValidUrl() {
String url = "http://localhost/polarion/wi-attachment/elibrary/EL-14852/attachment.png";
String result = resourceProvider.getWorkItemIdFromAttachmentUrl(url);
assertEquals("EL-14852", result);
}
@SuppressWarnings("unchecked")
void getPolarionUrlResolverWithoutGenericUrlChildResolver() throws Exception {
ParentUrlResolver parentUrlResolverMock = mock(ParentUrlResolver.class);
Field childResolversField = ParentUrlResolver.class.getDeclaredField("childResolvers");
childResolversField.setAccessible(true);

@Test
void getWorkItemIdFromAttachmentUrl_InvalidUrl() {
String url = "http://example.com/invalid/url";
String result = fileResourceProviderMock.getWorkItemIdFromAttachmentUrl(url);
assertNull(result);
IUrlResolver mockResolver1 = mock(IUrlResolver.class);
IUrlResolver mockResolver2 = mock(GenericUrlResolver.class);
IUrlResolver mockResolver3 = mock(IUrlResolver.class);

List<IUrlResolver> childResolvers = List.of(mockResolver1, mockResolver2, mockResolver3);
childResolversField.set(parentUrlResolverMock, childResolvers);

try (MockedStatic<PolarionUrlResolver> polarionUrlResolverMock = mockStatic(PolarionUrlResolver.class)) {
polarionUrlResolverMock.when(PolarionUrlResolver::getInstance).thenReturn(parentUrlResolverMock);

IAttachmentUrlResolver result = resourceProvider.getPolarionUrlResolverWithoutGenericUrlChildResolver();

assertTrue(result instanceof ParentUrlResolver);
ParentUrlResolver resultParent = (ParentUrlResolver) result;

List<IUrlResolver> filteredResolvers =
(List<IUrlResolver>) childResolversField.get(resultParent);

assertEquals(2, filteredResolvers.size());
assertTrue(filteredResolvers.contains(mockResolver1));
assertTrue(filteredResolvers.contains(mockResolver3));
assertFalse(filteredResolvers.contains(mockResolver2));
}
}
}

0 comments on commit 32ce943

Please sign in to comment.