Skip to content

Commit 29c8b51

Browse files
committed
test(home): rewrite view and loader tests for new layout
1 parent 656ffe3 commit 29c8b51

3 files changed

Lines changed: 125 additions & 47 deletions

File tree

docs/views/home.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,25 @@
22

33
## Purpose
44

5-
First impression for every visitor. Explains what Flexion Labs is, highlights featured labs, grounds the pitch with real numbers, and hands visitors off to the right next step.
5+
First impression for every visitor. Introduces Flexion Labs with a hero, showcases the three Flexion Solutions offerings as featured labs, and hands visitors off to the commitment and about pages.
66

77
## Inputs
88

9-
- `catalog` — the merged catalog.
10-
- `hero``{ hero, intro }` read from `content/home.md` front-matter.
9+
- `hero``{ title, subtitle, intro, learnMore }` read from `content/home.md` front-matter. `intro` is pre-rendered HTML; the others are strings.
10+
- `featured`array of `FeaturedLab` loaded from `content/featured/*.md` sorted by `order` ascending.
1111
- `config` — base path, build time.
1212

1313
## Behavior
1414

15-
- **When the page loads, then** the hero statement is the `<h1>`, followed by the intro paragraph.
16-
- **When there are repos flagged `featured: true` and not hidden, then** one card is rendered per featured repo in the order they appear in the catalog.
17-
- **When there are no featured repos, then** the featured section renders its heading and an empty grid (acceptable for v1; may be hardened later).
18-
- **When the catalog has N non-hidden repos, then** the stats strip renders `N public projects`, the count of `tier: active` repos as `actively maintained`, and the count of distinct languages.
19-
- **When the page loads, then** three audience paths link to `/work/`, `/commitment/`, and `/about/`.
15+
- **When the page loads, then** the hero renders the `title` as `<h1>`, the `subtitle` as a tagline paragraph, and the rendered `intro` HTML as the intro block.
16+
- **When there are featured labs, then** one `LabCard` is rendered per lab in `order` ascending.
17+
- **When the page loads, then** a "Learn more" section renders two teasers linking to `/commitment/` and `/about/` respectively.
18+
- **The stats strip is not rendered.** The catalog directory is disabled in this pass.
2019

2120
## Fallbacks
2221

23-
- None — every section renders; empty collections produce empty grids.
22+
- If `content/featured/` is empty or missing, the featured section renders its heading with no cards.
23+
- If `subtitle` or `intro` is empty, that element is omitted.
2424

2525
## Tests
2626

tests/build/hero.test.ts

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,48 @@ import { writeFileSync, mkdtempSync, mkdirSync } from 'node:fs'
44
import { tmpdir } from 'node:os'
55
import { join } from 'node:path'
66

