feat: add block description to mobile curriculum (#45370)

* feat: add block description to mobile curriculum

* feat: add superblock names
This commit is contained in:
Sem Bauke
2022-03-22 20:11:44 +01:00
committed by GitHub
parent caaa416be0
commit 567e99231f
4 changed files with 125 additions and 11 deletions

View File

@ -177,10 +177,15 @@ async function buildBlocks({ basename: blockName }, curriculum, superBlock) {
__dirname,
`./challenges/_meta/${blockName}/meta.json`
);
let blockMeta;
try {
blockMeta = require(metaPath);
if (fs.existsSync(metaPath)) {
// try to read the file, if the meta path does not exist it should be a certification.
// As they do not have meta files.
const blockMeta = JSON.parse(fs.readFileSync(metaPath));
const { isUpcomingChange } = blockMeta;
if (typeof isUpcomingChange !== 'boolean') {
throw Error(
`meta file at ${metaPath} is missing 'isUpcomingChange', it must be 'true' or 'false'`
@ -192,10 +197,7 @@ async function buildBlocks({ basename: blockName }, curriculum, superBlock) {
const blockInfo = { meta: blockMeta, challenges: [] };
curriculum[superBlock].blocks[blockName] = blockInfo;
}
} catch (e) {
if (e.code !== 'MODULE_NOT_FOUND') {
throw e;
}
} else {
curriculum['certifications'].blocks[blockName] = { challenges: [] };
}
}

View File

@ -3,6 +3,10 @@ const path = require('path');
exports.buildMobileCurriculum = function buildMobileCurriculum(json) {
const mobileStaticPath = path.resolve(__dirname, '../../../client/static');
const blockIntroPath = path.resolve(
__dirname,
'../../../client/i18n/locales/english/intro.json'
);
fs.mkdirSync(`${mobileStaticPath}/mobile`, { recursive: true });
writeAndParseCurriculumJson(json);
@ -12,7 +16,14 @@ exports.buildMobileCurriculum = function buildMobileCurriculum(json) {
key => key !== 'certifications'
);
writeToFile('availableSuperblocks', { superblocks: superBlockKeys });
writeToFile('availableSuperblocks', {
// removing "/" as it will create an extra sub-path when accessed via an endpoint
superblocks: [
superBlockKeys.map(key => key.replace(/\//, '-')),
getSuperBlockNames(superBlockKeys)
]
});
for (let i = 0; i < superBlockKeys.length; i++) {
const superBlock = {};
@ -25,16 +36,32 @@ exports.buildMobileCurriculum = function buildMobileCurriculum(json) {
for (let j = 0; j < blockNames.length; j++) {
superBlock[superBlockKeys[i]]['blocks'][blockNames[j]] = {};
superBlock[superBlockKeys[i]]['blocks'][blockNames[j]]['desc'] =
getBlockDescription(superBlockKeys[i], blockNames[j]);
superBlock[superBlockKeys[i]]['blocks'][blockNames[j]]['challenges'] =
curriculum[superBlockKeys[i]]['blocks'][blockNames[j]]['meta'];
}
writeToFile(superBlockKeys[i], superBlock);
writeToFile(superBlockKeys[i].replace(/\//, '-'), superBlock);
}
}
function writeToFile(filename, json) {
const fullPath = `${mobileStaticPath}/mobile/${filename}.json`;
function getBlockDescription(superBlockKey, blockKey) {
const intros = JSON.parse(fs.readFileSync(blockIntroPath));
return intros[superBlockKey]['blocks'][blockKey]['intro'];
}
function getSuperBlockNames(superBlockKeys) {
const superBlocks = JSON.parse(fs.readFileSync(blockIntroPath));
return superBlockKeys.map(key => superBlocks[key].title);
}
function writeToFile(fileName, json) {
const fullPath = `${mobileStaticPath}/mobile/${fileName}.json`;
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
fs.writeFileSync(fullPath, JSON.stringify(json, null, 2));
}

View File

@ -0,0 +1,53 @@
const path = require('path');
const fs = require('fs');
const { AssertionError } = require('chai');
const { getChallengesForLang } = require('../../../curriculum/getChallenges');
const { buildMobileCurriculum } = require('./build-mobile-curriculum');
const { mobileSchemaValidator } = require('./mobileSchema');
describe('mobile curriculum build', () => {
const mobileStaticPath = path.resolve(__dirname, '../../../client/static');
const blockIntroPath = path.resolve(
__dirname,
'../../../client/i18n/locales/english/intro.json'
);
const validateMobileSuperBlock = mobileSchemaValidator();
let curriculum;
beforeAll(async () => {
curriculum = await getChallengesForLang('english');
await buildMobileCurriculum(curriculum);
}, 20000);
test('the mobile curriculum should have a static folder with multiple files', () => {
expect(fs.existsSync(`${mobileStaticPath}/mobile`)).toBe(true);
expect(fs.readdirSync(`${mobileStaticPath}/mobile`).length).toBeGreaterThan(
0
);
});
test('the mobile curriculum should have access to the intro.json file', () => {
expect(fs.existsSync(blockIntroPath)).toBe(true);
});
test('the files generated should have the correct schema', () => {
const fileArray = fs.readdirSync(`${mobileStaticPath}/mobile`);
fileArray
.filter(fileInArray => fileInArray !== 'availableSuperblocks.json')
.forEach(fileInArray => {
const fileContent = fs.readFileSync(
`${mobileStaticPath}/mobile/${fileInArray}`
);
const result = validateMobileSuperBlock(JSON.parse(fileContent));
if (result.error) {
throw new AssertionError(result.error, `file: ${fileInArray}`);
}
});
});
});

View File

@ -0,0 +1,32 @@
const Joi = require('joi');
const blockSchema = Joi.object({}).keys({
desc: Joi.array().min(1),
challenges: Joi.object({}).keys({
name: Joi.string(),
isUpcomingChange: Joi.bool(),
usesMultifileEditor: Joi.bool().optional(),
hasEditableBoundaries: Joi.bool().optional(),
isBeta: Joi.bool().optional(),
dashedName: Joi.string(),
order: Joi.number(),
time: Joi.string().allow(''),
template: Joi.string().allow(''),
required: Joi.array(),
superBlock: Joi.string(),
challengeOrder: Joi.array().items(Joi.array().min(1))
})
});
const subSchema = Joi.object({}).keys({
blocks: Joi.object({}).pattern(Joi.string(), Joi.object().concat(blockSchema))
});
const schema = Joi.object({}).pattern(
Joi.string(),
Joi.object().concat(subSchema)
);
exports.mobileSchemaValidator = () => {
return superblock => schema.validate(superblock);
};