From 130be686aade73eab1ca7b612e2169eb31fddb86 Mon Sep 17 00:00:00 2001 From: Lisa Kim Date: Wed, 30 Oct 2024 16:58:20 -0700 Subject: [PATCH] Fix bug where after create/cancel, specifiable fields were retained --- .../RequestCheckout/RequestCheckout.tsx | 1 + .../NewRequest/useSpecifiableFields.ts | 11 +++ .../useAccessRequestCheckout.test.tsx | 99 +++++++++++++++++++ .../useAccessRequestCheckout.ts | 2 + 4 files changed, 113 insertions(+) diff --git a/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx b/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx index 7a62033067a23..0eef8fe799e57 100644 --- a/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx +++ b/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx @@ -279,6 +279,7 @@ export function RequestCheckout({ {({ validator }) => ( <> {!isRequestKubeResourceError && + createAttempt.status !== 'failed' && fetchResourceRequestRolesAttempt.status === 'failed' && ( { + const kube = makeKube(); + const cluster = makeRootCluster(); + const appContext = new MockAppContext(); + appContext.clustersService.setState(draftState => { + draftState.clusters.set(rootClusterUri, cluster); + }); + await appContext.workspacesService.setActiveWorkspace(rootClusterUri); + await appContext.workspacesService + .getWorkspaceAccessRequestsService(rootClusterUri) + .addOrRemoveResource({ + kind: 'kube', + resource: kube, + }); + + let mockedCreateAccessRequestFn = jest.spyOn( + appContext.tshd, + 'createAccessRequest' + ); + + const wrapper = ({ children }) => ( + + {children} + + ); + + let { result } = renderHook(useAccessRequestCheckout, { + wrapper, + }); + + await waitFor(() => { + result.current.setSelectedReviewers([{ value: 'bob', label: 'bob' }]); + expect(result.current.selectedReviewers).toEqual([ + { value: 'bob', label: 'bob' }, + ]); + }); + + await waitFor(() => { + result.current.setSelectedResourceRequestRoles(['apple', 'banana']); + expect(result.current.selectedResourceRequestRoles).toEqual([ + 'apple', + 'banana', + ]); + }); + + await waitFor(async () => { + await result.current.createRequest({ + suggestedReviewers: result.current.selectedReviewers.map(r => r.value), + }); + expect(mockedCreateAccessRequestFn).toHaveBeenCalledWith({ + rootClusterUri: '/clusters/teleport-local', + resourceIds: [ + { + clusterName: 'teleport-local', + kind: 'kube_cluster', + name: kube.name, + subResourceName: '', + }, + ], + roles: ['apple', 'banana'], + suggestedReviewers: ['bob'], + }); + }); + + // Call create again, should've cleared reviewers and previous roles. + mockedCreateAccessRequestFn.mockClear(); + await waitFor(async () => { + // A successful create would've cleared all selected resources, + // so we add it back here to allow creating again. + expect(result.current.pendingAccessRequests).toHaveLength(0); + await appContext.workspacesService + .getWorkspaceAccessRequestsService(rootClusterUri) + .addOrRemoveResource({ + kind: 'kube', + resource: kube, + }); + }); + + await waitFor(async () => { + await result.current.createRequest({ + suggestedReviewers: result.current.selectedReviewers.map(r => r.value), + }); + expect(mockedCreateAccessRequestFn).toHaveBeenCalledWith({ + rootClusterUri: '/clusters/teleport-local', + resourceIds: [ + { + clusterName: 'teleport-local', + kind: 'kube_cluster', + name: kube.name, + subResourceName: '', + }, + ], + // These fields gotten cleared after the first create. + roles: [], + suggestedReviewers: [], + }); + }); +}); diff --git a/web/packages/teleterm/src/ui/AccessRequestCheckout/useAccessRequestCheckout.ts b/web/packages/teleterm/src/ui/AccessRequestCheckout/useAccessRequestCheckout.ts index 7f8095a019828..4d70ada109b16 100644 --- a/web/packages/teleterm/src/ui/AccessRequestCheckout/useAccessRequestCheckout.ts +++ b/web/packages/teleterm/src/ui/AccessRequestCheckout/useAccessRequestCheckout.ts @@ -77,6 +77,7 @@ export default function useAccessRequestCheckout() { onDryRunChange, startTime, onStartTimeChange, + reset: resetSpecifiableFields, } = useSpecifiableFields(); const [showCheckout, setShowCheckout] = useState(false); @@ -371,6 +372,7 @@ export default function useAccessRequestCheckout() { } function reset() { + resetSpecifiableFields(); if (workspaceAccessRequest) { return workspaceAccessRequest.clearPendingAccessRequest(); }