Use UUIDs in group database schema

This commit is contained in:
Fedor Indutny 2021-10-26 15:59:08 -07:00 committed by GitHub
parent 74fde10ff5
commit 63fcdbe787
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
79 changed files with 4530 additions and 3664 deletions

View file

@ -3,30 +3,34 @@
import { assert } from 'chai';
import type { ConversationType } from '../../state/ducks/conversations';
import { getDefaultConversation } from '../helpers/getDefaultConversation';
import { UUID } from '../../types/UUID';
import type { UUIDStringType } from '../../types/UUID';
import { getDefaultConversationWithUuid } from '../helpers/getDefaultConversation';
import { getGroupMemberships } from '../../util/getGroupMemberships';
describe('getGroupMemberships', () => {
const normalConversation1 = getDefaultConversation();
const normalConversation2 = getDefaultConversation();
const unregisteredConversation = getDefaultConversation({
const normalConversation1 = getDefaultConversationWithUuid();
const normalConversation2 = getDefaultConversationWithUuid();
const unregisteredConversation = getDefaultConversationWithUuid({
discoveredUnregisteredAt: Date.now(),
});
function getConversationById(id: string): undefined | ConversationType {
function getConversationByUuid(
uuid: UUIDStringType
): undefined | ConversationType {
return [
normalConversation1,
normalConversation2,
unregisteredConversation,
].find(conversation => conversation.id === id);
].find(conversation => conversation.uuid === uuid);
}
describe('memberships', () => {
it('returns an empty array if passed undefined', () => {
const conversation = {};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.memberships;
assert.isEmpty(result);
@ -35,7 +39,7 @@ describe('getGroupMemberships', () => {
it('returns an empty array if passed an empty array', () => {
const conversation = { memberships: [] };
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.memberships;
assert.isEmpty(result);
@ -45,13 +49,13 @@ describe('getGroupMemberships', () => {
const conversation = {
memberships: [
{
conversationId: 'garbage',
uuid: UUID.generate().toString(),
isAdmin: true,
},
],
};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.memberships;
assert.isEmpty(result);
@ -61,13 +65,13 @@ describe('getGroupMemberships', () => {
const conversation = {
memberships: [
{
conversationId: unregisteredConversation.id,
uuid: unregisteredConversation.uuid,
isAdmin: true,
},
],
};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.memberships;
assert.lengthOf(result, 1);
@ -81,17 +85,17 @@ describe('getGroupMemberships', () => {
const conversation = {
memberships: [
{
conversationId: normalConversation2.id,
uuid: normalConversation2.uuid,
isAdmin: false,
},
{
conversationId: normalConversation1.id,
uuid: normalConversation1.uuid,
isAdmin: true,
},
],
};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.memberships;
assert.lengthOf(result, 2);
@ -110,7 +114,7 @@ describe('getGroupMemberships', () => {
it('returns an empty array if passed undefined', () => {
const conversation = {};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.pendingApprovalMemberships;
assert.isEmpty(result);
@ -119,7 +123,7 @@ describe('getGroupMemberships', () => {
it('returns an empty array if passed an empty array', () => {
const conversation = { pendingApprovalMemberships: [] };
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.pendingApprovalMemberships;
assert.isEmpty(result);
@ -127,10 +131,10 @@ describe('getGroupMemberships', () => {
it("filters out conversation IDs that don't exist", () => {
const conversation = {
pendingApprovalMemberships: [{ conversationId: 'garbage' }],
pendingApprovalMemberships: [{ uuid: UUID.generate().toString() }],
};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.pendingApprovalMemberships;
assert.isEmpty(result);
@ -138,12 +142,10 @@ describe('getGroupMemberships', () => {
it('filters out unregistered conversations', () => {
const conversation = {
pendingApprovalMemberships: [
{ conversationId: unregisteredConversation.id },
],
pendingApprovalMemberships: [{ uuid: unregisteredConversation.uuid }],
};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.pendingApprovalMemberships;
assert.isEmpty(result);
@ -152,12 +154,12 @@ describe('getGroupMemberships', () => {
it('hydrates pending-approval memberships', () => {
const conversation = {
pendingApprovalMemberships: [
{ conversationId: normalConversation2.id },
{ conversationId: normalConversation1.id },
{ uuid: normalConversation2.uuid },
{ uuid: normalConversation1.uuid },
],
};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.pendingApprovalMemberships;
assert.lengthOf(result, 2);
@ -170,7 +172,7 @@ describe('getGroupMemberships', () => {
it('returns an empty array if passed undefined', () => {
const conversation = {};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.pendingMemberships;
assert.isEmpty(result);
@ -179,7 +181,7 @@ describe('getGroupMemberships', () => {
it('returns an empty array if passed an empty array', () => {
const conversation = { pendingMemberships: [] };
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.pendingMemberships;
assert.isEmpty(result);
@ -188,11 +190,14 @@ describe('getGroupMemberships', () => {
it("filters out conversation IDs that don't exist", () => {
const conversation = {
pendingMemberships: [
{ conversationId: 'garbage', addedByUserId: normalConversation1.id },
{
uuid: UUID.generate().toString(),
addedByUserId: normalConversation1.uuid,
},
],
};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.pendingMemberships;
assert.isEmpty(result);
@ -202,37 +207,40 @@ describe('getGroupMemberships', () => {
const conversation = {
pendingMemberships: [
{
conversationId: unregisteredConversation.id,
addedByUserId: normalConversation1.id,
uuid: unregisteredConversation.uuid,
addedByUserId: normalConversation1.uuid,
},
],
};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.pendingMemberships;
assert.isEmpty(result);
});
it('hydrates pending memberships', () => {
const abc = UUID.generate().toString();
const xyz = UUID.generate().toString();
const conversation = {
pendingMemberships: [
{ conversationId: normalConversation2.id, addedByUserId: 'abc' },
{ conversationId: normalConversation1.id, addedByUserId: 'xyz' },
{ uuid: normalConversation2.uuid, addedByUserId: abc },
{ uuid: normalConversation1.uuid, addedByUserId: xyz },
],
};
const result = getGroupMemberships(conversation, getConversationById)
const result = getGroupMemberships(conversation, getConversationByUuid)
.pendingMemberships;
assert.lengthOf(result, 2);
assert.deepEqual(result[0], {
member: normalConversation2,
metadata: { addedByUserId: 'abc' },
metadata: { addedByUserId: abc },
});
assert.deepEqual(result[1], {
member: normalConversation1,
metadata: { addedByUserId: 'xyz' },
metadata: { addedByUserId: xyz },
});
});
});

View file

@ -1,33 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { isValidGuid } from '../../util/isValidGuid';
describe('isValidGuid', () => {
const LOWERCASE_V4_UUID = '9cb737ce-2bb3-4c21-9fe0-d286caa0ca68';
it('returns false for non-strings', () => {
assert.isFalse(isValidGuid(undefined));
assert.isFalse(isValidGuid(null));
assert.isFalse(isValidGuid(1234));
});
it('returns false for non-UUID strings', () => {
assert.isFalse(isValidGuid(''));
assert.isFalse(isValidGuid('hello world'));
assert.isFalse(isValidGuid(` ${LOWERCASE_V4_UUID}`));
assert.isFalse(isValidGuid(`${LOWERCASE_V4_UUID} `));
});
it("returns false for UUIDs that aren't version 4", () => {
assert.isFalse(isValidGuid('a200a6e0-d2d9-11eb-bda7-dd5936a30ddf'));
assert.isFalse(isValidGuid('2adb8b83-4f2c-55ca-a481-7f98b716e615'));
});
it('returns true for v4 UUIDs', () => {
assert.isTrue(isValidGuid(LOWERCASE_V4_UUID));
assert.isTrue(isValidGuid(LOWERCASE_V4_UUID.toUpperCase()));
});
});