diff --git a/src/main/java/org/javarosa/entities/Entity.java b/src/main/java/org/javarosa/entities/Entity.java deleted file mode 100644 index 38dcea514..000000000 --- a/src/main/java/org/javarosa/entities/Entity.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.javarosa.entities; - -import kotlin.Pair; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class Entity { - - public final String dataset; - public final List> properties; - - @Nullable - public final String id; - - @Nullable - public final String label; - - public final Integer version; - public final EntityAction action; - - public Entity(EntityAction action, String dataset, @Nullable String id, @Nullable String label, Integer version, List> properties) { - this.dataset = dataset; - this.id = id; - this.label = label; - this.version = version; - this.properties = properties; - this.action = action; - } -} diff --git a/src/main/java/org/javarosa/entities/EntityAction.java b/src/main/java/org/javarosa/entities/EntityAction.java deleted file mode 100644 index 52f9be9e6..000000000 --- a/src/main/java/org/javarosa/entities/EntityAction.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.javarosa.entities; - -public enum EntityAction { - CREATE, - UPDATE -} diff --git a/src/main/java/org/javarosa/entities/EntityFormFinalizationProcessor.java b/src/main/java/org/javarosa/entities/EntityFormFinalizationProcessor.java deleted file mode 100644 index 823bffe48..000000000 --- a/src/main/java/org/javarosa/entities/EntityFormFinalizationProcessor.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.javarosa.entities; - -import kotlin.Pair; -import org.javarosa.core.model.FormDef; -import org.javarosa.core.model.IDataReference; -import org.javarosa.core.model.data.IAnswerData; -import org.javarosa.core.model.instance.FormInstance; -import org.javarosa.core.model.instance.TreeElement; -import org.javarosa.entities.internal.Entities; -import org.javarosa.entities.internal.EntityFormExtra; -import org.javarosa.entities.internal.EntityFormParser; -import org.javarosa.form.api.FormEntryFinalizationProcessor; -import org.javarosa.form.api.FormEntryModel; -import org.javarosa.model.xform.XPathReference; - -import java.util.List; -import java.util.stream.Collectors; - -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; - -public class EntityFormFinalizationProcessor implements FormEntryFinalizationProcessor { - - @Override - public void processForm(FormEntryModel formEntryModel) { - FormDef formDef = formEntryModel.getForm(); - FormInstance mainInstance = formDef.getMainInstance(); - - EntityFormExtra entityFormExtra = formDef.getExtras().get(EntityFormExtra.class); - List> saveTos = entityFormExtra.getSaveTos(); - - TreeElement entityElement = EntityFormParser.getEntityElement(mainInstance); - if (entityElement != null) { - EntityAction action = EntityFormParser.parseAction(entityElement); - String dataset = EntityFormParser.parseDataset(entityElement); - - if (action == EntityAction.CREATE) { - Entity entity = createEntity(entityElement, 1, dataset, saveTos, mainInstance, action); - formEntryModel.getExtras().put(new Entities(asList(entity))); - } else if (action == EntityAction.UPDATE){ - int baseVersion = EntityFormParser.parseBaseVersion(entityElement); - int newVersion = baseVersion + 1; - Entity entity = createEntity(entityElement, newVersion, dataset, saveTos, mainInstance, action); - formEntryModel.getExtras().put(new Entities(asList(entity))); - } else { - formEntryModel.getExtras().put(new Entities(emptyList())); - } - } - } - - private Entity createEntity(TreeElement entityElement, int version, String dataset, List> saveTos, FormInstance mainInstance, EntityAction action) { - List> fields = saveTos.stream().map(saveTo -> { - IDataReference reference = saveTo.getFirst(); - IAnswerData answerData = mainInstance.resolveReference(reference).getValue(); - - if (answerData != null) { - return new Pair<>(saveTo.getSecond(), answerData.getDisplayText()); - } else { - return new Pair<>(saveTo.getSecond(), ""); - } - }).collect(Collectors.toList()); - - String id = EntityFormParser.parseId(entityElement); - String label = EntityFormParser.parseLabel(entityElement); - return new Entity(action, dataset, id, label, version, fields); - } -} diff --git a/src/main/java/org/javarosa/entities/EntityXFormParserFactory.java b/src/main/java/org/javarosa/entities/EntityXFormParserFactory.java deleted file mode 100644 index 4ee8cd4ac..000000000 --- a/src/main/java/org/javarosa/entities/EntityXFormParserFactory.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.javarosa.entities; - -import org.javarosa.entities.internal.EntityFormParseProcessor; -import org.javarosa.xform.parse.IXFormParserFactory; -import org.javarosa.xform.parse.XFormParser; -import org.jetbrains.annotations.NotNull; - -public class EntityXFormParserFactory extends IXFormParserFactory.Wrapper { - - public EntityXFormParserFactory(IXFormParserFactory base) { - super(base); - } - - @Override - public XFormParser apply(@NotNull XFormParser xFormParser) { - EntityFormParseProcessor processor = new EntityFormParseProcessor(); - xFormParser.addProcessor(processor); - - return xFormParser; - } -} diff --git a/src/main/java/org/javarosa/entities/UnrecognizedEntityVersionException.java b/src/main/java/org/javarosa/entities/UnrecognizedEntityVersionException.java deleted file mode 100644 index e5f9b74ff..000000000 --- a/src/main/java/org/javarosa/entities/UnrecognizedEntityVersionException.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.javarosa.entities; - -import org.javarosa.xform.parse.XFormParser; - -public class UnrecognizedEntityVersionException extends XFormParser.ParseException { -} diff --git a/src/main/java/org/javarosa/entities/internal/Entities.java b/src/main/java/org/javarosa/entities/internal/Entities.java deleted file mode 100644 index 9064e9a2a..000000000 --- a/src/main/java/org/javarosa/entities/internal/Entities.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.javarosa.entities.internal; - -import org.javarosa.entities.Entity; - -import java.util.List; - -public class Entities { - - private final List entities; - - public Entities(List entities) { - this.entities = entities; - } - - public List getEntities() { - return entities; - } -} diff --git a/src/main/java/org/javarosa/entities/internal/EntityConstants.java b/src/main/java/org/javarosa/entities/internal/EntityConstants.java deleted file mode 100644 index 81edc3f27..000000000 --- a/src/main/java/org/javarosa/entities/internal/EntityConstants.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.javarosa.entities.internal; - -public class EntityConstants { - - private EntityConstants() {} - - public static final String ELEMENT_ENTITY = "entity"; - public static final String ELEMENT_LABEL = "label"; - - public static final String ATTRIBUTE_DATASET = "dataset"; - public static final String ATTRIBUTE_ID = "id"; - public static final String ATTRIBUTE_BASE_VERSION = "baseVersion"; - public static final String ATTRIBUTE_CREATE = "create"; - public static final String ATTRIBUTE_UPDATE = "update"; -} diff --git a/src/main/java/org/javarosa/entities/internal/EntityFormExtra.java b/src/main/java/org/javarosa/entities/internal/EntityFormExtra.java deleted file mode 100644 index 8b370a931..000000000 --- a/src/main/java/org/javarosa/entities/internal/EntityFormExtra.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.javarosa.entities.internal; - -import kotlin.Pair; -import org.javarosa.core.util.externalizable.DeserializationException; -import org.javarosa.core.util.externalizable.ExtUtil; -import org.javarosa.core.util.externalizable.ExtWrapMap; -import org.javarosa.core.util.externalizable.Externalizable; -import org.javarosa.core.util.externalizable.PrototypeFactory; -import org.javarosa.model.xform.XPathReference; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class EntityFormExtra implements Externalizable { - - private List> saveTos = new ArrayList<>(); - - public EntityFormExtra() { - } - - public EntityFormExtra(List> saveTos) { - this.saveTos = saveTos; - } - - public List> getSaveTos() { - return saveTos; - } - - @Override - public void readExternal(DataInputStream in, PrototypeFactory pf) throws IOException, DeserializationException { - HashMap saveToMap = (HashMap) ExtUtil.read(in, new ExtWrapMap(XPathReference.class, String.class), pf); - saveTos = saveToMap.entrySet().stream().map(entry -> new Pair<>(entry.getKey(), entry.getValue())).collect(Collectors.toList()); - } - - @Override - public void writeExternal(DataOutputStream out) throws IOException { - Map saveTosMap = saveTos.stream() - .collect(Collectors.toMap(Pair::getFirst, Pair::getSecond)); - ExtUtil.write(out, new ExtWrapMap(new HashMap<>(saveTosMap))); - } -} diff --git a/src/main/java/org/javarosa/entities/internal/EntityFormParseProcessor.java b/src/main/java/org/javarosa/entities/internal/EntityFormParseProcessor.java deleted file mode 100644 index 31b3a3688..000000000 --- a/src/main/java/org/javarosa/entities/internal/EntityFormParseProcessor.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.javarosa.entities.internal; - -import kotlin.Pair; -import org.javarosa.core.model.DataBinding; -import org.javarosa.core.model.FormDef; -import org.javarosa.entities.UnrecognizedEntityVersionException; -import org.javarosa.model.xform.XPathReference; -import org.javarosa.xform.parse.XFormParser; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Stream; - -public class EntityFormParseProcessor implements XFormParser.BindAttributeProcessor, XFormParser.FormDefProcessor, XFormParser.ModelAttributeProcessor { - - private static final String ENTITIES_NAMESPACE = "http://www.opendatakit.org/xforms/entities"; - private static final String[] SUPPORTED_VERSIONS = {"2022.1", "2023.1"}; - - private final List> saveTos = new ArrayList<>(); - private boolean versionPresent; - - @Override - public Set> getModelAttributes() { - HashSet> attributes = new HashSet<>(); - attributes.add(new Pair<>(ENTITIES_NAMESPACE, "entities-version")); - - return attributes; - } - - @Override - public void processModelAttribute(String name, String value) throws XFormParser.ParseException { - versionPresent = true; - - if (Stream.of(SUPPORTED_VERSIONS).noneMatch(value::startsWith)) { - throw new UnrecognizedEntityVersionException(); - } - } - - @Override - public Set> getBindAttributes() { - HashSet> attributes = new HashSet<>(); - attributes.add(new Pair<>(ENTITIES_NAMESPACE, "saveto")); - - return attributes; - } - - @Override - public void processBindAttribute(String name, String value, DataBinding binding) { - saveTos.add(new Pair<>((XPathReference) binding.getReference(), value)); - } - - @Override - public void processFormDef(FormDef formDef) throws XFormParser.ParseException { - if (!versionPresent && EntityFormParser.getEntityElement(formDef.getMainInstance()) != null) { - throw new XFormParser.MissingModelAttributeException(ENTITIES_NAMESPACE, "entities-version"); - } - - EntityFormExtra entityFormExtra = new EntityFormExtra(saveTos); - formDef.getExtras().put(entityFormExtra); - } -} diff --git a/src/main/java/org/javarosa/entities/internal/EntityFormParser.java b/src/main/java/org/javarosa/entities/internal/EntityFormParser.java deleted file mode 100644 index 8a5dcff41..000000000 --- a/src/main/java/org/javarosa/entities/internal/EntityFormParser.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.javarosa.entities.internal; - -import org.javarosa.core.model.data.IAnswerData; -import org.javarosa.core.model.instance.FormInstance; -import org.javarosa.core.model.instance.TreeElement; -import org.javarosa.entities.EntityAction; -import org.javarosa.xpath.expr.XPathFuncExpr; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import static org.javarosa.entities.internal.EntityConstants.ATTRIBUTE_BASE_VERSION; -import static org.javarosa.entities.internal.EntityConstants.ATTRIBUTE_CREATE; -import static org.javarosa.entities.internal.EntityConstants.ATTRIBUTE_DATASET; -import static org.javarosa.entities.internal.EntityConstants.ATTRIBUTE_ID; -import static org.javarosa.entities.internal.EntityConstants.ATTRIBUTE_UPDATE; -import static org.javarosa.entities.internal.EntityConstants.ELEMENT_ENTITY; -import static org.javarosa.entities.internal.EntityConstants.ELEMENT_LABEL; - -public class EntityFormParser { - - private EntityFormParser() { - - } - - public static String parseDataset(TreeElement entity) { - return entity.getAttributeValue(null, ATTRIBUTE_DATASET); - } - - @Nullable - public static String parseLabel(TreeElement entity) { - TreeElement labelElement = entity.getFirstChild(ELEMENT_LABEL); - - if (labelElement != null) { - IAnswerData labelValue = labelElement.getValue(); - - if (labelValue != null) { - return String.valueOf(labelValue.getValue()); - } else { - return null; - } - } else { - return null; - } - } - - @Nullable - public static String parseId(TreeElement entity) { - return entity.getAttributeValue("", ATTRIBUTE_ID); - } - - public static Integer parseBaseVersion(TreeElement entity) { - try { - return Integer.valueOf(entity.getAttributeValue("", ATTRIBUTE_BASE_VERSION)); - } catch (NumberFormatException e) { - return 0; - } - } - - @Nullable - public static TreeElement getEntityElement(FormInstance mainInstance) { - TreeElement root = mainInstance.getRoot(); - TreeElement meta = root.getFirstChild("meta"); - - if (meta != null) { - return meta.getFirstChild(ELEMENT_ENTITY); - } else { - return null; - } - } - - @Nullable - public static EntityAction parseAction(@NotNull TreeElement entity) { - String create = entity.getAttributeValue(null, ATTRIBUTE_CREATE); - String update = entity.getAttributeValue(null, ATTRIBUTE_UPDATE); - - if (update != null) { - if (XPathFuncExpr.boolStr(update)) { - return EntityAction.UPDATE; - } - } - - if (create != null) { - if (XPathFuncExpr.boolStr(create)) { - return EntityAction.CREATE; - } - } - - return null; - } -} diff --git a/src/test/java/org/javarosa/entities/EntitiesTest.java b/src/test/java/org/javarosa/entities/EntitiesTest.java deleted file mode 100644 index d1e714a59..000000000 --- a/src/test/java/org/javarosa/entities/EntitiesTest.java +++ /dev/null @@ -1,607 +0,0 @@ -package org.javarosa.entities; - -import kotlin.Pair; -import org.javarosa.core.model.instance.TreeElement; -import org.javarosa.test.Scenario; -import org.javarosa.test.XFormsElement; -import org.javarosa.core.util.externalizable.DeserializationException; -import org.javarosa.entities.internal.Entities; -import org.javarosa.xform.parse.XFormParser; -import org.javarosa.xform.parse.XFormParserFactory; -import org.javarosa.xform.util.XFormUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.util.List; - -import static java.util.Arrays.asList; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.javarosa.test.BindBuilderXFormsElement.bind; -import static org.javarosa.test.XFormsElement.body; -import static org.javarosa.test.XFormsElement.head; -import static org.javarosa.test.XFormsElement.input; -import static org.javarosa.test.XFormsElement.item; -import static org.javarosa.test.XFormsElement.mainInstance; -import static org.javarosa.test.XFormsElement.model; -import static org.javarosa.test.XFormsElement.select1; -import static org.javarosa.test.XFormsElement.setvalue; -import static org.javarosa.test.XFormsElement.t; -import static org.javarosa.test.XFormsElement.title; - -public class EntitiesTest { - - private final EntityXFormParserFactory entityXFormParserFactory = new EntityXFormParserFactory(new XFormParserFactory()); - - @Before - public void setup() { - XFormUtils.setXFormParserFactory(entityXFormParserFactory); - } - - @After - public void teardown() { - XFormUtils.setXFormParserFactory(new XFormParserFactory()); - } - - @Test - public void fillingFormWithoutCreate_doesNotCreateAnyEntities() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Entity form"), - model(asList(new Pair<>("entities:entities-version", "2022.1.1")), - mainInstance( - t("data id=\"entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\"") - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name") - ) - ), - body( - input("/data/name") - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - - scenario.next(); - scenario.answer("Tom Wambsgans"); - - scenario.finalizeInstance(); - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(0)); - } - - @Test - public void fillingFormWithCreate_makesEntityAvailable() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("entities:entities-version", "2022.1.1")), - mainInstance( - t("data id=\"create-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\" create=\"1\" id=\"\"", - t("label") - ) - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name"), - bind("/data/meta/entity/@id").type("string"), - bind("/data/meta/entity/label").type("string").calculate("/data/name"), - setvalue("odk-instance-first-load", "/data/meta/entity/@id", "uuid()") - ) - ), - body( - input("/data/name") - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - - scenario.next(); - scenario.answer("Tom Wambsgans"); - - scenario.finalizeInstance(); - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - assertThat(entities.get(0).dataset, equalTo("people")); - assertThat(entities.get(0).id, equalTo(scenario.answerOf("/data/meta/entity/@id").getValue())); - assertThat(entities.get(0).label, equalTo("Tom Wambsgans")); - assertThat(entities.get(0).version, equalTo(1)); - assertThat(entities.get(0).properties, equalTo(asList(new Pair<>("name", "Tom Wambsgans")))); - assertThat(entities.get(0).action, equalTo(EntityAction.CREATE)); - } - - @Test - public void fillingFormWithCreate_withoutAnId_makesEntityAvailable() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("entities:entities-version", "2022.1.1")), - mainInstance( - t("data id=\"create-entity-form\"", - t("id"), - t("name"), - t("meta", - t("entity dataset=\"people\" create=\"1\" id=\"\"", - t("label") - ) - ) - ) - ), - bind("/data/id").type("string"), - bind("/data/meta/entity/@id").type("string").calculate("/data/id"), - bind("/data/meta/entity/label").type("string").calculate("/data/name") - ) - ), - body( - input("/data/id"), - input("/data/name") - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - scenario.finalizeInstance(); - - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - assertThat(entities.get(0).dataset, equalTo("people")); - assertThat(entities.get(0).id, equalTo(null)); - assertThat(entities.get(0).action, equalTo(EntityAction.CREATE)); - } - - @Test - public void fillingFormWithUpdate_makesEntityAvailable() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Update entity form"), - model(asList(new Pair<>("entities:entities-version", "2023.1.0")), - mainInstance( - t("data id=\"update-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\" update=\"1\" id=\"123\" baseVersion=\"1\"", - t("label") - ) - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name"), - bind("/data/meta/entity/@id").type("string"), - bind("/data/meta/entity/label").type("string").calculate("/data/name") - ) - ), - body( - input("/data/name") - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - - scenario.next(); - scenario.answer("Tom Wambsgans"); - - scenario.finalizeInstance(); - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - assertThat(entities.get(0).dataset, equalTo("people")); - assertThat(entities.get(0).id, equalTo("123")); - assertThat(entities.get(0).label, equalTo("Tom Wambsgans")); - assertThat(entities.get(0).version, equalTo(2)); - assertThat(entities.get(0).properties, equalTo(asList(new Pair<>("name", "Tom Wambsgans")))); - assertThat(entities.get(0).action, equalTo(EntityAction.UPDATE)); - } - - @Test - public void fillingFormWithUpdate_andNoLabel_makesEntityAvailableWithNullLabel() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Update entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Update entity form"), - model(asList(new Pair<>("entities:entities-version", "2023.1.0")), - mainInstance( - t("data id=\"update-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\" update=\"1\" id=\"123\" baseVersion=\"1\"") - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name"), - bind("/data/meta/entity/@id").type("string") - ) - ), - body( - input("/data/name") - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - - scenario.next(); - scenario.answer("Tom Wambsgans"); - - scenario.finalizeInstance(); - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - assertThat(entities.get(0).dataset, equalTo("people")); - assertThat(entities.get(0).id, equalTo("123")); - assertThat(entities.get(0).label, equalTo(null)); - assertThat(entities.get(0).version, equalTo(2)); - assertThat(entities.get(0).properties, equalTo(asList(new Pair<>("name", "Tom Wambsgans")))); - } - - @Test - public void fillingFormWithUpdate_withNullId_makesEntityAvailable() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Update entity form"), - model(asList(new Pair<>("entities:entities-version", "2023.1.0")), - mainInstance( - t("data id=\"update-entity-form\"", - t("id"), - t("meta", - t("entity dataset=\"people\" update=\"1\" id=\"\" baseVersion=\"\"") - ) - ) - ), - bind("/data/id").type("string"), - bind("/data/meta/entity/@id").type("string").calculate("/data/id").readonly() - ) - ), - body( - input("/data/id") - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - scenario.finalizeInstance(); - - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - assertThat(entities.get(0).dataset, equalTo("people")); - assertThat(entities.get(0).id, equalTo(null)); - assertThat(entities.get(0).action, equalTo(EntityAction.UPDATE)); - } - - @Test - public void fillingFormWithCreateAndUpdate_makesEntityAvailableAsSecondVersion() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Upsert entity form"), - model(asList(new Pair<>("entities:entities-version", "2023.1.0")), - mainInstance( - t("data id=\"upsert-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\" create=\"1\" update=\"1\" id=\"123\" baseVersion=\"1\"", - t("label") - ) - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name"), - bind("/data/meta/entity/label").type("string").calculate("/data/name") - ) - ), - body( - input("/data/name") - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - - scenario.next(); - scenario.answer("Tom Wambsgans"); - - scenario.finalizeInstance(); - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - assertThat(entities.get(0).dataset, equalTo("people")); - assertThat(entities.get(0).id, equalTo("123")); - assertThat(entities.get(0).label, equalTo("Tom Wambsgans")); - assertThat(entities.get(0).version, equalTo(2)); - assertThat(entities.get(0).properties, equalTo(asList(new Pair<>("name", "Tom Wambsgans")))); - assertThat(entities.get(0).action, equalTo(EntityAction.UPDATE)); - } - - @Test - public void fillingFormWithCreateAndUpdate_butNoBaseVersion_makesEntityAvailableAsFirstVersion() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Upsert entity form"), - model(asList(new Pair<>("entities:entities-version", "2023.1.0")), - mainInstance( - t("data id=\"upsert-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\" create=\"1\" update=\"1\" id=\"123\"", - t("label") - ) - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name"), - bind("/data/meta/entity/label").type("string").calculate("/data/name") - ) - ), - body( - input("/data/name") - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - - scenario.next(); - scenario.answer("Tom Wambsgans"); - - scenario.finalizeInstance(); - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - assertThat(entities.get(0).dataset, equalTo("people")); - assertThat(entities.get(0).id, equalTo("123")); - assertThat(entities.get(0).label, equalTo("Tom Wambsgans")); - assertThat(entities.get(0).version, equalTo(1)); - assertThat(entities.get(0).properties, equalTo(asList(new Pair<>("name", "Tom Wambsgans")))); - assertThat(entities.get(0).action, equalTo(EntityAction.UPDATE)); - } - - @Test - public void fillingFormWithDynamicCreateExpression_conditionallyCreatesEntities() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("entities:entities-version", "2022.1.1")), - mainInstance( - t("data id=\"create-entity-form\"", - t("name"), - t("join"), - t("meta", - t("entity dataset=\"members\" create=\"\" id=\"1\"") - ) - ) - ), - bind("/data/meta/entity/@create").calculate("/data/join = 'yes'"), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name") - ) - ), - body( - input("/data/name"), - select1("/data/join", item("yes", "Yes"), item("no", "No")) - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - - scenario.next(); - scenario.answer("Roman Roy"); - scenario.next(); - scenario.answer(scenario.choicesOf("/data/join").get(0)); - - scenario.finalizeInstance(); - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - - scenario.newInstance(); - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - scenario.next(); - scenario.answer("Roman Roy"); - scenario.next(); - scenario.answer(scenario.choicesOf("/data/join").get(1)); - - scenario.finalizeInstance(); - entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(0)); - } - - @Test - public void entityFormCanBeSerialized() throws IOException, DeserializationException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("entities:entities-version", "2022.1.1")), - mainInstance( - t("data id=\"create-entity-form\"", - t("name"), - t("meta", - t("entities:entity dataset=\"people\" create=\"1\" id=\"1\"") - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name") - ) - ), - body( - input("/data/name") - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - - Scenario deserializedScenario = scenario.serializeAndDeserializeForm(); - deserializedScenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - - deserializedScenario.next(); - deserializedScenario.answer("Shiv Roy"); - - deserializedScenario.finalizeInstance(); - List entities = deserializedScenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - assertThat(entities.get(0).dataset, equalTo("people")); - assertThat(entities.get(0).properties, equalTo(asList(new Pair<>("name", "Shiv Roy")))); - } - - @Test - public void entitiesNamespaceWorksRegardlessOfName() throws IOException, DeserializationException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("blah", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("blah:entities-version", "2022.1.1")), - mainInstance( - t("data id=\"create-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\" create=\"1\" id=\"1\"") - ) - ) - ), - bind("/data/name").type("string").withAttribute("blah", "saveto", "name") - ) - ), - body( - input("/data/name") - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - - scenario.next(); - scenario.answer("Tom Wambsgans"); - - scenario.finalizeInstance(); - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - assertThat(entities.get(0).properties, equalTo(asList(new Pair<>("name", "Tom Wambsgans")))); - } - - @Test - public void fillingFormWithSelectSaveTo_andWithCreate_savesValuesCorrectlyToEntity() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("entities:entities-version", "2022.1.1")), - mainInstance( - t("data id=\"create-entity-form\"", - t("team"), - t("meta", - t("entity dataset=\"people\" create=\"1\" id=\"1\"") - ) - ) - ), - bind("/data/team").type("string").withAttribute("entities", "saveto", "team") - ) - ), - body( - select1("/data/team", item("kendall", "Kendall"), item("logan", "Logan")) - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - - scenario.next(); - scenario.answer(scenario.choicesOf("/data/team").get(0)); - - scenario.finalizeInstance(); - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - assertThat(entities.get(0).properties, equalTo(asList(new Pair<>("team", "kendall")))); - } - - @Test - public void whenSaveToQuestionIsNotAnswered_entityPropertyIsEmptyString() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("entities:entities-version", "2022.1.1")), - mainInstance( - t("data id=\"create-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\" create=\"1\" id=\"1\"") - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name") - ) - ), - body( - input("/data/name") - ) - )); - - scenario.getFormEntryController().addPostProcessor(new EntityFormFinalizationProcessor()); - scenario.finalizeInstance(); - - List entities = scenario.getFormEntryController().getModel().getExtras().get(Entities.class).getEntities(); - assertThat(entities.size(), equalTo(1)); - assertThat(entities.get(0).properties, equalTo(asList(new Pair<>("name", "")))); - } - - @Test - public void savetoIsRemovedFromBindAttributesForClients() throws IOException, XFormParser.ParseException { - Scenario scenario = Scenario.init("Create entity form", XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("entities:entities-version", "2022.1.1")), - mainInstance( - t("data id=\"create-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\" create=\"1\"") - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name") - ) - ), - body( - input("/data/name") - ) - )); - - scenario.next(); - List bindAttributes = scenario.getFormEntryPromptAtIndex().getBindAttributes(); - boolean containsSaveTo = bindAttributes.stream().anyMatch(treeElement -> treeElement.getName().equals("saveto")); - assertThat(containsSaveTo, is(false)); - } -} diff --git a/src/test/java/org/javarosa/entities/EntityFormFinalizationProcessorTest.java b/src/test/java/org/javarosa/entities/EntityFormFinalizationProcessorTest.java deleted file mode 100644 index 13c92cef2..000000000 --- a/src/test/java/org/javarosa/entities/EntityFormFinalizationProcessorTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.javarosa.entities; - -import org.javarosa.test.Scenario; -import org.javarosa.test.XFormsElement; -import org.javarosa.entities.internal.Entities; -import org.javarosa.form.api.FormEntryModel; -import org.javarosa.xform.parse.XFormParserFactory; -import org.javarosa.xform.util.XFormUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.javarosa.test.BindBuilderXFormsElement.bind; -import static org.javarosa.test.XFormsElement.body; -import static org.javarosa.test.XFormsElement.head; -import static org.javarosa.test.XFormsElement.input; -import static org.javarosa.test.XFormsElement.mainInstance; -import static org.javarosa.test.XFormsElement.model; -import static org.javarosa.test.XFormsElement.t; -import static org.javarosa.test.XFormsElement.title; - -public class EntityFormFinalizationProcessorTest { - - private final EntityXFormParserFactory entityXFormParserFactory = new EntityXFormParserFactory(new XFormParserFactory()); - - @Before - public void setup() { - XFormUtils.setXFormParserFactory(entityXFormParserFactory); - } - - @After - public void teardown() { - XFormUtils.setXFormParserFactory(new XFormParserFactory()); - } - - @Test - public void whenFormDoesNotHaveEntityElement_addsNoEntitiesToExtras() throws Exception { - Scenario scenario = Scenario.init("Normal form", XFormsElement.html( - head( - title("Normal form"), - model( - mainInstance( - t("data id=\"normal\"", - t("name") - ) - ), - bind("/data/name").type("string") - ) - ), - body( - input("/data/name") - ) - )); - - EntityFormFinalizationProcessor processor = new EntityFormFinalizationProcessor(); - FormEntryModel model = scenario.getFormEntryController().getModel(); - processor.processForm(model); - assertThat(model.getExtras().get(Entities.class), equalTo(null)); - } -} \ No newline at end of file diff --git a/src/test/java/org/javarosa/entities/EntityFormParserTest.java b/src/test/java/org/javarosa/entities/EntityFormParserTest.java deleted file mode 100644 index e094344fe..000000000 --- a/src/test/java/org/javarosa/entities/EntityFormParserTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.javarosa.entities; - -import org.javarosa.core.model.data.IntegerData; -import org.javarosa.core.model.instance.TreeElement; -import org.javarosa.entities.internal.EntityFormParser; -import org.junit.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.javarosa.entities.internal.EntityConstants.ATTRIBUTE_CREATE; -import static org.javarosa.entities.internal.EntityConstants.ATTRIBUTE_UPDATE; -import static org.javarosa.entities.internal.EntityConstants.ELEMENT_ENTITY; -import static org.javarosa.entities.internal.EntityConstants.ELEMENT_LABEL; - -public class EntityFormParserTest { - - @Test - public void parseAction_findsCreateWithTrueString() { - TreeElement entityElement = new TreeElement(ELEMENT_ENTITY); - entityElement.setAttribute(null, ATTRIBUTE_CREATE, "true"); - - EntityAction action = EntityFormParser.parseAction(entityElement); - assertThat(action, equalTo(EntityAction.CREATE)); - } - - @Test - public void parseAction_findsUpdateWithTrueString() { - TreeElement entityElement = new TreeElement(ELEMENT_ENTITY); - entityElement.setAttribute(null, ATTRIBUTE_UPDATE, "true"); - - EntityAction dataset = EntityFormParser.parseAction(entityElement); - assertThat(dataset, equalTo(EntityAction.UPDATE)); - } - - @Test - public void parseLabel_whenLabelIsAnInt_convertsToString() { - TreeElement labelElement = new TreeElement(ELEMENT_LABEL); - labelElement.setAnswer(new IntegerData(0)); - TreeElement entityElement = new TreeElement(ELEMENT_ENTITY); - entityElement.addChild(labelElement); - - String label = EntityFormParser.parseLabel(entityElement); - assertThat(label, equalTo("0")); - } -} \ No newline at end of file diff --git a/src/test/java/org/javarosa/entities/internal/EntityFormParseProcessorTest.java b/src/test/java/org/javarosa/entities/internal/EntityFormParseProcessorTest.java deleted file mode 100644 index 146dba043..000000000 --- a/src/test/java/org/javarosa/entities/internal/EntityFormParseProcessorTest.java +++ /dev/null @@ -1,234 +0,0 @@ -package org.javarosa.entities.internal; - -import kotlin.Pair; -import org.javarosa.core.model.FormDef; -import org.javarosa.test.XFormsElement; -import org.javarosa.entities.UnrecognizedEntityVersionException; -import org.javarosa.xform.parse.XFormParser; -import org.javarosa.xform.parse.XFormParser.MissingModelAttributeException; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.InputStreamReader; - -import static java.util.Arrays.asList; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.javarosa.test.BindBuilderXFormsElement.bind; -import static org.javarosa.test.XFormsElement.body; -import static org.javarosa.test.XFormsElement.head; -import static org.javarosa.test.XFormsElement.input; -import static org.javarosa.test.XFormsElement.mainInstance; -import static org.javarosa.test.XFormsElement.model; -import static org.javarosa.test.XFormsElement.t; -import static org.javarosa.test.XFormsElement.title; -import static org.junit.Assert.fail; - -public class EntityFormParseProcessorTest { - - @Test - public void whenVersionIsMissing_parsesWithoutError() throws XFormParser.ParseException { - XFormsElement form = XFormsElement.html( - head( - title("Non entity form"), - model( - mainInstance( - t("data id=\"create-entity-form\"", - t("name"), - t("meta") - ) - ), - bind("/data/name").type("string") - ) - ), - body( - input("/data/name") - ) - ); - - EntityFormParseProcessor processor = new EntityFormParseProcessor(); - XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes()))); - parser.addProcessor(processor); - parser.parse(null); - } - - @Test - public void whenVersionIsMissing_andThereIsAnEntityElement_throwsException() { - XFormsElement form = XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model( - mainInstance( - t("data id=\"create-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\"") - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name") - ) - ), - body( - input("/data/name") - ) - ); - - EntityFormParseProcessor processor = new EntityFormParseProcessor(); - XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes()))); - parser.addProcessor(processor); - - try { - parser.parse(null); - fail("Expected exception!"); - } catch (Exception e) { - assertThat(e, instanceOf(MissingModelAttributeException.class)); - - MissingModelAttributeException missingModelAttributeException = (MissingModelAttributeException) e; - assertThat(missingModelAttributeException.getNamespace(), equalTo("http://www.opendatakit.org/xforms/entities")); - assertThat(missingModelAttributeException.getName(), equalTo("entities-version")); - } - } - - @Test(expected = UnrecognizedEntityVersionException.class) - public void whenVersionIsNotRecognized_throwsException() throws XFormParser.ParseException { - XFormsElement form = XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("entities:entities-version", "somethingElse")), - mainInstance( - t("data id=\"create-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\"") - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name") - ) - ), - body( - input("/data/name") - ) - ); - - EntityFormParseProcessor processor = new EntityFormParseProcessor(); - XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes()))); - parser.addProcessor(processor); - parser.parse(null); - } - - @Test - public void whenVersionIsNewPatch_parsesCorrectly() throws XFormParser.ParseException { - String newPatchVersion = "2022.1.12"; - - XFormsElement form = XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("entities:entities-version", newPatchVersion)), - mainInstance( - t("data id=\"create-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\"") - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name") - ) - ), - body( - input("/data/name") - ) - ); - - EntityFormParseProcessor processor = new EntityFormParseProcessor(); - XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes()))); - parser.addProcessor(processor); - - FormDef formDef = parser.parse(null); - assertThat(formDef.getExtras().get(EntityFormExtra.class), notNullValue()); - } - - @Test - public void whenVersionIsNewVersionWithUpdates_parsesCorrectly() throws XFormParser.ParseException { - String updateVersion = "2023.1.0"; - - XFormsElement form = XFormsElement.html( - asList( - new Pair<>("entities", "http://www.opendatakit.org/xforms/entities") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("entities:entities-version", updateVersion)), - mainInstance( - t("data id=\"update-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\" update=\"1\" id=\"17\"") - ) - ) - ), - bind("/data/name").type("string").withAttribute("entities", "saveto", "name") - ) - ), - body( - input("/data/name") - ) - ); - - EntityFormParseProcessor processor = new EntityFormParseProcessor(); - XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes()))); - parser.addProcessor(processor); - - FormDef formDef = parser.parse(null); - assertThat(formDef.getExtras().get(EntityFormExtra.class), notNullValue()); - } - - @Test - public void saveTosWithIncorrectNamespaceAreIgnored() throws XFormParser.ParseException { - XFormsElement form = XFormsElement.html( - asList( - new Pair<>("correct", "http://www.opendatakit.org/xforms/entities"), - new Pair<>("incorrect", "blah") - ), - head( - title("Create entity form"), - model(asList(new Pair<>("correct:entities-version", "2022.1.1")), - mainInstance( - t("data id=\"create-entity-form\"", - t("name"), - t("meta", - t("entity dataset=\"people\"") - ) - ) - ), - bind("/data/name").type("string").withAttribute("incorrect", "saveto", "name") - ) - ), - body( - input("/data/name") - ) - ); - - EntityFormParseProcessor processor = new EntityFormParseProcessor(); - XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes()))); - parser.addProcessor(processor); - - FormDef formDef = parser.parse(null); - assertThat(formDef.getExtras().get(EntityFormExtra.class).getSaveTos(), is(empty())); - } -} \ No newline at end of file