Skip to content

Commit

Permalink
[lib] Introduce MinimallyEncodedThreadCurrentUserInfo and validator
Browse files Browse the repository at this point in the history
Summary:
`ThreadCurrentUserInfo` type w/ `permissions` as string instead of `ThreadPermissions`.

Next diffs:
- Introduce `MinimallyEncodedRawThreadInfo`
- Higher level utilities for translating back/forth from `RawThreadInfo` <=> `MinimallyEncodedRawThreadInfo`. Found this to be cleaner API than encoding/decoding `RawThreadInfo.currentUser.permissions` and `RawThreadInfo.members[memberID].permissions` "manually" a bunch of different places.
- Native refactoring + migrations
- Web refactoring
- Flipping the switch

---

Depends on D9731

Test Plan: Unit tests, will be tested implicitly in subsequent diffs as well.

Reviewers: ashoat, rohan, ginsu, tomek

Reviewed By: ashoat

Subscribers: ashoat, tomek, wyilio

Differential Revision: https://phab.comm.dev/D9734
  • Loading branch information
atulsmadhugiri committed Nov 6, 2023
1 parent 3023e16 commit dc24c82
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 8 deletions.
20 changes: 18 additions & 2 deletions lib/permissions/minimally-encoded-thread-permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import type {
ThreadPermissionsInfo,
ThreadRolePermissionsBlob,
} from '../types/thread-permission-types.js';
import type { RoleInfo } from '../types/thread-types.js';
import { roleInfoValidator } from '../types/thread-types.js';
import type { RoleInfo, ThreadCurrentUserInfo } from '../types/thread-types.js';
import {
roleInfoValidator,
threadCurrentUserInfoValidator,
} from '../types/thread-types.js';
import { entries, invertObjectToMap } from '../utils/objects.js';
import { tRegex, tShape } from '../utils/validation-utils.js';
import type { TRegex } from '../utils/validation-utils.js';
Expand Down Expand Up @@ -196,6 +199,18 @@ const minimallyEncodedRoleInfoValidator: TInterface<MinimallyEncodedRoleInfo> =
permissions: t.list(tHexEncodedRolePermission),
});

export type MinimallyEncodedThreadCurrentUserInfo = {
...ThreadCurrentUserInfo,
+permissions: string,
};

const tHexEncodedPermissionsBitmask: TRegex = tRegex(/^[0-9a-fA-F]+$/);
const minimallyEncodedThreadCurrentUserInfoValidator: TInterface<MinimallyEncodedThreadCurrentUserInfo> =
tShape<MinimallyEncodedThreadCurrentUserInfo>({
...threadCurrentUserInfoValidator.meta.props,
permissions: tHexEncodedPermissionsBitmask,
});

export {
permissionsToBitmaskHex,
hasPermission,
Expand All @@ -204,4 +219,5 @@ export {
threadRolePermissionsBlobToBitmaskArray,
decodeThreadRolePermissionsBitmaskArray,
minimallyEncodedRoleInfoValidator,
minimallyEncodedThreadCurrentUserInfoValidator,
};
41 changes: 41 additions & 0 deletions lib/permissions/minimally-encoded-thread-permissions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
decodeThreadRolePermissionsBitmaskArray,
hasPermission,
minimallyEncodedRoleInfoValidator,
minimallyEncodedThreadCurrentUserInfoValidator,
permissionsToBitmaskHex,
rolePermissionToBitmaskHex,
threadRolePermissionsBlobToBitmaskArray,
Expand Down Expand Up @@ -282,3 +283,43 @@ describe('minimallyEncodedRoleInfoValidator', () => {
).toBe(false);
});
});

describe('minimallyEncodedThreadCurrentUserInfoValidator', () => {
it('should validate correctly formed MinimallyEncodedThreadCurrentUserInfo', () => {
expect(
minimallyEncodedThreadCurrentUserInfoValidator.is({
permissions: '100',
subscription: { home: true, pushNotifs: true },
}),
).toBe(true);
expect(
minimallyEncodedThreadCurrentUserInfoValidator.is({
permissions: 'ABCDEFABCDEFABCD',
subscription: { home: true, pushNotifs: true },
}),
).toBe(true);
});

it('should NOT validate malformed MinimallyEncodedThreadCurrentUserInfo', () => {
expect(
minimallyEncodedThreadCurrentUserInfoValidator.is({
permissions: 'INVALID',
subscription: { home: true, pushNotifs: true },
}),
).toBe(false);

expect(
minimallyEncodedThreadCurrentUserInfoValidator.is({
permissions: 'ABCDEF hello ABCDEFABCD',
subscription: { home: true, pushNotifs: true },
}),
).toBe(false);

expect(
minimallyEncodedThreadCurrentUserInfoValidator.is({
permissions: 100,
subscription: { home: true, pushNotifs: true },
}),
).toBe(false);
});
});
13 changes: 7 additions & 6 deletions lib/types/thread-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,13 @@ export type ThreadCurrentUserInfo = {
+subscription: ThreadSubscription,
+unread: ?boolean,
};
const threadCurrentUserInfoValidator = tShape<ThreadCurrentUserInfo>({
role: t.maybe(tID),
permissions: threadPermissionsInfoValidator,
subscription: threadSubscriptionValidator,
unread: t.maybe(t.Boolean),
});
export const threadCurrentUserInfoValidator: TInterface<ThreadCurrentUserInfo> =
tShape<ThreadCurrentUserInfo>({
role: t.maybe(tID),
permissions: threadPermissionsInfoValidator,
subscription: threadSubscriptionValidator,
unread: t.maybe(t.Boolean),
});

export type RawThreadInfo = {
+id: string,
Expand Down

0 comments on commit dc24c82

Please sign in to comment.