7+
function makeRoot(home: string): string {
8+
const root = mkdtempSync(join(tmpdir(), 'flexion-labs-'))
9+
mkdirSync(join(root, 'content'), { recursive: true })
10+
writeFileSync(join(root, 'content', 'home.md'), home)
11+
return root
12+
}
13+
714
describe('loadHero', () => {
8-
test('reads hero and intro from content/home.md front-matter', async () => {
9-
const root = mkdtempSync(join(tmpdir(), 'flexion-labs-'))
10-
mkdirSync(join(root, 'content'), { recursive: true })
11-
writeFileSync(
12-
join(root, 'content', 'home.md'),
13-
'---\nhero: Test hero.\nintro: Test intro.\n---\n',
15+
test('reads title, subtitle, intro (rendered) and learnMore from front-matter', async () => {
16+
const root = makeRoot(
17+
[
18+
'---',
19+
'title: Site Title',
20+
'subtitle: The subtitle',
21+
'intro: |',
22+
' First paragraph with a [link](https://example.com/).',
23+
'',
24+
' Second paragraph.',
25+
'learnMore:',
26+
' commitment: Commitment teaser.',
27+
' about: About teaser.',
28+
'---',
29+
'',
30+
].join('\n'),
1431
)
1532
const hero = await loadHero(root)
16-
expect(hero.hero).toBe('Test hero.')
17-
expect(hero.intro).toBe('Test intro.')
33+
expect(hero.title).toBe('Site Title')
34+
expect(hero.subtitle).toBe('The subtitle')
35+
expect(hero.intro).toContain('<a href="https://example.com/">link</a>')
36+
expect(hero.intro).toContain('First paragraph')
37+
expect(hero.intro).toContain('Second paragraph')
38+
expect(hero.learnMore.commitment).toBe('Commitment teaser.')
39+
expect(hero.learnMore.about).toBe('About teaser.')
40+
})
41+
42+
test('falls back to defaults when front-matter is empty', async () => {
43+
const root = makeRoot('---\n---\n')
44+
const hero = await loadHero(root)
45+
expect(hero.title).toBe('Flexion Labs')
46+
expect(hero.subtitle).toBe('')
47+
expect(hero.intro).toBe('')
48+
expect(hero.learnMore.commitment).toBe('')
49+
expect(hero.learnMore.about).toBe('')
1850
})
1951
})

tests/views/home.test.tsx

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,93 @@
11
import { describe, test, expect } from 'bun:test'
22
import { renderToHtml } from '../../src/build/render'
33
import { Home } from '../../src/pages/home'
4-
import { fixtureCatalog } from '../fixtures/catalog'
4+
import type { FeaturedLab } from '../../src/build/featured'
55

6-
const config = { basePath: '/', buildTime: '2026-04-27T12:00:00Z' }
7-
const heroContent = {
8-
hero: 'Public infrastructure, in the open.',
9-
intro: 'Flexion Labs gathers our open source work in one place.',
6+
const config = { basePath: '/', buildTime: '2026-05-01T12:00:00Z' }
7+
8+
const hero = {
9+
title: 'Flexion Labs',
10+
subtitle: 'Solutions for the public, in the open',
11+
intro: '<p>Flexion is committed to <a href="https://flexion.us/contact-us/">reach out to us</a> excellence.</p>',
12+
learnMore: {
13+
commitment: 'Flexion is open by default.',
14+
about: 'We help organizations stay future-ready.',
15+
},
1016
}
1117

18+
const featured: FeaturedLab[] = [
19+
{
20+
title: 'Forms Lab',
21+
tagline: 'Digitize forms to create modern, accessible experiences for public outreach.',
22+
order: 1,
23+
links: [
24+
{ label: 'Demo (Forms Platform)', url: 'https://pp4cc7kwbf.us-east-1.awsapprunner.com/' },
25+
{ label: 'GitHub repository — Forms Platform', url: 'https://github.com/flexion/forms' },
26+
],
27+
},
28+
{
29+
title: 'Messaging Lab',
30+
tagline: 'Text messaging services to deliver critical updates to the people you serve.',
31+
order: 2,
32+
links: [
33+
{ label: 'GitHub repository', url: 'https://github.com/flexion/flexion-notify' },
34+
],
35+
},
36+
{
37+
title: 'Document Extractor Lab',
38+
tagline: 'Accurately extract data from PDFs and images for faster application processing.',
39+
order: 3,
40+
links: [
41+
{ label: 'GitHub repository', url: 'https://github.com/flexion/document-extractor' },
42+
],
43+
},
44+
]
45+
1246
describe('Home', () => {
13-
test('renders the hero statement as the h1', async () => {
14-
const html = await renderToHtml(
15-
<Home catalog={fixtureCatalog} hero={heroContent} config={config} />,
16-
)
17-
expect(html).toMatch(/<h1[^>]*>Public infrastructure, in the open\.<\/h1>/)
47+
test('renders the site title as the h1', async () => {
48+
const html = await renderToHtml(<Home hero={hero} featured={featured} config={config} />)
49+
expect(html).toMatch(/<h1[^>]*>Flexion Labs<\/h1>/)
50+
})
51+
52+
test('renders the subtitle', async () => {
53+
const html = await renderToHtml(<Home hero={hero} featured={featured} config={config} />)
54+
expect(html).toContain('Solutions for the public, in the open')
1855
})
1956

20-
test('renders one card per featured entry', async () => {
21-
const html = await renderToHtml(
22-
<Home catalog={fixtureCatalog} hero={heroContent} config={config} />,
23-
)
24-
expect(html).toContain('messaging')
25-
expect(html).toContain('forms')
26-
expect(html).toContain('document-extractor')
27-
expect(html).not.toContain('old-prototype')
57+
test('renders the intro markdown as HTML including the reach-out link', async () => {
58+
const html = await renderToHtml(<Home hero={hero} featured={featured} config={config} />)
59+
expect(html).toContain('href="https://flexion.us/contact-us/"')
2860
})
2961

30-
test('renders quick stats reflecting the catalog', async () => {
31-
const html = await renderToHtml(
32-
<Home catalog={fixtureCatalog} hero={heroContent} config={config} />,
33-
)
34-
// 7 total repos in the fixture; 3 active.
35-
expect(html).toMatch(/7<\/strong>\s*public projects/)
36-
expect(html).toMatch(/3<\/strong>\s*actively maintained/)
62+
test('renders one LabCard per featured lab in order', async () => {
63+
const html = await renderToHtml(<Home hero={hero} featured={featured} config={config} />)
64+
const indexOf = (s: string) => html.indexOf(s)
65+
expect(indexOf('Forms Lab')).toBeGreaterThan(-1)
66+
expect(indexOf('Messaging Lab')).toBeGreaterThan(-1)
67+
expect(indexOf('Document Extractor Lab')).toBeGreaterThan(-1)
68+
expect(indexOf('Forms Lab')).toBeLessThan(indexOf('Messaging Lab'))
69+
expect(indexOf('Messaging Lab')).toBeLessThan(indexOf('Document Extractor Lab'))
3770
})
3871

39-
test('renders the three audience paths', async () => {
40-
const html = await renderToHtml(
41-
<Home catalog={fixtureCatalog} hero={heroContent} config={config} />,
42-
)
43-
expect(html).toContain('href="/work/"')
72+
test('renders each labs links inside its card', async () => {
73+
const html = await renderToHtml(<Home hero={hero} featured={featured} config={config} />)
74+
expect(html).toContain('href="https://github.com/flexion/forms"')
75+
expect(html).toContain('href="https://github.com/flexion/flexion-notify"')
76+
expect(html).toContain('href="https://github.com/flexion/document-extractor"')
77+
})
78+
79+
test('renders the Learn more section with commitment and about teasers', async () => {
80+
const html = await renderToHtml(<Home hero={hero} featured={featured} config={config} />)
81+
expect(html).toContain('Learn more')
82+
expect(html).toContain('Our open source commitment')
83+
expect(html).toContain('About Flexion')
4484
expect(html).toContain('href="/commitment/"')
4585
expect(html).toContain('href="/about/"')
4686
})
87+
88+
test('does not render the stats strip', async () => {
89+
const html = await renderToHtml(<Home hero={hero} featured={featured} config={config} />)
90+
expect(html).not.toContain('home-stats')
91+
expect(html).not.toContain('public projects')
92+
})
4793
})

0 commit comments

Comments
 (0)