package com.jaspersoft.jasperserver.jaxrs.client.apiadapters.reporting;
import com.jaspersoft.jasperserver.jaxrs.client.core.Callback;
import com.jaspersoft.jasperserver.jaxrs.client.core.JerseyRequest;
import com.jaspersoft.jasperserver.jaxrs.client.core.RequestExecution;
import com.jaspersoft.jasperserver.jaxrs.client.core.SessionStorage;
import com.jaspersoft.jasperserver.jaxrs.client.core.exceptions.JSClientException;
import com.jaspersoft.jasperserver.jaxrs.client.core.operationresult.OperationResult;
import com.jaspersoft.jasperserver.jaxrs.client.dto.reports.AttachmentDescriptor;
import com.jaspersoft.jasperserver.jaxrs.client.dto.reports.ExportDescriptor;
import com.jaspersoft.jasperserver.jaxrs.client.dto.reports.ReportExecutionStatusEntity;
import org.apache.commons.io.IOUtils;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import static com.jaspersoft.jasperserver.jaxrs.client.core.JerseyRequest.buildRequest;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.verifyStatic;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNotSame;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
/**
* Unit tests for {@link ExportExecutionRequestBuilder}
*/
@PrepareForTest({JerseyRequest.class, IOUtils.class, ExportExecutionRequestBuilder.class})
public class ExportExecutionRequestBuilderTest extends PowerMockTestCase {
@Mock
private SessionStorage sessionStorageMock;
@Mock
private ExportDescriptor descriptorMock;
@Mock
private JerseyRequest<String> stringJerseyRequestMock;
@Mock
private JerseyRequest<InputStream> streamJerseyRequestMock;
@Mock
private OperationResult<String> resultMock;
@Mock
private OperationResult<InputStream> streamedResultMock;
@Mock
private JerseyRequest<ReportExecutionStatusEntity> entityJerseyRequestMock;
@Mock
private OperationResult<ReportExecutionStatusEntity> statusEntityOperationResultMock;
@Mock
private InputStream streamMock;
@Mock
private ReportExecutionStatusEntity statusEntityMock;
@Mock
private HtmlReport reportMock;
@BeforeMethod
public void before() {
initMocks(this);
}
@Test (enabled = false)
public void should_return_HtmlReport_instance_if_ExportDescriptor_is_a_proper_val() throws Exception {
/* Given */
String exportId = "exportId";
String requestId = "requestId";
final AttachmentDescriptor desc = spy(new AttachmentDescriptor());
desc.setContentType("json");
desc.setFileName("myFile");
mockStatic(JerseyRequest.class);
when(buildRequest(sessionStorageMock, String.class, new String[]{"/reportExecutions", requestId, "/exports", exportId, "/outputResource"})).thenReturn(stringJerseyRequestMock);
doReturn(resultMock).when(stringJerseyRequestMock).get();
doReturn("entity").when(resultMock).getEntity();
doReturn(new ArrayList<AttachmentDescriptor>() {{
add(desc);
}}).when(descriptorMock).getAttachments();
ExportExecutionRequestBuilder builderSpy = spy(new ExportExecutionRequestBuilder(sessionStorageMock, requestId, exportId));
doReturn(statusEntityOperationResultMock).when(builderSpy).attachment(anyString());
doReturn(streamMock).when(statusEntityOperationResultMock).getEntity();
mockStatic(IOUtils.class);
when(IOUtils.toByteArray(streamMock)).thenReturn(new byte[]{});
/* When */
HtmlReport retrieved = builderSpy.htmlReport(descriptorMock);
/* Then */
assertNotNull(retrieved);
verifyStatic(times(1));
buildRequest(sessionStorageMock, String.class, new String[]{"/reportExecutions", requestId, "/exports", exportId, "/outputResource"});
verifyStatic(times(1));
IOUtils.toByteArray(streamMock);
verify(stringJerseyRequestMock, times(1)).get();
verify(resultMock, times(1)).getEntity();
verify(descriptorMock, times(1)).getAttachments();
verify(desc, times(2)).getFileName();
verify(builderSpy, times(1)).attachment(anyString());
}
@Test
public void should_retrieve_attachment_asynchronously() throws InterruptedException {
/** Given **/
String requestId = "requestId";
String exportId = "exportId";
String attachmentId = "attachmentId";
final AtomicInteger newThreadId = new AtomicInteger();
final int currentThreadId = (int) Thread.currentThread().getId();
ExportExecutionRequestBuilder builderSpy = Mockito.spy(new ExportExecutionRequestBuilder(sessionStorageMock, requestId, exportId));
mockStatic(JerseyRequest.class);
Mockito.when(buildRequest(eq(sessionStorageMock),
eq(InputStream.class),
eq(new String[]{"reportExecutions", requestId, "exports", exportId, "attachments", attachmentId}))).thenReturn(streamJerseyRequestMock);
Mockito.when(buildRequest(eq(sessionStorageMock),
eq(ReportExecutionStatusEntity.class),
eq(new String[]{"reportExecutions", requestId, "exports", exportId, "status"}))).thenReturn(entityJerseyRequestMock);
Mockito.doReturn(statusEntityOperationResultMock).when(entityJerseyRequestMock).get();
Mockito.doReturn(streamedResultMock).when(streamJerseyRequestMock).get();
Mockito.doReturn(statusEntityMock).when(statusEntityOperationResultMock).getEntity();
Mockito.doReturn("execution").doReturn("ready").when(statusEntityMock).getValue();
final Callback<OperationResult<InputStream>, Void> callback = Mockito.spy(new Callback<OperationResult<InputStream>, Void>() {
@Override
public Void execute(OperationResult<InputStream> data) {
newThreadId.set((int) Thread.currentThread().getId());
synchronized (this) {
this.notify();
}
return null;
}
});
/** When **/
RequestExecution retrieved = builderSpy.asyncAttachment(attachmentId, callback);
/** Wait **/
synchronized (callback) {
callback.wait(1000);
}
/** Then **/
assertNotNull(retrieved);
assertNotSame(currentThreadId, newThreadId.get());
verify(streamJerseyRequestMock, times(1)).get();
verify(entityJerseyRequestMock, times(2)).get();
verify(statusEntityOperationResultMock, times(2)).getEntity();
verify(statusEntityMock, times(2)).getValue();
verify(callback).execute(streamedResultMock);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void should_throw_exception_when_invalid_attachmentId() {
String requestId = "requestId";
String exportId = "exportId";
ExportExecutionRequestBuilder builderSpy = spy(new ExportExecutionRequestBuilder(sessionStorageMock, requestId, exportId));
builderSpy.asyncAttachment("", new Callback<OperationResult<InputStream>, Object>() {
@Override
public Object execute(OperationResult<InputStream> data) {
return null;
}
});
}
@Test
public void should_retrieve_output_resource_asynchronously() throws InterruptedException {
/** Given **/
String requestId = "requestId";
String exportId = "exportId";
final AtomicInteger newThreadId = new AtomicInteger();
final int currentThreadId = (int) Thread.currentThread().getId();
ExportExecutionRequestBuilder builderSpy = spy(new ExportExecutionRequestBuilder(sessionStorageMock, requestId, exportId));
mockStatic(JerseyRequest.class);
when(buildRequest(eq(sessionStorageMock),
eq(InputStream.class),
eq(new String[]{"reportExecutions", requestId, "exports", exportId, "outputResource"}))).thenReturn(streamJerseyRequestMock);
doReturn(streamedResultMock).when(streamJerseyRequestMock).get();
final Callback<OperationResult<InputStream>, Void> callback = spy(new Callback<OperationResult<InputStream>, Void>() {
@Override
public Void execute(OperationResult<InputStream> data) {
newThreadId.set((int) Thread.currentThread().getId());
synchronized (this) {
this.notify();
}
return null;
}
});
/** When **/
RequestExecution retrieved = builderSpy.asyncOutputResource(callback);
/** Wait **/
synchronized (callback) {
callback.wait(1000);
}
/** Then **/
assertNotNull(retrieved);
assertNotSame(currentThreadId, newThreadId.get());
verify(streamJerseyRequestMock, times(1)).get();
verify(callback).execute(streamedResultMock);
}
@Test
public void should_send_html_report_asynchronously() throws InterruptedException {
/** Given **/
String requestId = "requestId";
String exportId = "exportId";
final AtomicInteger newThreadId = new AtomicInteger();
final int currentThreadId = (int) Thread.currentThread().getId();
ExportExecutionRequestBuilder builderSpy = spy(new ExportExecutionRequestBuilder(sessionStorageMock, requestId, exportId));
PowerMockito.doReturn(reportMock).when(builderSpy).htmlReport(any(ExportDescriptor.class));
final Callback<HtmlReport, Void> callback = spy(new Callback<HtmlReport, Void>() {
@Override
public Void execute(HtmlReport data) {
newThreadId.set((int) Thread.currentThread().getId());
synchronized (this) {
this.notify();
}
return null;
}
});
/** When **/
RequestExecution retrieved = builderSpy.asyncHtmlReport(new ExportDescriptor(), callback);
/** Wait **/
synchronized (callback) {
callback.wait(1000);
}
/** Then **/
assertNotNull(retrieved);
assertNotSame(currentThreadId, newThreadId.get());
Mockito.verify(callback).execute(reportMock);
Mockito.verify(builderSpy).htmlReport(any(ExportDescriptor.class));
}
@Test
public void should_return_operation_result() {
/** Given **/
String requestId = "requestId";
String exportId = "exportId";
mockStatic(JerseyRequest.class);
when(buildRequest(eq(sessionStorageMock),
eq(InputStream.class),
eq(new String[]{"reportExecutions", requestId, "exports", exportId, "outputResource"}))).thenReturn(streamJerseyRequestMock);
doReturn(streamedResultMock).when(streamJerseyRequestMock).get();
ExportExecutionRequestBuilder builderSpy = spy(new ExportExecutionRequestBuilder(sessionStorageMock, requestId, exportId));
OperationResult<InputStream> retrieved = builderSpy.outputResource();
assertSame(retrieved, streamedResultMock);
verifyStatic();
buildRequest(eq(sessionStorageMock),
eq(InputStream.class),
eq(new String[]{"reportExecutions", requestId, "exports", exportId, "outputResource"}));
}
@Test
public void should_retrieve_status_entity_asynchronously() throws InterruptedException {
/** Given **/
String requestId = "requestId";
String exportId = "exportId";
final AtomicInteger newThreadId = new AtomicInteger();
final int currentThreadId = (int) Thread.currentThread().getId();
ExportExecutionRequestBuilder builderSpy = spy(new ExportExecutionRequestBuilder(sessionStorageMock, requestId, exportId));
mockStatic(JerseyRequest.class);
when(buildRequest(eq(sessionStorageMock),
eq(ReportExecutionStatusEntity.class),
eq(new String[]{"reportExecutions", requestId, "exports", exportId, "status"}))).thenReturn(entityJerseyRequestMock);
doReturn(statusEntityOperationResultMock).when(entityJerseyRequestMock).get();
final Callback<OperationResult<ReportExecutionStatusEntity>, Void> callback = spy(new Callback<OperationResult<ReportExecutionStatusEntity>, Void>() {
@Override
public Void execute(OperationResult<ReportExecutionStatusEntity> data) {
newThreadId.set((int) Thread.currentThread().getId());
synchronized (this) {
this.notify();
}
return null;
}
});
/** When **/
RequestExecution retrieved = builderSpy.asyncStatus(callback);
/** Wait **/
synchronized (callback) {
callback.wait(1000);
}
/** Then **/
assertNotNull(retrieved);
assertNotSame(currentThreadId, newThreadId.get());
verify(entityJerseyRequestMock, times(1)).get();
verify(callback).execute(statusEntityOperationResultMock);
}
@Test
public void should_get_attachment_as_stream() {
/** Given **/
String requestId = "requestId";
String exportId = "exportId";
String attachmentId = "attachmentId";
mockStatic(JerseyRequest.class);
when(buildRequest(eq(sessionStorageMock),
eq(InputStream.class),
eq(new String[]{"reportExecutions", requestId, "exports", exportId, "attachments", attachmentId}))).thenReturn(streamJerseyRequestMock);
PowerMockito.doReturn(streamedResultMock).when(streamJerseyRequestMock).get();
ExportExecutionRequestBuilder builderSpy = spy(new ExportExecutionRequestBuilder(sessionStorageMock, requestId, exportId));
PowerMockito.doReturn(statusEntityOperationResultMock).when(builderSpy).status();
PowerMockito.doReturn(statusEntityMock).when(statusEntityOperationResultMock).getEntity();
PowerMockito.doReturn("execution").doReturn("ready").when(statusEntityMock).getValue();
//
/** When **/
OperationResult<InputStream> retrieved = builderSpy.attachment(attachmentId);
/** Then **/
verifyStatic();
buildRequest(eq(sessionStorageMock),
eq(InputStream.class),
eq(new String[]{"reportExecutions", requestId, "exports", exportId, "attachments", attachmentId}));
assertNotNull(retrieved);
Mockito.verify(builderSpy, times(2)).status();
Mockito.verify(streamJerseyRequestMock).get();
Mockito.verify(statusEntityOperationResultMock, times(2)).getEntity();
Mockito.verify(statusEntityMock, times(2)).getValue();
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void should_throw_exception_when_invalid_id() {
String requestId = "requestId";
String exportId = "exportId";
ExportExecutionRequestBuilder builderSpy = spy(new ExportExecutionRequestBuilder(sessionStorageMock, requestId, exportId));
builderSpy.attachment("/");
}
@Test
public void should_throw_exception_when_cannot_read_stream() throws FileNotFoundException {
String requestId = "requestId";
String exportId = "exportId";
mockStatic(JerseyRequest.class);
PowerMockito.when(buildRequest(eq(sessionStorageMock),
eq(String.class),
eq(new String[]{"reportExecutions", requestId, "exports", exportId, "outputResource"}))).thenReturn(stringJerseyRequestMock);
PowerMockito.doReturn(resultMock).when(stringJerseyRequestMock).get();
PowerMockito.doReturn("____").when(resultMock).getEntity();
ExportExecutionRequestBuilder builderSpy = spy(new ExportExecutionRequestBuilder(sessionStorageMock, requestId, exportId));
PowerMockito.doReturn(streamedResultMock).when(builderSpy).attachment(anyString());
PowerMockito.doReturn(new InputStream() {
@Override
public int read() throws IOException {
throw new IOException();
}
}).when(streamedResultMock).getEntity();
ExportDescriptor descriptor = new ExportDescriptor();
descriptor.setAttachments(Arrays.asList(new AttachmentDescriptor()));
try {
builderSpy.htmlReport(descriptor);
} catch (Exception e) {
assertTrue(instanceOf(JSClientException.class).matches(e));
assertEquals(e.getMessage(), "Error while reading thumbnail content");
}
}
@AfterMethod
public void after() {
reset(sessionStorageMock, descriptorMock, stringJerseyRequestMock, resultMock, streamMock, statusEntityOperationResultMock);
}
}