Skip to content

Commit 20000e2

Browse files
authored
test: items excluded when not mentioned in order (#367)
1 parent dc6b7cb commit 20000e2

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

packages/astro/src/default/utils/content.spec.ts

+110
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as content from 'astro:content';
22
import { describe, expect, test, vi, type TaskContext } from 'vitest';
33
import { getTutorial, type CollectionEntryTutorial } from './content';
4+
import { logger } from './logger';
45

56
const getCollection = vi.mocked<() => Omit<CollectionEntryTutorial, 'render'>[]>(content.getCollection);
67
vi.mock('astro:content', () => ({ getCollection: vi.fn() }));
@@ -11,6 +12,8 @@ vi.mock(import('@tutorialkit/types'), async (importOriginal) => ({
1112
DEFAULT_LOCALIZATION: { mocked: 'default localization' } as any,
1213
}));
1314

15+
vi.mock(import('./logger'), async (importOriginal) => importOriginal());
16+
1417
expect.addSnapshotSerializer({
1518
serialize: (val) => JSON.stringify(val, null, 2),
1619
test: (value) => !(value instanceof Error),
@@ -95,6 +98,34 @@ test('multiple parts', async (ctx) => {
9598
await expect(collection).toMatchFileSnapshot(snapshotName(ctx));
9699
});
97100

101+
test('lessons with identical names in different chapters', async () => {
102+
getCollection.mockReturnValueOnce([
103+
{ id: 'meta.md', ...tutorial },
104+
{ id: '1-part/meta.md', ...part },
105+
106+
{ id: '1-part/1-chapter/meta.md', ...chapter },
107+
{
108+
id: '1-part/1-chapter/identical-lesson-name/content.md',
109+
...lesson,
110+
data: { ...lesson.data, focus: '/first.js' },
111+
},
112+
113+
{ id: '1-part/2-chapter/meta.md', ...chapter },
114+
{
115+
id: '1-part/2-chapter/identical-lesson-name/content.md',
116+
...lesson,
117+
data: { ...lesson.data, focus: '/second.js' },
118+
},
119+
]);
120+
121+
const collection = await getTutorial();
122+
const chapters = collection.parts['1-part'].chapters;
123+
124+
// verify that lesson.id is not used to define what makes a lesson unique (part.id + chapter.id too)
125+
expect(chapters['1-chapter'].lessons['identical-lesson-name']).toBeDefined();
126+
expect(chapters['2-chapter'].lessons['identical-lesson-name']).toBeDefined();
127+
});
128+
98129
describe('metadata inheriting', () => {
99130
test('lesson inherits metadata from tutorial', async () => {
100131
const data: CollectionEntryTutorial['data'] = {
@@ -212,6 +243,33 @@ describe('ordering', () => {
212243
expect(parts['2-part'].order).toBe(2);
213244
});
214245

246+
test('parts not mention in order are excluded ', async () => {
247+
vi.spyOn(logger, 'warn').mockImplementationOnce(vi.fn());
248+
249+
getCollection.mockReturnValueOnce([
250+
{
251+
id: 'meta.md',
252+
...tutorial,
253+
data: { ...tutorial.data, parts: ['2-part', '1-part'] },
254+
},
255+
{ id: '2-part/meta.md', ...part },
256+
{ id: 'excluded-part/meta.md', ...part },
257+
{ id: '1-part/meta.md', ...part },
258+
]);
259+
260+
const collection = await getTutorial();
261+
const parts = collection.parts;
262+
263+
expect(Object.keys(parts)).toHaveLength(2);
264+
expect(parts['excluded-part']).toBeUndefined();
265+
expect(parts['1-part']).toBeDefined();
266+
expect(parts['2-part']).toBeDefined();
267+
268+
expect(vi.mocked(logger.warn).mock.calls[0][0]).toMatchInlineSnapshot(
269+
`"An order was specified for the parts of the tutorial but 'excluded-part' is not included so it won't be visible."`,
270+
);
271+
});
272+
215273
test('chapters are ordered by default', async () => {
216274
getCollection.mockReturnValueOnce([
217275
{ id: 'meta.md', ...tutorial },
@@ -246,6 +304,30 @@ describe('ordering', () => {
246304
expect(chapters['2-chapter'].order).toBe(2);
247305
});
248306

307+
test('chapters not mention in order are excluded ', async () => {
308+
vi.spyOn(logger, 'warn').mockImplementationOnce(vi.fn());
309+
310+
getCollection.mockReturnValueOnce([
311+
{ id: 'meta.md', ...tutorial },
312+
{ id: '1-part/meta.md', ...part, data: { ...part.data, chapters: ['2-chapter', '1-chapter'] } },
313+
{ id: '1-part/2-chapter/meta.md', ...chapter },
314+
{ id: '1-part/excluded-chapter/meta.md', ...chapter },
315+
{ id: '1-part/1-chapter/meta.md', ...chapter },
316+
]);
317+
318+
const collection = await getTutorial();
319+
const chapters = collection.parts['1-part'].chapters;
320+
321+
expect(Object.keys(chapters)).toHaveLength(2);
322+
expect(chapters['excluded-part']).toBeUndefined();
323+
expect(chapters['1-chapter']).toBeDefined();
324+
expect(chapters['2-chapter']).toBeDefined();
325+
326+
expect(vi.mocked(logger.warn).mock.calls[0][0]).toMatchInlineSnapshot(
327+
`"An order was specified for part '1-part' but chapter 'excluded-chapter' is not included, so it won't be visible."`,
328+
);
329+
});
330+
249331
test('lessons are ordered by default', async () => {
250332
getCollection.mockReturnValueOnce([
251333
{ id: 'meta.md', ...tutorial },
@@ -288,6 +370,34 @@ describe('ordering', () => {
288370
expect(lessons['1-lesson'].order).toBe(1);
289371
expect(lessons['2-lesson'].order).toBe(2);
290372
});
373+
374+
test('lessons not mention in order are excluded ', async () => {
375+
vi.spyOn(logger, 'warn').mockImplementationOnce(vi.fn());
376+
377+
getCollection.mockReturnValueOnce([
378+
{ id: 'meta.md', ...tutorial },
379+
{ id: '1-part/meta.md', ...part },
380+
{
381+
id: '1-part/1-chapter/meta.md',
382+
...chapter,
383+
data: { ...chapter.data, lessons: ['2-lesson', '1-lesson'] },
384+
},
385+
{ id: '1-part/1-chapter/excluded-lesson/meta.md', ...lesson },
386+
{ id: '1-part/1-chapter/1-lesson/meta.md', ...lesson },
387+
{ id: '1-part/1-chapter/2-lesson/meta.md', ...lesson },
388+
]);
389+
390+
const collection = await getTutorial();
391+
const lessons = collection.parts['1-part'].chapters['1-chapter'].lessons;
392+
393+
expect(Object.keys(lessons)).toHaveLength(2);
394+
expect(lessons['1-lesson']).toBeDefined();
395+
expect(lessons['2-lesson']).toBeDefined();
396+
397+
expect(vi.mocked(logger.warn).mock.calls[0][0]).toMatchInlineSnapshot(
398+
`"An order was specified for chapter '1-chapter' but lesson 'excluded-lesson' is not included, so it won't be visible."`,
399+
);
400+
});
291401
});
292402

293403
describe('missing parts', () => {

0 commit comments

Comments
 (0)