Fix roadmap crash with plugin language packs (#26860)

Co-authored-by: m4air <m4air@Mac.localdomain>
This commit is contained in:
Neil
2026-10-10 00:26:21 -07:00
committed by GitHub
co-authored by m4air
parent f307391637
commit 48528c0128
2 changed files with 61 additions and 3 deletions
@@ -4,6 +4,9 @@ import type { ReactNode } from 'react'
import { act, cleanup, fireEvent, render, screen } from '@testing-library/react'
import { afterEach, describe, expect, it, vi } from 'vitest'
import ProjectRoadmap from './ProjectRoadmap'
import { i18n, setRendererPluginLanguagePacks, setRendererUiLanguage } from '@/i18n/i18n'
import { DEFAULT_LOCALE } from '@/i18n/supported-languages'
import { pluginLanguageResourceId } from '../../../../shared/plugins/plugin-language-pack-artifact'
import type {
GitHubProjectField,
GitHubProjectFieldValue,
@@ -94,13 +97,68 @@ function table(
}
}
afterEach(() => {
afterEach(async () => {
cleanup()
vi.useRealTimers()
window.localStorage.clear()
setRendererPluginLanguagePacks([])
await setRendererUiLanguage(DEFAULT_LOCALE)
})
describe('ProjectRoadmap', () => {
it.each([
['pt-BR', 'pt-BR'],
['en-US-US', DEFAULT_LOCALE]
])('renders date ticks and bars with plugin locale %s', async (packLocale, dateLocale) => {
const packId = 'plugin:stablyai.orca-portuguese/pt-BR' as const
const resourceLanguage = pluginLanguageResourceId(packId)
// The resource tag recorded in the Windows crash report on #25021.
expect(resourceLanguage).toBe(
'plugin0070006c007500670069006e003a0073007400610062006c007900610069002e006f007200630061002d0070006f00720074007500670075006500730065002f00700074002d00420052'
)
setRendererPluginLanguagePacks([
{
id: packId,
resourceLanguage,
pluginKey: 'stablyai.orca-portuguese',
locale: packLocale,
catalog: { common: { cancel: 'Cancelar' } }
}
])
await setRendererUiLanguage(packId)
expect(i18n.resolvedLanguage).toBe(resourceLanguage)
render(
<ProjectRoadmap
table={table(
[TITLE_FIELD, START_FIELD, TARGET_FIELD],
[
row('scheduled', 'Scheduled', [
{ kind: 'date', fieldId: START_FIELD.id, date: '2026-09-01' },
{ kind: 'date', fieldId: TARGET_FIELD.id, date: '2026-10-15' }
])
]
)}
fallback={<div>list</div>}
/>
)
const month = new Intl.DateTimeFormat(dateLocale, {
month: 'short',
timeZone: 'UTC'
}).format(new Date(Date.UTC(2026, 8, 1)))
expect(screen.getAllByText(month, { exact: false }).length).toBeGreaterThan(0)
const dateFormat = new Intl.DateTimeFormat(dateLocale, {
year: 'numeric',
month: 'short',
day: 'numeric',
timeZone: 'UTC'
})
const start = dateFormat.format(new Date(Date.UTC(2026, 8, 1)))
const end = dateFormat.format(new Date(Date.UTC(2026, 9, 15)))
expect(screen.getByRole('button', { name: `Scheduled — ${start} – ${end}` })).toBeTruthy()
})
it('moves the today marker across local midnight without resetting scroll and cleans up its timer', () => {
vi.useFakeTimers()
vi.setSystemTime(new Date(2026, 8, 5, 23, 59, 59))
@@ -3,7 +3,7 @@ import { CalendarClock } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { usePrefersReducedMotion } from '@/hooks/usePrefersReducedMotion'
import { cn } from '@/lib/utils'
import { i18n, translate } from '@/i18n/i18n'
import { getIntlLocale, translate } from '@/i18n/i18n'
import ProjectGroupHeader from './ProjectGroupHeader'
import ProjectRoadmapBar from './ProjectRoadmapBar'
import { ProjectTitleCell } from './ProjectCellIdentity'
@@ -48,7 +48,7 @@ export default function ProjectRoadmap({
}: Props): React.JSX.Element {
const view = table.selectedView
const prefersReducedMotion = usePrefersReducedMotion()
const locale = i18n.resolvedLanguage ?? i18n.language
const locale = getIntlLocale()
// Why: the grid lives on UTC calendar days (parseRoadmapDate), so "today"
// must be the viewer's LOCAL calendar date mapped to UTC midnight — the raw
// instant would shift the marker into the wrong day off UTC.