Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3332839
D7710.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
18 KB
Referenced Files
None
Subscribers
None
D7710.id.diff
View Options
diff --git a/keyserver/src/responders/message-responders.js b/keyserver/src/responders/message-responders.js
--- a/keyserver/src/responders/message-responders.js
+++ b/keyserver/src/responders/message-responders.js
@@ -1,7 +1,7 @@
// @flow
import invariant from 'invariant';
-import t from 'tcomb';
+import t, { type TInterface } from 'tcomb';
import { onlyOneEmojiRegex } from 'lib/shared/emojis.js';
import {
@@ -23,11 +23,14 @@
type SendEditMessageResponse,
type FetchPinnedMessagesRequest,
type FetchPinnedMessagesResult,
+ messageTruncationStatusesValidator,
+ rawMessageInfoValidator,
} from 'lib/types/message-types.js';
import type { EditMessageData } from 'lib/types/messages/edit.js';
import type { ReactionMessageData } from 'lib/types/messages/reaction.js';
import type { TextMessageData } from 'lib/types/messages/text.js';
import { threadPermissions } from 'lib/types/thread-types.js';
+import { userInfosValidator } from 'lib/types/user-types.js';
import { ServerError } from 'lib/utils/errors.js';
import { values } from 'lib/utils/objects.js';
import {
@@ -65,6 +68,10 @@
text: t.String,
sidebarCreation: t.maybe(t.Boolean),
});
+
+export const sendMessageResponseValidator: TInterface<SendMessageResponse> =
+ tShape<SendMessageResponse>({ newMessageInfo: rawMessageInfoValidator });
+
async function textMessageCreationResponder(
viewer: Viewer,
input: any,
@@ -118,6 +125,14 @@
cursors: t.dict(t.String, t.maybe(t.String)),
numberPerThread: t.maybe(t.Number),
});
+
+export const fetchMessageInfosResponseValidator: TInterface<FetchMessageInfosResponse> =
+ tShape<FetchMessageInfosResponse>({
+ rawMessageInfos: t.list(rawMessageInfoValidator),
+ truncationStatuses: messageTruncationStatusesValidator,
+ userInfos: userInfosValidator,
+ });
+
async function messageFetchResponder(
viewer: Viewer,
input: any,
@@ -305,6 +320,12 @@
targetMessageID: t.String,
text: t.String,
});
+
+export const sendEditMessageResponseValidator: TInterface<SendEditMessageResponse> =
+ tShape<SendEditMessageResponse>({
+ newMessageInfos: t.list(rawMessageInfoValidator),
+ });
+
async function editMessageCreationResponder(
viewer: Viewer,
input: any,
@@ -388,6 +409,12 @@
const fetchPinnedMessagesResponderInputValidator = tShape({
threadID: t.String,
});
+
+export const fetchPinnedMessagesResultValidator: TInterface<FetchPinnedMessagesResult> =
+ tShape<FetchPinnedMessagesResult>({
+ pinnedMessages: t.list(rawMessageInfoValidator),
+ });
+
async function fetchPinnedMessagesResponder(
viewer: Viewer,
input: any,
diff --git a/keyserver/src/responders/report-responders.js b/keyserver/src/responders/report-responders.js
--- a/keyserver/src/responders/report-responders.js
+++ b/keyserver/src/responders/report-responders.js
@@ -2,7 +2,7 @@
import type { $Response, $Request } from 'express';
import t from 'tcomb';
-import type { TStructProps } from 'tcomb';
+import type { TInterface, TStructProps } from 'tcomb';
import {
type ReportCreationResponse,
@@ -12,7 +12,9 @@
type ThreadInconsistencyReportShape,
type EntryInconsistencyReportShape,
reportTypes,
+ reportInfoValidator,
} from 'lib/types/report-types.js';
+import { userInfoValidator } from 'lib/types/user-types.js';
import { ServerError } from 'lib/utils/errors.js';
import {
tShape,
@@ -131,6 +133,9 @@
userInconsistencyReportCreationRequest,
]);
+export const reportCreationResponseValidator: TInterface<ReportCreationResponse> =
+ tShape<ReportCreationResponse>({ id: t.String });
+
async function reportCreationResponder(
viewer: Viewer,
input: any,
@@ -203,6 +208,12 @@
cursor: t.maybe(t.String),
});
+export const fetchErrorReportInfosResponseValidator: TInterface<FetchErrorReportInfosResponse> =
+ tShape<FetchErrorReportInfosResponse>({
+ reports: t.list(reportInfoValidator),
+ userInfos: t.list(userInfoValidator),
+ });
+
async function errorReportFetchInfosResponder(
viewer: Viewer,
input: any,
diff --git a/keyserver/src/responders/responder-validators.test.js b/keyserver/src/responders/responder-validators.test.js
--- a/keyserver/src/responders/responder-validators.test.js
+++ b/keyserver/src/responders/responder-validators.test.js
@@ -15,9 +15,24 @@
} from './entry-responders.js';
import { getSessionPublicKeysResponseValidator } from './keys-responders.js';
import { messageReportCreationResultValidator } from './message-report-responder.js';
+import {
+ fetchMessageInfosResponseValidator,
+ fetchPinnedMessagesResultValidator,
+ sendEditMessageResponseValidator,
+ sendMessageResponseValidator,
+} from './message-responders.js';
import { relationshipErrorsValidator } from './relationship-responders.js';
+import { reportCreationResponseValidator } from './report-responders.js';
import { userSearchResultValidator } from './search-responders.js';
import { siweNonceResponseValidator } from './siwe-nonce-responders.js';
+import {
+ changeThreadSettingsResultValidator,
+ leaveThreadResultValidator,
+ newThreadResponseValidator,
+ threadFetchMediaResultValidator,
+ threadJoinResultValidator,
+ toggleMessagePinResultValidator,
+} from './thread-responders.js';
import {
logInResponseValidator,
registerResponseValidator,
@@ -617,3 +632,289 @@
).toBe(false);
});
});
+
+describe('thread responders', () => {
+ it('should validate change thread settings response', () => {
+ const response = {
+ updatesResult: {
+ newUpdates: [
+ {
+ type: 1,
+ id: '93601',
+ time: 1682759546258,
+ threadInfo: {
+ id: '92796',
+ type: 6,
+ name: '',
+ description: '',
+ color: 'b8753d',
+ creationTime: 1682076700918,
+ parentThreadID: '1',
+ members: [],
+ roles: {},
+ currentUser: {
+ role: '85172',
+ permissions: {},
+ subscription: {
+ home: true,
+ pushNotifs: true,
+ },
+ unread: false,
+ },
+ repliesCount: 0,
+ containingThreadID: '1',
+ community: '1',
+ pinnedCount: 0,
+ },
+ },
+ ],
+ },
+ newMessageInfos: [
+ {
+ type: 4,
+ threadID: '92796',
+ creatorID: '83928',
+ time: 1682759546275,
+ field: 'color',
+ value: 'b8753d',
+ id: '93602',
+ },
+ ],
+ };
+ expect(changeThreadSettingsResultValidator.is(response)).toBe(true);
+ expect(
+ changeThreadSettingsResultValidator.is({
+ ...response,
+ newMessageInfos: undefined,
+ }),
+ ).toBe(false);
+ });
+
+ it('should validate leave thread response', () => {
+ const response = {
+ updatesResult: {
+ newUpdates: [
+ { type: 3, id: '93595', time: 1682759498811, threadID: '93561' },
+ ],
+ },
+ };
+ expect(leaveThreadResultValidator.is(response)).toBe(true);
+ expect(
+ leaveThreadResultValidator.is({
+ ...response,
+ updatedResult: undefined,
+ }),
+ ).toBe(false);
+ });
+
+ it('should validate new thread response', () => {
+ const response = {
+ newThreadID: '93619',
+ updatesResult: {
+ newUpdates: [
+ {
+ type: 4,
+ id: '93621',
+ time: 1682759805331,
+ threadInfo: {
+ id: '93619',
+ type: 5,
+ name: 'a',
+ description: '',
+ color: 'b8753d',
+ creationTime: 1682759805298,
+ parentThreadID: '92796',
+ members: [],
+ roles: {},
+ currentUser: {
+ role: '85172',
+ permissions: {},
+ subscription: {
+ home: true,
+ pushNotifs: true,
+ },
+ unread: false,
+ },
+ repliesCount: 0,
+ containingThreadID: '92796',
+ community: '1',
+ sourceMessageID: '93614',
+ pinnedCount: 0,
+ },
+ rawMessageInfos: [],
+ truncationStatus: 'exhaustive',
+ rawEntryInfos: [],
+ },
+ ],
+ },
+ userInfos: {
+ '256': { id: '256', username: 'ashoat' },
+ '83928': { id: '83928', username: 'temp_user3' },
+ },
+ newMessageInfos: [],
+ };
+ expect(newThreadResponseValidator.is(response)).toBe(true);
+ expect(
+ newThreadResponseValidator.is({
+ ...response,
+ newMessageInfos: {},
+ }),
+ ).toBe(false);
+ });
+
+ it('should validate thread join response', () => {
+ const response = {
+ rawMessageInfos: [
+ {
+ type: 8,
+ threadID: '93619',
+ creatorID: '83928',
+ time: 1682759915935,
+ id: '93640',
+ },
+ ],
+ truncationStatuses: {},
+ userInfos: {
+ '256': { id: '256', username: 'ashoat' },
+ '83928': { id: '83928', username: 'temp_user3' },
+ },
+ updatesResult: {
+ newUpdates: [],
+ },
+ };
+ expect(threadJoinResultValidator.is(response)).toBe(true);
+ expect(
+ threadJoinResultValidator.is({
+ ...response,
+ updatesResult: [],
+ }),
+ ).toBe(false);
+ });
+
+ it('should validate thread fetch media response', () => {
+ const response = {
+ media: [
+ {
+ type: 'photo',
+ id: '93642',
+ uri: 'http://0.0.0.0:3000/comm/upload/93642/1e0d7a5262952e3b',
+ dimensions: { width: 220, height: 220 },
+ },
+ ],
+ };
+ expect(threadFetchMediaResultValidator.is(response)).toBe(true);
+ expect(
+ threadFetchMediaResultValidator.is({ ...response, media: undefined }),
+ ).toBe(false);
+ });
+
+ it('should validate toggle message pin response', () => {
+ const response = { threadID: '123', newMessageInfos: [] };
+ expect(toggleMessagePinResultValidator.is(response)).toBe(true);
+ expect(
+ toggleMessagePinResultValidator.is({ ...response, threadID: undefined }),
+ ).toBe(false);
+ });
+});
+
+describe('message responders', () => {
+ it('should validate send message response', () => {
+ const response = {
+ newMessageInfo: {
+ type: 0,
+ threadID: '93619',
+ creatorID: '83928',
+ time: 1682761023640,
+ text: 'a',
+ localID: 'local3',
+ id: '93649',
+ },
+ };
+ expect(sendMessageResponseValidator.is(response)).toBe(true);
+ expect(
+ sendMessageResponseValidator.is({
+ ...response,
+ newMEssageInfos: undefined,
+ }),
+ ).toBe(false);
+ });
+
+ it('should validate fetch message infos response', () => {
+ const response = {
+ rawMessageInfos: [
+ {
+ type: 0,
+ id: '83954',
+ threadID: '83938',
+ time: 1673561155110,
+ creatorID: '256',
+ text: 'welcome to Comm!',
+ },
+ ],
+ truncationStatuses: { '83938': 'exhaustive' },
+ userInfos: {
+ '256': { id: '256', username: 'ashoat' },
+ '83928': { id: '83928', username: 'temp_user3' },
+ },
+ };
+ expect(fetchMessageInfosResponseValidator.is(response)).toBe(true);
+ expect(
+ fetchMessageInfosResponseValidator.is({
+ ...response,
+ userInfos: undefined,
+ }),
+ ).toBe(false);
+ });
+
+ it('should validate send edit message response', () => {
+ const response = {
+ newMessageInfos: [
+ {
+ type: 0,
+ id: '83954',
+ threadID: '83938',
+ time: 1673561155110,
+ creatorID: '256',
+ text: 'welcome to Comm!',
+ },
+ ],
+ };
+ expect(sendEditMessageResponseValidator.is(response)).toBe(true);
+ expect(
+ sendEditMessageResponseValidator.is({
+ ...response,
+ newMessageInfos: undefined,
+ }),
+ ).toBe(false);
+ });
+
+ it('should validate fetch pinned message response', () => {
+ const response = {
+ pinnedMessages: [
+ {
+ type: 0,
+ id: '83954',
+ threadID: '83938',
+ time: 1673561155110,
+ creatorID: '256',
+ text: 'welcome to Comm!',
+ },
+ ],
+ };
+ expect(fetchPinnedMessagesResultValidator.is(response)).toBe(true);
+ expect(
+ fetchPinnedMessagesResultValidator.is({
+ ...response,
+ pinnedMessages: undefined,
+ }),
+ ).toBe(false);
+ });
+});
+
+describe('report responders', () => {
+ it('should validate report creation response', () => {
+ const response = { id: '123' };
+ expect(reportCreationResponseValidator.is(response)).toBe(true);
+ expect(reportCreationResponseValidator.is({})).toBe(false);
+ });
+});
diff --git a/keyserver/src/responders/thread-responders.js b/keyserver/src/responders/thread-responders.js
--- a/keyserver/src/responders/thread-responders.js
+++ b/keyserver/src/responders/thread-responders.js
@@ -1,8 +1,14 @@
// @flow
import t from 'tcomb';
-import type { TUnion } from 'tcomb';
+import type { TInterface, TUnion } from 'tcomb';
+import { rawEntryInfoValidator } from 'lib/types/entry-types.js';
+import { mediaValidator } from 'lib/types/media-types.js';
+import {
+ rawMessageInfoValidator,
+ messageTruncationStatusesValidator,
+} from 'lib/types/message-types.js';
import {
type ThreadDeletionRequest,
type RoleChangeRequest,
@@ -20,7 +26,10 @@
type ToggleMessagePinRequest,
type ToggleMessagePinResult,
threadTypes,
+ rawThreadInfoValidator,
} from 'lib/types/thread-types.js';
+import { serverUpdateInfoValidator } from 'lib/types/update-types.js';
+import { userInfosValidator } from 'lib/types/user-types.js';
import { updateUserAvatarRequestValidator } from 'lib/utils/avatar-utils.js';
import { values } from 'lib/utils/objects.js';
import {
@@ -28,6 +37,7 @@
tNumEnum,
tColor,
tPassword,
+ tID,
} from 'lib/utils/validation-utils.js';
import {
@@ -53,6 +63,14 @@
accountPassword: t.maybe(tPassword),
});
+export const leaveThreadResultValidator: TInterface<LeaveThreadResult> =
+ tShape<LeaveThreadResult>({
+ threadInfos: t.maybe(t.dict(tID, rawThreadInfoValidator)),
+ updatesResult: tShape({
+ newUpdates: t.list(serverUpdateInfoValidator),
+ }),
+ });
+
async function threadDeletionResponder(
viewer: Viewer,
input: any,
@@ -71,6 +89,16 @@
}),
});
+export const changeThreadSettingsResultValidator: TInterface<ChangeThreadSettingsResult> =
+ tShape<ChangeThreadSettingsResult>({
+ newMessageInfos: t.list(rawMessageInfoValidator),
+ threadInfo: t.maybe(rawThreadInfoValidator),
+ threadInfos: t.maybe(t.dict(tID, rawThreadInfoValidator)),
+ updatesResult: tShape({
+ newUpdates: t.list(serverUpdateInfoValidator),
+ }),
+ });
+
async function roleUpdateResponder(
viewer: Viewer,
input: any,
@@ -154,6 +182,18 @@
...threadRequestValidationShape,
}),
]);
+
+export const newThreadResponseValidator: TInterface<NewThreadResponse> =
+ tShape<NewThreadResponse>({
+ updatesResult: tShape({
+ newUpdates: t.list(serverUpdateInfoValidator),
+ }),
+ newMessageInfos: t.list(rawMessageInfoValidator),
+ newThreadInfo: t.maybe(rawThreadInfoValidator),
+ userInfos: userInfosValidator,
+ newThreadID: t.maybe(tID),
+ });
+
async function threadCreationResponder(
viewer: Viewer,
input: any,
@@ -171,6 +211,19 @@
calendarQuery: t.maybe(entryQueryInputValidator),
inviteLinkSecret: t.maybe(t.String),
});
+
+export const threadJoinResultValidator: TInterface<ThreadJoinResult> =
+ tShape<ThreadJoinResult>({
+ threadInfos: t.maybe(t.dict(tID, rawThreadInfoValidator)),
+ updatesResult: tShape({
+ newUpdates: t.list(serverUpdateInfoValidator),
+ }),
+ rawMessageInfos: t.list(rawMessageInfoValidator),
+ truncationStatuses: messageTruncationStatusesValidator,
+ userInfos: userInfosValidator,
+ rawEntryInfos: t.maybe(t.list(rawEntryInfoValidator)),
+ });
+
async function threadJoinResponder(
viewer: Viewer,
input: any,
@@ -190,6 +243,10 @@
limit: t.Number,
offset: t.Number,
});
+
+export const threadFetchMediaResultValidator: TInterface<ThreadFetchMediaResult> =
+ tShape<ThreadFetchMediaResult>({ media: t.list(mediaValidator) });
+
async function threadFetchMediaResponder(
viewer: Viewer,
input: any,
@@ -203,6 +260,13 @@
messageID: t.String,
action: t.enums.of(['pin', 'unpin']),
});
+
+export const toggleMessagePinResultValidator: TInterface<ToggleMessagePinResult> =
+ tShape<ToggleMessagePinResult>({
+ newMessageInfos: t.list(rawMessageInfoValidator),
+ threadID: tID,
+ });
+
async function toggleMessagePinResponder(
viewer: Viewer,
input: any,
diff --git a/lib/types/report-types.js b/lib/types/report-types.js
--- a/lib/types/report-types.js
+++ b/lib/types/report-types.js
@@ -1,6 +1,7 @@
// @flow
import invariant from 'invariant';
+import t, { type TInterface } from 'tcomb';
import { type PlatformDetails } from './device-types.js';
import { type RawEntryInfo, type CalendarQuery } from './entry-types.js';
@@ -8,6 +9,7 @@
import type { AppState, BaseAction } from './redux-types.js';
import { type RawThreadInfo } from './thread-types.js';
import type { UserInfo, UserInfos } from './user-types.js';
+import { tPlatformDetails, tShape } from '../utils/validation-utils.js';
export type EnabledReports = {
+crashReports: boolean,
@@ -188,6 +190,13 @@
+creationTime: number,
};
+export const reportInfoValidator: TInterface<ReportInfo> = tShape<ReportInfo>({
+ id: t.String,
+ viewerID: t.String,
+ platformDetails: tPlatformDetails,
+ creationTime: t.Number,
+});
+
export type FetchErrorReportInfosRequest = {
+cursor: ?string,
};
diff --git a/lib/types/user-types.js b/lib/types/user-types.js
--- a/lib/types/user-types.js
+++ b/lib/types/user-types.js
@@ -1,6 +1,6 @@
// @flow
-import t, { type TInterface } from 'tcomb';
+import t, { type TInterface, type TDict } from 'tcomb';
import {
type DefaultNotificationPayload,
@@ -45,6 +45,10 @@
avatar: t.maybe(clientAvatarValidator),
});
export type UserInfos = { +[id: string]: UserInfo };
+export const userInfosValidator: TDict<UserInfos> = t.dict(
+ t.String,
+ userInfoValidator,
+);
export type AccountUserInfo = {
+id: string,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 22, 2:09 AM (4 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2555274
Default Alt Text
D7710.id.diff (18 KB)
Attached To
Mode
D7710: [keyserver] Introduce report, message and thread responder validators
Attached
Detach File
Event Timeline
Log In to Comment