mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
fix(tools): ensure module name is available in external curricula data (#60610)
This commit is contained in:
@@ -1787,6 +1787,7 @@
|
|||||||
"css-variables": "Variables",
|
"css-variables": "Variables",
|
||||||
"css-grid": "Grid",
|
"css-grid": "Grid",
|
||||||
"css-animations": "Animations",
|
"css-animations": "Animations",
|
||||||
|
"review-css": "CSS Review",
|
||||||
"exam-css": "CSS Exam",
|
"exam-css": "CSS Exam",
|
||||||
"code-editors": "Code Editors",
|
"code-editors": "Code Editors",
|
||||||
"javascript-variables-and-strings": "Variables and Strings",
|
"javascript-variables-and-strings": "Variables and Strings",
|
||||||
@@ -1809,6 +1810,7 @@
|
|||||||
"recursion": "Recursion",
|
"recursion": "Recursion",
|
||||||
"functional-programming": "Functional Programming",
|
"functional-programming": "Functional Programming",
|
||||||
"asynchronous-javascript": "Asynchronous JavaScript",
|
"asynchronous-javascript": "Asynchronous JavaScript",
|
||||||
|
"review-javascript": "JavaScript Review",
|
||||||
"exam-javascript": "JavaScript Exam",
|
"exam-javascript": "JavaScript Exam",
|
||||||
"react-fundamentals": "React Fundamentals",
|
"react-fundamentals": "React Fundamentals",
|
||||||
"react-state-hooks-and-routing": "React State, Hooks, and Routing",
|
"react-state-hooks-and-routing": "React State, Hooks, and Routing",
|
||||||
|
|||||||
@@ -74,18 +74,25 @@ ${result.error.message}`
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('the super block files generated should have the correct schema', async () => {
|
test('the super block files generated should have the correct schema', async () => {
|
||||||
|
const superBlocks = Object.values(SuperBlocks);
|
||||||
|
|
||||||
const fileArray = (
|
const fileArray = (
|
||||||
await readdirp.promise(`${clientStaticPath}/curriculum-data/${VERSION}`, {
|
await readdirp.promise(`${clientStaticPath}/curriculum-data/${VERSION}`, {
|
||||||
directoryFilter: ['!challenges'],
|
directoryFilter: ['!challenges'],
|
||||||
fileFilter: entry => {
|
fileFilter: entry => {
|
||||||
// The directory contains super block files and other curriculum-related files.
|
// The directory contains super block files and other curriculum-related files.
|
||||||
// We're only interested in super block ones.
|
// We're only interested in super block ones.
|
||||||
const superBlocks = Object.values(SuperBlocks);
|
const isSuperBlock = superBlocks.some(superBlock =>
|
||||||
return superBlocks.includes(entry.basename);
|
entry.basename.includes(superBlock)
|
||||||
|
);
|
||||||
|
|
||||||
|
return isSuperBlock;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
).map(file => file.path);
|
).map(file => file.path);
|
||||||
|
|
||||||
|
expect(fileArray.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
fileArray.forEach(fileInArray => {
|
fileArray.forEach(fileInArray => {
|
||||||
const fileContent = fs.readFileSync(
|
const fileContent = fs.readFileSync(
|
||||||
`${clientStaticPath}/curriculum-data/${VERSION}/${fileInArray}`,
|
`${clientStaticPath}/curriculum-data/${VERSION}/${fileInArray}`,
|
||||||
@@ -102,21 +109,30 @@ ${result.error.message}`);
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('block-based super blocks and blocks should have the correct data', async () => {
|
test('block-based super blocks and blocks should have the correct data', async () => {
|
||||||
|
const superBlocks = Object.values(SuperBlocks);
|
||||||
|
|
||||||
const superBlockFiles = (
|
const superBlockFiles = (
|
||||||
await readdirp.promise(`${clientStaticPath}/curriculum-data/${VERSION}`, {
|
await readdirp.promise(`${clientStaticPath}/curriculum-data/${VERSION}`, {
|
||||||
directoryFilter: ['!challenges'],
|
directoryFilter: ['!challenges'],
|
||||||
fileFilter: entry => {
|
fileFilter: entry => {
|
||||||
// The directory contains super block files and other curriculum-related files.
|
// The directory contains super block files and other curriculum-related files.
|
||||||
// We're only interested in super block ones.
|
// We're only interested in super block ones.
|
||||||
const superBlocks = Object.values(SuperBlocks);
|
const isSuperBlock = superBlocks.some(superBlock =>
|
||||||
return (
|
entry.basename.includes(superBlock)
|
||||||
superBlocks.includes(entry.basename) &&
|
|
||||||
!chapterBasedSuperBlocks.includes(entry.basename)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isChapterBasedSuperBlock = chapterBasedSuperBlocks.some(
|
||||||
|
chapterBasedSuperBlock =>
|
||||||
|
entry.basename.includes(chapterBasedSuperBlock)
|
||||||
|
);
|
||||||
|
|
||||||
|
return isSuperBlock && !isChapterBasedSuperBlock;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
).map(file => file.path);
|
).map(file => file.path);
|
||||||
|
|
||||||
|
expect(superBlockFiles.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
superBlockFiles.forEach(file => {
|
superBlockFiles.forEach(file => {
|
||||||
const fileContentJson = fs.readFileSync(
|
const fileContentJson = fs.readFileSync(
|
||||||
`${clientStaticPath}/curriculum-data/${VERSION}/${file}`,
|
`${clientStaticPath}/curriculum-data/${VERSION}/${file}`,
|
||||||
@@ -135,33 +151,43 @@ ${result.error.message}`);
|
|||||||
// Randomly pick a block to check its data.
|
// Randomly pick a block to check its data.
|
||||||
const blocks = superBlockData.blocks;
|
const blocks = superBlockData.blocks;
|
||||||
const randomBlockIndex = Math.floor(Math.random() * blocks.length);
|
const randomBlockIndex = Math.floor(Math.random() * blocks.length);
|
||||||
|
const randomBlock = blocks[randomBlockIndex];
|
||||||
|
|
||||||
expect(superBlockData.intro).toEqual(intros[superBlock].intro);
|
expect(superBlockData.intro).toEqual(intros[superBlock].intro);
|
||||||
expect(superBlockData.blocks[randomBlockIndex].intro).toEqual(
|
expect(superBlockData.blocks[randomBlockIndex].intro).toEqual(
|
||||||
intros[superBlock].blocks[randomBlockIndex].intro
|
intros[superBlock].blocks[randomBlock.meta.dashedName as string].intro
|
||||||
);
|
);
|
||||||
expect(superBlockData.blocks[randomBlockIndex].meta.name).toEqual(
|
expect(superBlockData.blocks[randomBlockIndex].meta.name).toEqual(
|
||||||
intros[superBlock].blocks[randomBlockIndex].title
|
intros[superBlock].blocks[randomBlock.meta.dashedName as string].title
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('chapter-based super blocks and blocks should have the correct data', async () => {
|
test('chapter-based super blocks and blocks should have the correct data', async () => {
|
||||||
|
const superBlocks = Object.values(SuperBlocks);
|
||||||
|
|
||||||
const superBlockFiles = (
|
const superBlockFiles = (
|
||||||
await readdirp.promise(`${clientStaticPath}/curriculum-data/${VERSION}`, {
|
await readdirp.promise(`${clientStaticPath}/curriculum-data/${VERSION}`, {
|
||||||
directoryFilter: ['!challenges'],
|
directoryFilter: ['!challenges'],
|
||||||
fileFilter: entry => {
|
fileFilter: entry => {
|
||||||
// The directory contains super block files and other curriculum-related files.
|
// The directory contains super block files and other curriculum-related files.
|
||||||
// We're only interested in super block ones.
|
// We're only interested in super block ones.
|
||||||
const superBlocks = Object.values(SuperBlocks);
|
const isSuperBlock = superBlocks.some(superBlock =>
|
||||||
return (
|
entry.basename.includes(superBlock)
|
||||||
superBlocks.includes(entry.basename) &&
|
|
||||||
chapterBasedSuperBlocks.includes(entry.basename)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isChapterBasedSuperBlock = chapterBasedSuperBlocks.some(
|
||||||
|
chapterBasedSuperBlock =>
|
||||||
|
entry.basename.includes(chapterBasedSuperBlock)
|
||||||
|
);
|
||||||
|
|
||||||
|
return isSuperBlock && isChapterBasedSuperBlock;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
).map(file => file.path);
|
).map(file => file.path);
|
||||||
|
|
||||||
|
expect(superBlockFiles.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
superBlockFiles.forEach(file => {
|
superBlockFiles.forEach(file => {
|
||||||
const fileContentJson = fs.readFileSync(
|
const fileContentJson = fs.readFileSync(
|
||||||
`${clientStaticPath}/curriculum-data/${VERSION}/${file}`,
|
`${clientStaticPath}/curriculum-data/${VERSION}/${file}`,
|
||||||
@@ -182,42 +208,51 @@ ${result.error.message}`);
|
|||||||
] as ChapterBasedCurriculumIntros[SuperBlocks];
|
] as ChapterBasedCurriculumIntros[SuperBlocks];
|
||||||
|
|
||||||
// Randomly pick a chapter.
|
// Randomly pick a chapter.
|
||||||
const chapters = superBlockData.chapters;
|
const chapters = superBlockData.chapters.filter(
|
||||||
|
({ comingSoon }) => !comingSoon
|
||||||
|
);
|
||||||
const randomChapterIndex = Math.floor(Math.random() * chapters.length);
|
const randomChapterIndex = Math.floor(Math.random() * chapters.length);
|
||||||
const randomChapter = chapters[randomChapterIndex];
|
const randomChapter = chapters[randomChapterIndex];
|
||||||
|
|
||||||
// Randomly pick a module.
|
// Randomly pick a module.
|
||||||
const modules = randomChapter.modules;
|
const modules = randomChapter.modules.filter(
|
||||||
|
({ comingSoon }) => !comingSoon
|
||||||
|
);
|
||||||
const randomModuleIndex = Math.floor(Math.random() * modules.length);
|
const randomModuleIndex = Math.floor(Math.random() * modules.length);
|
||||||
const randomModule = modules[randomModuleIndex];
|
const randomModule = modules[randomModuleIndex];
|
||||||
|
|
||||||
// Randomly pick a block.
|
// Randomly pick a block.
|
||||||
const blocks = randomModule.blocks;
|
const blocks = randomModule.blocks;
|
||||||
const randomBlockIndex = Math.floor(Math.random() * blocks.length);
|
const randomBlockIndex = Math.floor(Math.random() * blocks.length);
|
||||||
|
const randomBlock = blocks[randomBlockIndex];
|
||||||
|
|
||||||
// Check super block data
|
// Check super block data
|
||||||
expect(superBlockData.intro).toEqual(superBlockIntros.intro);
|
expect(superBlockData.intro).toEqual(superBlockIntros.intro);
|
||||||
|
|
||||||
// Check chapter data
|
// Check chapter data
|
||||||
expect(superBlockData.chapters[randomChapterIndex].name).toEqual(
|
expect(superBlockData.chapters[randomChapterIndex].name).toEqual(
|
||||||
superBlockIntros.chapters[randomChapterIndex]
|
superBlockIntros.chapters[randomChapter.dashedName]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Check module data
|
// Check module data
|
||||||
expect(
|
expect(
|
||||||
superBlockData.chapters[randomChapterIndex].modules[randomModuleIndex]
|
superBlockData.chapters[randomChapterIndex].modules[randomModuleIndex]
|
||||||
.name
|
.name
|
||||||
).toEqual(superBlockIntros.modules[randomModuleIndex]);
|
).toEqual(superBlockIntros.modules[randomModule.dashedName]);
|
||||||
|
|
||||||
// Check block data
|
// Check block data
|
||||||
expect(
|
expect(
|
||||||
superBlockData.chapters[randomChapterIndex].modules[randomModuleIndex]
|
superBlockData.chapters[randomChapterIndex].modules[randomModuleIndex]
|
||||||
.blocks[randomBlockIndex].intro
|
.blocks[randomBlockIndex].intro
|
||||||
).toEqual(superBlockIntros.blocks[randomBlockIndex].intro);
|
).toEqual(
|
||||||
|
superBlockIntros.blocks[randomBlock.meta.dashedName as string].intro
|
||||||
|
);
|
||||||
expect(
|
expect(
|
||||||
superBlockData.chapters[randomChapterIndex].modules[randomModuleIndex]
|
superBlockData.chapters[randomChapterIndex].modules[randomModuleIndex]
|
||||||
.blocks[randomBlockIndex].meta.name
|
.blocks[randomBlockIndex].meta.name
|
||||||
).toEqual(superBlockIntros.blocks[randomBlockIndex].title);
|
).toEqual(
|
||||||
|
superBlockIntros.blocks[randomBlock.meta.dashedName as string].title
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user