mirror of
https://github.com/supabase/supabase.git
synced 2026-10-18 15:49:09 +03:00
fix(studio): preserve health advisor hook order
This commit is contained in:
1 parent
557c84a300
commit
1134871b8b
2 files changed
+110
-15
No files matched your search
@@ -20,24 +20,10 @@ import type { NextPageWithLayout } from '@/types'
|
||||
|
||||
const ProjectHealthLints: NextPageWithLayout = () => {
|
||||
const router = useRouter()
|
||||
const { preset, id, ref } = useParams()
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const { ref } = useParams()
|
||||
const { hasLoaded: flagsLoaded } = useFeatureFlags()
|
||||
const isHealthAdvisorEnabled = useFlag('healthAdvisor') === true
|
||||
|
||||
const [filters, setFilters] = useState<{ level: LINTER_LEVELS; filters: string[] }[]>([
|
||||
{ level: LINTER_LEVELS.ERROR, filters: [] },
|
||||
{ level: LINTER_LEVELS.WARN, filters: [] },
|
||||
{ level: LINTER_LEVELS.INFO, filters: [] },
|
||||
])
|
||||
const [currentTab, setCurrentTab] = useState<LINTER_LEVELS>(
|
||||
parseLinterLevel(preset) ?? LINTER_LEVELS.ERROR
|
||||
)
|
||||
const { data, isPending, isRefetching, refetch } = useProjectHealthLintsQuery(
|
||||
{ projectRef: project?.ref },
|
||||
{ enabled: isHealthAdvisorEnabled }
|
||||
)
|
||||
|
||||
const isFlagLoading = IS_PLATFORM && !flagsLoaded
|
||||
|
||||
useEffect(() => {
|
||||
@@ -48,6 +34,25 @@ const ProjectHealthLints: NextPageWithLayout = () => {
|
||||
|
||||
if (isFlagLoading || !isHealthAdvisorEnabled) return null
|
||||
|
||||
return <ProjectHealthLintsContent />
|
||||
}
|
||||
|
||||
const ProjectHealthLintsContent = () => {
|
||||
const { preset, id } = useParams()
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
|
||||
const [filters, setFilters] = useState<{ level: LINTER_LEVELS; filters: string[] }[]>([
|
||||
{ level: LINTER_LEVELS.ERROR, filters: [] },
|
||||
{ level: LINTER_LEVELS.WARN, filters: [] },
|
||||
{ level: LINTER_LEVELS.INFO, filters: [] },
|
||||
])
|
||||
const [currentTab, setCurrentTab] = useState<LINTER_LEVELS>(
|
||||
parseLinterLevel(preset) ?? LINTER_LEVELS.ERROR
|
||||
)
|
||||
const { data, isPending, isRefetching, refetch } = useProjectHealthLintsQuery({
|
||||
projectRef: project?.ref,
|
||||
})
|
||||
|
||||
// Health checks are platform-only. If this page is opened self-hosted the query stays
|
||||
// disabled, and `isPending` would otherwise spin forever.
|
||||
const isLoading = IS_PLATFORM && isPending
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import ProjectHealthLints from '@/pages/project/[ref]/advisors/health'
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
flags: { hasLoaded: false, enabled: false },
|
||||
router: { replace: vi.fn() },
|
||||
query: vi.fn(),
|
||||
shortcuts: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('common', () => ({
|
||||
useFeatureFlags: () => ({ hasLoaded: mocks.flags.hasLoaded }),
|
||||
useFlag: () => mocks.flags.enabled,
|
||||
useParams: () => ({ ref: 'test-project' }),
|
||||
}))
|
||||
vi.mock('next/router', () => ({ useRouter: () => mocks.router }))
|
||||
vi.mock('@/lib/constants', () => ({ IS_PLATFORM: true }))
|
||||
vi.mock('@/hooks/misc/useSelectedProject', () => ({
|
||||
useSelectedProjectQuery: () => ({ data: { ref: 'test-project' } }),
|
||||
}))
|
||||
vi.mock('@/data/lint/health-lints-query', () => ({
|
||||
useProjectHealthLintsQuery: mocks.query,
|
||||
}))
|
||||
vi.mock('@/components/interfaces/Linter/useAdvisorPageShortcuts', () => ({
|
||||
useAdvisorPageShortcuts: mocks.shortcuts,
|
||||
}))
|
||||
vi.mock('@/components/interfaces/Linter/Linter.utils', () => ({
|
||||
lintInfoMap: [],
|
||||
parseLinterLevel: () => undefined,
|
||||
}))
|
||||
vi.mock('@/components/interfaces/Linter/LinterDataGrid', () => ({
|
||||
LinterDataGrid: () => null,
|
||||
}))
|
||||
vi.mock('@/components/interfaces/Linter/LinterFilters', () => ({ default: () => null }))
|
||||
vi.mock('@/components/interfaces/Linter/LintPageTabs', () => ({ default: () => null }))
|
||||
vi.mock('@/components/layouts/AdvisorsLayout/AdvisorsLayout', () => ({ default: () => null }))
|
||||
vi.mock('@/components/layouts/DefaultLayout', () => ({ DefaultLayout: () => null }))
|
||||
vi.mock('@/components/ui/Forms/FormHeader', () => ({
|
||||
FormHeader: ({ title }: { title: string }) => <h1>{title}</h1>,
|
||||
}))
|
||||
vi.mock('ui', () => ({ LoadingLine: () => null }))
|
||||
|
||||
describe('Health Advisor feature flag', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mocks.flags.hasLoaded = false
|
||||
mocks.flags.enabled = false
|
||||
mocks.query.mockReturnValue({
|
||||
data: [],
|
||||
isPending: false,
|
||||
isRefetching: false,
|
||||
refetch: vi.fn(),
|
||||
})
|
||||
})
|
||||
|
||||
it('renders after the flag loads without changing hook order', () => {
|
||||
const { rerender } = render(<ProjectHealthLints />)
|
||||
|
||||
expect(screen.queryByRole('heading', { name: 'Health Advisor' })).not.toBeInTheDocument()
|
||||
expect(mocks.router.replace).not.toHaveBeenCalled()
|
||||
expect(mocks.query).not.toHaveBeenCalled()
|
||||
expect(mocks.shortcuts).not.toHaveBeenCalled()
|
||||
|
||||
mocks.flags.hasLoaded = true
|
||||
mocks.flags.enabled = true
|
||||
rerender(<ProjectHealthLints />)
|
||||
|
||||
expect(screen.getByRole('heading', { name: 'Health Advisor' })).toBeInTheDocument()
|
||||
expect(mocks.query).toHaveBeenCalled()
|
||||
expect(mocks.shortcuts).toHaveBeenCalled()
|
||||
expect(mocks.router.replace).not.toHaveBeenCalled()
|
||||
|
||||
mocks.flags.enabled = false
|
||||
rerender(<ProjectHealthLints />)
|
||||
|
||||
expect(screen.queryByRole('heading', { name: 'Health Advisor' })).not.toBeInTheDocument()
|
||||
expect(mocks.router.replace).toHaveBeenCalledWith('/project/test-project/advisors/security')
|
||||
})
|
||||
|
||||
it('redirects when the loaded flag is disabled without mounting health functionality', () => {
|
||||
mocks.flags.hasLoaded = true
|
||||
render(<ProjectHealthLints />)
|
||||
|
||||
expect(mocks.router.replace).toHaveBeenCalledWith('/project/test-project/advisors/security')
|
||||
expect(mocks.query).not.toHaveBeenCalled()
|
||||
expect(mocks.shortcuts).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user