Skip to content
This repository has been archived by the owner on Oct 1, 2022. It is now read-only.

Testing with odk-xpath lib #87

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"karma-rollup-preprocessor": "^7.0.0",
"karma-safari-launcher": "1.0.x",
"mocha": "6.0.x",
"odk-xpath": "0.0.1-beta.2",
"odk-xpath": "0.0.1-beta.4",
"rollup": "^1.8.0"
}
}
67 changes: 48 additions & 19 deletions test/spec/functions-openrosa.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,11 @@ describe( 'Custom "OpenRosa" functions', () => {
} );

it( 'uuid()', () => {
const result = g.doc.evaluate( 'uuid()', g.doc, null, g.win.XPathResult.STRING_TYPE );
let result = g.doc.evaluate( 'uuid()', g.doc, null, g.win.XPathResult.STRING_TYPE );
expect( result.stringValue ).to.have.length( 36 );

result = g.doc.evaluate( 'uuid(6)', g.doc, null, g.win.XPathResult.STRING_TYPE );
expect( result.stringValue ).to.have.length( 6 );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no particular format requirement, so this should be good! Fyi, this is the ODK Collect code: https://github.com/opendatakit/javarosa/blob/59611cc0755dfbaf6631866ff15d6a9a516df704/src/main/java/org/javarosa/core/util/PropertyUtils.java#L54

} );

it( 'int()', () => {
Expand Down Expand Up @@ -1021,7 +1024,7 @@ describe( 'Custom "OpenRosa" functions', () => {
g.win.XPathJS.customXPathFunction.remove( 'comment-status' );
} );

xit( 'can be added', () => {
it( 'can be added', () => {
const obj = {
status: 'good'
};
Expand All @@ -1035,23 +1038,17 @@ describe( 'Custom "OpenRosa" functions', () => {
expect( test1 ).to.throw( /Failed to execute/ );

// Add custom function
g.win.XPathJS.customXPathFunction.add( 'comment-status', {
fn( a ) {
const curValue = a.toString();
let status = '';

try {
status = JSON.parse( curValue ).status;
} catch ( e ) {
console.error( 'Could not parse JSON from', curValue );
}

return new g.win.XPathJS.customXPathFunction.type.StringType( status );
},
args: [ {
t: 'string'
} ],
ret: 'string'
g.win.XPathJS.customXPathFunction.add( 'comment-status', function( a ) {
if(arguments.length !== 1) throw new g.win.Error('Invalid args');
const curValue = a.v[0]; // {t: 'arr', v: [{'status': 'good'}]}
let status = '';
try {
status = JSON.parse( curValue ).status;
} catch ( e ) {
console.error( 'Could not parse JSON from', curValue );
}

return new g.win.XPathJS.customXPathFunction.type.StringType( status );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks good. Feel free to change more if e.g. XPathJS.customXPathFunction.type.StringType is an awkward solution in your library. Will you have some documentation on how to add custom functions in your library?

} );

// Check functioning:
Expand All @@ -1068,4 +1065,36 @@ describe( 'Custom "OpenRosa" functions', () => {

} );

describe('digest', () => {
it( 'digest', () => {
[
["digest('abc', 'SHA-1', 'hex')", 'a9993e364706816aba3e25717850c26c9cd0d89d'],
["digest('abc', 'SHA-256', 'hex')", 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'],
["digest('abc', 'SHA-256')", 'ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0='],
["digest('abc', 'SHA-256', 'base64')", 'ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=']
].forEach( async ([expr, expected]) => {
var result = g.doc.evaluate(expr, g.doc, null, g.win.XPathResult.STRING_TYPE, null);

// The web crypto api only supports async functions and does not support md5
// https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-digest
// https://www.w3.org/2012/webcrypto/track/issues/24
// Is this a weird promise?
expect(await (result.stringValue)).to.equal(expected);
});

const invalidAlgoTest = () => {
g.doc.evaluate("digest('abc', 'XYZ', 'hex')", g.doc, null, g.win.XPathResult.STRING_TYPE, null);
}

expect(invalidAlgoTest).to.throw();

const invalidEncodingTest = () => {
g.doc.evaluate("digest('abc', 'SHA-1', 'x')", g.doc, null, g.win.XPathResult.STRING_TYPE, null);
}

expect(invalidEncodingTest).to.throw();
} );
} );


Copy link
Member Author

@MartijnR MartijnR Aug 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, I don't think we can do asynchronous functions in XPath. I am also not very enthusiastic about adding a large library to do this synchronously, so I'm wondering if we should just forget about supporting digest(). It's quite an obscure function.

We do include a library in enketo-express called node-forge to encrypt submissions, which if used in odk-xpath would not increase the size (if the versions are in sync?) in Enketo Express. Not sure if that would support synchronous digest generation.

} );