From f30e40a446d89fbfd6cab70dd20eaa5775c39928 Mon Sep 17 00:00:00 2001 From: Suejung Shin Date: Mon, 23 Dec 2024 11:13:34 -0800 Subject: [PATCH 1/7] chore: Migrate updateProfile to ts --- src/services/user/useUpdateProfile.ts | 47 +++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/services/user/useUpdateProfile.ts b/src/services/user/useUpdateProfile.ts index 17622460dd..0fcb2a9231 100644 --- a/src/services/user/useUpdateProfile.ts +++ b/src/services/user/useUpdateProfile.ts @@ -1,8 +1,42 @@ import { useMutation, useQueryClient } from '@tanstack/react-query' +import { z } from 'zod' import config from 'config' import Api from 'shared/api' +import { NetworkErrorObject, rejectNetworkError } from 'shared/api/helpers' + +const CurrentUserFragment = z.object({ + email: z.string(), + privateAccess: z.boolean(), + onboardingCompleted: z.boolean(), + businessEmail: z.string(), + user: z.object({ + name: z.string(), + username: z.string(), + avatarUrl: z.string(), + avatar: z.string(), + student: z.boolean(), + studentCreatedAt: z.string(), + studentUpdatedAt: z.string(), + }), + trackingMetadata: z.object({ + service: z.string(), + ownerid: z.string(), + serviceId: z.string(), + }), +}) + +const CurrentUserFragmentSchema = z.object({ + me: CurrentUserFragment.nullable(), + error: z + .discriminatedUnion('__typename', [ + z.object({ + __typename: z.literal('ValidationError'), + }), + ]) + .nullable(), +}) const currentUserFragment = ` fragment CurrentUserFragment on Me { @@ -72,9 +106,18 @@ export function useUpdateProfile({ provider }: { provider: string }) { email, }, }, - }).then((res) => res?.data?.updateProfile?.me) + }) }, - onSuccess: (user) => { + onSuccess: ({ data }) => { + const parsedData = CurrentUserFragmentSchema.safeParse(data) + if (!parsedData.success) { + return rejectNetworkError({ + status: 404, + data: {}, + dev: 'useUpdateProfile - 404 failed to parse', + } satisfies NetworkErrorObject) + } + queryClient.setQueryData(['currentUser', provider], () => user) if (config.IS_SELF_HOSTED) { From 2eecb3884e447155bd513b4f82fc96297ae78dc2 Mon Sep 17 00:00:00 2001 From: Suejung Shin Date: Wed, 1 Jan 2025 22:03:52 -0800 Subject: [PATCH 2/7] fix tests --- .../Admin/DetailsSection/DetailsSection.jsx | 4 +- src/services/user/useUpdateProfile.test.tsx | 48 +++++++++---- src/services/user/useUpdateProfile.ts | 69 +++++++++++-------- 3 files changed, 76 insertions(+), 45 deletions(-) diff --git a/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.jsx b/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.jsx index 1617993b3b..deb744f22c 100644 --- a/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.jsx +++ b/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.jsx @@ -39,7 +39,9 @@ function DetailsSection({ email, name }) { function submit(formData) { mutate(formData, { - onSuccess: (updatedUser) => { + onSuccess: ({ data }) => { + const updatedUser = data?.updateProfile?.me + queryClient.invalidateQueries(['user', provider]) addToast({ diff --git a/src/services/user/useUpdateProfile.test.tsx b/src/services/user/useUpdateProfile.test.tsx index afdb3ad857..a121fd7e34 100644 --- a/src/services/user/useUpdateProfile.test.tsx +++ b/src/services/user/useUpdateProfile.test.tsx @@ -88,11 +88,17 @@ describe('useUpdateProfile', () => { await waitFor(() => expect(result.current.data).toStrictEqual({ - avatarUrl: 'http://127.0.0.1/avatar-url', - email: 'newemail@test.com', - name: 'new name', - onboardingCompleted: false, - username: 'TerrySmithDC', + data: { + updateProfile: { + me: { + avatarUrl: 'http://127.0.0.1/avatar-url', + email: 'newemail@test.com', + name: 'new name', + onboardingCompleted: false, + username: 'TerrySmithDC', + }, + }, + }, }) ) }) @@ -108,11 +114,17 @@ describe('useUpdateProfile', () => { await waitFor(() => expect(result.current.data).toStrictEqual({ - avatarUrl: 'http://127.0.0.1/avatar-url', - email: 'newemail@test.com', - name: 'new name', - onboardingCompleted: false, - username: 'TerrySmithDC', + data: { + updateProfile: { + me: { + avatarUrl: 'http://127.0.0.1/avatar-url', + email: 'newemail@test.com', + name: 'new name', + onboardingCompleted: false, + username: 'TerrySmithDC', + }, + }, + }, }) ) }) @@ -153,11 +165,17 @@ describe('useUpdateProfile', () => { await waitFor(() => expect(result.current.data).toStrictEqual({ - avatarUrl: 'http://127.0.0.1/avatar-url', - email: 'newemail@test.com', - name: 'new name', - onboardingCompleted: false, - username: 'TerrySmithDC', + data: { + updateProfile: { + me: { + avatarUrl: 'http://127.0.0.1/avatar-url', + email: 'newemail@test.com', + name: 'new name', + onboardingCompleted: false, + username: 'TerrySmithDC', + }, + }, + }, }) ) }) diff --git a/src/services/user/useUpdateProfile.ts b/src/services/user/useUpdateProfile.ts index 0fcb2a9231..b9a9b71844 100644 --- a/src/services/user/useUpdateProfile.ts +++ b/src/services/user/useUpdateProfile.ts @@ -7,35 +7,43 @@ import Api from 'shared/api' import { NetworkErrorObject, rejectNetworkError } from 'shared/api/helpers' const CurrentUserFragment = z.object({ - email: z.string(), - privateAccess: z.boolean(), - onboardingCompleted: z.boolean(), - businessEmail: z.string(), - user: z.object({ - name: z.string(), - username: z.string(), - avatarUrl: z.string(), - avatar: z.string(), - student: z.boolean(), - studentCreatedAt: z.string(), - studentUpdatedAt: z.string(), - }), - trackingMetadata: z.object({ - service: z.string(), - ownerid: z.string(), - serviceId: z.string(), - }), + email: z.string().nullish(), + privateAccess: z.boolean().nullish(), + onboardingCompleted: z.boolean().nullish(), + businessEmail: z.string().nullish(), + user: z + .object({ + name: z.string().nullish(), + username: z.string().nullish(), + avatarUrl: z.string().nullish(), + avatar: z.string().nullish(), + student: z.boolean().nullish(), + studentCreatedAt: z.string().nullish(), + studentUpdatedAt: z.string().nullish(), + }) + .nullish(), + trackingMetadata: z + .object({ + service: z.string().nullish(), + ownerid: z.number().nullish(), + serviceId: z.string().nullish(), + }) + .nullish(), }) -const CurrentUserFragmentSchema = z.object({ - me: CurrentUserFragment.nullable(), - error: z - .discriminatedUnion('__typename', [ - z.object({ - __typename: z.literal('ValidationError'), - }), - ]) - .nullable(), +const UpdateProfileResponseSchema = z.object({ + updateProfile: z + .object({ + me: CurrentUserFragment.nullish(), + error: z + .discriminatedUnion('__typename', [ + z.object({ + __typename: z.literal('ValidationError'), + }), + ]) + .nullish(), + }) + .nullish(), }) const currentUserFragment = ` @@ -109,7 +117,7 @@ export function useUpdateProfile({ provider }: { provider: string }) { }) }, onSuccess: ({ data }) => { - const parsedData = CurrentUserFragmentSchema.safeParse(data) + const parsedData = UpdateProfileResponseSchema.safeParse(data) if (!parsedData.success) { return rejectNetworkError({ status: 404, @@ -118,7 +126,10 @@ export function useUpdateProfile({ provider }: { provider: string }) { } satisfies NetworkErrorObject) } - queryClient.setQueryData(['currentUser', provider], () => user) + queryClient.setQueryData( + ['currentUser', provider], + () => parsedData.data.updateProfile?.me + ) if (config.IS_SELF_HOSTED) { queryClient.invalidateQueries(['SelfHostedCurrentUser']) From 7cbf5b2c009568307a9c92fa638801bc0efb4a42 Mon Sep 17 00:00:00 2001 From: Suejung Shin Date: Wed, 1 Jan 2025 22:11:49 -0800 Subject: [PATCH 3/7] missed some fields --- src/services/user/useUpdateProfile.ts | 38 ++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/services/user/useUpdateProfile.ts b/src/services/user/useUpdateProfile.ts index b9a9b71844..ffc17f7bf8 100644 --- a/src/services/user/useUpdateProfile.ts +++ b/src/services/user/useUpdateProfile.ts @@ -6,6 +6,25 @@ import config from 'config' import Api from 'shared/api' import { NetworkErrorObject, rejectNetworkError } from 'shared/api/helpers' +const TypeProjectsSchema = z.array( + z.union([ + z.literal('PERSONAL'), + z.literal('YOUR_ORG'), + z.literal('OPEN_SOURCE'), + z.literal('EDUCATIONAL'), + ]) +) + +const GoalsSchema = z.array( + z.union([ + z.literal('STARTING_WITH_TESTS'), + z.literal('IMPROVE_COVERAGE'), + z.literal('MAINTAIN_COVERAGE'), + z.literal('TEAM_REQUIREMENTS'), + z.literal('OTHER'), + ]) +) + const CurrentUserFragment = z.object({ email: z.string().nullish(), privateAccess: z.boolean().nullish(), @@ -27,6 +46,24 @@ const CurrentUserFragment = z.object({ service: z.string().nullish(), ownerid: z.number().nullish(), serviceId: z.string().nullish(), + plan: z.string().nullish(), + staff: z.boolean().nullish(), + hasYaml: z.boolean(), + bot: z.string().nullish(), + delinquent: z.boolean().nullish(), + didTrial: z.boolean().nullish(), + planProvider: z.string().nullish(), + planUserCount: z.number().nullish(), + createdAt: z.string().nullish(), + updatedAt: z.string().nullish(), + profile: z + .object({ + createdAt: z.string().nullish(), + otherGoal: z.string().nullish(), + typeProjects: TypeProjectsSchema.nullish(), + goals: GoalsSchema.nullish(), + }) + .nullish(), }) .nullish(), }) @@ -68,7 +105,6 @@ fragment CurrentUserFragment on Me { plan staff hasYaml - service bot delinquent didTrial From a72cd1583c81a14ebd49e361f773286fea9a6498 Mon Sep 17 00:00:00 2001 From: Suejung Shin Date: Thu, 2 Jan 2025 08:38:14 -0800 Subject: [PATCH 4/7] fix tests --- src/services/user/useUpdateProfile.test.tsx | 56 +++++++++------------ src/services/user/useUpdateProfile.ts | 26 +++++----- 2 files changed, 36 insertions(+), 46 deletions(-) diff --git a/src/services/user/useUpdateProfile.test.tsx b/src/services/user/useUpdateProfile.test.tsx index a121fd7e34..ae29b180ae 100644 --- a/src/services/user/useUpdateProfile.test.tsx +++ b/src/services/user/useUpdateProfile.test.tsx @@ -50,9 +50,13 @@ describe('useUpdateProfile', () => { server.use( graphql.mutation('UpdateProfile', (info) => { const newUser = { - ...user, - name: info.variables.input.name, email: info.variables.input.email, + onboardingCompleted: user.onboardingCompleted, + user: { + name: info.variables.input.name, + username: user.username, + avatarUrl: user.avatarUrl, + }, } return HttpResponse.json({ @@ -88,16 +92,12 @@ describe('useUpdateProfile', () => { await waitFor(() => expect(result.current.data).toStrictEqual({ - data: { - updateProfile: { - me: { - avatarUrl: 'http://127.0.0.1/avatar-url', - email: 'newemail@test.com', - name: 'new name', - onboardingCompleted: false, - username: 'TerrySmithDC', - }, - }, + email: 'newemail@test.com', + onboardingCompleted: false, + user: { + avatarUrl: 'http://127.0.0.1/avatar-url', + name: 'new name', + username: 'TerrySmithDC', }, }) ) @@ -114,16 +114,12 @@ describe('useUpdateProfile', () => { await waitFor(() => expect(result.current.data).toStrictEqual({ - data: { - updateProfile: { - me: { - avatarUrl: 'http://127.0.0.1/avatar-url', - email: 'newemail@test.com', - name: 'new name', - onboardingCompleted: false, - username: 'TerrySmithDC', - }, - }, + email: 'newemail@test.com', + onboardingCompleted: false, + user: { + avatarUrl: 'http://127.0.0.1/avatar-url', + name: 'new name', + username: 'TerrySmithDC', }, }) ) @@ -165,16 +161,12 @@ describe('useUpdateProfile', () => { await waitFor(() => expect(result.current.data).toStrictEqual({ - data: { - updateProfile: { - me: { - avatarUrl: 'http://127.0.0.1/avatar-url', - email: 'newemail@test.com', - name: 'new name', - onboardingCompleted: false, - username: 'TerrySmithDC', - }, - }, + email: 'newemail@test.com', + onboardingCompleted: false, + user: { + avatarUrl: 'http://127.0.0.1/avatar-url', + name: 'new name', + username: 'TerrySmithDC', }, }) ) diff --git a/src/services/user/useUpdateProfile.ts b/src/services/user/useUpdateProfile.ts index ffc17f7bf8..72cc43b4f3 100644 --- a/src/services/user/useUpdateProfile.ts +++ b/src/services/user/useUpdateProfile.ts @@ -150,22 +150,20 @@ export function useUpdateProfile({ provider }: { provider: string }) { email, }, }, + }).then((res) => { + const parsedData = UpdateProfileResponseSchema.safeParse(res.data) + if (!parsedData.success) { + return rejectNetworkError({ + status: 404, + data: {}, + dev: 'useUpdateProfile - 404 failed to parse', + } satisfies NetworkErrorObject) + } + return parsedData.data.updateProfile?.me }) }, - onSuccess: ({ data }) => { - const parsedData = UpdateProfileResponseSchema.safeParse(data) - if (!parsedData.success) { - return rejectNetworkError({ - status: 404, - data: {}, - dev: 'useUpdateProfile - 404 failed to parse', - } satisfies NetworkErrorObject) - } - - queryClient.setQueryData( - ['currentUser', provider], - () => parsedData.data.updateProfile?.me - ) + onSuccess: (res) => { + queryClient.setQueryData(['currentUser', provider], () => res) if (config.IS_SELF_HOSTED) { queryClient.invalidateQueries(['SelfHostedCurrentUser']) From 8d47ccd91977047f64c7eb44c3ad1855d5a25cb0 Mon Sep 17 00:00:00 2001 From: Suejung Shin Date: Thu, 2 Jan 2025 08:53:50 -0800 Subject: [PATCH 5/7] cleanup --- .../tabs/Admin/DetailsSection/DetailsSection.jsx | 4 +--- .../tabs/OrgUploadToken/RegenerateOrgUploadToken.jsx | 4 +++- src/services/user/useUpdateProfile.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.jsx b/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.jsx index deb744f22c..1617993b3b 100644 --- a/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.jsx +++ b/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.jsx @@ -39,9 +39,7 @@ function DetailsSection({ email, name }) { function submit(formData) { mutate(formData, { - onSuccess: ({ data }) => { - const updatedUser = data?.updateProfile?.me - + onSuccess: (updatedUser) => { queryClient.invalidateQueries(['user', provider]) addToast({ diff --git a/src/pages/AccountSettings/tabs/OrgUploadToken/RegenerateOrgUploadToken.jsx b/src/pages/AccountSettings/tabs/OrgUploadToken/RegenerateOrgUploadToken.jsx index 4d1f813202..b5d2e4ec6b 100644 --- a/src/pages/AccountSettings/tabs/OrgUploadToken/RegenerateOrgUploadToken.jsx +++ b/src/pages/AccountSettings/tabs/OrgUploadToken/RegenerateOrgUploadToken.jsx @@ -17,7 +17,9 @@ const TokenFormatEnum = Object.freeze({ const UploadToken = ({ token, format }) => { const [hideClipboard, setHideClipboard] = useState(true) - const encodedToken = hideClipboard && format + token.replace(/[^w-]|/g, 'x') + const encodedToken = hideClipboard + ? format + token.replace(/[^w-]|/g, 'x') + : undefined return (
diff --git a/src/services/user/useUpdateProfile.ts b/src/services/user/useUpdateProfile.ts index 72cc43b4f3..2a327226ae 100644 --- a/src/services/user/useUpdateProfile.ts +++ b/src/services/user/useUpdateProfile.ts @@ -162,8 +162,8 @@ export function useUpdateProfile({ provider }: { provider: string }) { return parsedData.data.updateProfile?.me }) }, - onSuccess: (res) => { - queryClient.setQueryData(['currentUser', provider], () => res) + onSuccess: (currentUser) => { + queryClient.setQueryData(['currentUser', provider], () => currentUser) if (config.IS_SELF_HOSTED) { queryClient.invalidateQueries(['SelfHostedCurrentUser']) From 8cba7448a21ef03427c4c2113d5d9f0e33765f83 Mon Sep 17 00:00:00 2001 From: Suejung Shin Date: Thu, 2 Jan 2025 10:31:40 -0800 Subject: [PATCH 6/7] make schema validation stricter --- src/services/user/useUpdateProfile.test.tsx | 35 ++++++++- src/services/user/useUpdateProfile.ts | 81 ++++++++------------- src/services/user/useUser.ts | 4 +- 3 files changed, 65 insertions(+), 55 deletions(-) diff --git a/src/services/user/useUpdateProfile.test.tsx b/src/services/user/useUpdateProfile.test.tsx index ae29b180ae..47b47ddd9d 100644 --- a/src/services/user/useUpdateProfile.test.tsx +++ b/src/services/user/useUpdateProfile.test.tsx @@ -16,6 +16,11 @@ const user = { name: 'terry', avatarUrl: 'http://127.0.0.1/avatar-url', onboardingCompleted: false, + privateAccess: true, + businessEmail: null, + student: false, + studentCreatedAt: null, + studentUpdatedAt: null, } const queryClient = new QueryClient({ @@ -52,10 +57,16 @@ describe('useUpdateProfile', () => { const newUser = { email: info.variables.input.email, onboardingCompleted: user.onboardingCompleted, + privateAccess: user.privateAccess, + businessEmail: user.businessEmail, user: { name: info.variables.input.name, username: user.username, avatarUrl: user.avatarUrl, + avatar: user.avatarUrl, + student: user.student, + studentCreatedAt: user.studentCreatedAt, + studentUpdatedAt: user.studentUpdatedAt, }, } @@ -93,11 +104,17 @@ describe('useUpdateProfile', () => { await waitFor(() => expect(result.current.data).toStrictEqual({ email: 'newemail@test.com', + privateAccess: true, onboardingCompleted: false, + businessEmail: null, user: { - avatarUrl: 'http://127.0.0.1/avatar-url', name: 'new name', username: 'TerrySmithDC', + avatarUrl: 'http://127.0.0.1/avatar-url', + avatar: 'http://127.0.0.1/avatar-url', + student: false, + studentCreatedAt: null, + studentUpdatedAt: null, }, }) ) @@ -115,11 +132,17 @@ describe('useUpdateProfile', () => { await waitFor(() => expect(result.current.data).toStrictEqual({ email: 'newemail@test.com', + privateAccess: true, onboardingCompleted: false, + businessEmail: null, user: { - avatarUrl: 'http://127.0.0.1/avatar-url', name: 'new name', username: 'TerrySmithDC', + avatarUrl: 'http://127.0.0.1/avatar-url', + avatar: 'http://127.0.0.1/avatar-url', + student: false, + studentCreatedAt: null, + studentUpdatedAt: null, }, }) ) @@ -162,11 +185,17 @@ describe('useUpdateProfile', () => { await waitFor(() => expect(result.current.data).toStrictEqual({ email: 'newemail@test.com', + privateAccess: true, onboardingCompleted: false, + businessEmail: null, user: { - avatarUrl: 'http://127.0.0.1/avatar-url', name: 'new name', username: 'TerrySmithDC', + avatarUrl: 'http://127.0.0.1/avatar-url', + avatar: 'http://127.0.0.1/avatar-url', + student: false, + studentCreatedAt: null, + studentUpdatedAt: null, }, }) ) diff --git a/src/services/user/useUpdateProfile.ts b/src/services/user/useUpdateProfile.ts index 2a327226ae..beb924bbc3 100644 --- a/src/services/user/useUpdateProfile.ts +++ b/src/services/user/useUpdateProfile.ts @@ -6,64 +6,45 @@ import config from 'config' import Api from 'shared/api' import { NetworkErrorObject, rejectNetworkError } from 'shared/api/helpers' -const TypeProjectsSchema = z.array( - z.union([ - z.literal('PERSONAL'), - z.literal('YOUR_ORG'), - z.literal('OPEN_SOURCE'), - z.literal('EDUCATIONAL'), - ]) -) - -const GoalsSchema = z.array( - z.union([ - z.literal('STARTING_WITH_TESTS'), - z.literal('IMPROVE_COVERAGE'), - z.literal('MAINTAIN_COVERAGE'), - z.literal('TEAM_REQUIREMENTS'), - z.literal('OTHER'), - ]) -) +import { GoalsSchema, TypeProjectsSchema } from './useUser' const CurrentUserFragment = z.object({ - email: z.string().nullish(), - privateAccess: z.boolean().nullish(), - onboardingCompleted: z.boolean().nullish(), - businessEmail: z.string().nullish(), - user: z - .object({ - name: z.string().nullish(), - username: z.string().nullish(), - avatarUrl: z.string().nullish(), - avatar: z.string().nullish(), - student: z.boolean().nullish(), - studentCreatedAt: z.string().nullish(), - studentUpdatedAt: z.string().nullish(), - }) - .nullish(), + email: z.string().nullable(), + privateAccess: z.boolean().nullable(), + onboardingCompleted: z.boolean(), + businessEmail: z.string().nullable(), + user: z.object({ + name: z.string().nullable(), + username: z.string(), + avatarUrl: z.string(), + avatar: z.string(), + student: z.boolean(), + studentCreatedAt: z.string().nullable(), + studentUpdatedAt: z.string().nullable(), + }), trackingMetadata: z .object({ - service: z.string().nullish(), - ownerid: z.number().nullish(), - serviceId: z.string().nullish(), - plan: z.string().nullish(), - staff: z.boolean().nullish(), + service: z.string(), + ownerid: z.number(), + serviceId: z.string(), + plan: z.string().nullable(), + staff: z.boolean().nullable(), hasYaml: z.boolean(), - bot: z.string().nullish(), - delinquent: z.boolean().nullish(), - didTrial: z.boolean().nullish(), - planProvider: z.string().nullish(), - planUserCount: z.number().nullish(), - createdAt: z.string().nullish(), - updatedAt: z.string().nullish(), + bot: z.string().nullable(), + delinquent: z.boolean().nullable(), + didTrial: z.boolean().nullable(), + planProvider: z.string().nullable(), + planUserCount: z.number().nullable(), + createdAt: z.string().nullable(), + updatedAt: z.string().nullable(), profile: z .object({ - createdAt: z.string().nullish(), - otherGoal: z.string().nullish(), - typeProjects: TypeProjectsSchema.nullish(), - goals: GoalsSchema.nullish(), + createdAt: z.string(), + otherGoal: z.string().nullable(), + typeProjects: TypeProjectsSchema, + goals: GoalsSchema, }) - .nullish(), + .nullable(), }) .nullish(), }) diff --git a/src/services/user/useUser.ts b/src/services/user/useUser.ts index 6d49884f14..cfaf131aa1 100644 --- a/src/services/user/useUser.ts +++ b/src/services/user/useUser.ts @@ -5,7 +5,7 @@ import { z } from 'zod' import Api from 'shared/api' import { NetworkErrorObject } from 'shared/api/helpers' -const TypeProjectsSchema = z.array( +export const TypeProjectsSchema = z.array( z.union([ z.literal('PERSONAL'), z.literal('YOUR_ORG'), @@ -14,7 +14,7 @@ const TypeProjectsSchema = z.array( ]) ) -const GoalsSchema = z.array( +export const GoalsSchema = z.array( z.union([ z.literal('STARTING_WITH_TESTS'), z.literal('IMPROVE_COVERAGE'), From db6d0b630c308fc6fd93e4bfe653061366cf61e8 Mon Sep 17 00:00:00 2001 From: Suejung Shin Date: Thu, 2 Jan 2025 10:59:26 -0800 Subject: [PATCH 7/7] fix tests --- .../DetailsSection/DetailsSection.test.jsx | 33 ++++++++++++++----- .../NameEmailCard/NameEmailCard.test.jsx | 13 +++++++- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.test.jsx b/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.test.jsx index f9a7fa562e..c5ead2af64 100644 --- a/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.test.jsx +++ b/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.test.jsx @@ -33,6 +33,10 @@ beforeEach(() => { server.resetHandlers() }) +afterEach(() => { + vi.clearAllMocks() +}) + afterAll(() => { server.close() }) @@ -43,7 +47,7 @@ describe('DetailsSection', () => { const mutate = vi.fn() const addNotification = vi.fn() - useAddNotification.mockReturnValue(addNotification) + vi.mocked(useAddNotification).mockReturnValue(addNotification) server.use( graphql.mutation('UpdateProfile', (info) => { mutate(info.variables) @@ -52,15 +56,23 @@ describe('DetailsSection', () => { data: { updateProfile: { me: { - username: 'donald duck', email: info.variables.input.email ? info.variables.input.email : 'donald@duck.com', - name: info.variables.input.name - ? info.variables.input.name - : 'donald duck', - avatarUrl: 'http://127.0.0.1/avatar-url', - onboardingCompleted: false, + onboardingCompleted: true, + privateAccess: null, + businessEmail: null, + user: { + name: info.variables.input.name + ? info.variables.input.name + : 'donald duck', + username: 'donald duck', + avatarUrl: 'http://127.0.0.1/avatar-url', + avatar: 'http://127.0.0.1/avatar-url', + student: false, + studentCreatedAt: null, + studentUpdatedAt: null, + }, }, }, }, @@ -218,10 +230,15 @@ describe('DetailsSection', () => { ) }) }) - describe('when mutation is not successful', () => { it('adds an error notification', async () => { const { user, addNotification } = setup() + server.use( + graphql.mutation('UpdateProfile', () => { + return HttpResponse.error() + }) + ) + render(, { wrapper, }) diff --git a/src/pages/AccountSettings/tabs/Profile/NameEmailCard/NameEmailCard.test.jsx b/src/pages/AccountSettings/tabs/Profile/NameEmailCard/NameEmailCard.test.jsx index dda1f98247..23a270bb47 100644 --- a/src/pages/AccountSettings/tabs/Profile/NameEmailCard/NameEmailCard.test.jsx +++ b/src/pages/AccountSettings/tabs/Profile/NameEmailCard/NameEmailCard.test.jsx @@ -60,7 +60,18 @@ describe('NameEmailCard', () => { updateProfile: { me: { email: json.variables.input.email || '', - user: { name: json.variables.input.name || '' }, + privateAccess: null, + onboardingCompleted: true, + businessEmail: null, + user: { + name: json.variables.input.name || '', + username: 'test', + avatarUrl: 'http://127.0.0.1/avatar-url', + avatar: 'http://127.0.0.1/avatar-url', + student: false, + studentCreatedAt: null, + studentUpdatedAt: null, + }, }, }, },