diff --git a/lib/permissions/minimally-encoded-thread-permissions-test-data.js b/lib/permissions/minimally-encoded-thread-permissions-test-data.js --- a/lib/permissions/minimally-encoded-thread-permissions-test-data.js +++ b/lib/permissions/minimally-encoded-thread-permissions-test-data.js @@ -353,4 +353,322 @@ pinnedCount: 0, }; -export { exampleRawThreadInfoA, exampleMinimallyEncodedRawThreadInfoA }; +const expectedDecodedExampleRawThreadInfoA: RawThreadInfo = { + id: '85171', + type: threadTypes.PERSONAL, + name: '', + description: '', + color: '6d49ab', + creationTime: 1675887298557, + parentThreadID: '1', + members: [ + { + id: '256', + role: null, + permissions: { + know_of: { + value: true, + source: 'null', + }, + visible: { + value: true, + source: 'null', + }, + voiced: { + value: true, + source: 'null', + }, + edit_entries: { + value: true, + source: 'null', + }, + edit_thread: { + value: true, + source: 'null', + }, + edit_thread_description: { + value: true, + source: 'null', + }, + edit_thread_color: { + value: true, + source: 'null', + }, + delete_thread: { + value: true, + source: 'null', + }, + create_subthreads: { + value: true, + source: 'null', + }, + create_sidebars: { + value: true, + source: 'null', + }, + join_thread: { + value: true, + source: 'null', + }, + edit_permissions: { + value: true, + source: 'null', + }, + add_members: { + value: true, + source: 'null', + }, + remove_members: { + value: true, + source: 'null', + }, + change_role: { + value: true, + source: 'null', + }, + leave_thread: { + value: false, + source: null, + }, + react_to_message: { + value: false, + source: null, + }, + edit_message: { + value: false, + source: null, + }, + manage_pins: { + value: true, + source: 'null', + }, + manage_invite_links: { + source: null, + value: false, + }, + edit_thread_avatar: { + source: null, + value: false, + }, + }, + isSender: false, + }, + { + id: '83853', + role: '85172', + permissions: { + know_of: { + value: true, + source: 'null', + }, + visible: { + value: true, + source: 'null', + }, + voiced: { + value: true, + source: 'null', + }, + edit_entries: { + value: true, + source: 'null', + }, + edit_thread: { + value: true, + source: 'null', + }, + edit_thread_description: { + value: true, + source: 'null', + }, + edit_thread_color: { + value: true, + source: 'null', + }, + delete_thread: { + value: false, + source: null, + }, + create_subthreads: { + value: false, + source: null, + }, + create_sidebars: { + value: true, + source: 'null', + }, + join_thread: { + value: false, + source: null, + }, + edit_permissions: { + value: false, + source: null, + }, + add_members: { + value: false, + source: null, + }, + remove_members: { + value: false, + source: null, + }, + change_role: { + value: false, + source: null, + }, + leave_thread: { + value: false, + source: null, + }, + react_to_message: { + value: true, + source: 'null', + }, + edit_message: { + value: true, + source: 'null', + }, + manage_pins: { + value: false, + source: null, + }, + manage_invite_links: { + source: null, + value: false, + }, + edit_thread_avatar: { + source: null, + value: false, + }, + }, + isSender: true, + }, + ], + roles: { + '85172': { + id: '85172', + name: 'Members', + permissions: { + know_of: true, + visible: true, + voiced: true, + react_to_message: true, + edit_message: true, + edit_entries: true, + edit_thread: true, + edit_thread_color: true, + edit_thread_description: true, + create_sidebars: true, + descendant_open_know_of: true, + descendant_open_visible: true, + child_open_join_thread: true, + }, + isDefault: true, + }, + }, + currentUser: { + role: '85172', + permissions: { + know_of: { + value: true, + source: 'null', + }, + visible: { + value: true, + source: 'null', + }, + voiced: { + value: true, + source: 'null', + }, + edit_entries: { + value: true, + source: 'null', + }, + edit_thread: { + value: true, + source: 'null', + }, + edit_thread_description: { + value: true, + source: 'null', + }, + edit_thread_color: { + value: true, + source: 'null', + }, + delete_thread: { + value: false, + source: null, + }, + create_subthreads: { + value: false, + source: null, + }, + create_sidebars: { + value: true, + source: 'null', + }, + join_thread: { + value: false, + source: null, + }, + edit_permissions: { + value: false, + source: null, + }, + add_members: { + value: false, + source: null, + }, + remove_members: { + value: false, + source: null, + }, + change_role: { + value: false, + source: null, + }, + leave_thread: { + value: false, + source: null, + }, + react_to_message: { + value: true, + source: 'null', + }, + edit_message: { + value: true, + source: 'null', + }, + manage_pins: { + value: false, + source: null, + }, + manage_invite_links: { + source: null, + value: false, + }, + edit_thread_avatar: { + source: null, + value: false, + }, + }, + subscription: { + home: true, + pushNotifs: true, + }, + unread: false, + }, + repliesCount: 0, + containingThreadID: '1', + community: '1', + pinnedCount: 0, +}; + +export { + exampleRawThreadInfoA, + exampleMinimallyEncodedRawThreadInfoA, + expectedDecodedExampleRawThreadInfoA, +}; diff --git a/lib/permissions/minimally-encoded-thread-permissions.js b/lib/permissions/minimally-encoded-thread-permissions.js --- a/lib/permissions/minimally-encoded-thread-permissions.js +++ b/lib/permissions/minimally-encoded-thread-permissions.js @@ -239,6 +239,15 @@ permissions: threadRolePermissionsBlobToBitmaskArray(roleInfo.permissions), }); +const decodeMinimallyEncodedRoleInfo = ( + minimallyEncodedRoleInfo: MinimallyEncodedRoleInfo, +): RoleInfo => ({ + ...minimallyEncodedRoleInfo, + permissions: decodeThreadRolePermissionsBitmaskArray( + minimallyEncodedRoleInfo.permissions, + ), +}); + export type MinimallyEncodedThreadCurrentUserInfo = { ...ThreadCurrentUserInfo, +permissions: string, @@ -258,6 +267,15 @@ permissions: permissionsToBitmaskHex(threadCurrentUserInfo.permissions), }); +const decodeMinimallyEncodedThreadCurrentUserInfo = ( + minimallyEncodedThreadCurrentUserInfo: MinimallyEncodedThreadCurrentUserInfo, +): ThreadCurrentUserInfo => ({ + ...minimallyEncodedThreadCurrentUserInfo, + permissions: threadPermissionsFromBitmaskHex( + minimallyEncodedThreadCurrentUserInfo.permissions, + ), +}); + export type MinimallyEncodedMemberInfo = { ...MemberInfo, +permissions: string, @@ -276,6 +294,15 @@ permissions: permissionsToBitmaskHex(memberInfo.permissions), }); +const decodeMinimallyEncodedMemberInfo = ( + minimallyEncodedMemberInfo: MinimallyEncodedMemberInfo, +): MemberInfo => ({ + ...minimallyEncodedMemberInfo, + permissions: threadPermissionsFromBitmaskHex( + minimallyEncodedMemberInfo.permissions, + ), +}); + export type MinimallyEncodedRawThreadInfo = { ...RawThreadInfo, +members: $ReadOnlyArray, @@ -303,6 +330,19 @@ }; }; +const decodeMinimallyEncodedRawThreadInfo = ( + minimallyEncodedRawThreadInfo: MinimallyEncodedRawThreadInfo, +): RawThreadInfo => { + const { members, roles, currentUser, ...rest } = + minimallyEncodedRawThreadInfo; + return { + ...rest, + members: members.map(decodeMinimallyEncodedMemberInfo), + roles: _mapValues(decodeMinimallyEncodedRoleInfo)(roles), + currentUser: decodeMinimallyEncodedThreadCurrentUserInfo(currentUser), + }; +}; + export { permissionsToBitmaskHex, threadPermissionsFromBitmaskHex, @@ -316,4 +356,5 @@ minimallyEncodedMemberInfoValidator, minimallyEncodedRawThreadInfoValidator, minimallyEncodeRawThreadInfo, + decodeMinimallyEncodedRawThreadInfo, }; diff --git a/lib/permissions/minimally-encoded-thread-permissions.test.js b/lib/permissions/minimally-encoded-thread-permissions.test.js --- a/lib/permissions/minimally-encoded-thread-permissions.test.js +++ b/lib/permissions/minimally-encoded-thread-permissions.test.js @@ -3,8 +3,10 @@ import { exampleMinimallyEncodedRawThreadInfoA, exampleRawThreadInfoA, + expectedDecodedExampleRawThreadInfoA, } from './minimally-encoded-thread-permissions-test-data.js'; import { + decodeMinimallyEncodedRawThreadInfo, decodeRolePermissionBitmask, decodeThreadRolePermissionsBitmaskArray, hasPermission, @@ -428,3 +430,13 @@ ).toBe(true); }); }); + +describe('decodeMinimallyEncodedRawThreadInfo', () => { + it('should correctly decode minimallyEncodedRawThreadInfo', () => { + expect( + decodeMinimallyEncodedRawThreadInfo( + minimallyEncodeRawThreadInfo(exampleRawThreadInfoA), + ), + ).toStrictEqual(expectedDecodedExampleRawThreadInfoA); + }); +});