Skip to content

Commit fcea408

Browse files
authored
Merge pull request #41 from yanokwa/add-tests
2 parents 1c00717 + d35dc23 commit fcea408

File tree

6 files changed

+97
-38
lines changed

6 files changed

+97
-38
lines changed

.github/workflows/publish.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ jobs:
1313
contents: read
1414
steps:
1515
- name: Check out the repo
16-
uses: actions/checkout@v2
16+
uses: actions/checkout@v4
1717

18+
- name: Run tests
19+
run: bash test.sh
20+
1821
- name: Log in to Docker Hub
1922
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
2023
with:

.github/workflows/test.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: Test
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
test:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v4
10+
- name: Run tests
11+
run: bash test.sh

README.md

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,47 +14,13 @@ FLASK_APP=app/main.py:app FLASK_DEBUG=1 flask run
1414
# Run in Docker
1515
```
1616
docker build --tag pyxform-http .
17-
docker run --detach --publish 5001:80 pyxform-http
17+
docker run --detach --publish 5000:80 pyxform-http
1818
```
1919

2020
# Test forms
2121

22-
A form that converts successfully (with chunked encoding!)
2322
```
24-
curl --request POST --header "X-XlsForm-FormId-Fallback: pyxform-clean" --header 'Transfer-Encoding: chunked' --data-binary @test/pyxform-clean.xlsx http://127.0.0.1:5001/api/v1/convert
23+
bash test.sh
2524
```
2625

27-
A form that fails to convert and returns a pyxform error
28-
```
29-
curl --request POST --header "X-XlsForm-FormId-Fallback: pyxform-error" --data-binary @test/pyxform-error.xlsx http://127.0.0.1:5001/api/v1/convert
30-
```
31-
32-
A form that converts successfully and also returns pyxform warnings
33-
```
34-
curl --request POST --header "X-XlsForm-FormId-Fallback: pyxform-warning" --data-binary @test/pyxform-warning.xlsx http://127.0.0.1:5001/api/v1/convert
35-
```
36-
37-
A form that passes pyxform's internal checks, but fails ODK Validate's checks
38-
```
39-
curl --request POST --header "X-XlsForm-FormId-Fallback: validate-error" --data-binary @test/validate-error.xlsx http://127.0.0.1:5001/api/v1/convert
40-
```
41-
42-
A form that converts successfully (with external choices)
43-
```
44-
curl --request POST --header "X-XlsForm-FormId-Fallback: external-choices" --data-binary @test/external-choices.xlsx http://127.0.0.1:5001/api/v1/convert
45-
```
46-
47-
A form that converts successfully (with no id)
48-
```
49-
curl --request POST --data-binary @test/pyxform-clean.xlsx http://127.0.0.1:5001/api/v1/convert
50-
```
51-
52-
A form that converts successfully (with percent encoded id)
53-
```
54-
curl --request POST --header "X-XlsForm-FormId-Fallback: example%40example.org" --data-binary @test/pyxform-clean.xlsx http://127.0.0.1:5001/api/v1/convert
55-
```
56-
57-
A form that converts successfully (with no id, in XLS format)
58-
```
59-
curl --request POST --data-binary @test/pyxform-clean.xls http://127.0.0.1:5001/api/v1/convert
60-
```
26+
The test script builds, runs, stops, and removes a pyxform-http-tester container

