test/src/lib/server/AddReferencesStream.spec.js
import { StatusCodes } from 'node-opcua';
import expect from '../../../expect';
import NodeId from '../../../../src/lib/model/opcua/NodeId';
import AddReferencesStream from '../../../../src/lib/server/AddReferencesStream';
import { ReferenceTypeIds } from '../../../../src/lib/model/Node';
/** @test {AddReferencesStream} */
describe('AddReferencesStream', function () {
/** @test {AddReferencesStream#scriptId} */
describe('#scriptId', function () {
it("should return the AddReferences script's id", function () {
expect(
AddReferencesStream.prototype.scriptId.value,
'to equal',
'SYSTEM.LIBRARY.ATVISE.SERVERSCRIPTS.atscm.AddReferences'
);
});
});
/** @test {AddReferencesStream#scriptParameters} */
describe('#scriptParameters', function () {
it('should return null without references', function () {
expect(
AddReferencesStream.prototype.scriptParameters({ references: new Map() }),
'to be',
null
);
});
it('should return null witout additional references', function () {
expect(
AddReferencesStream.prototype.scriptParameters({
references: new Map([
[ReferenceTypeIds.toParent, new Set([1])],
[ReferenceTypeIds.HasTypeDefinition, new Set([2])],
[ReferenceTypeIds.HasModellingRule, new Set([3])],
]),
}),
'to be',
null
);
});
it('should return JSON string for additional references', function () {
expect(
AddReferencesStream.prototype.scriptParameters({
references: new Map([
[ReferenceTypeIds.toParent, new Set([1])],
[ReferenceTypeIds.HasTypeDefinition, new Set([2])],
[ReferenceTypeIds.HasModellingRule, new Set([3])],
[
ReferenceTypeIds.HasComponent,
new Set(['SYSTEM.LIBRARY.ATVISE.ALARMCATEGORIES.Error']),
],
]),
}),
'to satisfy',
{
paramObjString: {
// eslint-disable-next-line max-len
value:
'{"references":[{"referenceIdValue":47,"items":["ns=1;s=SYSTEM.LIBRARY.ATVISE.ALARMCATEGORIES.Error"]}]}',
},
}
);
});
});
/** @test {AddReferencesStream#processErrorMessage} */
describe('#processErrorMessage', function () {
it('should decorate the error message', function () {
expect(
AddReferencesStream.prototype.processErrorMessage({
nodeId: new NodeId('ns=1;s=AGENT.OBJECTS.Test'),
}),
'to contain',
'AGENT.OBJECTS.Test',
'adding references'
);
});
});
/** @test {AddReferencesStream#handleOutputArguments} */
describe('#handleOutputArguments', function () {
it('should error with bad status codes', function () {
return expect(
AddReferencesStream.prototype.handleOutputArguments.bind(null, {}, [
{ value: StatusCodes.Bad },
{ value: 'Something bad happened' },
]),
'to call the callback with error',
'Something bad happened'
);
});
it('should retry when script had failures', async function () {
const stream = new AddReferencesStream();
const file = { nodeId: new NodeId('AGENT.OBJECTS.Failing') };
const handleOutput = AddReferencesStream.prototype.handleOutputArguments.bind(stream, file, [
{ value: StatusCodes.Good },
{},
{},
{
value: [{ value: [new NodeId('A.Referenced.Node')] }],
},
]);
// The first time adding references fails is ignored
await expect(handleOutput, 'to call the callback without error');
// and pushed to the retry stack
expect(Array.from(stream._retry.values()), 'to equal', ['AGENT.OBJECTS.Failing']);
// The second time it should fail.
await expect(
handleOutput,
'to call the callback with error',
/Failed to create reference.+A.Referenced.Node/i
);
});
it('should continue without failures', function () {
return expect(
AddReferencesStream.prototype.handleOutputArguments.bind(null, {}, [
{ value: StatusCodes.Good },
{},
{},
{
value: [{ value: [] }],
},
]),
'to call the callback without error'
);
});
});
});