signal-desktop/ts/test-both/state/selectors/search_test.ts

212 lines
5.6 KiB
TypeScript

// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import {
ConversationType,
getEmptyState as getEmptyConversationState,
MessageType,
} from '../../../state/ducks/conversations';
import { noopAction } from '../../../state/ducks/noop';
import { getEmptyState as getEmptySearchState } from '../../../state/ducks/search';
import { getEmptyState as getEmptyUserState } from '../../../state/ducks/user';
import { getMessageSearchResultSelector } from '../../../state/selectors/search';
import { StateType, reducer as rootReducer } from '../../../state/reducer';
describe('both/state/selectors/search', () => {
const getEmptyRootState = (): StateType => {
return rootReducer(undefined, noopAction());
};
function getDefaultMessage(id: string): MessageType {
return {
id,
conversationId: 'conversationId',
source: 'source',
sourceUuid: 'sourceUuid',
type: 'incoming' as const,
received_at: Date.now(),
attachments: [],
sticker: {},
unread: false,
};
}
function getDefaultConversation(id: string): ConversationType {
return {
id,
type: 'direct',
title: `${id} title`,
};
}
describe('#getMessageSearchResultSelector', () => {
it('returns undefined if message not found in lookup', () => {
const state = getEmptyRootState();
const selector = getMessageSearchResultSelector(state);
const actual = selector('random-id');
assert.strictEqual(actual, undefined);
});
it('returns undefined if type is unexpected', () => {
const id = 'message-id';
const state = {
...getEmptyRootState(),
search: {
...getEmptySearchState(),
messageLookup: {
[id]: {
...getDefaultMessage(id),
type: 'keychange' as const,
snippet: 'snippet',
},
},
},
};
const selector = getMessageSearchResultSelector(state);
const actual = selector(id);
assert.strictEqual(actual, undefined);
});
it('returns incoming message', () => {
const searchId = 'search-id';
const fromId = 'from-id';
const toId = 'to-id';
const from = getDefaultConversation(fromId);
const to = getDefaultConversation(toId);
const state = {
...getEmptyRootState(),
conversations: {
...getEmptyConversationState(),
conversationLookup: {
[fromId]: from,
[toId]: to,
},
},
search: {
...getEmptySearchState(),
messageLookup: {
[searchId]: {
...getDefaultMessage(searchId),
type: 'incoming' as const,
sourceUuid: fromId,
conversationId: toId,
snippet: 'snippet',
},
},
},
};
const selector = getMessageSearchResultSelector(state);
const actual = selector(searchId);
const expected = {
from,
to,
id: searchId,
conversationId: toId,
sentAt: undefined,
snippet: 'snippet',
isSelected: false,
isSearchingInConversation: false,
};
assert.deepEqual(actual, expected);
});
it('returns outgoing message and caches appropriately', () => {
const searchId = 'search-id';
const fromId = 'from-id';
const toId = 'to-id';
const from = getDefaultConversation(fromId);
const to = getDefaultConversation(toId);
const state = {
...getEmptyRootState(),
user: {
...getEmptyUserState(),
ourConversationId: fromId,
},
conversations: {
...getEmptyConversationState(),
conversationLookup: {
[fromId]: from,
[toId]: to,
},
},
search: {
...getEmptySearchState(),
messageLookup: {
[searchId]: {
...getDefaultMessage(searchId),
type: 'outgoing' as const,
conversationId: toId,
snippet: 'snippet',
},
},
},
};
const selector = getMessageSearchResultSelector(state);
const actual = selector(searchId);
const expected = {
from,
to,
id: searchId,
conversationId: toId,
sentAt: undefined,
snippet: 'snippet',
isSelected: false,
isSearchingInConversation: false,
};
assert.deepEqual(actual, expected);
// Update the conversation lookup, but not the conversations in question
const secondState = {
...state,
conversations: {
...state.conversations,
conversationLookup: {
...state.conversations.conversationLookup,
},
},
};
const secondSelector = getMessageSearchResultSelector(secondState);
const secondActual = secondSelector(searchId);
assert.strictEqual(secondActual, actual);
// Update a conversation involved in rendering this search result
const thirdState = {
...state,
conversations: {
...state.conversations,
conversationLookup: {
...state.conversations.conversationLookup,
[fromId]: {
...from,
name: 'new-name',
},
},
},
};
const thirdSelector = getMessageSearchResultSelector(thirdState);
const thirdActual = thirdSelector(searchId);
assert.notStrictEqual(actual, thirdActual);
});
});
});