'use strict'; const { expect } = require('chai'); const { v4 } = require('uuid'); const sinon = require('sinon'); const rewire = require('rewire'); const FakeNantumModule = require('../utils/fake-nantum-module'); const { sampleEvent1, sampleVenRegistration1, sampleReport1, sampleVen1 } = require('../modules/nantum-responses'); const { registerReportMax, createdReportGenerated1, updateReportTelemetryStatus, } = require('../xml/report/js-requests'); const { createReportGenerated1, createReportGenerated2, } = require('../xml/report/js-responses'); const { poll: oadrPollMessage } = require('../xml/poll/js-requests'); describe('Report', function() { let clock; let rewired; let nantum; let uuidSequence; after(async () => { clock.restore(); }); beforeEach(async () => { clock = sinon.useFakeTimers(new Date('2020-04-26T01:00:00.000Z').getTime()); uuidSequence = 0; }); before(async () => { nantum = new FakeNantumModule({ events: [sampleEvent1], venRegistrations: [sampleVenRegistration1], vens: [sampleVen1], }); rewired = rewire('../../../processes/report.js'); rewired.__set__({ nantum, v4: () => `uuid${uuidSequence++}`, }); }); describe('requesting VEN reports', function() { it('successfully registers reports', async () => { const venId = registerReportMax.venId; const commonName = v4() .replace(/-/g, '') .substring(0, 12); const registeredReport = await rewired.registerReports( registerReportMax, commonName, venId, ); expect(registeredReport.responseCode).to.eql('200'); expect(nantum.venReports.length).to.eql(1); expect(nantum.venReports[0].reports).to.eql(sampleReport1); }); it('requests reports on next poll', async () => { const venId = registerReportMax.venId; const commonName = v4() .replace(/-/g, '') .substring(0, 12); const pollResponse = await rewired.pollForReports( oadrPollMessage, commonName, venId, ); expect(pollResponse).to.eql(createReportGenerated1); }); it('does not request reports again immediately following poll', async () => { const venId = registerReportMax.venId; const commonName = v4() .replace(/-/g, '') .substring(0, 12); const pollResponse = await rewired.pollForReports( oadrPollMessage, commonName, venId, ); expect(pollResponse).to.eql(undefined); }); it('does request reports again immediately following poll when enough time has elapsed', async () => { clock = sinon.useFakeTimers( new Date('2020-04-26T01:01:30.000Z').getTime(), ); const venId = registerReportMax.venId; const commonName = v4() .replace(/-/g, '') .substring(0, 12); const pollResponse = await rewired.pollForReports( oadrPollMessage, commonName, venId, ); expect(pollResponse).to.eql(createReportGenerated2); }); it('re-sends create request when no data received for 95 seconds', async () => { const venId = registerReportMax.venId; const commonName = v4() .replace(/-/g, '') .substring(0, 12); const pollResponse1 = await rewired.pollForReports( oadrPollMessage, commonName, venId, ); expect(pollResponse1).to.eql(undefined); await rewired.registerReports(registerReportMax, commonName, venId); const pollResponse2 = await rewired.pollForReports( oadrPollMessage, commonName, venId, ); // should immediately request 2 reports expect(pollResponse2).to.not.be.undefined; expect(pollResponse2.requests.length).to.eql(2); // ven should respond that it has accepted those 2 report requests const createdResponse = await rewired.createdReports( createdReportGenerated1, commonName, venId, ); expect(createdResponse.responseCode).to.eql('200'); // ven sends report telemetry data const receiveResponse = await rewired.receiveReportData( updateReportTelemetryStatus, commonName, venId, ); expect(receiveResponse.responseCode).to.eql('200'); // advance time 45 seconds. subscription is valid, should not resubscribe clock = sinon.useFakeTimers( new Date('2020-04-26T01:00:45.000Z').getTime(), ); const pollResponse3 = await rewired.pollForReports( oadrPollMessage, commonName, venId, ); expect(pollResponse3).to.be.undefined; clock = sinon.useFakeTimers( new Date('2020-04-26T01:01:35.000Z').getTime(), ); // advance +95 seconds // should trigger a create request because data is stale const pollResponse4 = await rewired.pollForReports( oadrPollMessage, commonName, venId, ); expect(pollResponse4).to.not.be.undefined; expect(pollResponse4._type).to.eql('oadrCreateReport'); expect(pollResponse4.requests.length).to.eql(2); }); it('re-sends create request when created not received', async () => { const venId = registerReportMax.venId; const commonName = v4() .replace(/-/g, '') .substring(0, 12); await rewired.registerReports(registerReportMax, commonName, venId); const pollResponse1 = await rewired.pollForReports( oadrPollMessage, commonName, venId, ); expect(pollResponse1).to.not.be.undefined; expect(pollResponse1.requests.length).to.eql(2); // advance time 8 seconds. should offer to re-subscribe clock = sinon.useFakeTimers( new Date('2020-04-26T01:00:08.000Z').getTime(), ); const pollResponse2 = await rewired.pollForReports( oadrPollMessage, commonName, venId, ); expect(pollResponse2).to.not.be.undefined; expect(pollResponse2.requests.length).to.eql(2); // now VEN sends created response const createdResponse = await rewired.createdReports( createdReportGenerated1, commonName, venId, ); expect(createdResponse.responseCode).to.eql('200'); // advance time 8 seconds. should not offer to re-subscribe. clock = sinon.useFakeTimers( new Date('2020-04-26T01:00:16.000Z').getTime(), ); const pollResponse3 = await rewired.pollForReports( oadrPollMessage, commonName, venId, ); expect(pollResponse3).to.be.undefined; }); }); });