Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions scripts/velocity/field-velocity-panel.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,19 @@ function elements(node) {
}

for (const { key, label } of FOCUS_AREAS) {
test(`${key} staged panel retains charts and selected-area methodology/toolkit links without public route wiring`, async (t) => {
test(`${key} overview includes the shared panel, original strategy and selected-area methodology/toolkit links`, async (t) => {
assert.ok(existsSync('src/components/AreaFieldVelocity.tsx'), 'missing reusable area panel')
t.mock.method(globalThis, 'fetch', async () => new Response(null, { status: 503 }))
t.mock.method(console, 'warn', () => {})
const Panel = source('components/AreaFieldVelocity.tsx').default
// The component is retained for a later launch, but no public page mounts it.
// Public-route absence is covered separately by preview-only.test.mjs.
const panelTree = await Panel({ area: key })
const Page = source(key === 'economies-governance' ? 'app/areas/economies-governance/page.tsx' : 'app/areas/[slug]/page.tsx').default
const tree = await Page({ params: Promise.resolve({ slug: key }) })
const children = elements(tree)
const panel = children.find(el => el.type === Panel)
assert.ok(panel, `${key} page does not mount shared panel`)
assert.equal(panel.props.area, key)
assert.ok(children.some(el => el.props.id === 'opportunity-spaces'), 'existing strategy preserved')
const panelTree = await Panel(panel.props)
if (key === 'economies-governance') {
assert.deepEqual(elements(panelTree).find(el => el.type === Dashboard).props.liveOutputs, {}, 'area panel must retain the overview live-output channel even when providers are unavailable')
}
Expand All @@ -64,7 +69,7 @@ for (const { key, label } of FOCUS_AREAS) {

assert.match(html, /id="field-velocity"/)
assert.ok(html.includes(`${label} field velocity</h2>`))

assert.ok(tree.props.className.includes('area-overview'))
assert.ok(panelTree.props.className.includes('area-field-velocity'))
assert.ok(panelTree.props.className.includes(key === 'neurotech' ? 'bg-gray-100' : 'bg-gray-200'))
assert.doesNotMatch(panelTree.props.className, /border-y|px-4|bg-gray-50/)
Expand Down
18 changes: 2 additions & 16 deletions scripts/velocity/preview-only.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import React from 'react'
import { readFileSync } from 'node:fs'
import { source } from './test-source-loader.mjs'

const Panel = source('components/AreaFieldVelocity.tsx').default
const Dashboard = source('components/ImpactDashboardV2.tsx').default
const Methodology = source('components/MeasuringQuestionsV2.tsx').default
const { FOCUS_AREAS, FIELD_VELOCITY_OVERVIEW } = source('lib/field-velocity.ts')
Expand All @@ -19,21 +18,8 @@ function offlineProviders(t) {
t.mock.method(console, 'warn', () => {})
}

for (const { key } of FOCUS_AREAS) {
test(`${key} public detail keeps existing content but does not mount field velocity or preview links`, async (t) => {
offlineProviders(t)
const route = key === 'economies-governance' ? 'app/areas/economies-governance/page.tsx' : 'app/areas/[slug]/page.tsx'
const Page = source(route).default
const nodes = elements(await Page({ params: Promise.resolve({ slug: key }) }))
assert.ok(!nodes.some(node => node.type === Panel || node.type === Dashboard || node.type === Methodology), 'unreleased field velocity must not mount on public pages')
assert.ok(!nodes.some(node => node.props.id === 'field-velocity'))
assert.ok(!nodes.some(node => /impact-preview|#fv\/|#field-velocity|#methodology|#toolkit/.test(node.props.href ?? '')), 'no discovery links to the unlisted preview')
assert.ok(nodes.some(node => node.props.id === 'opportunity-spaces'), 'original strategy remains')
const existingLink = key === 'economies-governance' ? '/areas/economies-governance/projects/' : '/insights/'
assert.ok(nodes.some(node => node.props.href === existingLink), 'original Explore/Insights content remains')
assert.doesNotMatch(readFileSync(`src/${route}`, 'utf8'), /from ['"]@\/(?:components\/(?:AreaFieldVelocity|ImpactDashboardV2|MeasuringQuestionsV2)|lib\/field-velocity[^'"]*)['"]/, 'public routes must not load field-velocity modules')
})
}
// Public detail mounting is covered by field-velocity-panel.test.mjs.
// The cross-field overview itself keeps its existing unlisted route.

test('the exact unlisted overview retains all fields, charts, methodology and noindex metadata', async (t) => {
offlineProviders(t)
Expand Down
4 changes: 3 additions & 1 deletion src/app/areas/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type { Metadata } from 'next'
import AreaFieldVelocity from '@/components/AreaFieldVelocity'
import { isFocusAreaKey } from '@/lib/field-velocity-data'

import EditPageButton from '@/components/EditPageButton'
import { PageEditHistoryByline } from '@/components/EditHistoryByline'
Expand Down Expand Up @@ -287,7 +289,7 @@ export default async function AreaPage({ params }: Props) {
</section>
)}

{/* Field velocity is preview-only until a separate public launch. */}
{isFocusAreaKey(slug) && <AreaFieldVelocity area={slug} />}

{/* Insights — latest posts, publications, and talks for this focus area */}
{areaInsights.length > 0 && (
Expand Down
4 changes: 2 additions & 2 deletions src/app/areas/economies-governance/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Link from 'next/link'
import type { Metadata } from 'next'

import AreaFieldVelocity from '@/components/AreaFieldVelocity'
import EditPageButton from '@/components/EditPageButton'
import { PageEditHistoryByline } from '@/components/EditHistoryByline'
import AuthorCard from '@/components/AuthorCard'
Expand Down Expand Up @@ -255,7 +255,7 @@ export default async function FA2MainPage() {
</div>
</section>

{/* Field velocity is preview-only until a separate public launch. */}
<AreaFieldVelocity area="economies-governance" />

{/* Explore */}
<h2 className="text-sm text-gray-500 uppercase tracking-wide mb-6">Explore</h2>
Expand Down