Skip to content

Commit 748964c

Browse files
dwightgunningSculptor
andcommitted
test: getOutdoorPagesCollection unit tests
Mocks astro:content's getCollection via vi.mock. Tests cover draft filtering (with and without DRAFT_MODE=1), descending sort by activityDate, fallback to updatedAt then publishedAt, and graceful handling of entries with no date fields. Co-authored-by: Sculptor <sculptor@imbue.com>
1 parent b39579e commit 748964c

1 file changed

Lines changed: 109 additions & 0 deletions

File tree

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { describe, it, expect, vi, beforeEach } from 'vitest';
2+
import type { CollectionEntry } from 'astro:content';
3+
4+
vi.mock('astro:content', () => ({
5+
getCollection: vi.fn(),
6+
}));
7+
8+
import { getCollection } from 'astro:content';
9+
import getOutdoorPagesCollection from './getOutdoorPagesCollection';
10+
11+
const mockGetCollection = vi.mocked(getCollection);
12+
13+
type FilterFn = (entry: { data: { draft: boolean } }) => boolean;
14+
15+
function makeEntry(overrides: {
16+
id?: string;
17+
draft?: boolean;
18+
activityDate?: Date;
19+
updatedAt?: Date;
20+
publishedAt?: Date;
21+
}): CollectionEntry<'outdoors'> {
22+
return {
23+
id: overrides.id ?? 'test-entry',
24+
collection: 'outdoors',
25+
data: {
26+
draft: overrides.draft ?? false,
27+
activityDate: overrides.activityDate,
28+
updatedAt: overrides.updatedAt,
29+
publishedAt: overrides.publishedAt,
30+
},
31+
} as unknown as CollectionEntry<'outdoors'>;
32+
}
33+
34+
beforeEach(() => {
35+
vi.unstubAllEnvs();
36+
mockGetCollection.mockReset();
37+
});
38+
39+
describe('getOutdoorPagesCollection', () => {
40+
it('filters out draft entries when DRAFT_MODE is not set', async () => {
41+
const published = makeEntry({ id: 'published', draft: false });
42+
const draft = makeEntry({ id: 'draft', draft: true });
43+
44+
mockGetCollection.mockImplementation(async (_collection, filter) => {
45+
return [published, draft].filter((e) => (filter as FilterFn)(e));
46+
});
47+
48+
const result = await getOutdoorPagesCollection();
49+
expect(result.map((e) => e.id)).toEqual(['published']);
50+
});
51+
52+
it('includes draft entries when DRAFT_MODE=1', async () => {
53+
vi.stubEnv('DRAFT_MODE', '1');
54+
const published = makeEntry({ id: 'published', draft: false });
55+
const draft = makeEntry({ id: 'draft', draft: true });
56+
57+
mockGetCollection.mockImplementation(async (_collection, filter) => {
58+
return [published, draft].filter((e) => (filter as FilterFn)(e));
59+
});
60+
61+
const result = await getOutdoorPagesCollection();
62+
const ids = result.map((e) => e.id);
63+
expect(ids).toContain('draft');
64+
expect(ids).toContain('published');
65+
});
66+
67+
it('sorts by activityDate descending', async () => {
68+
const entries = [
69+
makeEntry({ id: 'old', activityDate: new Date('2021-01-01') }),
70+
makeEntry({ id: 'new', activityDate: new Date('2023-06-01') }),
71+
makeEntry({ id: 'mid', activityDate: new Date('2022-03-15') }),
72+
];
73+
mockGetCollection.mockResolvedValue(entries);
74+
75+
const result = await getOutdoorPagesCollection();
76+
expect(result.map((e) => e.id)).toEqual(['new', 'mid', 'old']);
77+
});
78+
79+
it('falls back to updatedAt when activityDate is absent', async () => {
80+
const entries = [
81+
makeEntry({ id: 'a', updatedAt: new Date('2021-01-01') }),
82+
makeEntry({ id: 'b', updatedAt: new Date('2023-01-01') }),
83+
];
84+
mockGetCollection.mockResolvedValue(entries);
85+
86+
const result = await getOutdoorPagesCollection();
87+
expect(result[0]!.id).toBe('b');
88+
expect(result[1]!.id).toBe('a');
89+
});
90+
91+
it('falls back to publishedAt when activityDate and updatedAt are absent', async () => {
92+
const entries = [
93+
makeEntry({ id: 'early', publishedAt: new Date('2020-01-01') }),
94+
makeEntry({ id: 'late', publishedAt: new Date('2024-01-01') }),
95+
];
96+
mockGetCollection.mockResolvedValue(entries);
97+
98+
const result = await getOutdoorPagesCollection();
99+
expect(result[0]!.id).toBe('late');
100+
expect(result[1]!.id).toBe('early');
101+
});
102+
103+
it('does not crash when entries have no date fields', async () => {
104+
const entries = [makeEntry({ id: 'nodates' })];
105+
mockGetCollection.mockResolvedValue(entries);
106+
107+
await expect(getOutdoorPagesCollection()).resolves.toHaveLength(1);
108+
});
109+
});

0 commit comments

Comments
 (0)