'use strict'; const { readFileSync } = require('fs'); const path = require('path'); const { expect } = require('chai'); const sinon = require('sinon'); const { Ven } = require('../../client/ven'); const app = require('../../server'); const { sequelize, Ven: VenDb } = require('../../db'); const { port } = require('../../config'); describe('VEN to VTN interactions', function() { const venId = '17:32:59:FD:0E:B5:99:31:27:9C'; describe('registration and event retrieval', async function() { let clock; after(async () => { clock.restore(); }); let ven; before(async () => { clock = sinon.useFakeTimers( new Date('2020-04-26T01:00:00.000Z').getTime(), ); await sequelize.sync(); await VenDb.destroy({ truncate: true }); await app.start(); const clientCrtPem = readFileSync( path.join(__dirname, 'integration-client.crt'), 'utf-8', ); ven = new Ven( `http://127.0.0.1:${port}`, clientCrtPem, 'aabbccddeeff', venId, 'ven.js1', ); }); it('should successfully return a vtnId from queryRegistration', async () => { const queryResponse = await ven.queryRegistration(); expect(queryResponse.vtnId).to.be.a('string'); }); it('should successfully register and receive a vtnId and registrationId', async () => { const registrationResponse = await ven.register(); expect(registrationResponse.vtnId).to.be.a('string'); expect(registrationResponse.registrationId).to.be.a('string'); }); it('should successfully return a registrationId and venId from queryRegistration', async () => { const queryResponse = await ven.queryRegistration(); expect(queryResponse.vtnId).to.be.a('string'); expect(queryResponse.registrationId).to.be.a('string'); expect(queryResponse.venId).to.be.a('string'); }); it('should return an event from requestEvents', async () => { const eventResponse = await ven.requestEvents(); expect(eventResponse.events.length).to.eql(1); expect(eventResponse.vtnId).to.be.a('string'); }); it('should successfully cancel that registration', async () => { const cancelResponse = await ven.cancelRegistration(); expect(cancelResponse.registrationId).to.be.a('string'); expect(cancelResponse.venId).to.be.a('string'); }); after(async () => { await app.stop(); }); }); describe('poll', async function() { let ven; let clock; after(async () => { clock.restore(); }); before(async () => { clock = sinon.useFakeTimers( new Date('2020-04-26T01:00:00.000Z').getTime(), ); await sequelize.sync(); await VenDb.destroy({ truncate: true }); await app.start(); const clientCrtPem = readFileSync( path.join(__dirname, 'integration-client.crt'), 'utf-8', ); ven = new Ven( `http://127.0.0.1:${port}`, clientCrtPem, 'aabbccddeeff', venId, 'ven.js1', ); await ven.register(); }); it('should successfully poll for events', async () => { const pollResponse = await ven.poll(); expect(pollResponse._type).to.eql('oadrDistributeEvent'); expect(pollResponse.events.length).to.eql(1); }); after(async () => { await app.stop(); }); }); describe('report', async function() { let ven; let clock; after(async () => { clock.restore(); }); before(async () => { clock = sinon.useFakeTimers( new Date('2020-04-26T01:00:00.000Z').getTime(), ); await sequelize.sync(); await VenDb.destroy({ truncate: true }); await app.start(); const clientCrtPem = readFileSync( path.join(__dirname, 'integration-client.crt'), 'utf-8', ); ven = new Ven( `http://127.0.0.1:${port}`, clientCrtPem, 'aabbccddeeff', venId, 'ven.js1', ); await ven.register(); const pollResponse = await ven.poll(); const events = pollResponse.events; const eventId = events[0].eventDescriptor.eventId; const modificationNumber = events[0].eventDescriptor.modificationNumber; await ven.opt('optIn', eventId, modificationNumber); }); it('should successfully subscribe to reports and receive data', async () => { const reqs = [ { reportRequestId: '31c5ce71a68a73ece370', reportSpecifierId: 'TELEMETRY_STATUS', createdDateTime: '2020-05-07T10:05:41.421-06:00', duration: 'PT1H', reportName: 'METADATA_TELEMETRY_STATUS', descriptions: [ { reportId: 'ts1', reportType: 'x-resourceStatus', readingType: 'x-notApplicable', samplingRate: { minPeriod: 'PT1M', maxPeriod: 'PT1H', onChange: false, }, }, ], }, { reportRequestId: '3d92d98e0b65d94e60a7', reportSpecifierId: 'TELEMETRY_USAGE', createdDateTime: '2020-05-07T10:05:41.421-06:00', duration: 'PT1H', reportName: 'METADATA_TELEMETRY_USAGE', descriptions: [ { reportId: 'rep1', reportType: 'usage', readingType: 'Direct Read', samplingRate: { minPeriod: 'PT1M', maxPeriod: 'PT1H', onChange: false, }, }, ], }, ]; // register reports await ven.registerReports(reqs); const pollResponse = await ven.poll(); // poll has a request to create reports expect(pollResponse._type).to.eql('oadrCreateReport'); const createRequestId = pollResponse.reportRequestId; const [ telemetryStatusReportRequestId, telemetryUsageReportRequestId, ] = pollResponse.requests.map(x => x.reportRequestId); // notify vtn that reports have been created await ven.notifyCreatedReports(createRequestId, [ telemetryStatusReportRequestId, telemetryUsageReportRequestId, ]); // poll is empty, no reports to create const pollResponse2 = await ven.poll(); expect(pollResponse2._type).to.eql('oadrResponse'); // send report const reports = [ { createdDateTime: '2020-05-08T21:27:49.591-06:00', duration: 'PT1M', intervals: [ { duration: 'PT1M', reportPayloads: [ { dataQuality: 'Quality Good - Non Specific', payloadFloat: 161.97970171999845, reportId: 'rep1', }, ], startDate: '2020-05-08T21:26:49.562-06:00', }, ], reportName: 'TELEMETRY_USAGE', reportRequestId: telemetryUsageReportRequestId, reportSpecifierId: 'TELEMETRY_USAGE', startDate: '2020-05-08T21:26:49.562-06:00', }, { createdDateTime: '2020-05-13T10:56:11.058-06:00', duration: 'PT1M', intervals: [ { duration: 'PT1M', reportPayloads: [ { dataQuality: 'Quality Good - Non Specific', payloadStatus: { online: true, manualOverride: false, loadControlState: { oadrLevelOffset: { oadrNormal: 40, oadrCurrent: 50, }, }, }, reportId: 'rep1', }, ], startDate: '2020-05-13T10:56:11.058-06:00', }, ], reportName: 'TELEMETRY_STATUS', reportRequestId: telemetryStatusReportRequestId, reportSpecifierId: 'TELEMETRY_STATUS', startDate: '2020-05-13T10:56:11.058-06:00', }, ]; await ven.sendReportData(reports); }); after(async () => { await app.stop(); }); }); describe('optIn', async function() { let clock; after(async () => { clock.restore(); }); let ven, events, pollResponse; before(async () => { clock = sinon.useFakeTimers( new Date('2020-04-26T01:00:00.000Z').getTime(), ); await sequelize.sync(); await VenDb.destroy({ truncate: true }); await app.start(); const clientCrtPem = readFileSync( path.join(__dirname, 'integration-client.crt'), 'utf-8', ); ven = new Ven( `http://127.0.0.1:${port}`, clientCrtPem, 'aabbccddeeff', venId, 'ven.js1', ); await ven.register(); pollResponse = await ven.poll(); events = pollResponse.events; }); it('should successfully poll for events', async () => { expect(pollResponse._type).to.eql('oadrDistributeEvent'); expect(pollResponse.events.length).to.eql(1); }); it('should return same events if not opted', async () => { const pollResponse = await ven.poll(); expect(pollResponse._type).to.eql('oadrDistributeEvent'); expect(pollResponse.events.length).to.eql(1); }); it('should return no events if opted', async () => { const eventId = events[0].eventDescriptor.eventId; const modificationNumber = events[0].eventDescriptor.modificationNumber; await ven.opt('optIn', eventId, modificationNumber); const pollResponse = await ven.poll(); expect(pollResponse._type).to.eql('oadrResponse'); }); after(async () => { await app.stop(); }); }); });