Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
longzheng committed Aug 14, 2024
1 parent 25f8a52 commit 6301601
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 36 deletions.
34 changes: 0 additions & 34 deletions src/sep2/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,40 +31,6 @@ beforeAll(() => {
});
});

// it('discover should get device capabilities and childs', async () => {
// sep2Client.discover();

// expect(timeLink.href).toBe('/api/v2/tm');
// expect(endDeviceListLink.href).toBe('/api/v2/edev');
// expect(mirrorUsagePointListLink.href).toBe('/api/v2/mup');
// });

// it('should assert time delta successfully', async () => {
// mockAxios
// .onGet('http://example.com/time')
// .reply(200, getMockFile('getTm.xml'));

// // mock system date to match the time in the mock file
// const mockDate = new Date(1682475024000);
// vi.setSystemTime(mockDate);

// await sep2Client.getTime('/time');
// });

// it('should assert time delta with exception', async () => {
// mockAxios
// .onGet('http://example.com/time')
// .reply(200, getMockFile('getTm.xml'));

// // mock system date to not match the time in the mock file
// const mockDate = new Date(1582475024000);
// vi.setSystemTime(mockDate);

// await expect(
// async () => await sep2Client.getTime('/time'),
// ).rejects.toThrowError('Clock is not synced with Utility Server');
// });

// it('should get end device list', async () => {
// mockAxios
// .onGet('http://example.com/edev')
Expand Down
41 changes: 41 additions & 0 deletions src/sep2/helpers/deviceCapability.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { describe, it, expect, vi, beforeAll } from 'vitest';
import { SEP2Client } from '../client';
import { mockCert, mockKey } from '../../../tests/sep2/cert';
import { DeviceCapabilityHelper } from './deviceCapability';
import MockAdapter from 'axios-mock-adapter';
import axios from 'axios';
import { getMockFile } from './mocks';

const mockAxios = new MockAdapter(axios);

const sep2Client = new SEP2Client({
sep2Config: {
host: 'http://example.com',
dcapUri: '/dcap',
pen: 12345,
},
cert: mockCert,
key: mockKey,
});

beforeAll(() => {
mockAxios
.onGet('http://example.com/dcap')
.reply(200, getMockFile('getDcap.xml'));
});

describe('DeviceCapabilityHelper', () => {
it('should emit data event with response', async () => {
const eventSpy = vi.fn();

new DeviceCapabilityHelper({
client: sep2Client,
href: '/dcap',
defaultPollRateSeconds: 30,
}).on('data', eventSpy);

await vi.waitFor(() => expect(eventSpy).toHaveBeenCalled());

expect(eventSpy).toHaveBeenCalledOnce();
});
});
92 changes: 92 additions & 0 deletions src/sep2/helpers/time.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import {
describe,
it,
expect,
vi,
beforeAll,
beforeEach,
afterEach,
} from 'vitest';
import { SEP2Client } from '../client';
import { mockCert, mockKey } from '../../../tests/sep2/cert';
import MockAdapter from 'axios-mock-adapter';
import axios from 'axios';
import { getMockFile } from './mocks';
import { TimeHelper } from './time';

const mockAxios = new MockAdapter(axios);

const sep2Client = new SEP2Client({
sep2Config: {
host: 'http://example.com',
dcapUri: '/dcap',
pen: 12345,
},
cert: mockCert,
key: mockKey,
});

beforeAll(() => {
mockAxios
.onGet('http://example.com/api/v2/tm')
.reply(200, getMockFile('getTm.xml'));
});

describe('TimeHelper', () => {
beforeEach(() => {
// tell vitest we use mocked time
vi.useFakeTimers();
});

afterEach(() => {
// restoring date after each test run
vi.useRealTimers();
});

it('should not should if clock is in sync', async () => {
const time = new TimeHelper();

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const spy = vi.spyOn(time, 'assertTime' as any);

time.init({
client: sep2Client,
href: '/api/v2/tm',
defaultPollRateSeconds: 30,
});

// mock system date to match the time in the mock file
const mockDate = new Date(1682475024000);
vi.setSystemTime(mockDate);

await vi.waitFor(() => expect(spy).toHaveBeenCalled());

expect(spy).toHaveBeenCalledOnce();
});

it('should throw error if clock is not in sync', async () => {
const fn = vi.fn();

process.on('unhandledRejection', fn);

const time = new TimeHelper();

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const spy = vi.spyOn(time, 'assertTime' as any);

time.init({
client: sep2Client,
href: '/api/v2/tm',
defaultPollRateSeconds: 30,
});

// mock system date to match the time in the mock file
const mockDate = new Date(1582475024000);
vi.setSystemTime(mockDate);

await vi.waitFor(() => expect(spy).toHaveBeenCalled());

expect(spy).toHaveBeenCalledOnce();
expect(fn).toHaveBeenCalledOnce();
});
});
15 changes: 13 additions & 2 deletions src/sep2/helpers/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ import { type SEP2Client } from '../client';
import { PollableResource } from './pollableResource';
import type { Time } from '../models/time';
import { parseTimeXml } from '../models/time';
import type { Logger } from 'pino';
import { logger as pinoLogger } from '../../logger';

export class TimeHelper {
private href: string | null = null;
private timePollableResource: TimePollableResource | null = null;
private logger: Logger;

constructor() {
this.logger = pinoLogger.child({ module: 'TimeHelper' });
}

public init({
client,
Expand Down Expand Up @@ -37,12 +44,16 @@ export class TimeHelper {
const now = new Date();
const delta = now.getTime() - time.currentTime.getTime();

if (Math.abs(delta) > 60000) {
// 1 minute in milliseconds
// 1 minute tolerance
if (Math.abs(delta) > 60 * 1_000) {
throw new Error(
`Clock is not synced with Utility Server, delta ${delta}ms`,
);
}

this.logger.info(
`Clock is synced with Utility Server, delta ${delta}ms`,
);
}

public destroy() {
Expand Down

0 comments on commit 6301601

Please sign in to comment.