package eu.dnetlib.iis.wf.export.actionmanager.sequencefile;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import com.googlecode.protobuf.format.JsonFormat;
import eu.dnetlib.actionmanager.actions.AtomicAction;
import eu.dnetlib.actionmanager.common.Agent;
import eu.dnetlib.data.proto.OafProtos;
/**
* Field accessor test class.
* @author mhorst
*
*/
public class FieldAccessorTest {
//------------------------ TESTS ---------------------------------
@Test
public void testAccessingValuesUsingDecoder() throws Exception {
FieldAccessor accessor = new FieldAccessor();
accessor.registerDecoder("targetValue", new OafFieldDecoder());
String rawSetId = "rawset-id";
String agentId = "agent-id";
String agentName = "agent-name";
AtomicAction action = new AtomicAction(rawSetId, new Agent(agentId, agentName, Agent.AGENT_TYPE.service));
byte[] decodedTargetValue = decodeTargetValue(new String(
IOUtils.toByteArray(FieldAccessorTest.class
.getResourceAsStream("/eu/dnetlib/iis/wf/export/actionmanager/sequencefile/resultProject.json")),
"utf8"));
action.setTargetValue(decodedTargetValue);
assertEquals(rawSetId, accessor.getValue("rawSet", action));
assertEquals(agentId, accessor.getValue("agent.id", action));
assertEquals(agentName, accessor.getValue("agent.name", action));
assertEquals(Agent.AGENT_TYPE.service, accessor.getValue("agent.type", action));
assertEquals("relation", accessor.getValue("$targetValue.kind", action).toString());
assertEquals("resultProject", accessor.getValue("$targetValue.rel.relType", action).toString());
}
@Test(expected=FieldAccessorException.class)
public void testAccessingValuesForInvalidPath() throws Exception {
FieldAccessor accessor = new FieldAccessor();
accessor.registerDecoder("targetValue", new OafFieldDecoder());
String rawSetId = "rawset-id";
String agentId = "agent-id";
String agentName = "agent-name";
AtomicAction action = new AtomicAction(rawSetId, new Agent(agentId, agentName,
Agent.AGENT_TYPE.service));
accessor.getValue("agent.unknown", action);
}
@Test
public void testAccessingNullValue() throws Exception {
FieldAccessor accessor = new FieldAccessor();
accessor.registerDecoder("targetValue", new OafFieldDecoder());
AtomicAction action = new AtomicAction(null, new Agent("agent-id", "agent-name",
Agent.AGENT_TYPE.service));
assertNull(accessor.getValue("rawSet", action));
}
@Test
public void testAccessingArrayElement() throws Exception {
FieldAccessor accessor = new FieldAccessor();
ArrayWrapper object = new ArrayWrapper(new String[] {"name-1","name-2"});
assertEquals("name-1", accessor.getValue("names[0]", object));
assertEquals("name-2", accessor.getValue("names[1]", object));
}
@Test(expected=FieldAccessorException.class)
public void testAccessingNonExistingArrayElement() throws Exception {
FieldAccessor accessor = new FieldAccessor();
ArrayWrapper object = new ArrayWrapper(new String[] {"name-1","name-2"});
accessor.getValue("names[2]", object);
}
@Test
public void testAccessingArrayElementWithInvalidPath() throws Exception {
FieldAccessor accessor = new FieldAccessor();
ArrayWrapper object = new ArrayWrapper(new String[] {"name-1", "name-2"});
try {
assertEquals("name-1", accessor.getValue("names[[0]", object));
fail("Exception should be thrown when accessing array with invalid field path");
} catch(FieldAccessorException e) {
// OK
}
try {
assertEquals("name-1", accessor.getValue("names[", object));
fail("Exception should be thrown when accessing array with invalid field path");
} catch(FieldAccessorException e) {
// OK
}
try {
assertEquals("name-1", accessor.getValue("names]", object));
fail("Exception should be thrown when accessing array with invalid field path");
} catch(FieldAccessorException e) {
// OK
}
// we should be able to handle this scenario
assertEquals("name-1", accessor.getValue("names[0]]", object));
}
@Test
public void testAccessingListElement() throws Exception {
FieldAccessor accessor = new FieldAccessor();
ListWrapper object = new ListWrapper(Arrays.asList(new String[] {"name-1", "name-2"}));
assertEquals("name-1", accessor.getValue("names[0]", object));
assertEquals("name-2", accessor.getValue("names[1]", object));
}
@Test(expected=FieldAccessorException.class)
public void testAccessingNonExistingListElement() throws Exception {
FieldAccessor accessor = new FieldAccessor();
ListWrapper object = new ListWrapper(Arrays.asList(new String[] {"name-1", "name-2"}));
accessor.getValue("names[2]", object);
}
@Test
public void testAccessingDecodedArrayElement() throws Exception {
FieldAccessor accessor = new FieldAccessor();
accessor.registerDecoder("names", new ArrayProducingDecoder(new String[] {"decoded-1", "decoded-2"}));
ArrayWrapper object = new ArrayWrapper(new String[] {"name-1","name-2"});
assertEquals("decoded-1", accessor.getValue("$names[0]", object));
assertEquals("decoded-2", accessor.getValue("$names[1]", object));
}
@Test
public void testAccessingValuesWithPropertyUtils() throws Exception {
String[] array = new String[] {"name-1","name-2"};
ArrayWrapper object = new ArrayWrapper(array);
assertEquals(array, PropertyUtils.getProperty(object, "names"));
assertEquals("name-1", PropertyUtils.getIndexedProperty(object, "names", 0));
}
//------------------------ PRIVATE -------------------------------
private byte[] decodeTargetValue(final String json) throws Exception {
OafProtos.Oaf.Builder oaf = OafProtos.Oaf.newBuilder();
JsonFormat.merge(json, oaf);
return oaf.build().toByteArray();
}
//------------------------ INNER CLASSES ------------------------
public static class ArrayWrapper {
final String[] _names;
public ArrayWrapper(String[] names) {
this._names = names;
}
public String[] getNames() {
return _names;
}
}
public static class ListWrapper {
private List<String> _names;
public void setNames(List<String> names) {
this._names = names;
}
public ListWrapper(List<String> names) {
this._names = names;
}
public List<String> getNames() {
return _names;
}
}
public static class ArrayProducingDecoder implements FieldDecoder {
String[] predefinedArray;
public ArrayProducingDecoder(String[] predefinedArray) {
this.predefinedArray = predefinedArray;
}
@Override
public Object decode(Object source) throws FieldDecoderException {
return predefinedArray;
}
@Override
public boolean canHandle(Object source) {
return true;
}
}
}