test.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/bin/bash
2+
3+
set -o errexit
4+
set -o nounset
5+
set -o pipefail
6+
7+
docker build --quiet --tag pyxform-http . >/dev/null
8+
docker run --detach --publish 5000:80 --name pyxform-http-tester pyxform-http >/dev/null
9+
10+
# wait for docker container to come up
11+
sleep 1
12+
13+
test_failed="false"
14+
15+
test_1_actual=$(curl --silent --request POST --header "X-XlsForm-FormId-Fallback: pyxform-clean" --header 'Transfer-Encoding: chunked' --data-binary @test/pyxform-clean.xlsx http://127.0.0.1:5000/api/v1/convert)
16+
test_1_expected='{"error":null,"itemsets":null,"result":"<?xml version=\"1.0\"?><h:html xmlns=\"http://www.w3.org/2002/xforms\" xmlns:ev=\"http://www.w3.org/2001/xml-events\" xmlns:h=\"http://www.w3.org/1999/xhtml\" xmlns:jr=\"http://openrosa.org/javarosa\" xmlns:odk=\"http://www.opendatakit.org/xforms\" xmlns:orx=\"http://openrosa.org/xforms\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><h:head><h:title>pyxform-clean</h:title><model odk:xforms-version=\"1.0.0\"><instance><data id=\"pyxform-clean\"><name/><age/><meta><instanceID/></meta></data></instance><bind nodeset=\"/data/name\" type=\"string\"/><bind nodeset=\"/data/age\" type=\"int\"/><bind jr:preload=\"uid\" nodeset=\"/data/meta/instanceID\" readonly=\"true()\" type=\"string\"/></model></h:head><h:body><input ref=\"/data/name\"><label>what is your name</label></input><input ref=\"/data/age\"><label>what is your age</label></input></h:body></h:html>","status":200,"warnings":[]}'
17+
if [ "$test_1_actual" != "$test_1_expected" ]; then
18+
echo "test 1 failed: form that converts (with chunked encoding)"
19+
test_failed="true"
20+
fi
21+
22+
test_2_actual=$(curl --silent --request POST --header "X-XlsForm-FormId-Fallback: pyxform-error" --data-binary @test/pyxform-error.xlsx http://127.0.0.1:5000/api/v1/convert)
23+
test_2_expected='{"error":"Unknown question type '\''textX'\''.","itemsets":null,"result":null,"status":400,"warnings":null}'
24+
if [ "$test_2_actual" != "$test_2_expected" ]; then
25+
echo "test 2 failed: form that fails to convert and returns a pyxform error"
26+
test_failed="true"
27+
fi
28+
29+
test_3_actual=$(curl --silent --request POST --header "X-XlsForm-FormId-Fallback: pyxform-warning" --data-binary @test/pyxform-warning.xlsx http://127.0.0.1:5000/api/v1/convert)
30+
test_3_expected='{"error":null,"itemsets":null,"result":"<?xml version=\"1.0\"?><h:html xmlns=\"http://www.w3.org/2002/xforms\" xmlns:ev=\"http://www.w3.org/2001/xml-events\" xmlns:h=\"http://www.w3.org/1999/xhtml\" xmlns:jr=\"http://openrosa.org/javarosa\" xmlns:odk=\"http://www.opendatakit.org/xforms\" xmlns:orx=\"http://openrosa.org/xforms\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><h:head><h:title>pyxform-warning</h:title><model odk:xforms-version=\"1.0.0\"><instance><data id=\"pyxform-warning\"><name/><group><age/></group><meta><instanceID/></meta></data></instance><bind nodeset=\"/data/name\" type=\"string\"/><bind nodeset=\"/data/group/age\" type=\"string\"/><bind jr:preload=\"uid\" nodeset=\"/data/meta/instanceID\" readonly=\"true()\" type=\"string\"/></model></h:head><h:body><input ref=\"/data/name\"><label>what is your name</label></input><group ref=\"/data/group\"><input ref=\"/data/group/age\"><label>what is your age</label></input></group></h:body></h:html>","status":200,"warnings":["[row : 3] Group has no label: {'\''name'\'': '\''group'\'', '\''type'\'': '\''begin group'\''}"]}'
31+
if [ "$test_3_actual" != "$test_3_expected" ]; then
32+
echo "test 3 failed: form that converts and also returns pyxform warnings"
33+
test_failed="true"
34+
fi
35+
36+
test_4_actual=$(curl --silent --request POST --header "X-XlsForm-FormId-Fallback: validate-error" --data-binary @test/validate-error.xlsx http://127.0.0.1:5000/api/v1/convert)
37+
test_4_expected='{"error":"ODK Validate Errors:\n>> Something broke the parser. See above for a hint.\nError evaluating field '\''concat'\'' (${concat}[1]): The problem was located in Calculate expression for ${concat}\nXPath evaluation: cannot handle function '\''concatx'\''\nCaused by: org.javarosa.xpath.XPathUnhandledException: The problem was located in Calculate expression for ${concat}\nXPath evaluation: cannot handle function '\''concatx'\''\n\t... 10 more\n\nThe following files failed validation:\n${validate-error}.xml\n\nResult: Invalid","itemsets":null,"result":null,"status":400,"warnings":null}'
38+
if [ "$test_4_actual" != "$test_4_expected" ]; then
39+
echo "test 4 failed: form that passes pyxform's internal checks, but fails ODK Validate's checks"
40+
test_failed="true"
41+
fi
42+
43+
test_5_actual=$(curl --silent --request POST --header "X-XlsForm-FormId-Fallback: external-choices" --data-binary @test/external-choices.xlsx http://127.0.0.1:5000/api/v1/convert)
44+
test_5_expected='{"error":null,"itemsets":"\"list_name\",\"name\",\"label\",\"province\",\"district\"\n\"districts\",\"district_a\",\"District A (in Province 1)\",\"province_1\",\"None\"\n\"districts\",\"district_b\",\"District B (in Province 1)\",\"province_1\",\"None\"\n\"districts\",\"district_c\",\"District C (in Province 2)\",\"province_2\",\"None\"\n\"None\",\"None\",\"None\",\"None\",\"None\"\n\"lots\",\"lot_10\",\"Lot 10 (in District A)\",\"province_1\",\"district_a\"\n\"lots\",\"lot_20\",\"Lot 20 (in District A)\",\"province_1\",\"district_a\"\n\"lots\",\"lot_30\",\"Lot 30 (In District B)\",\"province_1\",\"district_b\"\n\"lots\",\"lot_40\",\"Lot 40 (In District C)\",\"province_2\",\"district_c\"\n","result":"<?xml version=\"1.0\"?><h:html xmlns=\"http://www.w3.org/2002/xforms\" xmlns:ev=\"http://www.w3.org/2001/xml-events\" xmlns:h=\"http://www.w3.org/1999/xhtml\" xmlns:jr=\"http://openrosa.org/javarosa\" xmlns:odk=\"http://www.opendatakit.org/xforms\" xmlns:orx=\"http://openrosa.org/xforms\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><h:head><h:title>external-choices</h:title><model odk:xforms-version=\"1.0.0\"><instance><data id=\"external-choices\"><province/><district/><lot/><meta><instanceID/></meta></data></instance><bind nodeset=\"/data/province\" type=\"string\"/><bind nodeset=\"/data/district\" type=\"string\"/><bind nodeset=\"/data/lot\" type=\"string\"/><bind jr:preload=\"uid\" nodeset=\"/data/meta/instanceID\" readonly=\"true()\" type=\"string\"/></model></h:head><h:body><select1 ref=\"/data/province\"><label>Province</label><item><label>Province 1</label><value>province_1</value></item><item><label>Province 2</label><value>province_2</value></item></select1><input ref=\"/data/district\" query=\"instance('\''districts'\'')/root/item[province= /data/province ]\"><label>District</label></input><input ref=\"/data/lot\" query=\"instance('\''lots'\'')/root/item[province= /data/province and district= /data/district ]\"><label>Lot</label></input></h:body></h:html>","status":200,"warnings":[]}'
45+
if [ "$test_5_actual" != "$test_5_expected" ]; then
46+
echo "test 5 failed: form that converts (with external choices)"
47+
test_failed="true"
48+
fi
49+
50+
# test removes uuid from actual and expected
51+
test_6_actual=$(curl --silent --request POST --data-binary @test/pyxform-clean.xlsx http://127.0.0.1:5000/api/v1/convert | sed 's/[0-9a-f-]\{36\}//g')
52+
test_6_expected=$(echo '{"error":null,"itemsets":null,"result":"<?xml version=\"1.0\"?><h:html xmlns=\"http://www.w3.org/2002/xforms\" xmlns:ev=\"http://www.w3.org/2001/xml-events\" xmlns:h=\"http://www.w3.org/1999/xhtml\" xmlns:jr=\"http://openrosa.org/javarosa\" xmlns:odk=\"http://www.opendatakit.org/xforms\" xmlns:orx=\"http://openrosa.org/xforms\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><h:head><h:title>pyxform-clean</h:title><model odk:xforms-version=\"1.0.0\"><instance><data id=\"a126d83c-ac40-4fd1-b3b0-9f32affacd14\"><name/><age/><meta><instanceID/></meta></data></instance><bind nodeset=\"/data/name\" type=\"string\"/><bind nodeset=\"/data/age\" type=\"int\"/><bind jr:preload=\"uid\" nodeset=\"/data/meta/instanceID\" readonly=\"true()\" type=\"string\"/></model></h:head><h:body><input ref=\"/data/name\"><label>what is your name</label></input><input ref=\"/data/age\"><label>what is your age</label></input></h:body></h:html>","status":200,"warnings":[]}' | sed 's/[0-9a-f-]\{36\}//g')
53+
if [ "$test_6_actual" != "$test_6_expected" ]; then
54+
echo "test 6 failed: form that converts (with no id)"
55+
test_failed="true"
56+
fi
57+
58+
# test removes uuid from actual and expected
59+
test_7_actual=$(curl --silent --request POST --header "X-XlsForm-FormId-Fallback: example%40example.org" --data-binary @test/pyxform-clean.xlsx http://127.0.0.1:5000/api/v1/convert | sed 's/[0-9a-f-]\{36\}//g')
60+
test_7_expected=$(echo '{"error":null,"itemsets":null,"result":"<?xml version=\"1.0\"?><h:html xmlns=\"http://www.w3.org/2002/xforms\" xmlns:ev=\"http://www.w3.org/2001/xml-events\" xmlns:h=\"http://www.w3.org/1999/xhtml\" xmlns:jr=\"http://openrosa.org/javarosa\" xmlns:odk=\"http://www.opendatakit.org/xforms\" xmlns:orx=\"http://openrosa.org/xforms\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><h:head><h:title>pyxform-clean</h:title><model odk:xforms-version=\"1.0.0\"><instance><data id=\"[email protected]\"><name/><age/><meta><instanceID/></meta></data></instance><bind nodeset=\"/data/name\" type=\"string\"/><bind nodeset=\"/data/age\" type=\"int\"/><bind jr:preload=\"uid\" nodeset=\"/data/meta/instanceID\" readonly=\"true()\" type=\"string\"/></model></h:head><h:body><input ref=\"/data/name\"><label>what is your name</label></input><input ref=\"/data/age\"><label>what is your age</label></input></h:body></h:html>","status":200,"warnings":[]}' | sed 's/[0-9a-f-]\{36\}//g')
61+
if [ "$test_7_actual" != "$test_7_expected" ]; then
62+
echo "test 7 failed: form that converts (with percent encoded id)"
63+
test_failed="true"
64+
fi
65+
66+
# test removes uuid from actual and expected
67+
test_8_actual=$(curl --silent --request POST --data-binary @test/pyxform-clean.xls http://127.0.0.1:5000/api/v1/convert | sed 's/[0-9a-f-]\{36\}//g')
68+
test_8_expected=$(echo '{"error":null,"itemsets":null,"result":"<?xml version=\"1.0\"?><h:html xmlns=\"http://www.w3.org/2002/xforms\" xmlns:ev=\"http://www.w3.org/2001/xml-events\" xmlns:h=\"http://www.w3.org/1999/xhtml\" xmlns:jr=\"http://openrosa.org/javarosa\" xmlns:odk=\"http://www.opendatakit.org/xforms\" xmlns:orx=\"http://openrosa.org/xforms\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><h:head><h:title>pyxform-clean</h:title><model odk:xforms-version=\"1.0.0\"><instance><data id=\"bbf27b70-9eb7-4659-9933-c22cb9e1451b\"><name/><age/><meta><instanceID/></meta></data></instance><bind nodeset=\"/data/name\" type=\"string\"/><bind nodeset=\"/data/age\" type=\"int\"/><bind jr:preload=\"uid\" nodeset=\"/data/meta/instanceID\" readonly=\"true()\" type=\"string\"/></model></h:head><h:body><input ref=\"/data/name\"><label>what is your name</label></input><input ref=\"/data/age\"><label>what is your age</label></input></h:body></h:html>","status":200,"warnings":[]}' | sed 's/[0-9a-f-]\{36\}//g')
69+
if [ "$test_8_actual" != "$test_8_expected" ]; then
70+
echo "test 8 failed: form that converts (with no id, in XLS format)"
71+
test_failed="true"
72+
fi
73+
74+
docker container stop pyxform-http-tester >/dev/null
75+
docker container rm pyxform-http-tester >/dev/null
76+
77+
if [ "$test_failed" == "true" ] ; then
78+
exit 1
79+
fi

test/pyxform-clean.xls

1 KB
Binary file not shown.

test/pyxform-clean.xlsx

1.22 KB
Binary file not shown.

0 commit comments

Comments
 (0)