Files
crashtestdev/tests/index-page.test.mjs
T

161 lines
5.8 KiB
JavaScript

import { describe, it } from 'node:test';
import { strict as assert } from 'node:assert';
import { readFileSync, existsSync } from 'node:fs';
import { resolve } from 'node:path';
const pagePath = resolve('src/pages/index.astro');
function readPage() {
return readFileSync(pagePath, 'utf-8');
}
describe('Index page', () => {
it('should exist at src/pages/index.astro', () => {
assert.ok(existsSync(pagePath), 'Index page file should exist');
});
describe('Imports', () => {
it('should import getCollection from astro:content', () => {
const content = readPage();
assert.match(content, /import\s+.*getCollection.*from\s+['"]astro:content['"]/, 'should import getCollection');
});
it('should import BaseLayout', () => {
const content = readPage();
assert.match(content, /import\s+BaseLayout\s+from\s+['"].*BaseLayout\.astro['"]/, 'should import BaseLayout');
});
it('should import NavBar', () => {
const content = readPage();
assert.match(content, /import\s+NavBar\s+from\s+['"].*NavBar\.astro['"]/, 'should import NavBar');
});
it('should import getReadingTime', () => {
const content = readPage();
assert.match(content, /import\s+.*getReadingTime.*from\s+['"].*reading-time['"]/, 'should import getReadingTime');
});
});
describe('Data fetching', () => {
it('should fetch all posts with getCollection', () => {
const content = readPage();
assert.match(content, /getCollection\s*\(\s*['"]posts['"]\s*\)/, 'should call getCollection("posts")');
});
});
describe('Hero section', () => {
it('should have a hero section', () => {
const content = readPage();
assert.match(content, /class="hero"/, 'should have a section with class hero');
});
it('should have the site title Crash Test Dev as a heading', () => {
const content = readPage();
assert.match(content, /<h1[^>]*>Crash Test Dev<\/h1>/, 'should have h1 with site title');
});
it('should have a tagline in prose font', () => {
const content = readPage();
assert.match(content, /class="tagline"/, 'should have a tagline element');
});
it('should have an author byline', () => {
const content = readPage();
assert.match(content, /class="byline"/, 'should have a byline element');
});
});
describe('Featured excerpt section', () => {
it('should have a featured excerpt section', () => {
const content = readPage();
assert.match(content, /class="featured"/, 'should have a section with class featured');
});
it('should contain an excerpt blockquote', () => {
const content = readPage();
assert.match(content, /<blockquote[^>]*class="excerpt"/, 'should have a blockquote with class excerpt');
});
it('should have a link to the full post', () => {
const content = readPage();
// The featured section should contain a link to read the full post
assert.match(content, /class="featured-link"/, 'should have a featured-link to the full post');
});
});
describe('Series section', () => {
it('should have a series section', () => {
const content = readPage();
assert.match(content, /class="series"/, 'should have a section with class series');
});
it('should mention the Rage series', () => {
const content = readPage();
assert.match(content, /Rage/, 'should mention Rage in the series section');
});
it('should list planned posts', () => {
const content = readPage();
assert.match(content, /class="series-item"/, 'should have series items');
});
it('should indicate coming soon items', () => {
const content = readPage();
assert.match(content, /coming soon/i, 'should indicate coming soon posts');
});
});
describe('All posts section', () => {
it('should have a posts listing section below the pitch', () => {
const content = readPage();
assert.match(content, /class="all-posts"/, 'should have a section with class all-posts');
});
it('should map posts to compact entries', () => {
const content = readPage();
assert.match(content, /sortedPosts\.map/, 'should map sortedPosts');
});
it('should show post titles as links', () => {
const content = readPage();
// Each post entry should link to its page
assert.match(content, /posts\/\$\{post\.id\}/, 'should link to post pages');
});
});
describe('Layout', () => {
it('should use BaseLayout with title Crash Test Dev', () => {
const content = readPage();
assert.match(content, /<BaseLayout\s+title\s*=\s*['"]Crash Test Dev['"]/, 'should have BaseLayout with title');
});
it('should include NavBar in nav slot', () => {
const content = readPage();
assert.match(content, /<NavBar\s+slot\s*=\s*["']nav["']/, 'should have NavBar with slot="nav"');
});
});
describe('Style', () => {
it('should use --width-prose for content width', () => {
const content = readPage();
assert.match(content, /max-width\s*:\s*var\(--width-prose\)/, 'should constrain content to prose width');
});
it('should use --font-structure for hero heading', () => {
const content = readPage();
assert.match(content, /\.hero[\s\S]*?font-family\s*:\s*var\(--font-structure\)/, 'should use structure font in hero');
});
it('should use --font-prose for excerpt', () => {
const content = readPage();
assert.match(content, /\.excerpt[\s\S]*?font-family\s*:\s*var\(--font-prose\)/, 'should use prose font for excerpt');
});
it('should not have the old .post-list as the main layout', () => {
const content = readPage();
// The old flat list structure should be gone
assert.doesNotMatch(content, /<ArticleCard/, 'should not use ArticleCard component');
});
});
});