Unit Testing multiple javascript dependencies under javascript policy

jsara
New Member

I have a JavaScript policy as below, with multiple js files where, JS-Transform-GetEntityRequestV3.js invokes the function "jsonPath(obj, expr, arg){...}" from jsonpath-0.8.0.js

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="JS-Transform-Response">
    <Properties/>
    <ResourceURL>jsc://JS-Transform-GetEntityRequestMain.js</ResourceURL>
    <IncludeURL>jsc://JS-Transform-GetEntityRequestV3.js</IncludeURL>
    <IncludeURL>jsc://jsonpath-0.8.0.js</IncludeURL>
</Javascript>

I am trying to write test cases using mocha/chai/sinon for JS-Transform-GetEntityRequestV3.js and getting "ReferenceError: jsonPath is not defined" as the function is in another js file. Could you please let me know if there is a way to handle this rather than moving the jsonPath() function to the same js file?

Any help would be appreciated

Below is my test code:

var assert = require('chai').assert;
var sinon = require('sinon');
var rewire = require('rewire');
var transformFunctions = rewire('../transform/JS-Transform-GetEntityRequestV3.js');
var jsonpathFunctions = rewire('../transform/jsonpath-0.8.0.js');

var result = {
    "uri": "entities/157KsIFj",
    "type": "configuration/entityTypes/Guest"


describe('GET transformation logic functions', () =>{
	it('Map Addresses', () =>{
			
		var mapAddress = transformFunctions.__get__ ('mapAddress');
		var attributes = result.attributes
		var mappedAddress = mapAddress(attributes);
		assert.isNotNull(mappedAddress, 'returned mapped address');


	});


});



Solved Solved
0 1 258
1 ACCEPTED SOLUTION

Hi Jsara,

When Apigee sees a policy configuration like this:

<Javascript timeLimit="200" name="JS-Transform-Response">
    <Properties/>
    <ResourceURL>jsc://JS-Transform-GetEntityRequestMain.js</ResourceURL>
    <IncludeURL>jsc://JS-Transform-GetEntityRequestV3.js</IncludeURL>
    <IncludeURL>jsc://jsonpath-0.8.0.js</IncludeURL>
</Javascript>

It concatenates the modules specified by "IncludeURL" elements, with the modules specified in ResourceURL, and then compiles the result.

If the jsonpath-0.8.0.js exports things (like the function "jsonPath") into the global namespace, then it will be in the global namespace. There is no way to tell Apigee to place the exports from a module into a different sub-namespace, in the way that you could with nodejs' require() statement.

There are workarounds.

One is to modify the modules you include to export into a well-known global. You can do this with an IIFE (see article here). If you're clever about handling the exports in the module, it will work well at runtime and also in your unit test scenario.

Another workaround is ... rather than moving the jsonPath function to the same file, instead... at test time, dynamically create a file in the same way that Apigee does, by concatenating the contents of each of the included modules. You could be clever and read the JS policy file, and concatenate each of the modules from IncludeURL and ResourceURL in the way I described, then import (require? rewire?) THAT concatenated thing. That might give you the behavior you want.

View solution in original post

1 REPLY 1

Hi Jsara,

When Apigee sees a policy configuration like this:

<Javascript timeLimit="200" name="JS-Transform-Response">
    <Properties/>
    <ResourceURL>jsc://JS-Transform-GetEntityRequestMain.js</ResourceURL>
    <IncludeURL>jsc://JS-Transform-GetEntityRequestV3.js</IncludeURL>
    <IncludeURL>jsc://jsonpath-0.8.0.js</IncludeURL>
</Javascript>

It concatenates the modules specified by "IncludeURL" elements, with the modules specified in ResourceURL, and then compiles the result.

If the jsonpath-0.8.0.js exports things (like the function "jsonPath") into the global namespace, then it will be in the global namespace. There is no way to tell Apigee to place the exports from a module into a different sub-namespace, in the way that you could with nodejs' require() statement.

There are workarounds.

One is to modify the modules you include to export into a well-known global. You can do this with an IIFE (see article here). If you're clever about handling the exports in the module, it will work well at runtime and also in your unit test scenario.

Another workaround is ... rather than moving the jsonPath function to the same file, instead... at test time, dynamically create a file in the same way that Apigee does, by concatenating the contents of each of the included modules. You could be clever and read the JS policy file, and concatenate each of the modules from IncludeURL and ResourceURL in the way I described, then import (require? rewire?) THAT concatenated thing. That might give you the behavior you want.