testing connection object

This commit is contained in:
balzack 2024-07-07 10:41:45 -07:00
parent 3bedc7acd7
commit 3ef40a532f
4 changed files with 178 additions and 8 deletions

View File

@ -0,0 +1,50 @@
import { EventEmitter } from 'eventemitter3';
import { Revision, Ringing } from '../src/entities';
export class MockConnection {
private emitter: EventEmitter;
constructor() {
this.emitter = new EventEmitter();
}
public close() {
}
public addRevisionListener(ev: (revision: Revision) => void): void {
this.emitter.on('revision', ev);
}
public removeRevisionListener(ev: (revision: Revision) => void): void {
this.emitter.off('revision', ev);
}
public addRingListener(ev: (ringing: Ringing) => void): void {
this.emitter.on('ringing', ev);
}
public removeRingListener(ev: (ringing: Ringing) => void): void {
this.emitter.off('ringing', ev);
}
public addStatusListener(ev: (status: string) => void): void {
this.emitter.on('status', ev);
}
public removeStatusListener(ev: (status: string) => void): void {
this.emitter.off('status', ev);
}
public emitRevision(revision: Revision): void {
this.emitter.emit('revision', revision);
}
public emitRing(ring: Ringing): void {
this.emitter.emit('ringing', ring);
}
public emitStatus(status: string): void {
this.emitter.emit('status', status);
}
}

View File

@ -1,22 +1,26 @@
import { DatabagSDK } from '../src/index';
import { type SessionParams } from '../src/types';
import { Connection } from '../src/connection';
import { MockConnection } from '../__mocks__/connection';
let mockClose = jest.fn();
const mock = new MockConnection();
jest.mock('../src/connection', () => {
return {
Connection: jest.fn().mockImplementation(() => {
return { close: mockClose };
return mock;
})
}
})
test('allocates session correctly', async () => {
let status: string = '';
const sdk = new DatabagSDK(null);
const params: SessionParams = { topicBatch: 0, tagBatch: 0, channelTypes: [], pushType: '', deviceToken: '', notifications: [], deviceId: '', version: '', appName: '' };
const session = await sdk.login('handle', 'password', 'url', null, params);
session.addStatusListener((ev: string) => { status = ev; });
const account = session.getAccount();
account.enableNotifications();
//expect(r).toBe(5);
mock.emitStatus('connected');
expect(status).toBe('connected');
});

103
app/sdk/src/connection.ts Normal file
View File

@ -0,0 +1,103 @@
import { EventEmitter } from 'eventemitter3';
import { Revision, Ringing } from './entities';
export class Connection {
private closed: boolean;
private emitter: EventEmitter;
private websocket: WebSocket;
constructor(token: string, url: string) {
this.closed = false;
this.emitter = new EventEmitter();
this.websocket = this.setWebSocket(token, url);
}
public close() {
this.closed = true;
if (this.websocket) {
this.websocket.close();
}
}
public addRevisionListener(ev: (revision: Revision) => void): void {
this.emitter.on('revision', ev);
}
public removeRevisionListener(ev: (revision: Revision) => void): void {
this.emitter.off('revision', ev);
}
public addRingListener(ev: (ringing: Ringing) => void): void {
this.emitter.on('ringing', ev);
}
public removeRingListener(ev: (ringing: Ringing) => void): void {
this.emitter.off('ringing', ev);
}
public addStatusListener(ev: (status: string) => void): void {
this.emitter.on('status', ev);
}
public removeStatusListener(ev: (status: string) => void): void {
this.emitter.off('status', ev);
}
private setWebSocket(token: string, url: string): WebSocket {
if (this.closed) {
this.emitter.emit('status', 'closed');
return this.websocket;
}
this.emitter.emit('status', 'connecting');
const wsUrl = `ws${url.split('http')?.[1]}/status?mode=ring`;
const ws = new WebSocket(url);
ws.onmessage = (e) => {
try {
if (e.data === '') {
this.close();
}
const activity = JSON.parse(e.data);
this.emitter.emit('status', 'connected');
if (activity.revision) {
this.emitter.emit('revision', activity.revision as Revision);
}
else if (activity.ring) {
const { cardId, callId, calleeToken, ice, iceUrl, iceUsername, icePassword } = activity.ring;
const ringing: Ringing = { cardId, callId, calleeToken, ice: ice ? ice : [{ urls: iceUrl, username: iceUsername, credential: icePassword }] };
this.emitter.emit('ring', ringing);
}
else {
this.emitter.emit('revision', activity as Revision);
}
}
catch (err) {
console.log(err);
ws.close();
}
}
ws.onclose = (e) => {
console.log(e);
this.emitter.emit('status', 'disconnected');
setTimeout(() => {
if (ws != null) {
ws.onmessage = () => {}
ws.onclose = () => {}
ws.onopen = () => {}
ws.onerror = () => {}
this.websocket = this.setWebSocket(token, url);
}
}, 1000);
}
ws.onopen = () => {
ws.send(JSON.stringify({ AppToken: token }))
}
ws.onerror = (e) => {
console.log(e)
ws.close();
}
return ws;
}
}

View File

@ -13,10 +13,11 @@ import { RingModule } from './ring';
import { Connection } from './connection';
import type { Session, SqlStore, WebStore, Crypto, Account, Identity, Contact, Ring, Alias, Attribute, Content, Stream, Focus } from './api';
import { Revision, Ringing } from './entities';
export class SessionModule implements Session {
private statusEmitter: EventEmitter;
private emitter: EventEmitter;
private store: SqlStore | WebStore | null;
private crypto: Crypto | null;
private token: string;
@ -38,7 +39,7 @@ export class SessionModule implements Session {
this.token = token;
this.url = url;
this.sync = true;
this.statusEmitter = new EventEmitter();
this.emitter = new EventEmitter();
this.account = new AccountModule(token, url, this.setSync);
this.identity = new IdentityModule(token, url, this.setSync);
this.contact = new ContactModule(token, url, this.setSync);
@ -48,14 +49,26 @@ export class SessionModule implements Session {
this.stream = new StreamModule(this.contact, this.content);
this.ring = new RingModule();
this.connection = new Connection(token, url);
this.connection.addStatusListener((ev: string) => {
this.emitter.emit('status', ev);
});
this.connection.addRevisionListener((ev: Revision) => {
// handle revision
});
this.connection.addRingListener((ev: Ringing) => {
// handle ringing
});
}
public addStatusListener(ev: (status: string) => void): void {
this.statusEmitter.on('status', ev);
this.emitter.on('status', ev);
}
public removeStatusListener(ev: (status: string) => void): void {
this.statusEmitter.off('status', ev);
this.emitter.off('status', ev);
}
public setSync(sync: boolean) {