Introduce Service Id Types
Co-authored-by: Scott Nonnenberg <scott@signal.org>
This commit is contained in:
parent
414c0a58d3
commit
366b875fd2
269 changed files with 5832 additions and 5550 deletions
|
@ -26,7 +26,7 @@ describe('ContactsParser', () => {
|
|||
const contactInfoBuffer = Proto.ContactDetails.encode({
|
||||
name: 'Zero Cool',
|
||||
number: '+10000000000',
|
||||
uuid: '7198E1BD-1293-452A-A098-F982FF201902',
|
||||
aci: '7198E1BD-1293-452A-A098-F982FF201902',
|
||||
avatar: { contentType: 'image/jpeg', length: avatarBuffer.length },
|
||||
}).finish();
|
||||
|
||||
|
@ -52,10 +52,7 @@ describe('ContactsParser', () => {
|
|||
count += 1;
|
||||
assert.strictEqual(contact.name, 'Zero Cool');
|
||||
assert.strictEqual(contact.number, '+10000000000');
|
||||
assert.strictEqual(
|
||||
contact.uuid,
|
||||
'7198e1bd-1293-452a-a098-f982ff201902'
|
||||
);
|
||||
assert.strictEqual(contact.aci, '7198e1bd-1293-452a-a098-f982ff201902');
|
||||
assert.strictEqual(contact.avatar?.contentType, 'image/jpeg');
|
||||
assert.strictEqual(contact.avatar?.length, 255);
|
||||
assert.strictEqual(contact.avatar?.data.byteLength, 255);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import { assert } from 'chai';
|
||||
|
||||
import { normalizeAci } from '../types/ServiceId';
|
||||
import {
|
||||
getCountryCodeValue,
|
||||
getBucketValue,
|
||||
|
@ -10,7 +11,7 @@ import {
|
|||
} from '../RemoteConfig';
|
||||
|
||||
describe('RemoteConfig', () => {
|
||||
const uuid = '15b9729c-51ea-4ddb-b516-652befe78062';
|
||||
const uuid = normalizeAci('15b9729c-51ea-4ddb-b516-652befe78062', 'test');
|
||||
|
||||
describe('#innerIsBucketValueEnabled', () => {
|
||||
// Note: bucketValue is 497941 for 'desktop.stories2' key
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import { assert } from 'chai';
|
||||
import { times } from 'lodash';
|
||||
import { updateRemoteConfig } from '../helpers/RemoteConfigStub';
|
||||
import { UUID } from '../../types/UUID';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
|
||||
import { isConversationTooBigToRing } from '../../conversations/isConversationTooBigToRing';
|
||||
|
||||
|
@ -12,7 +12,7 @@ const CONFIG_KEY = 'global.calling.maxGroupCallRingSize';
|
|||
|
||||
describe('isConversationTooBigToRing', () => {
|
||||
const fakeMemberships = (count: number) =>
|
||||
times(count, () => ({ uuid: UUID.generate().toString(), isAdmin: false }));
|
||||
times(count, () => ({ uuid: generateAci(), isAdmin: false }));
|
||||
|
||||
it('returns false if there are no memberships (i.e., for a direct conversation)', () => {
|
||||
assert.isFalse(isConversationTooBigToRing({}));
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { assert } from 'chai';
|
||||
|
||||
import { UUID } from '../../types/UUID';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
import { _maybeBuildAddBannedMemberActions } from '../../groups';
|
||||
import { getClientZkGroupCipher, decryptUuid } from '../../util/zkgroup';
|
||||
import { updateRemoteConfig } from '../helpers/RemoteConfigStub';
|
||||
|
@ -11,10 +11,10 @@ import { updateRemoteConfig } from '../helpers/RemoteConfigStub';
|
|||
const HARD_LIMIT_KEY = 'global.groupsv2.groupSizeHardLimit';
|
||||
|
||||
describe('group add banned member', () => {
|
||||
const uuid = UUID.generate();
|
||||
const ourUuid = UUID.generate();
|
||||
const serviceId = generateAci();
|
||||
const ourAci = generateAci();
|
||||
const existing = Array.from({ length: 10 }, (_, index) => ({
|
||||
uuid: UUID.generate().toString(),
|
||||
uuid: generateAci(),
|
||||
timestamp: index,
|
||||
}));
|
||||
const secretParams =
|
||||
|
@ -36,8 +36,8 @@ describe('group add banned member', () => {
|
|||
it('should add banned member without deleting', () => {
|
||||
const actions = _maybeBuildAddBannedMemberActions({
|
||||
clientZkGroupCipher,
|
||||
uuid,
|
||||
ourUuid,
|
||||
serviceId,
|
||||
ourAci,
|
||||
group: {
|
||||
bannedMembersV2: [],
|
||||
},
|
||||
|
@ -49,7 +49,7 @@ describe('group add banned member', () => {
|
|||
clientZkGroupCipher,
|
||||
actions.addMembersBanned?.[0]?.added?.userId ?? new Uint8Array(0)
|
||||
),
|
||||
uuid.toString()
|
||||
serviceId
|
||||
);
|
||||
assert.strictEqual(actions.deleteMembersBanned, null);
|
||||
});
|
||||
|
@ -57,8 +57,8 @@ describe('group add banned member', () => {
|
|||
it('should add banned member while deleting the oldest', () => {
|
||||
const actions = _maybeBuildAddBannedMemberActions({
|
||||
clientZkGroupCipher,
|
||||
uuid,
|
||||
ourUuid,
|
||||
serviceId,
|
||||
ourAci,
|
||||
group: {
|
||||
bannedMembersV2: [...existing],
|
||||
},
|
||||
|
@ -77,7 +77,7 @@ describe('group add banned member', () => {
|
|||
clientZkGroupCipher,
|
||||
actions.addMembersBanned?.[0]?.added?.userId ?? new Uint8Array(0)
|
||||
),
|
||||
uuid.toString()
|
||||
serviceId
|
||||
);
|
||||
assert.deepStrictEqual(
|
||||
deleted,
|
||||
|
@ -91,8 +91,8 @@ describe('group add banned member', () => {
|
|||
it('should not ban ourselves', () => {
|
||||
const actions = _maybeBuildAddBannedMemberActions({
|
||||
clientZkGroupCipher,
|
||||
uuid: ourUuid,
|
||||
ourUuid,
|
||||
serviceId: ourAci,
|
||||
ourAci,
|
||||
group: {
|
||||
bannedMembersV2: [],
|
||||
},
|
||||
|
@ -105,10 +105,10 @@ describe('group add banned member', () => {
|
|||
it('should not ban already banned person', () => {
|
||||
const actions = _maybeBuildAddBannedMemberActions({
|
||||
clientZkGroupCipher,
|
||||
uuid,
|
||||
ourUuid,
|
||||
serviceId,
|
||||
ourAci,
|
||||
group: {
|
||||
bannedMembersV2: [{ uuid: uuid.toString(), timestamp: 1 }],
|
||||
bannedMembersV2: [{ uuid: serviceId, timestamp: 1 }],
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import { UUID } from '../../types/UUID';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
import {
|
||||
_isGroupChangeMessageBounceable,
|
||||
_mergeGroupChangeMessages,
|
||||
|
@ -11,13 +12,13 @@ import {
|
|||
|
||||
describe('group message merging', () => {
|
||||
const defaultMessage = {
|
||||
id: UUID.generate().toString(),
|
||||
conversationId: UUID.generate().toString(),
|
||||
id: generateUuid(),
|
||||
conversationId: generateUuid(),
|
||||
timestamp: Date.now(),
|
||||
sent_at: Date.now(),
|
||||
received_at: Date.now(),
|
||||
};
|
||||
const uuid = UUID.generate().toString();
|
||||
const uuid = generateAci();
|
||||
|
||||
describe('_isGroupChangeMessageBounceable', () => {
|
||||
it('should return true for admin approval add', () => {
|
||||
|
@ -106,7 +107,7 @@ describe('group message merging', () => {
|
|||
details: [
|
||||
{
|
||||
type: 'admin-approval-add-one' as const,
|
||||
uuid: UUID.generate().toString(),
|
||||
uuid: generateAci(),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -118,7 +119,7 @@ describe('group message merging', () => {
|
|||
details: [
|
||||
{
|
||||
type: 'admin-approval-remove-one' as const,
|
||||
uuid: UUID.generate().toString(),
|
||||
uuid: generateAci(),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@ import type {
|
|||
UUIDFetchStateType,
|
||||
UUIDFetchStateKeyType,
|
||||
} from '../../util/uuidFetchState';
|
||||
import type { lookupConversationWithoutUuid } from '../../util/lookupConversationWithoutUuid';
|
||||
import type { lookupConversationWithoutServiceId } from '../../util/lookupConversationWithoutServiceId';
|
||||
import { sleep } from '../../util/sleep';
|
||||
import * as durations from '../../util/durations';
|
||||
import type { ConversationType } from '../../state/ducks/conversations';
|
||||
|
@ -18,9 +18,9 @@ const VALID_IDENTIFIERS = new Set<UUIDFetchStateKeyType>([
|
|||
'username:bobross',
|
||||
]);
|
||||
|
||||
export function makeFakeLookupConversationWithoutUuid(
|
||||
export function makeFakeLookupConversationWithoutServiceId(
|
||||
saveConversation?: (convo: ConversationType) => void
|
||||
): typeof lookupConversationWithoutUuid {
|
||||
): typeof lookupConversationWithoutServiceId {
|
||||
const cache = new Map<UUIDFetchStateKeyType, ConversationType>();
|
||||
|
||||
return async options => {
|
|
@ -3,9 +3,11 @@
|
|||
|
||||
import casual from 'casual';
|
||||
import { sample } from 'lodash';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import type { ConversationType } from '../../state/ducks/conversations';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import { UUID } from '../../types/UUID';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
import type { GroupListItemConversationType } from '../../components/conversationList/GroupListItem';
|
||||
import { getRandomColor } from './getRandomColor';
|
||||
import { ConversationColors } from '../../types/Colors';
|
||||
|
@ -32,14 +34,14 @@ export function getDefaultConversation(
|
|||
conversationColor: ConversationColors[0],
|
||||
color: getRandomColor(),
|
||||
firstName,
|
||||
id: UUID.generate().toString(),
|
||||
id: generateUuid(),
|
||||
isMe: false,
|
||||
lastUpdated: casual.unix_time,
|
||||
markedUnread: Boolean(overrideProps.markedUnread),
|
||||
sharedGroupNames: [],
|
||||
title: `${firstName} ${lastName}`,
|
||||
titleNoDefault: `${firstName} ${lastName}`,
|
||||
uuid: UUID.generate().toString(),
|
||||
uuid: generateAci(),
|
||||
...overrideProps,
|
||||
type: 'direct' as const,
|
||||
acknowledgedGroupNameCollisions: undefined,
|
||||
|
@ -63,7 +65,7 @@ export function getDefaultGroup(
|
|||
overrideProps: Partial<ConversationType> = {}
|
||||
): ConversationType {
|
||||
const memberships = Array.from(Array(casual.integer(1, 20)), () => ({
|
||||
uuid: UUID.generate().toString(),
|
||||
uuid: generateAci(),
|
||||
isAdmin: Boolean(casual.coin_flip),
|
||||
}));
|
||||
|
||||
|
@ -75,10 +77,10 @@ export function getDefaultGroup(
|
|||
color: getRandomColor(),
|
||||
conversationColor: ConversationColors[0],
|
||||
groupDescription: casual.sentence,
|
||||
groupId: UUID.generate().toString(),
|
||||
groupId: generateUuid(),
|
||||
groupLink: casual.url,
|
||||
groupVersion: 2,
|
||||
id: UUID.generate().toString(),
|
||||
id: generateUuid(),
|
||||
isMe: false,
|
||||
lastUpdated: casual.unix_time,
|
||||
markedUnread: Boolean(overrideProps.markedUnread),
|
||||
|
@ -86,7 +88,7 @@ export function getDefaultGroup(
|
|||
memberships,
|
||||
sharedGroupNames: [],
|
||||
title: casual.title,
|
||||
uuid: UUID.generate().toString(),
|
||||
uuid: generateAci(),
|
||||
acknowledgedGroupNameCollisions: {},
|
||||
storySendMode: StorySendMode.IfActive,
|
||||
...overrideProps,
|
||||
|
@ -96,8 +98,8 @@ export function getDefaultGroup(
|
|||
|
||||
export function getDefaultConversationWithUuid(
|
||||
overrideProps: Partial<ConversationType> = {},
|
||||
uuid: UUIDStringType = UUID.generate().toString()
|
||||
): ConversationType & { uuid: UUIDStringType } {
|
||||
uuid: ServiceIdString = generateAci()
|
||||
): ConversationType & { uuid: ServiceIdString } {
|
||||
return {
|
||||
...getDefaultConversation(overrideProps),
|
||||
uuid,
|
||||
|
|
|
@ -6,7 +6,8 @@ import casual from 'casual';
|
|||
import type { StoryDistributionListDataType } from '../../state/ducks/storyDistributionLists';
|
||||
import type { StoryDistributionListWithMembersDataType } from '../../types/Stories';
|
||||
import { MY_STORY_ID } from '../../types/Stories';
|
||||
import { UUID } from '../../types/UUID';
|
||||
import { generateStoryDistributionId } from '../../types/StoryDistributionId';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
import { getDefaultConversation } from './getDefaultConversation';
|
||||
|
||||
export function getFakeDistributionListsWithMembers(): Array<StoryDistributionListWithMembersDataType> {
|
||||
|
@ -34,10 +35,10 @@ export function getFakeDistributionLists(): Array<StoryDistributionListDataType>
|
|||
export function getFakeDistributionList(): StoryDistributionListDataType {
|
||||
return {
|
||||
allowsReplies: Boolean(casual.coin_flip),
|
||||
id: UUID.generate().toString(),
|
||||
id: generateStoryDistributionId(),
|
||||
isBlockList: false,
|
||||
memberUuids: Array.from(Array(casual.integer(3, 12)), () =>
|
||||
UUID.generate().toString()
|
||||
memberServiceIds: Array.from(Array(casual.integer(3, 12)), () =>
|
||||
generateAci()
|
||||
),
|
||||
name: casual.title,
|
||||
};
|
||||
|
@ -48,7 +49,7 @@ export function getMyStories(): StoryDistributionListDataType {
|
|||
allowsReplies: true,
|
||||
id: MY_STORY_ID,
|
||||
isBlockList: true,
|
||||
memberUuids: [],
|
||||
memberServiceIds: [],
|
||||
name: MY_STORY_ID,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import casual from 'casual';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import type { AttachmentType } from '../../types/Attachment';
|
||||
import type { ConversationType } from '../../state/ducks/conversations';
|
||||
|
@ -11,7 +12,6 @@ import type {
|
|||
StoryViewType,
|
||||
} from '../../types/Stories';
|
||||
import * as durations from '../../util/durations';
|
||||
import { UUID } from '../../types/UUID';
|
||||
import { getDefaultConversation } from './getDefaultConversation';
|
||||
import { fakeAttachment, fakeThumbnail } from './fakeAttachment';
|
||||
import { MY_STORY_ID, ResolvedSendStatus } from '../../types/Stories';
|
||||
|
@ -28,7 +28,7 @@ export function getFakeMyStory(id?: string, name?: string): MyStoryType {
|
|||
const storyCount = casual.integer(2, 6);
|
||||
|
||||
return {
|
||||
id: id || UUID.generate().toString(),
|
||||
id: id || generateUuid(),
|
||||
name: name || id === MY_STORY_ID ? 'My Stories' : casual.catch_phrase,
|
||||
reducedSendStatus: ResolvedSendStatus.Sent,
|
||||
stories: Array.from(Array(storyCount), () => ({
|
||||
|
@ -45,7 +45,7 @@ export function getFakeStoryView(
|
|||
): StoryViewType {
|
||||
const sender = getDefaultConversation();
|
||||
|
||||
const messageId = UUID.generate().toString();
|
||||
const messageId = generateUuid();
|
||||
|
||||
return {
|
||||
attachment: getAttachmentWithThumbnail(
|
||||
|
|
|
@ -11,7 +11,9 @@ import {
|
|||
import type { ProcessedAttachment } from '../textsecure/Types.d';
|
||||
import { SignalService as Proto } from '../protobuf';
|
||||
import { IMAGE_GIF } from '../types/MIME';
|
||||
import { generateAci } from '../types/ServiceId';
|
||||
|
||||
const AUTHOR_SERVICE_ID = generateAci();
|
||||
const FLAGS = Proto.DataMessage.Flags;
|
||||
|
||||
const TIMESTAMP = Date.now();
|
||||
|
@ -122,7 +124,7 @@ describe('processDataMessage', () => {
|
|||
const out = check({
|
||||
quote: {
|
||||
id: Long.fromNumber(1),
|
||||
authorUuid: 'author',
|
||||
authorAci: AUTHOR_SERVICE_ID,
|
||||
text: 'text',
|
||||
attachments: [
|
||||
{
|
||||
|
@ -136,7 +138,7 @@ describe('processDataMessage', () => {
|
|||
|
||||
assert.deepStrictEqual(out.quote, {
|
||||
id: 1,
|
||||
authorUuid: 'author',
|
||||
authorAci: AUTHOR_SERVICE_ID,
|
||||
text: 'text',
|
||||
attachments: [
|
||||
{
|
||||
|
@ -188,7 +190,7 @@ describe('processDataMessage', () => {
|
|||
{
|
||||
emoji: '😎',
|
||||
remove: false,
|
||||
targetAuthorUuid: undefined,
|
||||
targetAuthorAci: undefined,
|
||||
targetTimestamp: TIMESTAMP,
|
||||
}
|
||||
);
|
||||
|
@ -204,7 +206,7 @@ describe('processDataMessage', () => {
|
|||
{
|
||||
emoji: '😎',
|
||||
remove: true,
|
||||
targetAuthorUuid: undefined,
|
||||
targetAuthorAci: undefined,
|
||||
targetTimestamp: TIMESTAMP,
|
||||
}
|
||||
);
|
||||
|
|
|
@ -2,21 +2,21 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { UUID } from '../types/UUID';
|
||||
import { generateAci } from '../types/ServiceId';
|
||||
|
||||
import { processSyncMessage } from '../textsecure/processSyncMessage';
|
||||
|
||||
describe('processSyncMessage', () => {
|
||||
const destinationUuid = UUID.generate().toString();
|
||||
const destinationServiceId = generateAci();
|
||||
|
||||
it('should normalize UUIDs in sent (aci)', () => {
|
||||
it('should normalize UUIDs in sent', () => {
|
||||
const out = processSyncMessage({
|
||||
sent: {
|
||||
destinationAci: destinationUuid.toUpperCase(),
|
||||
destinationServiceId: destinationServiceId.toUpperCase(),
|
||||
|
||||
unidentifiedStatus: [
|
||||
{
|
||||
destinationAci: destinationUuid.toUpperCase(),
|
||||
destinationServiceId: destinationServiceId.toUpperCase(),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -24,51 +24,12 @@ describe('processSyncMessage', () => {
|
|||
|
||||
assert.deepStrictEqual(out, {
|
||||
sent: {
|
||||
destinationUuid: {
|
||||
aci: destinationUuid,
|
||||
pni: undefined,
|
||||
},
|
||||
destinationServiceId,
|
||||
|
||||
storyMessageRecipients: undefined,
|
||||
unidentifiedStatus: [
|
||||
{
|
||||
destinationUuid: {
|
||||
aci: destinationUuid,
|
||||
pni: undefined,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should normalize UUIDs in sent (pni)', () => {
|
||||
const out = processSyncMessage({
|
||||
sent: {
|
||||
destinationPni: destinationUuid.toUpperCase(),
|
||||
|
||||
unidentifiedStatus: [
|
||||
{
|
||||
destinationPni: destinationUuid.toUpperCase(),
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(out, {
|
||||
sent: {
|
||||
destinationUuid: {
|
||||
aci: undefined,
|
||||
pni: destinationUuid,
|
||||
},
|
||||
|
||||
storyMessageRecipients: undefined,
|
||||
unidentifiedStatus: [
|
||||
{
|
||||
destinationUuid: {
|
||||
aci: undefined,
|
||||
pni: destinationUuid,
|
||||
},
|
||||
destinationServiceId,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -6,6 +6,7 @@ import { v4 as uuid } from 'uuid';
|
|||
import { omit } from 'lodash';
|
||||
import type { MessageReactionType } from '../../model-types.d';
|
||||
import { isEmpty } from '../../util/iterables';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
|
||||
import {
|
||||
addOutgoingReaction,
|
||||
|
@ -24,7 +25,7 @@ describe('reaction utilities', () => {
|
|||
): MessageReactionType => ({
|
||||
emoji,
|
||||
fromId: OUR_CONVO_ID,
|
||||
targetAuthorUuid: uuid(),
|
||||
targetAuthorUuid: generateAci(),
|
||||
targetTimestamp: Date.now(),
|
||||
timestamp: Date.now(),
|
||||
...(isPending ? { isSentByConversationId: { [uuid()]: false } } : {}),
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import {
|
||||
ComposerStep,
|
||||
|
@ -27,7 +28,7 @@ import {
|
|||
getComposeSelectedContacts,
|
||||
getContactNameColorSelector,
|
||||
getConversationByIdSelector,
|
||||
getConversationUuidsStoppingSend,
|
||||
getConversationServiceIdsStoppingSend,
|
||||
getConversationsByTitleSelector,
|
||||
getConversationSelector,
|
||||
getConversationsStoppingSend,
|
||||
|
@ -46,8 +47,8 @@ import { noopAction } from '../../../state/ducks/noop';
|
|||
import type { StateType } from '../../../state/reducer';
|
||||
import { reducer as rootReducer } from '../../../state/reducer';
|
||||
import { setupI18n } from '../../../util/setupI18n';
|
||||
import { UUID } from '../../../types/UUID';
|
||||
import type { UUIDStringType } from '../../../types/UUID';
|
||||
import type { ServiceIdString } from '../../../types/ServiceId';
|
||||
import { generateAci, getAciFromPrefix } from '../../../types/ServiceId';
|
||||
import enMessages from '../../../../_locales/en/messages.json';
|
||||
import {
|
||||
getDefaultConversation,
|
||||
|
@ -61,8 +62,8 @@ import {
|
|||
} from '../../helpers/defaultComposerStates';
|
||||
|
||||
describe('both/state/selectors/conversations-extra', () => {
|
||||
const UUID_1 = UUID.generate().toString();
|
||||
const UUID_2 = UUID.generate().toString();
|
||||
const SERVICE_ID_1 = generateAci();
|
||||
const SERVICE_ID_2 = generateAci();
|
||||
|
||||
const getEmptyRootState = (): StateType => {
|
||||
return rootReducer(undefined, noopAction());
|
||||
|
@ -90,7 +91,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
|
||||
function makeConversationWithUuid(
|
||||
id: string
|
||||
): ConversationType & { uuid: UUIDStringType } {
|
||||
): ConversationType & { uuid: ServiceIdString } {
|
||||
const title = `${id} title`;
|
||||
|
||||
return getDefaultConversationWithUuid(
|
||||
|
@ -100,7 +101,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title,
|
||||
titleNoDefault: title,
|
||||
},
|
||||
UUID.fromPrefix(id).toString()
|
||||
getAciFromPrefix(id)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -315,32 +316,32 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
});
|
||||
|
||||
it('returns all conversations stopping send', () => {
|
||||
const convo1 = makeConversation(UUID_1);
|
||||
const convo2 = makeConversation(UUID_2);
|
||||
const convo1 = makeConversation(SERVICE_ID_1);
|
||||
const convo2 = makeConversation(SERVICE_ID_2);
|
||||
const state: StateType = {
|
||||
...getEmptyRootState(),
|
||||
conversations: {
|
||||
...getEmptyState(),
|
||||
conversationLookup: {
|
||||
[UUID_1]: convo1,
|
||||
[UUID_2]: convo2,
|
||||
[SERVICE_ID_1]: convo1,
|
||||
[SERVICE_ID_2]: convo2,
|
||||
},
|
||||
verificationDataByConversation: {
|
||||
'convo a': {
|
||||
type: ConversationVerificationState.PendingVerification as const,
|
||||
uuidsNeedingVerification: [UUID_1],
|
||||
serviceIdsNeedingVerification: [SERVICE_ID_1],
|
||||
},
|
||||
'convo b': {
|
||||
type: ConversationVerificationState.PendingVerification as const,
|
||||
uuidsNeedingVerification: [UUID_2, UUID_1],
|
||||
serviceIdsNeedingVerification: [SERVICE_ID_2, SERVICE_ID_1],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
assert.sameDeepMembers(getConversationUuidsStoppingSend(state), [
|
||||
UUID_1,
|
||||
UUID_2,
|
||||
assert.sameDeepMembers(getConversationServiceIdsStoppingSend(state), [
|
||||
SERVICE_ID_1,
|
||||
SERVICE_ID_2,
|
||||
]);
|
||||
|
||||
assert.sameDeepMembers(getConversationsStoppingSend(state), [
|
||||
|
@ -368,7 +369,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
[abc.uuid]: abc,
|
||||
[def.uuid]: def,
|
||||
},
|
||||
invitedUuidsForNewlyCreatedGroup: [def.uuid, abc.uuid],
|
||||
invitedServiceIdsForNewlyCreatedGroup: [def.uuid, abc.uuid],
|
||||
},
|
||||
};
|
||||
const result = getInvitedContactsForNewlyCreatedGroup(state);
|
||||
|
@ -1144,7 +1145,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'No timestamp',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1165,7 +1166,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'B',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1186,7 +1187,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'C',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1207,7 +1208,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'A',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1228,7 +1229,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'First!',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1270,7 +1271,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'Pin Two',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1292,7 +1293,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'Pin Three',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1314,7 +1315,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'Pin One',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1353,7 +1354,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'Pin Two',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1374,7 +1375,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'Pin Three',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1395,7 +1396,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'Pin One',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1417,7 +1418,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'Pin One',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
@ -1438,7 +1439,7 @@ describe('both/state/selectors/conversations-extra', () => {
|
|||
title: 'Pin One',
|
||||
unreadCount: 1,
|
||||
isSelected: false,
|
||||
typingContactId: UUID.generate().toString(),
|
||||
typingContactId: generateUuid(),
|
||||
|
||||
acceptedMessageRequest: true,
|
||||
}),
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
getSearchResults,
|
||||
} from '../../../state/selectors/search';
|
||||
import { makeLookup } from '../../../util/makeLookup';
|
||||
import { UUID } from '../../../types/UUID';
|
||||
import { generateAci } from '../../../types/ServiceId';
|
||||
import {
|
||||
getDefaultConversation,
|
||||
getDefaultConversationWithUuid,
|
||||
|
@ -58,7 +58,7 @@ describe('both/state/selectors/search', () => {
|
|||
received_at: NOW,
|
||||
sent_at: NOW,
|
||||
source: 'source',
|
||||
sourceUuid: UUID.generate().toString(),
|
||||
sourceUuid: generateAci(),
|
||||
timestamp: NOW,
|
||||
type: 'incoming' as const,
|
||||
readStatus: ReadStatus.Read,
|
||||
|
|
|
@ -11,9 +11,15 @@ import {
|
|||
insertRange,
|
||||
processBodyRangesForSearchResult,
|
||||
} from '../../types/BodyRange';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
|
||||
const SERVICE_ID_1 = generateAci();
|
||||
const SERVICE_ID_2 = generateAci();
|
||||
const SERVICE_ID_3 = generateAci();
|
||||
const SERVICE_ID_4 = generateAci();
|
||||
|
||||
const mentionInfo = {
|
||||
mentionUuid: 'someid',
|
||||
mentionUuid: SERVICE_ID_1,
|
||||
conversationID: 'convoid',
|
||||
replacementText: 'dude',
|
||||
};
|
||||
|
@ -785,14 +791,14 @@ describe('BodyRanges', () => {
|
|||
{
|
||||
start: 0,
|
||||
length: 1,
|
||||
mentionUuid: '7d007e95-771d-43ad-9191-eaa86c773cb8',
|
||||
mentionUuid: SERVICE_ID_2,
|
||||
replacementText: 'Alice',
|
||||
conversationID: 'x',
|
||||
},
|
||||
{
|
||||
start: 21,
|
||||
length: 1,
|
||||
mentionUuid: '7d007e95-771d-43ad-9191-eaa86c773cb8',
|
||||
mentionUuid: SERVICE_ID_2,
|
||||
replacementText: 'Eve',
|
||||
conversationID: 'x',
|
||||
},
|
||||
|
@ -821,21 +827,21 @@ describe('BodyRanges', () => {
|
|||
{
|
||||
start: 18,
|
||||
length: 1,
|
||||
mentionUuid: '7d007e95-771d-43ad-9191-eaa86c773cb8',
|
||||
mentionUuid: SERVICE_ID_2,
|
||||
replacementText: 'Alice',
|
||||
conversationID: 'x',
|
||||
},
|
||||
{
|
||||
start: 39,
|
||||
length: 1,
|
||||
mentionUuid: '7d007e95-771d-43ad-9191-eaa86c773cb8',
|
||||
mentionUuid: SERVICE_ID_2,
|
||||
replacementText: 'Bob',
|
||||
conversationID: 'x',
|
||||
},
|
||||
{
|
||||
start: 45,
|
||||
length: 1,
|
||||
mentionUuid: '7d007e95-771d-43ad-9191-eaa86c773cb8',
|
||||
mentionUuid: SERVICE_ID_2,
|
||||
replacementText: 'Eve',
|
||||
conversationID: 'x',
|
||||
},
|
||||
|
@ -941,14 +947,14 @@ describe('BodyRanges', () => {
|
|||
{
|
||||
start: 0,
|
||||
length: 1,
|
||||
mentionUuid: 'blarg',
|
||||
mentionUuid: SERVICE_ID_3,
|
||||
replacementText: 'jerry',
|
||||
conversationID: 'x',
|
||||
},
|
||||
{
|
||||
start: 7,
|
||||
length: 1,
|
||||
mentionUuid: 'abcdef',
|
||||
mentionUuid: SERVICE_ID_4,
|
||||
replacementText: 'fred',
|
||||
conversationID: 'x',
|
||||
},
|
||||
|
@ -986,14 +992,14 @@ describe('BodyRanges', () => {
|
|||
{
|
||||
start: 49,
|
||||
length: 1,
|
||||
mentionUuid: 'abcdef',
|
||||
mentionUuid: SERVICE_ID_4,
|
||||
replacementText: 'alice',
|
||||
conversationID: 'x',
|
||||
},
|
||||
{
|
||||
start: 55,
|
||||
length: 1,
|
||||
mentionUuid: 'abcdef',
|
||||
mentionUuid: SERVICE_ID_4,
|
||||
replacementText: 'bob',
|
||||
conversationID: 'x',
|
||||
},
|
||||
|
@ -1019,21 +1025,21 @@ describe('BodyRanges', () => {
|
|||
{
|
||||
start: 0,
|
||||
length: 1,
|
||||
mentionUuid: 'abcdef',
|
||||
mentionUuid: SERVICE_ID_4,
|
||||
replacementText: 'eve',
|
||||
conversationID: 'x',
|
||||
},
|
||||
{
|
||||
start: 52,
|
||||
length: 1,
|
||||
mentionUuid: 'abcdef',
|
||||
mentionUuid: SERVICE_ID_4,
|
||||
replacementText: 'alice',
|
||||
conversationID: 'x',
|
||||
},
|
||||
{
|
||||
start: 58,
|
||||
length: 1,
|
||||
mentionUuid: 'abcdef',
|
||||
mentionUuid: SERVICE_ID_4,
|
||||
replacementText: 'bob',
|
||||
conversationID: 'x',
|
||||
},
|
||||
|
|
46
ts/test-both/types/StoryDistributionId_test.ts
Normal file
46
ts/test-both/types/StoryDistributionId_test.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
import * as sinon from 'sinon';
|
||||
|
||||
import type { LoggerType } from '../../types/Logging';
|
||||
import { normalizeStoryDistributionId } from '../../types/StoryDistributionId';
|
||||
|
||||
describe('StoryDistributionId', () => {
|
||||
let warn: sinon.SinonStub;
|
||||
let logger: Pick<LoggerType, 'warn'>;
|
||||
|
||||
beforeEach(() => {
|
||||
warn = sinon.stub();
|
||||
logger = { warn };
|
||||
});
|
||||
|
||||
describe('normalizeStoryDistributionId', () => {
|
||||
it('converts uuid to lower case', () => {
|
||||
const uuid = generateUuid();
|
||||
assert.strictEqual(
|
||||
normalizeStoryDistributionId(uuid, 'context 1', logger),
|
||||
uuid
|
||||
);
|
||||
assert.strictEqual(
|
||||
normalizeStoryDistributionId(uuid.toUpperCase(), 'context 2', logger),
|
||||
uuid
|
||||
);
|
||||
|
||||
sinon.assert.notCalled(warn);
|
||||
});
|
||||
|
||||
it("warns if passed a string that's not a UUID", () => {
|
||||
normalizeStoryDistributionId('not-UUID-at-all', 'context 3', logger);
|
||||
sinon.assert.calledOnce(warn);
|
||||
sinon.assert.calledWith(
|
||||
warn,
|
||||
'Normalizing invalid story distribution id: ' +
|
||||
'not-UUID-at-all to not-uuid-at-all in ' +
|
||||
'context "context 3"'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -4,106 +4,120 @@
|
|||
import { assert } from 'chai';
|
||||
|
||||
import type { RecipientsByConversation } from '../../state/ducks/stories';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
|
||||
import { UUID } from '../../types/UUID';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
import { generateStoryDistributionId } from '../../types/StoryDistributionId';
|
||||
import {
|
||||
getAllUuids,
|
||||
filterUuids,
|
||||
getAllServiceIds,
|
||||
filterServiceIds,
|
||||
} from '../../util/blockSendUntilConversationsAreVerified';
|
||||
|
||||
describe('both/util/blockSendUntilConversationsAreVerified', () => {
|
||||
const UUID_1 = UUID.generate().toString();
|
||||
const UUID_2 = UUID.generate().toString();
|
||||
const UUID_3 = UUID.generate().toString();
|
||||
const UUID_4 = UUID.generate().toString();
|
||||
const SERVICE_ID_1 = generateAci();
|
||||
const SERVICE_ID_2 = generateAci();
|
||||
const SERVICE_ID_3 = generateAci();
|
||||
const SERVICE_ID_4 = generateAci();
|
||||
|
||||
describe('#getAllUuids', () => {
|
||||
const LIST_ID_1 = generateStoryDistributionId();
|
||||
const LIST_ID_2 = generateStoryDistributionId();
|
||||
const LIST_ID_3 = generateStoryDistributionId();
|
||||
|
||||
describe('#getAllServiceIds', () => {
|
||||
it('should return empty set for empty object', () => {
|
||||
const starting: RecipientsByConversation = {};
|
||||
const expected: Array<UUIDStringType> = [];
|
||||
const actual = getAllUuids(starting);
|
||||
const expected: Array<ServiceIdString> = [];
|
||||
const actual = getAllServiceIds(starting);
|
||||
|
||||
assert.sameMembers(Array.from(actual), expected);
|
||||
});
|
||||
it('should return uuids multiple conversations', () => {
|
||||
it('should return serviceIds multiple conversations', () => {
|
||||
const starting: RecipientsByConversation = {
|
||||
abc: {
|
||||
uuids: [UUID_1, UUID_2],
|
||||
[LIST_ID_1]: {
|
||||
serviceIds: [SERVICE_ID_1, SERVICE_ID_2],
|
||||
},
|
||||
def: {
|
||||
uuids: [],
|
||||
[LIST_ID_2]: {
|
||||
serviceIds: [],
|
||||
},
|
||||
ghi: {
|
||||
uuids: [UUID_2, UUID_3],
|
||||
[LIST_ID_3]: {
|
||||
serviceIds: [SERVICE_ID_2, SERVICE_ID_3],
|
||||
},
|
||||
};
|
||||
const expected: Array<UUIDStringType> = [UUID_1, UUID_2, UUID_3];
|
||||
const actual = getAllUuids(starting);
|
||||
const expected: Array<ServiceIdString> = [
|
||||
SERVICE_ID_1,
|
||||
SERVICE_ID_2,
|
||||
SERVICE_ID_3,
|
||||
];
|
||||
const actual = getAllServiceIds(starting);
|
||||
|
||||
assert.sameMembers(Array.from(actual), expected);
|
||||
});
|
||||
it('should return uuids from byDistributionId and its parent', () => {
|
||||
it('should return serviceIds from byDistributionId and its parent', () => {
|
||||
const starting: RecipientsByConversation = {
|
||||
abc: {
|
||||
uuids: [UUID_1, UUID_2],
|
||||
[LIST_ID_1]: {
|
||||
serviceIds: [SERVICE_ID_1, SERVICE_ID_2],
|
||||
byDistributionId: {
|
||||
abc: {
|
||||
uuids: [UUID_3],
|
||||
[LIST_ID_1]: {
|
||||
serviceIds: [SERVICE_ID_3],
|
||||
},
|
||||
def: {
|
||||
uuids: [],
|
||||
[LIST_ID_2]: {
|
||||
serviceIds: [],
|
||||
},
|
||||
ghi: {
|
||||
uuids: [UUID_4],
|
||||
[LIST_ID_3]: {
|
||||
serviceIds: [SERVICE_ID_4],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const expected: Array<UUIDStringType> = [UUID_1, UUID_2, UUID_3, UUID_4];
|
||||
const actual = getAllUuids(starting);
|
||||
const expected: Array<ServiceIdString> = [
|
||||
SERVICE_ID_1,
|
||||
SERVICE_ID_2,
|
||||
SERVICE_ID_3,
|
||||
SERVICE_ID_4,
|
||||
];
|
||||
const actual = getAllServiceIds(starting);
|
||||
|
||||
assert.sameMembers(Array.from(actual), expected);
|
||||
});
|
||||
it('should return uuids from byDistributionId with empty parent', () => {
|
||||
it('should return serviceIds from byDistributionId with empty parent', () => {
|
||||
const starting: RecipientsByConversation = {
|
||||
abc: {
|
||||
uuids: [],
|
||||
[LIST_ID_1]: {
|
||||
serviceIds: [],
|
||||
byDistributionId: {
|
||||
abc: {
|
||||
uuids: [UUID_3],
|
||||
[LIST_ID_1]: {
|
||||
serviceIds: [SERVICE_ID_3],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const expected: Array<UUIDStringType> = [UUID_3];
|
||||
const actual = getAllUuids(starting);
|
||||
const expected: Array<ServiceIdString> = [SERVICE_ID_3];
|
||||
const actual = getAllServiceIds(starting);
|
||||
|
||||
assert.sameMembers(Array.from(actual), expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#filterUuids', () => {
|
||||
describe('#filterServiceIds', () => {
|
||||
const starting: RecipientsByConversation = {
|
||||
abc: {
|
||||
uuids: [UUID_1],
|
||||
[LIST_ID_1]: {
|
||||
serviceIds: [SERVICE_ID_1],
|
||||
byDistributionId: {
|
||||
abc: {
|
||||
uuids: [UUID_2, UUID_3],
|
||||
[LIST_ID_1]: {
|
||||
serviceIds: [SERVICE_ID_2, SERVICE_ID_3],
|
||||
},
|
||||
def: {
|
||||
uuids: [UUID_1],
|
||||
[LIST_ID_2]: {
|
||||
serviceIds: [SERVICE_ID_1],
|
||||
},
|
||||
},
|
||||
},
|
||||
def: {
|
||||
uuids: [UUID_1, UUID_4],
|
||||
[LIST_ID_2]: {
|
||||
serviceIds: [SERVICE_ID_1, SERVICE_ID_4],
|
||||
},
|
||||
ghi: {
|
||||
uuids: [UUID_3],
|
||||
[LIST_ID_3]: {
|
||||
serviceIds: [SERVICE_ID_3],
|
||||
byDistributionId: {
|
||||
abc: {
|
||||
uuids: [UUID_4],
|
||||
[LIST_ID_1]: {
|
||||
serviceIds: [SERVICE_ID_4],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -111,34 +125,35 @@ describe('both/util/blockSendUntilConversationsAreVerified', () => {
|
|||
|
||||
it('should return empty object if predicate always returns false', () => {
|
||||
const expected: RecipientsByConversation = {};
|
||||
const actual = filterUuids(starting, () => false);
|
||||
const actual = filterServiceIds(starting, () => false);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
it('should return exact copy of object if predicate always returns true', () => {
|
||||
const expected = starting;
|
||||
const actual = filterUuids(starting, () => true);
|
||||
const actual = filterServiceIds(starting, () => true);
|
||||
|
||||
assert.notStrictEqual(actual, expected);
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
it('should return just a few uuids for selective predicate', () => {
|
||||
it('should return just a few serviceIds for selective predicate', () => {
|
||||
const expected: RecipientsByConversation = {
|
||||
abc: {
|
||||
uuids: [],
|
||||
[LIST_ID_1]: {
|
||||
serviceIds: [],
|
||||
byDistributionId: {
|
||||
abc: {
|
||||
uuids: [UUID_2, UUID_3],
|
||||
[LIST_ID_1]: {
|
||||
serviceIds: [SERVICE_ID_2, SERVICE_ID_3],
|
||||
},
|
||||
},
|
||||
},
|
||||
ghi: {
|
||||
uuids: [UUID_3],
|
||||
[LIST_ID_3]: {
|
||||
serviceIds: [SERVICE_ID_3],
|
||||
},
|
||||
};
|
||||
const actual = filterUuids(
|
||||
const actual = filterServiceIds(
|
||||
starting,
|
||||
(uuid: UUIDStringType) => uuid === UUID_2 || uuid === UUID_3
|
||||
(uuid: ServiceIdString) =>
|
||||
uuid === SERVICE_ID_2 || uuid === SERVICE_ID_3
|
||||
);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
import { assert } from 'chai';
|
||||
import type { ConversationType } from '../../state/ducks/conversations';
|
||||
import { UUID } from '../../types/UUID';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import { generateAci, normalizeAci } from '../../types/ServiceId';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
import { getDefaultConversationWithUuid } from '../helpers/getDefaultConversation';
|
||||
|
||||
import { getGroupMemberships } from '../../util/getGroupMemberships';
|
||||
|
@ -16,14 +16,14 @@ describe('getGroupMemberships', () => {
|
|||
discoveredUnregisteredAt: Date.now(),
|
||||
});
|
||||
|
||||
function getConversationByUuid(
|
||||
uuid: UUIDStringType
|
||||
function getConversationByServiceId(
|
||||
serviceId: ServiceIdString
|
||||
): undefined | ConversationType {
|
||||
return [
|
||||
normalConversation1,
|
||||
normalConversation2,
|
||||
unregisteredConversation,
|
||||
].find(conversation => conversation.uuid === uuid);
|
||||
].find(conversation => conversation.uuid === serviceId);
|
||||
}
|
||||
|
||||
describe('memberships', () => {
|
||||
|
@ -32,7 +32,7 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).memberships;
|
||||
|
||||
assert.isEmpty(result);
|
||||
|
@ -43,7 +43,7 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).memberships;
|
||||
|
||||
assert.isEmpty(result);
|
||||
|
@ -53,7 +53,7 @@ describe('getGroupMemberships', () => {
|
|||
const conversation = {
|
||||
memberships: [
|
||||
{
|
||||
uuid: UUID.generate().toString(),
|
||||
uuid: generateAci(),
|
||||
isAdmin: true,
|
||||
},
|
||||
],
|
||||
|
@ -61,7 +61,7 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).memberships;
|
||||
|
||||
assert.isEmpty(result);
|
||||
|
@ -71,7 +71,7 @@ describe('getGroupMemberships', () => {
|
|||
const conversation = {
|
||||
memberships: [
|
||||
{
|
||||
uuid: unregisteredConversation.uuid,
|
||||
uuid: normalizeAci(unregisteredConversation.uuid, 'test'),
|
||||
isAdmin: true,
|
||||
},
|
||||
],
|
||||
|
@ -79,7 +79,7 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).memberships;
|
||||
|
||||
assert.lengthOf(result, 1);
|
||||
|
@ -93,11 +93,11 @@ describe('getGroupMemberships', () => {
|
|||
const conversation = {
|
||||
memberships: [
|
||||
{
|
||||
uuid: normalConversation2.uuid,
|
||||
uuid: normalizeAci(normalConversation2.uuid, 'test'),
|
||||
isAdmin: false,
|
||||
},
|
||||
{
|
||||
uuid: normalConversation1.uuid,
|
||||
uuid: normalizeAci(normalConversation1.uuid, 'test'),
|
||||
isAdmin: true,
|
||||
},
|
||||
],
|
||||
|
@ -105,7 +105,7 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).memberships;
|
||||
|
||||
assert.lengthOf(result, 2);
|
||||
|
@ -126,7 +126,7 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).pendingApprovalMemberships;
|
||||
|
||||
assert.isEmpty(result);
|
||||
|
@ -137,7 +137,7 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).pendingApprovalMemberships;
|
||||
|
||||
assert.isEmpty(result);
|
||||
|
@ -145,12 +145,12 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
it("filters out conversation IDs that don't exist", () => {
|
||||
const conversation = {
|
||||
pendingApprovalMemberships: [{ uuid: UUID.generate().toString() }],
|
||||
pendingApprovalMemberships: [{ uuid: generateAci() }],
|
||||
};
|
||||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).pendingApprovalMemberships;
|
||||
|
||||
assert.isEmpty(result);
|
||||
|
@ -158,12 +158,14 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
it('filters out unregistered conversations', () => {
|
||||
const conversation = {
|
||||
pendingApprovalMemberships: [{ uuid: unregisteredConversation.uuid }],
|
||||
pendingApprovalMemberships: [
|
||||
{ uuid: normalizeAci(unregisteredConversation.uuid, 'test') },
|
||||
],
|
||||
};
|
||||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).pendingApprovalMemberships;
|
||||
|
||||
assert.isEmpty(result);
|
||||
|
@ -172,14 +174,14 @@ describe('getGroupMemberships', () => {
|
|||
it('hydrates pending-approval memberships', () => {
|
||||
const conversation = {
|
||||
pendingApprovalMemberships: [
|
||||
{ uuid: normalConversation2.uuid },
|
||||
{ uuid: normalConversation1.uuid },
|
||||
{ uuid: normalizeAci(normalConversation2.uuid, 'test') },
|
||||
{ uuid: normalizeAci(normalConversation1.uuid, 'test') },
|
||||
],
|
||||
};
|
||||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).pendingApprovalMemberships;
|
||||
|
||||
assert.lengthOf(result, 2);
|
||||
|
@ -194,7 +196,7 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).pendingMemberships;
|
||||
|
||||
assert.isEmpty(result);
|
||||
|
@ -205,7 +207,7 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).pendingMemberships;
|
||||
|
||||
assert.isEmpty(result);
|
||||
|
@ -215,15 +217,15 @@ describe('getGroupMemberships', () => {
|
|||
const conversation = {
|
||||
pendingMemberships: [
|
||||
{
|
||||
uuid: UUID.generate().toString(),
|
||||
addedByUserId: normalConversation1.uuid,
|
||||
uuid: generateAci(),
|
||||
addedByUserId: normalizeAci(normalConversation1.uuid, 'test'),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).pendingMemberships;
|
||||
|
||||
assert.isEmpty(result);
|
||||
|
@ -234,22 +236,22 @@ describe('getGroupMemberships', () => {
|
|||
pendingMemberships: [
|
||||
{
|
||||
uuid: unregisteredConversation.uuid,
|
||||
addedByUserId: normalConversation1.uuid,
|
||||
addedByUserId: normalizeAci(normalConversation1.uuid, 'test'),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).pendingMemberships;
|
||||
|
||||
assert.isEmpty(result);
|
||||
});
|
||||
|
||||
it('hydrates pending memberships', () => {
|
||||
const abc = UUID.generate().toString();
|
||||
const xyz = UUID.generate().toString();
|
||||
const abc = generateAci();
|
||||
const xyz = generateAci();
|
||||
|
||||
const conversation = {
|
||||
pendingMemberships: [
|
||||
|
@ -260,7 +262,7 @@ describe('getGroupMemberships', () => {
|
|||
|
||||
const result = getGroupMemberships(
|
||||
conversation,
|
||||
getConversationByUuid
|
||||
getConversationByServiceId
|
||||
).pendingMemberships;
|
||||
|
||||
assert.lengthOf(result, 2);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { assert } from 'chai';
|
||||
|
||||
import { isValidUuid } from '../../types/UUID';
|
||||
import { isValidUuid } from '../../util/isValidUuid';
|
||||
|
||||
describe('isValidUuid', () => {
|
||||
const LOWERCASE_V4_UUID = '9cb737ce-2bb3-4c21-9fe0-d286caa0ca68';
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
import * as sinon from 'sinon';
|
||||
|
||||
import type { LoggerType } from '../../types/Logging';
|
||||
import { normalizeUuid } from '../../util/normalizeUuid';
|
||||
|
||||
describe('normalizeUuid', () => {
|
||||
let warn: sinon.SinonStub;
|
||||
let logger: Pick<LoggerType, 'warn'>;
|
||||
|
||||
beforeEach(() => {
|
||||
warn = sinon.stub();
|
||||
logger = { warn };
|
||||
});
|
||||
|
||||
it('converts uuid to lower case', () => {
|
||||
const uuid = generateUuid();
|
||||
assert.strictEqual(normalizeUuid(uuid, 'context 1', logger), uuid);
|
||||
assert.strictEqual(
|
||||
normalizeUuid(uuid.toUpperCase(), 'context 2', logger),
|
||||
uuid
|
||||
);
|
||||
|
||||
sinon.assert.notCalled(warn);
|
||||
});
|
||||
|
||||
it("warns if passed a string that's not a UUID", () => {
|
||||
normalizeUuid('not-UUID-at-all', 'context 3', logger);
|
||||
sinon.assert.calledOnce(warn);
|
||||
sinon.assert.calledWith(
|
||||
warn,
|
||||
'Normalizing invalid uuid: not-UUID-at-all to not-uuid-at-all in ' +
|
||||
'context "context 3"'
|
||||
);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue