package com.belladati.sdk.dataset.impl; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotEquals; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.belladati.sdk.dataset.Attribute; import com.belladati.sdk.dataset.AttributeType; import com.belladati.sdk.dataset.AttributeValue; import com.belladati.sdk.dataset.DataSet; import com.belladati.sdk.dataset.Indicator; import com.belladati.sdk.dataset.IndicatorType; import com.belladati.sdk.dataset.data.DataColumn; import com.belladati.sdk.dataset.data.DataTable; import com.belladati.sdk.dataset.impl.DataSetImpl; import com.belladati.sdk.exception.dataset.data.NoColumnsException; import com.belladati.sdk.exception.impl.InvalidIndicatorException; import com.belladati.sdk.test.SDKTest; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; @Test public class DataSetStructureTest extends SDKTest { private final String dataSetsUri = "/api/dataSets"; private final String dataSetId = "123"; private final String name = "name"; private final String description = "data set description"; private final String owner = "data set owner"; private final String lastChange = "Mon, 16 Apr 2012 10:17:26 GMT"; private final String id = "id"; private final String code = "code"; private final String formula = "some formula"; /** No attributes field means no attributes. */ public void attributesMissing() { server.register(dataSetsUri + "/" + dataSetId, builder.buildDataSetNode(dataSetId, name, description, owner, lastChange).toString()); DataSet dataSet = service.loadDataSet(dataSetId); assertEquals(dataSet.getAttributes(), Collections.emptyList()); } /** Empty attributes array means no attributes. */ public void attributesEmpty() { ObjectNode node = builder.buildDataSetNode(dataSetId, name, description, owner, lastChange); node.put("attributes", new ObjectMapper().createArrayNode()); server.register(dataSetsUri + "/" + dataSetId, node.toString()); DataSet dataSet = service.loadDataSet(dataSetId); assertEquals(dataSet.getAttributes(), Collections.emptyList()); } /** Invalid attributes are ignored. */ @Test(dataProvider = "invalidAttributes") public void attributeInvalid(JsonNode attribute) { ObjectNode node = builder.buildDataSetNode(dataSetId, name, description, owner, lastChange); node.put("attributes", new ObjectMapper().createArrayNode().add(attribute)); server.register(dataSetsUri + "/" + dataSetId, node.toString()); DataSet dataSet = service.loadDataSet(dataSetId); assertEquals(dataSet.getAttributes(), Collections.emptyList()); } /** Valid attribute types are parsed correctly. */ @Test(dataProvider = "attributeTypes") public void attributeTypes(String jsonType, AttributeType type) { ObjectNode node = builder.buildDataSetNode(dataSetId, name, description, owner, lastChange); node.put("attributes", new ObjectMapper().createArrayNode().add(builder.buildAttributeNode(id, name, code, jsonType))); server.register(dataSetsUri + "/" + dataSetId, node.toString()); DataSet dataSet = service.loadDataSet(dataSetId); assertEquals(dataSet.getAttributes().size(), 1); Attribute attribute = dataSet.getAttributes().get(0); assertEquals(attribute.getId(), id); assertEquals(attribute.getName(), name); assertEquals(attribute.getCode(), code); assertEquals(attribute.getType(), type); } /** data set attributes can load values just like report attributes */ @Test public void loadAttributeValues() { ObjectNode node = builder.buildDataSetNode(dataSetId, name, description, owner, lastChange); node.put("attributes", new ObjectMapper().createArrayNode().add(builder.buildAttributeNode(id, name, code, "string"))); server.register(dataSetsUri + "/" + dataSetId, node.toString()); DataSet dataSet = service.loadDataSet(dataSetId); Attribute attribute = dataSet.getAttributes().get(0); String label = "label"; String value = "value"; final ObjectNode valueNode = new ObjectMapper().createObjectNode(); valueNode.put("values", new ObjectMapper().createArrayNode().add(builder.buildAttributeValueNode(label, value))); server.register(dataSetsUri + "/" + dataSetId + "/attributes/" + code + "/values", valueNode.toString()); List<AttributeValue> values = attribute.getValues().load().get(); assertEquals(values.size(), 1); assertEquals(values.get(0).getLabel(), label); assertEquals(values.get(0).getValue(), value); assertEquals(attribute.toString(), name); assertEquals(values.get(0).toString(), label); } /** No indicators field means no indicators. */ public void indicatorsMissing() { server.register(dataSetsUri + "/" + dataSetId, builder.buildDataSetNode(dataSetId, name, description, owner, lastChange).toString()); DataSet dataSet = service.loadDataSet(dataSetId); assertEquals(dataSet.getIndicators(), Collections.emptyList()); } /** Empty indicators array means no indicators. */ public void indicatorsEmpty() { ObjectNode node = builder.buildDataSetNode(dataSetId, name, description, owner, lastChange); node.put("indicators", new ObjectMapper().createArrayNode()); server.register(dataSetsUri + "/" + dataSetId, node.toString()); DataSet dataSet = service.loadDataSet(dataSetId); assertEquals(dataSet.getIndicators(), Collections.emptyList()); } /** Invalid indicators are ignored. */ @Test(dataProvider = "invalidIndicators") public void indicatorInvalid(JsonNode indicator) { ObjectNode node = builder.buildDataSetNode(dataSetId, name, description, owner, lastChange); node.put("indicators", new ObjectMapper().createArrayNode().add(indicator)); server.register(dataSetsUri + "/" + dataSetId, node.toString()); DataSet dataSet = service.loadDataSet(dataSetId); assertEquals(dataSet.getIndicators(), Collections.emptyList()); } /** Data indicators are parsed correctly. */ public void dataIndicator() { ObjectNode node = builder.buildDataSetNode(dataSetId, name, description, owner, lastChange); node.put("indicators", new ObjectMapper().createArrayNode().add(builder.buildIndicatorNode(id, name, code, formula, "data_indicator"))); server.register(dataSetsUri + "/" + dataSetId, node.toString()); DataSet dataSet = service.loadDataSet(dataSetId); assertEquals(dataSet.getIndicators().size(), 1); Indicator indicator = dataSet.getIndicators().get(0); assertEquals(indicator.getId(), id); assertEquals(indicator.getName(), name); assertEquals(indicator.getCode(), code); assertEquals(indicator.getFormula(), null); assertEquals(indicator.getType(), IndicatorType.DATA); } /** equals and hashcode work as expected for indicators */ public void indicatorEquality() throws InvalidIndicatorException { IndicatorImpl att1 = new IndicatorImpl(builder.buildIndicatorNode(id, name, code, formula, "formula_indicator")); IndicatorImpl att2 = new IndicatorImpl(builder.buildIndicatorNode(id, "", "", "", "formula_indicator")); IndicatorImpl att3 = new IndicatorImpl(builder.buildIndicatorNode("otherId", "", "", "", "formula_indicator")); assertEquals(att1, att2); assertEquals(att1.hashCode(), att2.hashCode()); assertNotEquals(att1, att3); assertFalse(att1.equals(new Object())); } /** Formula indicators are parsed correctly. */ public void formulaIndicator() { ObjectNode node = builder.buildDataSetNode(dataSetId, name, description, owner, lastChange); node.put("indicators", new ObjectMapper().createArrayNode().add(builder.buildIndicatorNode(id, name, code, formula, "formula_indicator"))); server.register(dataSetsUri + "/" + dataSetId, node.toString()); DataSet dataSet = service.loadDataSet(dataSetId); assertEquals(dataSet.getIndicators().size(), 1); Indicator indicator = dataSet.getIndicators().get(0); assertEquals(indicator.getId(), id); assertEquals(indicator.getName(), name); assertEquals(indicator.getCode(), null); assertEquals(indicator.getFormula(), formula); assertEquals(indicator.getType(), IndicatorType.FORMULA); } /** Indicator groups are parsed correctly. */ public void groupIndicator() { ObjectNode node = builder.buildDataSetNode(dataSetId, name, description, owner, lastChange); node.put("indicators", new ObjectMapper().createArrayNode().add(builder.buildIndicatorNode(id, name, code, formula, "indicator_group"))); server.register(dataSetsUri + "/" + dataSetId, node.toString()); DataSet dataSet = service.loadDataSet(dataSetId); assertEquals(dataSet.getIndicators().size(), 1); Indicator indicator = dataSet.getIndicators().get(0); assertEquals(indicator.getId(), id); assertEquals(indicator.getName(), name); assertEquals(indicator.getCode(), null); assertEquals(indicator.getFormula(), null); assertEquals(indicator.getType(), IndicatorType.GROUP); } /** data set without columns can't create import table */ @Test(expectedExceptions = NoColumnsException.class) public void emptyDataSetTable() { DataSet dataSet = new DataSetImpl(service, builder.buildDataSetNode(id, name, description, owner, lastChange)); dataSet.createDataTable(); } /** data set can create import table */ public void dataSetTable() { String attributeCode = "A"; String indicatorCode = "I"; ObjectNode node = builder.buildDataSetNode(dataSetId, name, description, owner, lastChange); node.put("attributes", new ObjectMapper().createArrayNode().add(builder.buildAttributeNode(id, name, attributeCode, "String"))); node.put("indicators", new ObjectMapper().createArrayNode() .add(builder.buildIndicatorNode(id, name, indicatorCode, formula, "data_indicator"))); DataTable table = new DataSetImpl(service, node).createDataTable(); assertEquals(table.getColumns(), Arrays.asList(new DataColumn(attributeCode), new DataColumn(indicatorCode))); } /** Provides attribute JSON that's invalid in some way. */ @DataProvider(name = "invalidAttributes") protected Object[][] invalidAttributeProvider() { String id = "id"; String name = "name"; String code = "code"; String type = "String"; // invalid is if code or name is null or doesn't exist return new Object[][] { { builder.buildAttributeNode(null, name, code, type) }, { builder.buildAttributeNode(id, null, code, type) }, { builder.buildAttributeNode(id, name, null, type) }, { builder.buildAttributeNode(id, name, code, null) }, { builder.buildAttributeNode(id, name, code, type).retain("name", "code", "type") }, { builder.buildAttributeNode(id, name, code, type).retain("id", "code", "type") }, { builder.buildAttributeNode(id, name, code, type).retain("id", "name", "type") }, { builder.buildAttributeNode(id, name, code, type).retain("id", "name", "code") }, { builder.buildAttributeNode(id, name, code, "other_type") } }; } /** Provides attribute types and corresponding enum items. */ @DataProvider(name = "attributeTypes") protected Object[][] attributeTypeProvider() { return new Object[][] { { "String", AttributeType.TEXT }, { "Date", AttributeType.DATE }, { "Time", AttributeType.TIME }, { "Point", AttributeType.GEO_POINT }, { "sTRING", AttributeType.TEXT } }; } /** Provides indicator JSON that's invalid in some way. */ @DataProvider(name = "invalidIndicators") protected Object[][] invalidIndicatorProvider() { String id = "id"; String name = "name"; String code = "code"; String formula = "formula"; String type = "indicator_group"; // invalid is if code or name is null or doesn't exist return new Object[][] { { builder.buildIndicatorNode(null, name, code, formula, type) }, { builder.buildIndicatorNode(id, null, code, formula, type) }, { builder.buildIndicatorNode(id, name, null, formula, "data_indicator") }, { builder.buildIndicatorNode(id, name, code, null, "formula_indicator") }, { builder.buildIndicatorNode(id, name, code, formula, null) }, { builder.buildIndicatorNode(id, name, code, formula, type).retain("name", "type") }, { builder.buildIndicatorNode(id, name, code, formula, type).retain("id", "type") }, { builder.buildIndicatorNode(id, name, code, formula, type).retain("id", "name") }, { builder.buildIndicatorNode(id, name, code, formula, "data_indicator").retain("id", "name", "type") }, { builder.buildIndicatorNode(id, name, code, formula, "formula_indicator").retain("id", "name", "type") }, { builder.buildIndicatorNode(id, name, code, formula, "other_type") } }; } }