Home Reference Source

src/users/Presence.spec.ts

import {WapiClient} from '@quobis/wapi-client';
import {expect} from 'chai';
import {TestScheduler} from 'rxjs/testing';
import sinon, {StubbedInstance, stubConstructor} from 'ts-sinon';

import {WacRequest} from '../wac-proxy/wac-stack/WacRequest';
import {PresenceService} from '../wac-proxy/wac-stack/presence/PresenceService';
import {PresenceDtoBuilder} from '../wac-proxy/wac-stack/presence/builders';
import {PresenceDto} from '../wac-proxy/wac-stack/presence/types';

import {Presence} from './Presence';
import {PresenceState} from './PresenceState';

const toPresenceState = (presenceDto: PresenceDto): PresenceState => ({
	online: presenceDto.online,
	activity: presenceDto.activity,
	mood: presenceDto.mood,
	note: presenceDto.note,
	avatar: presenceDto.avatar,
	displayName: presenceDto.displayName,
});

describe('users/Presence', () => {
	let testScheduler: TestScheduler;
	let presenceService: StubbedInstance<PresenceService>;

	beforeEach(() => {
		testScheduler = new TestScheduler((actual, expected) => {
			expect(actual).to.deep.equal(expected);
		});
		presenceService = stubConstructor(PresenceService, stubConstructor(WacRequest, stubConstructor(WapiClient)));
	});

	it('should be lazily created', () => {
		new Presence(presenceService, 'ownId');
		sinon.assert.notCalled(presenceService.subscribeToPresence$);
	});

	it('should provide an observable with the current state', () => {
		testScheduler.run(({expectObservable, cold, hot}) => {
			const presenceDto = PresenceDtoBuilder.of('ownId').build();
			presenceService.subscribeToPresence$.withArgs(presenceDto.address).returns(cold('17ms a|', {a: presenceDto}));
			sinon.stub(presenceService, 'event$').value(hot('^z 16ms 2ms b 10ms c', {
				z: {body: {...presenceDto, note: 'this event is ignored'}},
				b: {body: {...presenceDto, online: true}},
				c: {body: {...presenceDto, activity: 'busy'}},
			}));
			const presence = new Presence(presenceService, 'wac-user:ownId');

			expectObservable(presence.state$).toBe('17ms a 2ms b 10ms c ', {
				a: toPresenceState(presenceDto),
				b: toPresenceState({...presenceDto, online: true}),
				c: toPresenceState({...presenceDto, activity: 'busy'}),
			});
		});
	});

	it('should provide a method to update the state', () => {
		const presenceDto = PresenceDtoBuilder.of('ownId').build();

		testScheduler.run(({expectObservable, cold}) => {
			presenceService.update$.returns(cold('2ms a', {a: {...presenceDto, online: true}}));
			const presence = new Presence(presenceService, 'wac-user:ownId');

			expectObservable(presence.update({online: true})).toBe('2ms a ', {a: undefined});
		});
		sinon.assert.calledWith(presenceService.update$, 'wac-user:ownId', {
			online: true,
		});
	});
});