Home Reference Source

src/users-new/UserRepository.spec.ts

import {expect} from 'chai';
import {TestScheduler} from 'rxjs/testing';
import sinon, {StubbedInstance, stubConstructor} from 'ts-sinon';
import {Resolver} from '../wac-proxy/wac-stack/resolver/Resolver';
import {UserRepository} from './UserRepository';
import {WapiClient} from '@quobis/wapi-client';
import {WacRequest} from '../wac-proxy/wac-stack/WacRequest';
import {UserDto} from '../wac-proxy/wac-stack/resolver/types';
import {User} from './User';
import {PresenceService} from '../wac-proxy/wac-stack/presence/PresenceService';
import {PresenceDto} from '../wac-proxy/wac-stack/presence/types';
import {UserRole} from './UserRole';
import {UserDtoBuilder} from '../wac-proxy/wac-stack/resolver/builders';
import {PresenceDtoBuilder} from '../wac-proxy/wac-stack/presence/builders';

const createUserModel = (data: UserDto, presence: PresenceDto): User => ({
	id: data.id,
	domain: data.domain,
	username: data.username,
	email: data.email,
	mobilePhones: data.mobilePhone,
	alias: data.alias,
	role: UserRole.USER,
	gatewayUsername: data.gatewayUsername,
	online: presence.online,
	activity: presence.activity,
	mood: presence.mood,
	note: presence.note,
	avatar: presence.avatar,
	displayName: presence.displayName,
});

describe('users-new/UsersRepository', () => {
	let testScheduler: TestScheduler;
	let resolver: StubbedInstance<Resolver>;
	let presenceService: StubbedInstance<PresenceService>;

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

	it('should be lazily created', () => {
		new UserRepository(resolver, presenceService);
		sinon.assert.notCalled(resolver.getResolvedUsers$);
	});

	it('should initialize the user list with initial data', () => {
		testScheduler.run(({expectObservable, cold}) => {
			const userDto = UserDtoBuilder.of().build();
			const presenceDto = PresenceDtoBuilder.of(userDto.id).build();
			resolver.resolveUsers$.withArgs([userDto.id]).returns(cold('a|', {a: {resolved: [userDto], subscribed: [userDto.id]}}));
			presenceService.subscribeToPresences$.withArgs([`wac-user:${userDto.id}`]).returns(cold('a|', {a: [presenceDto]}));
			const userRepository = new UserRepository(resolver, presenceService);

			expectObservable(userRepository.getUser$(userDto.id)).toBe('100ms a', {
				a: createUserModel(userDto, presenceDto),
			});
		});
	});

	it('should update users every time that receives a change in their presence', () => {
		testScheduler.run(({expectObservable, cold, hot}) => {
			const userDto = UserDtoBuilder.of().build();
			const presenceDto = PresenceDtoBuilder.of(userDto.id).build();
			resolver.resolveUsers$.withArgs([userDto.id]).returns(cold('a|', {a: {resolved: [userDto], subscribed: [userDto.id]}}));
			presenceService.subscribeToPresences$.withArgs([`wac-user:${userDto.id}`]).returns(cold('a|', {a: [presenceDto]}));

			sinon.stub(presenceService, 'event$').value(hot('^ 499ms a 99ms b', {
				a: {body: {...presenceDto, online: false}},
				b: {body: {...presenceDto, activity: 'away'}},
			}));
			sinon.stub(resolver, 'event$').value(hot('^ 549ms a', {
				a: {body: {resolved: [{...userDto, alias: 'foo'}], subscribed: [userDto.id]}},
			}));
			const userRepository = new UserRepository(resolver, presenceService);

			expectObservable(userRepository.getUser$(userDto.id)).toBe('100ms a 399ms b 49ms c 49ms d', {
				a: createUserModel(userDto, presenceDto),
				b: createUserModel(userDto, {...presenceDto, online: false}),
				c: createUserModel({...userDto, alias: 'foo'}, {...presenceDto, online: false}),
				d: createUserModel({...userDto, alias: 'foo'}, {...presenceDto, activity: 'away'}),
			});
		});
		sinon.assert.calledOnce(presenceService.subscribeToPresences$);
	});
});