test: fix pre-existing unit drift — wrap Tooltip-needing renders in TooltipProvider (944/944 green)

This commit is contained in:
Francisco Ignácio Fontoura Solla 2026-07-30 05:35:25 -03:00
parent de2d457cf9
commit 40e7ecea33
3 changed files with 41 additions and 17 deletions

View file

@ -9,6 +9,7 @@ import { MunicipalityListSignalControl } from '@/components/campaign/municipalit
import { MunicipalityListTrendControl } from '@/components/campaign/municipality/MunicipalityListTrendControl'
import type { CampaignCellEditOverlayVariant } from '@/components/campaign/shared/CampaignCellEditOverlay'
import { MunicipalityPortfolioCell } from '@/components/campaign/shared/MunicipalityPortfolioCell'
import { TooltipProvider } from '@/components/ui/tooltip'
import { toVoteEstimateScenarioViewModel } from '@/lib/voteEstimate'
/**
@ -141,11 +142,16 @@ afterAll(() => {
Reflect.deleteProperty(Element.prototype, 'scrollIntoView')
})
// The Popover variant wraps its trigger in `CampaignHoverTooltip` (Radix),
// which refuses to render outside a provider; production mounts it in the
// `(app)` layout.
const renderWithTooltip = (ui: ReactElement) => render(createElement(TooltipProvider, null, ui))
describe('campaign cell edit overlay', () => {
it.each(overlayCases)(
'opens $name in a Drawer that names the município on touch',
async ({ triggerLabel, drawerTitle, footerLabel, element }) => {
render(element('sheet'))
renderWithTooltip(element('sheet'))
fireEvent.click(screen.getByRole('button', { name: triggerLabel }))
@ -176,7 +182,7 @@ describe('campaign cell edit overlay', () => {
it.each(overlayCases)(
'keeps $name in a Popover on the desktop table',
async ({ triggerLabel, element }) => {
render(element('popover'))
renderWithTooltip(element('popover'))
const trigger = screen.getByRole('button', { name: triggerLabel })
expect(trigger.getAttribute('aria-haspopup')).toBe('dialog')
@ -207,7 +213,7 @@ describe('campaign cell edit overlay', () => {
* "Salvando…", which cannot happen before one.
*/
it('does not mount the live region until the overlay has been opened once', () => {
render(
renderWithTooltip(
createElement(MunicipalityListTrendControl, {
municipalityID: 1,
municipalityName: MUNICIPALITY_NAME,
@ -237,7 +243,7 @@ describe('campaign cell edit overlay', () => {
)
vi.stubGlobal('fetch', fetchMock)
render(
renderWithTooltip(
createElement(MunicipalityListTrendControl, {
municipalityID: 1,
municipalityName: MUNICIPALITY_NAME,
@ -273,7 +279,7 @@ describe('campaign cell edit overlay', () => {
it('submits the signal form from a button rendered in the sheet footer', async () => {
const formAction = vi.fn(async () => ({}))
render(
renderWithTooltip(
// `createElement`'s typing puts a required `children` in props, so the
// rest-argument form this rule prefers does not type-check here.
// eslint-disable-next-line react/no-children-prop
@ -317,7 +323,7 @@ describe('campaign cell edit overlay', () => {
* edited.
*/
it('opens the município portfolio in a Drawer focused on its title', async () => {
render(
renderWithTooltip(
createElement(MunicipalityPortfolioCell, {
ownerId: 1,
ownerName: 'Maria Souza',

View file

@ -16,6 +16,7 @@ import { CampaignScopeBadge } from '@/components/campaign/shared/CampaignScopeBa
import { Progress } from '@/components/ui/Progress'
import { Toggle } from '@/components/ui/Toggle'
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/ToggleGroup'
import { TooltipProvider } from '@/components/ui/tooltip'
import type { CampaignColumnVisibility } from '@/lib/campaignColumnVisibility'
import { toVoteEstimateScenarioViewModel } from '@/lib/voteEstimate'
import type { CampaignFormActionState } from '@/utilities/campaignFormActionError'
@ -63,8 +64,19 @@ const mockAppRouter = stub<Parameters<typeof AppRouterContext.Provider>[0]['valu
prefetch: () => Promise.resolve(),
})
// Cells render `CampaignHoverTooltip` (Radix), which refuses to render outside
// a provider; production mounts it in the `(app)` layout.
const renderWithTooltip = (element: React.ReactElement) =>
renderToStaticMarkup(createElement(TooltipProvider, null, element))
const renderWithAppRouter = (element: React.ReactElement) =>
renderToStaticMarkup(createElement(AppRouterContext.Provider, { value: mockAppRouter }, element))
renderToStaticMarkup(
createElement(
AppRouterContext.Provider,
{ value: mockAppRouter },
createElement(TooltipProvider, null, element),
),
)
describe('campaign visual foundation', () => {
it('exposes the current progress value to assistive technology', () => {
@ -579,7 +591,7 @@ describe('campaign visual foundation', () => {
goalCoverageByScenario: createEmptyGoalCoverageByScenario(),
}
const withAdvisors = renderToStaticMarkup(
const withAdvisors = renderWithTooltip(
createElement(MunicipalityList, {
municipalities: [{ ...baseMunicipality, advisorIDs: [7] }],
advisorNamesById: new Map([[7, { id: 7, name: 'Ana Bastos', phone: null }]]),
@ -591,7 +603,7 @@ describe('campaign visual foundation', () => {
HEADER_TOOLTIP_COUNT + 1,
)
const withoutAdvisors = renderToStaticMarkup(
const withoutAdvisors = renderWithTooltip(
createElement(MunicipalityList, {
municipalities: [{ ...baseMunicipality, advisorIDs: [] }],
advisorNamesById: new Map<number, MunicipalityAdvisorSummary>(),
@ -606,7 +618,7 @@ describe('campaign visual foundation', () => {
})
it("wraps the coordinator's advisor Popover trigger in a tooltip, never doubling the affordance", () => {
const withAdvisors = renderToStaticMarkup(
const withAdvisors = renderWithTooltip(
createElement(MunicipalityListAdvisorsControl, {
municipalityID: 1,
municipalityName: 'Feira de Santana',
@ -624,7 +636,7 @@ describe('campaign visual foundation', () => {
// stays intact and functional.
expect(withAdvisors).toContain('aria-haspopup="dialog"')
const withoutAdvisors = renderToStaticMarkup(
const withoutAdvisors = renderWithTooltip(
createElement(MunicipalityListAdvisorsControl, {
municipalityID: 1,
municipalityName: 'Feira de Santana',
@ -641,7 +653,7 @@ describe('campaign visual foundation', () => {
})
it('shows the trend justification on hover only when one was recorded', () => {
const withNote = renderToStaticMarkup(
const withNote = renderWithTooltip(
createElement(MunicipalityListTrendControl, {
municipalityID: 1,
municipalityName: 'Feira de Santana',
@ -657,7 +669,7 @@ describe('campaign visual foundation', () => {
expect(withNote).toContain('aria-haspopup="dialog"')
expect(withNote).not.toContain('Salvar')
const withoutNote = renderToStaticMarkup(
const withoutNote = renderWithTooltip(
createElement(MunicipalityListTrendControl, {
municipalityID: 1,
municipalityName: 'Feira de Santana',

View file

@ -3,6 +3,7 @@ import { renderToStaticMarkup } from 'react-dom/server'
import { describe, expect, it } from 'vitest'
import { CampaignTable, CampaignTableHead } from '@/components/campaign/shared/CampaignTable'
import { TooltipProvider } from '@/components/ui/tooltip'
type Row = { id: number; name: string; note: string | null }
@ -11,8 +12,13 @@ const rows: Row[] = [
{ id: 2, name: 'Itaberaba', note: null },
]
// Cells/heads render `CampaignHoverTooltip` (Radix), which refuses to render
// outside a provider; production mounts it in the `(app)` layout.
const withTooltipProvider = (element: ReturnType<typeof createElement>) =>
renderToStaticMarkup(createElement(TooltipProvider, null, element))
const renderTable = (cellTooltip?: (row: Row) => string | null) =>
renderToStaticMarkup(
withTooltipProvider(
createElement(CampaignTable<Row>, {
columns: [
{
@ -40,7 +46,7 @@ describe('CampaignTable head', () => {
})
it('lets a column own its header when it needs more than its name', () => {
const html = renderToStaticMarkup(
const html = withTooltipProvider(
createElement(CampaignTable<Row>, {
columns: [
{
@ -101,7 +107,7 @@ describe('CampaignTable cellTooltip', () => {
*/
describe('CampaignTableHead description', () => {
it('renders unchanged when no description is declared', () => {
const html = renderToStaticMarkup(createElement(CampaignTableHead, {}, 'Território'))
const html = withTooltipProvider(createElement(CampaignTableHead, {}, 'Território'))
expect(html).toContain('Território')
expect(html).not.toContain('data-slot="tooltip-trigger"')
@ -109,7 +115,7 @@ describe('CampaignTableHead description', () => {
})
it('wraps the label in exactly one tooltip trigger when description is declared', () => {
const html = renderToStaticMarkup(
const html = withTooltipProvider(
createElement(
CampaignTableHead,
{ description: 'Território de Identidade a que o município pertence.' },