fe70e88bcc
Adds a users panel under the selected user pool: copyable app client ids, a create-user form that follows the pool's sign-in method, and the user list with delete. Maps the userpools icon key to the Cognito artwork.
90 lines
3.8 KiB
TypeScript
90 lines
3.8 KiB
TypeScript
import {QueryClient, QueryClientProvider} from '@tanstack/react-query'
|
|
import {render, screen} from '@testing-library/react'
|
|
import userEvent from '@testing-library/user-event'
|
|
import {beforeEach, expect, test, vi} from 'vitest'
|
|
import {CognitoUsersPanel} from './CognitoUsersPanel'
|
|
import type {CloudResource} from '@/types/resource'
|
|
|
|
const api = vi.hoisted(() => ({
|
|
deleteFlatItem: vi.fn(),
|
|
getCloudResource: vi.fn(),
|
|
listFlatItems: vi.fn(),
|
|
putFlatItem: vi.fn(),
|
|
}))
|
|
|
|
vi.mock('@/api/cloudProxyClient', () => api)
|
|
vi.mock('@/lib/accountStore', () => ({useAccountId: () => '000000000000'}))
|
|
|
|
const summary: CloudResource = {
|
|
id: 'us-east-1_8e65d229a', name: 'orders-users', cloud: 'aws', service: 'userpools', type: 'user-pool',
|
|
region: 'us-east-1', createdAt: null, metadata: {},
|
|
}
|
|
|
|
function pool(signInWith: 'email' | 'username'): CloudResource {
|
|
return {...summary, metadata: {signInWith, appClients: [{clientId: 'a8e5c7d38d3b4a1a97c9d822de', clientName: 'orders-users-client'}]}}
|
|
}
|
|
|
|
const alice = {
|
|
id: 'aa36ecc1-ed8a-43b5-84e9-988398c17436', collectionId: null, timestamp: '2026-10-23T16:01:22.000Z', metadata: {},
|
|
body: {username: 'aa36ecc1-ed8a-43b5-84e9-988398c17436', email: 'alice@example.com', status: 'CONFIRMED', enabled: true},
|
|
}
|
|
|
|
function renderPanel() {
|
|
const client = new QueryClient({defaultOptions: {queries: {retry: false}}})
|
|
return render(<QueryClientProvider client={client}><CognitoUsersPanel resource={summary} runtimeReachable/></QueryClientProvider>)
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
api.listFlatItems.mockResolvedValue({items: [alice], nextCursor: null})
|
|
api.putFlatItem.mockResolvedValue(alice)
|
|
api.deleteFlatItem.mockResolvedValue(undefined)
|
|
})
|
|
|
|
test('shows the app client id and the pool users', async () => {
|
|
api.getCloudResource.mockResolvedValue(pool('email'))
|
|
renderPanel()
|
|
|
|
expect(await screen.findByText('a8e5c7d38d3b4a1a97c9d822de')).toBeInTheDocument()
|
|
expect(screen.getByRole('button', {name: 'Copy Client ID'})).toBeInTheDocument()
|
|
expect(await screen.findByText('alice@example.com')).toBeInTheDocument()
|
|
expect(screen.getByText('CONFIRMED')).toBeInTheDocument()
|
|
expect(api.getCloudResource).toHaveBeenCalledWith('aws', 'userpools', summary.id, expect.anything())
|
|
})
|
|
|
|
test('creates an email user who can sign in immediately', async () => {
|
|
const user = userEvent.setup()
|
|
api.getCloudResource.mockResolvedValue(pool('email'))
|
|
renderPanel()
|
|
|
|
await screen.findByText('a8e5c7d38d3b4a1a97c9d822de')
|
|
await user.type(screen.getByLabelText('Email'), 'bob@example.com')
|
|
await user.type(screen.getByLabelText('Password'), 'Passw0rd!')
|
|
await user.click(screen.getByRole('button', {name: 'Create user'}))
|
|
|
|
expect(api.putFlatItem).toHaveBeenCalledWith('aws', 'userpools', summary.id, {email: 'bob@example.com', password: 'Passw0rd!', permanent: true})
|
|
})
|
|
|
|
test('creates a username user with a temporary password when asked', async () => {
|
|
const user = userEvent.setup()
|
|
api.getCloudResource.mockResolvedValue(pool('username'))
|
|
renderPanel()
|
|
|
|
await user.type(await screen.findByLabelText('Username'), 'bob')
|
|
await user.type(screen.getByLabelText('Password'), 'Passw0rd!')
|
|
await user.click(screen.getByLabelText(/User can sign in now/))
|
|
await user.click(screen.getByRole('button', {name: 'Create user'}))
|
|
|
|
expect(api.putFlatItem).toHaveBeenCalledWith('aws', 'userpools', summary.id, {username: 'bob', password: 'Passw0rd!', permanent: false})
|
|
})
|
|
|
|
test('deletes a user by its stored username', async () => {
|
|
const user = userEvent.setup()
|
|
api.getCloudResource.mockResolvedValue(pool('email'))
|
|
renderPanel()
|
|
|
|
await user.click(await screen.findByRole('button', {name: 'Delete user alice@example.com'}))
|
|
|
|
expect(api.deleteFlatItem).toHaveBeenCalledWith('aws', 'userpools', summary.id, alice.id)
|
|
})
|