Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes issue where time values gets stripped from DateTime data in Xpath calculations #932

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/main/java/org/javarosa/xpath/expr/XPathPathExpr.java
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,6 @@ public static Object unpackValue(IAnswerData val) {
return (new XFormAnswerDataSerializer()).serializeAnswerData(val);
} else if (val instanceof DateData) {
return val.getValue();
} else if (val instanceof DateTimeData) {
return val.getValue();
} else if (val instanceof BooleanData) {
return val.getValue();
} else if (val instanceof GeoPointData) {
Expand Down
54 changes: 40 additions & 14 deletions src/test/java/org/javarosa/core/model/test/FormDefTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.javarosa.core.model.condition.EvaluationContext;
import org.javarosa.core.model.condition.IFunctionHandler;
import org.javarosa.core.model.data.DateData;
import org.javarosa.core.model.data.DateTimeData;
import org.javarosa.core.model.data.IAnswerData;
import org.javarosa.core.model.data.IntegerData;
import org.javarosa.core.model.data.SelectOneData;
Expand All @@ -21,6 +22,7 @@
import org.javarosa.core.test.FormParseInit;
import org.javarosa.form.api.FormEntryController;
import org.javarosa.test_utils.ExprEvalUtils;
import org.javarosa.xform.util.XFormAnswerDataSerializer;
import org.javarosa.xpath.parser.XPathSyntaxException;
import org.junit.Assert;
import org.junit.Test;
Expand Down Expand Up @@ -374,10 +376,10 @@ public void testLoopedRepeatIndexFetches() throws Exception {
fec.stepToNextEvent();

fec.answerQuestion(new IntegerData(2));
while(fec.stepToNextEvent() != FormEntryController.EVENT_QUESTION);
while (fec.stepToNextEvent() != FormEntryController.EVENT_QUESTION) ;

fec.answerQuestion(new UncastData("yes"));
while(fec.stepToNextEvent() != FormEntryController.EVENT_QUESTION) ;
while (fec.stepToNextEvent() != FormEntryController.EVENT_QUESTION) ;

fec.getNextIndex(fec.getModel().getFormIndex(), true);
fec.answerQuestion(new IntegerData(2));
Expand All @@ -396,7 +398,7 @@ public void testLoopedRepeatIndexFetches() throws Exception {
@Test
public void testModelIterationLookahead() throws XPathSyntaxException {
FormParseInit fpi = new FormParseInit("/xform_tests/model_iteration_lookahead.xml");
FormEntryController fec = initFormEntry(fpi);
FormEntryController fec = initFormEntry(fpi);
stepThroughEntireForm(fec);

EvaluationContext evalCtx = fpi.getFormDef().getEvaluationContext();
Expand All @@ -416,7 +418,7 @@ public void testModelIterationLookahead() throws XPathSyntaxException {
public void testSimilarBindConditionsAreDistinguished() throws Exception {
FormParseInit fpi =
new FormParseInit("/xform_tests/test_display_conditions_regression.xml");
FormEntryController fec = initFormEntry(fpi);
FormEntryController fec = initFormEntry(fpi);

boolean visibleLabelWasPresent = false;
do {
Expand Down Expand Up @@ -489,6 +491,26 @@ public void testDeleteRepeatMultiplicities() throws IOException {
assertNotEquals(root.getChild("question1", 1), null);
}

@Test
public void testBindForDateTimeType() {
FormParseInit fpi = new FormParseInit("/xform_tests/datetime_bind.xml");
FormEntryController fec = initFormEntry(fpi);
DateTimeData answer = new DateTimeData(new Date());
do {
QuestionDef q = fpi.getCurrentQuestion();
if (q == null || q.getTextID() == null || "".equals(q.getTextID())) {
continue;
}
if (q.getTextID().equals("time-label")) {
fec.answerQuestion(answer);
}
} while (fec.stepToNextEvent() != FormEntryController.EVENT_END_OF_FORM);

// test that a value that should be updated has been updated
ExprEvalUtils.testEval("/data/case/update/time",
fpi.getFormDef().getInstance(), null, new XFormAnswerDataSerializer().serializeAnswerData(answer));
}

/**
* Regression: IText function in xpath was not properly using the current
* locale instead of the default
Expand All @@ -497,31 +519,33 @@ public void testDeleteRepeatMultiplicities() throws IOException {
public void testITextXPathFunction() throws XPathSyntaxException {
FormParseInit fpi = new FormParseInit("/xform_tests/itext_function.xml");
// init form with the 'new' locale instead of the default 'old' locale
FormEntryController fec = initFormEntry(fpi, "new");
FormEntryController fec = initFormEntry(fpi, "new");

boolean inlinePassed = false;
boolean nestedPassed = false;

do {
TreeReference currentRef = fec.getModel().getFormIndex().getReference();
if(currentRef == null) { continue; }
if(currentRef.genericize().toString().equals("/data/inline")) {
if (currentRef == null) {
continue;
}
if (currentRef.genericize().toString().equals("/data/inline")) {
assertEquals("Inline IText Method Callout", "right",
fec.getModel().getCaptionPrompt().getQuestionText());
inlinePassed = true;
}

if(currentRef.genericize().toString().equals("/data/nested")) {
if (currentRef.genericize().toString().equals("/data/nested")) {
assertEquals("Nexted IText Method Callout", "right",
fec.getModel().getCaptionPrompt().getQuestionText());
nestedPassed = true;
}
} while (fec.stepToNextEvent() != FormEntryController.EVENT_END_OF_FORM);

if(!inlinePassed) {
if (!inlinePassed) {
Assert.fail("Inline itext callout did not occur");
}
if(!nestedPassed) {
if (!nestedPassed) {
Assert.fail("Nested itext callout did not occur");
}

Expand All @@ -538,7 +562,7 @@ public void testITextXPathFunction() throws XPathSyntaxException {
@Test
public void testGroupRelevancyInsideRepeat() throws XPathSyntaxException {
FormParseInit fpi = new FormParseInit("/xform_tests/group_relevancy_in_repeat.xml");
FormEntryController fec = initFormEntry(fpi);
FormEntryController fec = initFormEntry(fpi);

do {
QuestionDef q = fpi.getCurrentQuestion();
Expand Down Expand Up @@ -627,13 +651,15 @@ public void testItemsetPopulationAndFilter() {
continue;
}
TreeReference currentRef = fec.getModel().getFormIndex().getReference();
if(currentRef == null) { continue; }
if (currentRef == null) {
continue;
}

if(currentRef.genericize().toString().equals("/data/filter")) {
if (currentRef.genericize().toString().equals("/data/filter")) {
fec.answerQuestion(new SelectOneData(new Selection("a")));
}

if(currentRef.genericize().toString().equals("/data/question")) {
if (currentRef.genericize().toString().equals("/data/question")) {
assertEquals("Itemset Filter returned the wrong size",
fec.getModel().getQuestionPrompt().getSelectChoices().size(),
3);
Expand Down
50 changes: 50 additions & 0 deletions src/test/resources/xform_tests/datetime_bind.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<h:html xmlns:h="http://www.w3.org/1999/xhtml" xmlns:orx="http://openrosa.org/jr/xforms" xmlns="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jr="http://openrosa.org/javarosa" xmlns:vellum="http://commcarehq.org/xforms/vellum">
<h:head>
<h:title>Registration Form</h:title>
<model>
<instance>
<data xmlns:jrm="http://dev.commcarehq.org/jr/xforms" xmlns="http://openrosa.org/formdesigner/9D86FB79-821E-4D3C-B084-666594D266BB" uiVersion="1" version="15" name="Registration Form">
<title/>
<time/>
<copy-1-of-time/>
<detail/>
<case xmlns="http://commcarehq.org/case/transaction/v2" case_id="" date_modified="" user_id=""><create><case_name/><owner_id/><case_type>commcare-reminder</case_type></create><update><detail/><time/><time_test/></update></case><orx:meta xmlns:cc="http://commcarehq.org/xforms"><orx:deviceID/><orx:timeStart/><orx:timeEnd/><orx:username/><orx:userID/><orx:instanceID/><cc:appVersion/><orx:drift/></orx:meta></data>
</instance>
<bind nodeset="/data/title" type="xsd:string" required="true()"/>
<bind nodeset="/data/time" type="xsd:dateTime"/>
<bind nodeset="/data/copy-1-of-time" type="xsd:time"/>
<bind nodeset="/data/detail" type="xsd:string"/>
<itext>
<translation lang="en" default="">
<text id="title-label">
<value>Case Name</value>
</text>
<text id="time-label">
<value>Remind on</value>
</text>
<text id="copy-1-of-time-label">
<value>time</value>
</text>
<text id="detail-label">
<value>Case Detail</value>
</text>
</translation>
</itext>
<bind calculate="/data/time" nodeset="/data/case/update/time" relevant="count(/data/time) &gt; 0"/>
</model>
</h:head>
<h:body>
<input ref="/data/title">
<label ref="jr:itext('title-label')"/>
</input>
<input ref="/data/time">
<label ref="jr:itext('time-label')"/>
</input>
<input ref="/data/copy-1-of-time">
<label ref="jr:itext('copy-1-of-time-label')"/>
</input>
<input ref="/data/detail">
<label ref="jr:itext('detail-label')"/>
</input>
</h:body>
</h:html>