packages/chat-stateful-client/src/TestHelpers.ts (138 lines of code) (raw):
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { PagedAsyncIterableIterator } from '@azure/core-paging';
import { ChatClient, ChatThreadItem } from '@azure/communication-chat';
import { ChatClientState } from './ChatClientState';
import { _createStatefulChatClientWithDeps, StatefulChatClient, StatefulChatClientArgs } from './StatefulChatClient';
import { createMockChatThreadClient } from './mocks/createMockChatThreadClient';
import { createMockIterator } from './mocks/createMockIterator';
import { MockCommunicationUserCredential } from './mocks/MockCommunicationUserCredential';
import { ChatMessageWithStatus } from './types/ChatMessageWithStatus';
/**
* @private
*/
export class StateChangeListener {
state: ChatClientState;
onChangeCalledCount = 0;
constructor(client: StatefulChatClient) {
this.state = client.getState();
client.onStateChange(this.onChange.bind(this));
}
private onChange(newState: ChatClientState): void {
this.onChangeCalledCount++;
this.state = newState;
}
}
/**
* @private
*
* An iterator that throws the given error when asynchronously iterating over items, directly or byPage.
*/
export const failingPagedAsyncIterator = <T>(error: Error): PagedAsyncIterableIterator<T, T[]> => {
return {
async next() {
throw error;
},
[Symbol.asyncIterator]() {
return this;
},
byPage: (): AsyncIterableIterator<T[]> => {
return {
async next() {
throw error;
},
[Symbol.asyncIterator]() {
return this;
}
};
}
};
};
/**
* @private
*/
export const defaultClientArgs: StatefulChatClientArgs = {
displayName: '',
userId: { communicationUserId: 'userId1' },
endpoint: '',
credential: new MockCommunicationUserCredential()
};
/**
* @private
*/
export type StatefulChatClientWithEventTrigger = StatefulChatClient & {
triggerEvent: (eventName: string, e: any) => Promise<void>;
};
/**
* @private
*/
export const createStatefulChatClientMock = (): StatefulChatClientWithEventTrigger => {
return _createStatefulChatClientWithDeps(
createMockChatClient(),
defaultClientArgs
) as StatefulChatClientWithEventTrigger;
};
/**
* @private
*/
export const messageTemplate: ChatMessageWithStatus = {
id: 'MessageId',
content: { message: 'MessageContent' },
clientMessageId: undefined,
createdOn: new Date(),
sender: {
kind: 'communicationUser',
communicationUserId: 'UserId'
},
senderDisplayName: 'User',
type: 'text',
sequenceId: '',
version: '',
status: 'delivered'
};
/**
* @private
*/
export const messageTemplateWithResourceCache: ChatMessageWithStatus = {
id: 'MessageId',
content: { message: 'MessageContent' },
clientMessageId: undefined,
createdOn: new Date(),
sender: {
kind: 'communicationUser',
communicationUserId: 'UserId'
},
senderDisplayName: 'User',
type: 'text',
sequenceId: '',
version: '',
status: 'delivered',
resourceCache: { resource1Url: { sourceUrl: 'blob:resource1' }, resource2Url: { sourceUrl: 'blob:resource2' } }
};
/**
* @private
*/
export type ChatClientWithEventTrigger = ChatClient & {
triggerEvent: (eventName: string, e: any) => Promise<void>;
};
/**
* @private
*/
export function createMockChatClient(): ChatClientWithEventTrigger {
const mockEventHandlersRef: { value: any } = { value: {} };
const mockChatClient: ChatClientWithEventTrigger = {} as any;
mockChatClient.createChatThread = async (request) => {
return {
chatThread: {
id: 'chatThreadId',
topic: request.topic,
createdOn: new Date(0),
createdBy: { kind: 'communicationUser', communicationUserId: 'user1' }
}
};
};
mockChatClient.listChatThreads = mockListChatThreads;
mockChatClient.deleteChatThread = emptyAsyncFunctionWithResponse;
mockChatClient.getChatThreadClient = (threadId) => {
return createMockChatThreadClient(threadId);
};
mockChatClient.on = ((event: Parameters<ChatClient['on']>[0], listener: (e: Event) => void) => {
mockEventHandlersRef.value[event] = listener;
}) as any;
mockChatClient.off = ((event: Parameters<ChatClient['on']>[0], listener: (e: Event) => void) => {
if (mockEventHandlersRef.value[event] === listener) {
mockEventHandlersRef.value[event] = undefined;
}
}) as any;
mockChatClient.startRealtimeNotifications = emptyAsyncFunctionWithResponse;
mockChatClient.stopRealtimeNotifications = emptyAsyncFunctionWithResponse;
mockChatClient.triggerEvent = async (eventName: string, e: any): Promise<void> => {
const handler = mockEventHandlersRef.value[eventName];
if (handler !== undefined) {
await handler(e);
}
};
return mockChatClient;
}
const mockListChatThreads = (): any => {
return createMockIterator(mockChatThreads);
};
// [1, 2 ... 5] array
const seedArray = Array.from(Array(5).keys());
/**
* @private
*/
export const mockChatThreads: ChatThreadItem[] = seedArray.map((seed) => ({
id: 'chatThreadId' + seed,
topic: 'topic' + seed,
createdOn: new Date(seed * 10000),
createdBy: { communicationUserId: 'user' + seed }
}));
const emptyAsyncFunctionWithResponse = async (): Promise<any> => {
return { _response: {} as any };
};