package com.belladati.sdk.report.impl;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Calendar;
import java.util.Collections;
import java.util.TimeZone;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.testng.annotations.Test;
import com.belladati.sdk.dataset.DataSetInfo;
import com.belladati.sdk.exception.server.InvalidJsonException;
import com.belladati.sdk.exception.server.InvalidStreamException;
import com.belladati.sdk.report.Report;
import com.belladati.sdk.report.ReportInfo;
import com.belladati.sdk.report.impl.ReportImpl;
import com.belladati.sdk.report.impl.ReportInfoImpl;
import com.belladati.sdk.test.SDKTest;
import com.belladati.sdk.test.TestRequestHandler;
import com.belladati.sdk.util.PaginatedList;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Tests behavior related to reports.
*
* @author Chris Hennigfeld
*/
@Test
public class ReportsTest extends SDKTest {
private final String reportsUri = "/api/reports";
private final String id = "123";
private final String name = "report name";
private final String description = "report description";
private final String owner = "report owner";
private final String lastChange = "Mon, 16 Apr 2012 10:17:26 GMT";
private final String viewId = id + "-aBcDeFgH";
/** Regular report info data is loaded correctly. */
public void loadReportInfo() {
PaginatedList<ReportInfo> reportInfos = service.getReportInfo();
registerSingleReport(builder.buildReportNode(id, name, description, owner, lastChange));
reportInfos.load();
server.assertRequestUris(reportsUri);
assertEquals(reportInfos.size(), 1);
ReportInfo info = reportInfos.get(0);
assertEquals(info.getId(), id);
assertEquals(info.getName(), name);
assertEquals(info.getDescription(), description);
assertEquals(info.getOwnerName(), owner);
Calendar expectedChange = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
expectedChange.set(2012, 3, 16, 10, 17, 26);
expectedChange.set(Calendar.MILLISECOND, 0);
assertEquals(info.getLastChange(), expectedChange.getTime());
assertEquals(info.toString(), name);
}
/** Report description may be null. */
public void infoNullDescription() {
registerSingleReport(builder.buildReportNode(id, name, null, owner, lastChange));
assertEquals(service.getReportInfo().load().get(0).getDescription(), "");
}
/** Report description may be missing. */
public void infoWithoutDescription() {
ObjectNode node = builder.buildReportNode(id, name, description, owner, lastChange);
node.remove("description");
registerSingleReport(node);
assertEquals(service.getReportInfo().load().get(0).getDescription(), "");
}
/** Report last change may be null. */
public void infoNullLastChange() {
registerSingleReport(builder.buildReportNode(id, name, description, owner, null));
assertNull(service.getReportInfo().load().get(0).getLastChange());
}
/** Report last change may be missing. */
public void infoWithoutLastChange() {
ObjectNode node = builder.buildReportNode(id, name, description, owner, lastChange);
node.remove("lastChange");
registerSingleReport(node);
assertNull(service.getReportInfo().load().get(0).getLastChange());
}
/** Report last change may be invalid format. */
public void infoInvalidLastChange() {
registerSingleReport(builder.buildReportNode(id, name, description, owner, "something invalid"));
assertNull(service.getReportInfo().load().get(0).getLastChange());
}
/** Getting a report info list multiple times returns the same list. */
public void reportInfoListSame() {
assertSame(service.getReportInfo(), service.getReportInfo());
}
/** Individual report can be loaded by ID through service. */
public void loadReport() {
server.register(reportsUri + "/" + id, builder.buildReportNode(id, name, description, owner, lastChange).toString());
Report report = service.loadReport(id);
server.assertRequestUris(reportsUri + "/" + id);
assertEquals(report.getId(), id);
assertEquals(report.getName(), name);
assertEquals(report.getDescription(), description);
assertEquals(report.getOwnerName(), owner);
Calendar expectedChange = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
expectedChange.set(2012, 3, 16, 10, 17, 26);
expectedChange.set(Calendar.MILLISECOND, 0);
assertEquals(report.getLastChange(), expectedChange.getTime());
assertEquals(report.getAttributes(), Collections.emptyList());
assertEquals(report.getViews(), Collections.emptyList());
assertEquals(report.toString(), name);
}
/** Report description may be null. */
public void reportNullDescription() {
server.register(reportsUri + "/" + id, builder.buildReportNode(id, name, null, owner, lastChange).toString());
Report report = service.loadReport(id);
assertEquals(report.getDescription(), "");
}
/** Report description may be missing. */
public void reportWithoutDescription() {
ObjectNode node = builder.buildReportNode(id, name, description, owner, lastChange);
node.remove("description");
server.register(reportsUri + "/" + id, node.toString());
Report report = service.loadReport(id);
assertEquals(report.getDescription(), "");
}
/** Report last change may be null. */
public void reportNullLastChange() {
server.register(reportsUri + "/" + id, builder.buildReportNode(id, name, description, owner, null).toString());
Report report = service.loadReport(id);
assertNull(report.getLastChange());
}
/** Report last change may be missing. */
public void reportWithoutLastChange() {
ObjectNode node = builder.buildReportNode(id, name, description, owner, lastChange);
node.remove("lastChange");
server.register(reportsUri + "/" + id, node.toString());
Report report = service.loadReport(id);
assertNull(report.getLastChange());
}
/** Report last change may be invalid format. */
public void reportInvalidLastChange() {
server.register(reportsUri + "/" + id,
builder.buildReportNode(id, name, description, owner, "something invalid").toString());
Report report = service.loadReport(id);
assertNull(report.getLastChange());
}
/** Report can be loaded from a report info object. */
public void loadReportFromInfo() {
String idRep = "id2";
String nameRep = "name2";
String descRep = "desc2";
String ownerRep = "owner2";
String lastChangeRep = "Tue, 17 Apr 2012 11:18:27 GMT";
registerSingleReport(builder.buildReportNode(id, name, description, owner, lastChange));
server.register(reportsUri + "/" + id,
builder.buildReportNode(idRep, nameRep, descRep, ownerRep, lastChangeRep).toString());
Report report = service.getReportInfo().load().get(0).loadDetails();
assertEquals(report.getId(), idRep);
assertEquals(report.getName(), nameRep);
assertEquals(report.getDescription(), descRep);
assertEquals(report.getOwnerName(), ownerRep);
Calendar expectedChange = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
expectedChange.set(2012, 3, 17, 11, 18, 27);
expectedChange.set(Calendar.MILLISECOND, 0);
assertEquals(report.getLastChange(), expectedChange.getTime());
assertEquals(report.getViews(), Collections.emptyList());
}
/** Invalid JSON. */
@Test(expectedExceptions = InvalidJsonException.class)
public void loadInvalidJson() throws InvalidJsonException {
registerSingleReport(builder.buildReportNode(id, name, description, owner, lastChange));
server.register(reportsUri + "/" + id, "invalid JSON");
service.getReportInfo().load().get(0).loadDetails();
}
/** Can load a report's thumbnail from service. */
public void loadThumbnailFromService() {
server.register(reportsUri + "/" + id + "/thumbnail", new TestRequestHandler() {
@Override
protected void handle(HttpHolder holder) throws IOException {
holder.response.setEntity(new InputStreamEntity(getTestImageStream()));
}
});
BufferedImage thumbnail = (BufferedImage) service.loadReportThumbnail(id);
server.assertRequestUris(reportsUri + "/" + id + "/thumbnail");
assertEquals(thumbnail.getWidth(), 56);
assertEquals(thumbnail.getHeight(), 46);
}
/** Can load a report's thumbnail from info. */
public void loadThumbnailFromReportInfo() {
ReportInfo reportInfo = new ReportInfoImpl(service, builder.buildReportNode(id, name, description, owner, lastChange));
server.register(reportsUri + "/" + id + "/thumbnail", new TestRequestHandler() {
@Override
protected void handle(HttpHolder holder) throws IOException {
holder.response.setEntity(new InputStreamEntity(getTestImageStream()));
}
});
BufferedImage thumbnail = (BufferedImage) reportInfo.loadThumbnail();
server.assertRequestUris(reportsUri + "/" + id + "/thumbnail");
assertEquals(thumbnail.getWidth(), 56);
assertEquals(thumbnail.getHeight(), 46);
}
/** Invalid thumbnail results in exception. */
@Test(expectedExceptions = InvalidStreamException.class)
public void loadInvalidThumbnail() throws InvalidStreamException {
ReportInfo reportInfo = new ReportInfoImpl(service, builder.buildReportNode(id, name, description, owner, lastChange));
server.register(reportsUri + "/" + id + "/thumbnail", "not a thumbnail image");
reportInfo.loadThumbnail();
}
/** equals/hashcode for report info */
public void reportInfoEquality() {
ReportInfo r1 = new ReportInfoImpl(service, builder.buildReportNode(id, name, description, owner, lastChange));
ReportInfo r2 = new ReportInfoImpl(service, builder.buildReportNode(id, "", "", "", null));
ReportInfo r3 = new ReportInfoImpl(service, builder.buildReportNode("otherId", name, description, owner, lastChange));
assertEquals(r1, r2);
assertEquals(r1.hashCode(), r2.hashCode());
assertFalse(r1.equals(new Object()));
assertNotEquals(r1, r3);
}
/** equals/hashcode for report */
public void reportEquality() {
Report r1 = new ReportImpl(service, builder.buildReportNode(id, name, description, owner, lastChange));
Report r2 = new ReportImpl(service, builder.buildReportNode(id, "", "", "", null));
Report r3 = new ReportImpl(service, builder.buildReportNode("otherId", name, description, owner, lastChange));
assertEquals(r1, r2);
assertEquals(r1.hashCode(), r2.hashCode());
assertFalse(r1.equals(new Object()));
assertNotEquals(r1, r3);
}
/** underlying data sets are loaded for reports */
public void reportDataSet() {
String idDS = "id2";
String nameDS = "name2";
String descDS = "desc2";
String ownerDS = "owner2";
String lastChangeDS = "Tue, 17 Apr 2012 11:18:27 GMT";
ObjectNode reportNode = builder.buildReportNode(id, name, description, owner, lastChange);
ObjectNode dataSetNode = builder.buildDataSetNode(idDS, nameDS, descDS, ownerDS, lastChangeDS);
((ObjectNode) reportNode.get("dataSet")).putAll(dataSetNode);
server.register(reportsUri + "/" + id, reportNode.toString());
Report report = service.loadReport(id);
DataSetInfo dataSet = report.getDataSet();
assertEquals(dataSet.getId(), idDS);
assertEquals(dataSet.getName(), nameDS);
assertEquals(dataSet.getDescription(), descDS);
assertEquals(dataSet.getOwnerName(), ownerDS);
Calendar expectedChange = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
expectedChange.set(2012, 3, 17, 11, 18, 27);
expectedChange.set(Calendar.MILLISECOND, 0);
assertEquals(dataSet.getLastChange(), expectedChange.getTime());
}
/** incomplete data set information is ignored */
public void incompleteDataSet() {
server.register(reportsUri + "/" + id, builder.buildReportNode(id, name, description, owner, lastChange).toString());
assertNull(service.loadReport(id).getDataSet());
}
/** missing data set information is ignored */
public void missingDataSet() {
ObjectNode reportNode = builder.buildReportNode(id, name, description, owner, lastChange);
reportNode.remove("dataSet");
server.register(reportsUri + "/" + id, reportNode.toString());
assertNull(service.loadReport(id).getDataSet());
}
/** data set details can be loaded from a report's data set info */
public void reportDataSetLoadDetails() {
ObjectNode reportNode = builder.buildReportNode(id, name, description, owner, lastChange);
ObjectNode dataSetNode = builder.buildDataSetNode(id, name, description, owner, lastChange);
((ObjectNode) reportNode.get("dataSet")).putAll(dataSetNode);
server.register(reportsUri + "/" + id, reportNode.toString());
server.register("/api/dataSets/" + id, dataSetNode.toString());
Report report = service.loadReport(id);
DataSetInfo dataSet = report.getDataSet();
assertNotNull(dataSet.loadDetails());
server.assertRequestUris(reportsUri + "/" + id, "/api/dataSets/" + id);
}
public void createImageView_fromService() {
registerCreateImage(id, viewId, "50", "100");
String newViewId = service.createImageView(id, "my view name", getTestImageFile(), 50, 100);
assertEquals(newViewId, viewId);
}
public void createImageView_fromReport() {
server.register(reportsUri + "/" + id, builder.buildReportNode(id, name, description, owner, lastChange).toString());
Report report = service.loadReport(id);
registerCreateImage(id, viewId, "30", "500");
String newViewId = report.createImageView("my view name", getTestImageFile(), 30, 500);
assertEquals(newViewId, viewId);
}
public void createImageView_fromReportInfo() {
registerSingleReport(builder.buildReportNode(id, name, description, owner, lastChange));
server.register(reportsUri + "/" + id, builder.buildReportNode(id, name, description, owner, lastChange).toString());
ReportInfo reportInfo = service.getReportInfo().load().get(0);
registerCreateImage(id, viewId, null, null);
String newViewId = reportInfo.createImageView("my view name", getTestImageFile(), null, null);
assertEquals(newViewId, viewId);
}
private void registerCreateImage(String reportId, String viewId, String width, String height) {
server.register(reportsUri + "/" + reportId + "/images", new TestRequestHandler() {
@Override
protected void handle(HttpHolder holder) throws IOException {
if (width != null) {
assertEquals(holder.getUrlParameters().get("width"), width);
}
if (height != null) {
assertEquals(holder.getUrlParameters().get("height"), height);
}
holder.response.setEntity(new StringEntity(viewId));
}
});
}
/**
* Tells the server to return the specified node as the only report node in
* a <tt>reports</tt> array.
*
* @param node the node to return
*/
private void registerSingleReport(JsonNode node) {
server.registerPaginatedItem(reportsUri, "reports", node);
}
}