From 6e2a757a9ffc3008072691970572a691307bea2b Mon Sep 17 00:00:00 2001 From: Max Duval Date: Mon, 29 Jan 2024 12:17:50 +0000 Subject: [PATCH] feat(discussion): parse user name response remove unused types --- .../src/components/Discussion/CommentForm.tsx | 5 +- dotcom-rendering/src/lib/discussionApi.tsx | 21 +++++- dotcom-rendering/src/types/discussion.ts | 73 ++++--------------- 3 files changed, 35 insertions(+), 64 deletions(-) diff --git a/dotcom-rendering/src/components/Discussion/CommentForm.tsx b/dotcom-rendering/src/components/Discussion/CommentForm.tsx index fbaac1aeed7..cac0652e843 100644 --- a/dotcom-rendering/src/components/Discussion/CommentForm.tsx +++ b/dotcom-rendering/src/components/Discussion/CommentForm.tsx @@ -421,13 +421,12 @@ export const CommentForm = ({ } const response = await addUserName(user.authStatus, userName); - if (response.status === 'ok') { + if (response.kind === 'ok') { // If we are able to submit userName we should continue with submitting comment void submitForm(); setUserNameMissing(false); } else { - response.errors && - setError(response.errors[0]?.message ?? 'unknown error'); + setError(response.error); } }; diff --git a/dotcom-rendering/src/lib/discussionApi.tsx b/dotcom-rendering/src/lib/discussionApi.tsx index 602d20a186d..5d89d4a002b 100644 --- a/dotcom-rendering/src/lib/discussionApi.tsx +++ b/dotcom-rendering/src/lib/discussionApi.tsx @@ -8,13 +8,13 @@ import type { GetDiscussionSuccess, OrderByType, ThreadsType, - UserNameResponse, } from '../types/discussion'; import { discussionApiResponseSchema, parseAbuseResponse, parseCommentRepliesResponse, parseCommentResponse, + postUsernameResponseSchema, } from '../types/discussion'; import type { SignedInWithCookies, SignedInWithOkta } from './identity'; import { getOptionsHeadersWithOkta } from './identity'; @@ -337,11 +337,11 @@ export const recommend = export const addUserName = async ( authStatus: SignedInWithCookies | SignedInWithOkta, userName: string, -): Promise => { +): Promise> => { const url = options.idApiUrl + `/user/me/username`; const authOptions = getOptionsHeadersWithOkta(authStatus); - const resp = await fetch(url, { + const jsonResult = await fetchJSON(url, { method: 'POST', body: JSON.stringify({ publicFields: { @@ -356,7 +356,20 @@ export const addUserName = async ( credentials: authOptions.credentials, }); - return resp.json(); + if (jsonResult.kind === 'error') { + return jsonResult; + } + + const result = safeParse(postUsernameResponseSchema, jsonResult.value); + + if (!result.success) { + return { kind: 'error', error: 'An unknown error occured' }; + } + if (result.output.status === 'error') { + return { kind: 'error', error: result.output.errors }; + } + + return { kind: 'ok', value: true }; }; export const pickComment = async ( diff --git a/dotcom-rendering/src/types/discussion.ts b/dotcom-rendering/src/types/discussion.ts index 143192ef944..bbe60e67482 100644 --- a/dotcom-rendering/src/types/discussion.ts +++ b/dotcom-rendering/src/types/discussion.ts @@ -252,63 +252,22 @@ export const parseAbuseResponse = (data: unknown): Result => { : { kind: 'error', error: output.message }; }; -type UserNameError = { - message: string; - description: string; - context: string; -}; - -type UserConsents = { - id: string; - actor: string; - version: number; - consented: boolean; - timestamp: string; - privacyPolicyVersion: number; -}; - -type UserGroups = { - path: string; - packageCode: string; -}; - -type UserNameUser = { - dates: { accountCreatedDate: string }; - consents: UserConsents[]; - userGroups: UserGroups[]; - publicFields: { - username: string; - displayName: string; - }; - statusFields: { - userEmailValidated: boolean; - }; - privateFields: { - legacyPackages: string; - legacyProducts: string; - // Optional fields. See scala @ https://github.com/guardian/identity/blob/07142212b1571d5f8e0a60585c6511abb3620f8c/identity-model-play/src/main/scala/com/gu/identity/model/play/PrivateFields.scala#L5-L18 - brazeUuid?: string; - puzzleUuid?: string; - googleTagId?: string; - firstName?: string; - secondName?: string; - registrationIp?: string; - lastActiveIpAddress?: string; - registrationType?: string; - registrationPlatform?: string; - telephoneNumber?: string; - title?: string; - }; - primaryEmailAddress: string; - id: string; - hasPassword: boolean; -}; - -export type UserNameResponse = { - status: 'ok' | 'error'; - user: UserNameUser; - errors?: UserNameError[]; -}; +export const postUsernameResponseSchema = variant('status', [ + object({ + status: literal('error'), + errors: transform( + array( + object({ + message: string(), + }), + ), + (input) => input[0]?.message ?? 'An unknown error occurred', + ), + }), + object({ + status: literal('ok'), + }), +]); const orderBy = ['newest', 'oldest', 'recommendations'] as const; export const isOrderBy = guard(orderBy);