|
2 | 2 | import { act } from 'react' |
3 | 3 | import { NuqsTestingAdapter } from 'nuqs/adapters/testing' |
4 | 4 | import { createRoot, type Root } from 'react-dom/client' |
5 | | -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' |
| 5 | +import { afterEach, beforeEach, expect, it, vi } from 'vitest' |
6 | 6 |
|
7 | 7 | const mocks = vi.hoisted(() => ({ |
8 | 8 | people: vi.fn(), |
9 | 9 | resend: vi.fn(), |
10 | 10 | revoke: vi.fn(), |
11 | | - disconnect: vi.fn(), |
12 | 11 | reset: vi.fn(), |
13 | 12 | resendState: { isPending: false, error: null as Error | null }, |
14 | 13 | revokeState: { isPending: false, error: null as Error | null }, |
15 | 14 | })) |
16 | 15 | vi.mock('@/hooks/queries/organization-accounts', () => ({ |
17 | 16 | useOrganizationAccountPeople: mocks.people, |
18 | | - usePersonalOrganizationAccounts: () => ({ |
19 | | - data: { |
20 | | - pages: [ |
21 | | - { |
22 | | - accounts: [ |
23 | | - { |
24 | | - credentialId: 'credential-1', |
25 | | - displayName: 'Personal Gmail', |
26 | | - organizationName: 'Example organization', |
27 | | - providerId: 'gmail', |
28 | | - status: 'active', |
29 | | - canReconnect: true, |
30 | | - }, |
31 | | - ], |
32 | | - }, |
33 | | - ], |
34 | | - }, |
35 | | - }), |
36 | 17 | useResendOrganizationAccountInvitation: () => ({ ...mocks.resendState, mutate: mocks.resend }), |
37 | 18 | useRevokeOrganizationAccountEnrollment: () => ({ |
38 | 19 | ...mocks.revokeState, |
39 | 20 | mutate: mocks.revoke, |
40 | 21 | reset: mocks.reset, |
41 | 22 | }), |
42 | | - useReconnectPersonalOrganizationAccount: () => ({}), |
43 | | - useDisconnectPersonalOrganizationAccount: () => ({ |
44 | | - mutate: mocks.disconnect, |
45 | | - reset: mocks.reset, |
46 | | - }), |
47 | 23 | })) |
48 | 24 | vi.mock('@/ee/credential-groups/components/organization-account-invite-modal', () => ({ |
49 | 25 | OrganizationAccountInviteModal: () => null, |
50 | 26 | })) |
51 | 27 |
|
52 | 28 | import { SettingsHeaderProvider, SettingsHeaderShell } from '@/components/settings/settings-header' |
53 | 29 | import { OrganizationAccountPeople } from '@/ee/credential-groups/components/organization-account-people' |
54 | | -import { PersonalOrganizationAccounts } from '@/ee/credential-groups/components/personal-organization-accounts' |
55 | 30 |
|
56 | 31 | let root: Root |
57 | 32 | let container: HTMLDivElement |
@@ -111,11 +86,6 @@ async function selectPersonAction(label: string) { |
111 | 86 | return action |
112 | 87 | } |
113 | 88 |
|
114 | | -async function openConfirmation(label: string) { |
115 | | - if (label === 'Revoke') await selectPersonAction(label) |
116 | | - else await act(async () => button(container, label).click()) |
117 | | -} |
118 | | - |
119 | 89 | async function renderPeople(searchConnection?: { optionId: string; providerName: string }) { |
120 | 90 | await act(async () => |
121 | 91 | root.render( |
@@ -156,58 +126,28 @@ it('keeps the compact People rows and resends from the actions menu', async () = |
156 | 126 | ) |
157 | 127 | }) |
158 | 128 |
|
159 | | -const cases = [ |
160 | | - { |
161 | | - label: 'Revoke', |
162 | | - component: <OrganizationAccountPeople organizationId='organization-1' />, |
163 | | - mutation: mocks.revoke, |
164 | | - target: 'person@example.com', |
165 | | - input: { organizationId: 'organization-1', enrollmentId: 'enrollment-1' }, |
166 | | - }, |
167 | | - { |
168 | | - label: 'Disconnect', |
169 | | - component: <PersonalOrganizationAccounts />, |
170 | | - mutation: mocks.disconnect, |
171 | | - target: 'Personal Gmail', |
172 | | - input: 'credential-1', |
173 | | - }, |
174 | | -] as const |
175 | | - |
176 | | -describe.each(cases)( |
177 | | - '$label organization account access', |
178 | | - ({ label, component, mutation, target, input }) => { |
179 | | - it('requires confirmation, allows cancellation, and never submits from an unfocused Enter', async () => { |
180 | | - await act(async () => |
181 | | - root.render( |
182 | | - <NuqsTestingAdapter hasMemory> |
183 | | - <SettingsHeaderProvider> |
184 | | - <SettingsHeaderShell>{component}</SettingsHeaderShell> |
185 | | - </SettingsHeaderProvider> |
186 | | - </NuqsTestingAdapter> |
187 | | - ) |
188 | | - ) |
189 | | - await openConfirmation(label) |
190 | | - let dialog = document.querySelector('[role="dialog"]') |
191 | | - expect(dialog?.textContent).toContain(target) |
192 | | - expect(mutation).not.toHaveBeenCalled() |
193 | | - await act(async () => |
194 | | - dialog?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })) |
195 | | - ) |
196 | | - expect(mutation).not.toHaveBeenCalled() |
197 | | - if (!dialog) throw new Error('Missing confirmation dialog') |
198 | | - await act(async () => button(dialog, 'Cancel').click()) |
199 | | - expect(mutation).not.toHaveBeenCalled() |
200 | | - await openConfirmation(label) |
201 | | - dialog = document.querySelector('[role="dialog"]') |
202 | | - if (!dialog) throw new Error('Missing confirmation dialog') |
203 | | - await act(async () => button(dialog, label).click()) |
204 | | - expect(mutation).toHaveBeenCalledExactlyOnceWith( |
205 | | - input, |
206 | | - expect.objectContaining({ onSuccess: expect.any(Function) }) |
207 | | - ) |
208 | | - }) |
209 | | - } |
210 | | -) |
| 129 | +it('requires revoke confirmation, allows cancellation, and never submits from an unfocused Enter', async () => { |
| 130 | + await renderPeople() |
| 131 | + await selectPersonAction('Revoke') |
| 132 | + let dialog = document.querySelector('[role="dialog"]') |
| 133 | + expect(dialog?.textContent).toContain('person@example.com') |
| 134 | + expect(mocks.revoke).not.toHaveBeenCalled() |
| 135 | + await act(async () => |
| 136 | + dialog?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })) |
| 137 | + ) |
| 138 | + expect(mocks.revoke).not.toHaveBeenCalled() |
| 139 | + if (!dialog) throw new Error('Missing confirmation dialog') |
| 140 | + await act(async () => button(dialog, 'Cancel').click()) |
| 141 | + expect(mocks.revoke).not.toHaveBeenCalled() |
| 142 | + await selectPersonAction('Revoke') |
| 143 | + dialog = document.querySelector('[role="dialog"]') |
| 144 | + if (!dialog) throw new Error('Missing confirmation dialog') |
| 145 | + await act(async () => button(dialog, 'Revoke').click()) |
| 146 | + expect(mocks.revoke).toHaveBeenCalledExactlyOnceWith( |
| 147 | + { organizationId: 'organization-1', enrollmentId: 'enrollment-1' }, |
| 148 | + expect.objectContaining({ onSuccess: expect.any(Function) }) |
| 149 | + ) |
| 150 | +}) |
211 | 151 |
|
212 | 152 | it('restores the existing People URL search and requests server-filtered results', async () => { |
213 | 153 | mocks.people.mockReturnValue({ data: { pages: [{ enrollments: [] }] }, hasNextPage: false }) |
|
0 commit comments