mirror of
https://github.com/supabase/supabase.git
synced 2026-06-28 19:39:19 -04:00
47dbbddc91
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Update to support text area for functions <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Secret inputs now accept and preserve multi-line values and auto-resize to fit content. * Secret values can be masked/unmasked via a show/hide toggle with tooltip; masking uses styled concealment. * Per-secret controls refined: clearer row layout, dedicated remove icon, and add/save controls moved to the card footer. * **Tests** * Added tests validating multi-line secret entry and that submitted payloads include embedded newlines. * Updated tests to assert masking/unmasking behavior via visual security styling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: kemal <hello@kemal.earth>
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import { fireEvent, screen, waitFor } from '@testing-library/react'
|
|
import userEvent from '@testing-library/user-event'
|
|
import { HttpResponse } from 'msw'
|
|
import { describe, expect, test } from 'vitest'
|
|
|
|
import { AddNewSecretForm } from './AddNewSecretForm'
|
|
import type { ProjectSecret } from '@/data/secrets/secrets-query'
|
|
import { customRender } from '@/tests/lib/custom-render'
|
|
import { addAPIMock } from '@/tests/lib/msw'
|
|
|
|
const multilineValue = '-----BEGIN CERTIFICATE-----\nline2\nline3\n-----END CERTIFICATE-----'
|
|
|
|
describe('AddNewSecretForm', () => {
|
|
test('renders the value field as a textarea so multiline pastes are preserved', () => {
|
|
addAPIMock({
|
|
method: 'get',
|
|
path: '/v1/projects/:ref/secrets',
|
|
response: () => HttpResponse.json<ProjectSecret[]>([]),
|
|
})
|
|
|
|
customRender(<AddNewSecretForm />)
|
|
|
|
const nameInput = screen.getByPlaceholderText('e.g. CLIENT_KEY')
|
|
expect(nameInput.tagName).toBe('INPUT')
|
|
|
|
const textareas = screen.getAllByRole('textbox')
|
|
const valueTextarea = textareas.find((el) => el.tagName === 'TEXTAREA')
|
|
expect(valueTextarea).toBeDefined()
|
|
})
|
|
|
|
test('submits a multiline value with newlines intact', async () => {
|
|
const requests: Array<{ ref: string | undefined; body: unknown }> = []
|
|
addAPIMock({
|
|
method: 'post',
|
|
path: '/v1/projects/:ref/secrets',
|
|
response: async ({ request, params }) => {
|
|
requests.push({ ref: params.ref as string | undefined, body: await request.json() })
|
|
return HttpResponse.json({}, { status: 201 })
|
|
},
|
|
})
|
|
addAPIMock({
|
|
method: 'get',
|
|
path: '/v1/projects/:ref/secrets',
|
|
response: () => HttpResponse.json<ProjectSecret[]>([]),
|
|
})
|
|
|
|
customRender(<AddNewSecretForm />)
|
|
|
|
const nameInput = screen.getByPlaceholderText('e.g. CLIENT_KEY')
|
|
const saveButton = screen.getByRole('button', { name: 'Save' })
|
|
|
|
await userEvent.type(nameInput, 'SSL_CERT')
|
|
|
|
const textareas = screen.getAllByRole('textbox')
|
|
const valueTextarea = textareas.find((el) => el.tagName === 'TEXTAREA')!
|
|
await userEvent.type(valueTextarea, multilineValue)
|
|
|
|
fireEvent.click(saveButton)
|
|
|
|
await waitFor(() => {
|
|
expect(requests).toEqual([
|
|
{
|
|
ref: 'default',
|
|
body: [{ name: 'SSL_CERT', value: multilineValue }],
|
|
},
|
|
])
|
|
})
|
|
})
|
|
})
|