feat: update Ask for help (#40114)
* feat: get helpCategory from frontmatter * DEBUG: sets all the projects to JavaScript This is just so the tests pass, it'll need to go. * fix: updated helpCategoryMap categories * fix: added Python to helpCategory frontmatter key Co-authored-by: Randell Dawson <rdawson@onepathtech.com>
This commit is contained in:
committed by
GitHub
parent
7857dc53f4
commit
e4a9b2988c
@ -35,6 +35,7 @@ export const ChallengeNode = PropTypes.shape({
|
|||||||
forumTopicId: PropTypes.number,
|
forumTopicId: PropTypes.number,
|
||||||
guideUrl: PropTypes.string,
|
guideUrl: PropTypes.string,
|
||||||
head: PropTypes.arrayOf(PropTypes.string),
|
head: PropTypes.arrayOf(PropTypes.string),
|
||||||
|
helpCategory: PropTypes.string,
|
||||||
instructions: PropTypes.string,
|
instructions: PropTypes.string,
|
||||||
isComingSoon: PropTypes.bool,
|
isComingSoon: PropTypes.bool,
|
||||||
isLocked: PropTypes.bool,
|
isLocked: PropTypes.bool,
|
||||||
|
@ -153,7 +153,8 @@ class ShowClassic extends Component {
|
|||||||
challengeNode: {
|
challengeNode: {
|
||||||
files,
|
files,
|
||||||
fields: { tests },
|
fields: { tests },
|
||||||
challengeType
|
challengeType,
|
||||||
|
helpCategory
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pageContext: { challengeMeta }
|
pageContext: { challengeMeta }
|
||||||
@ -161,7 +162,12 @@ class ShowClassic extends Component {
|
|||||||
initConsole('');
|
initConsole('');
|
||||||
createFiles(files);
|
createFiles(files);
|
||||||
initTests(tests);
|
initTests(tests);
|
||||||
updateChallengeMeta({ ...challengeMeta, title, challengeType });
|
updateChallengeMeta({
|
||||||
|
...challengeMeta,
|
||||||
|
title,
|
||||||
|
challengeType,
|
||||||
|
helpCategory
|
||||||
|
});
|
||||||
challengeMounted(challengeMeta.id);
|
challengeMounted(challengeMeta.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,6 +347,7 @@ export const query = graphql`
|
|||||||
description
|
description
|
||||||
instructions
|
instructions
|
||||||
challengeType
|
challengeType
|
||||||
|
helpCategory
|
||||||
videoUrl
|
videoUrl
|
||||||
forumTopicId
|
forumTopicId
|
||||||
fields {
|
fields {
|
||||||
|
@ -123,14 +123,20 @@ export class BackEnd extends Component {
|
|||||||
challengeNode: {
|
challengeNode: {
|
||||||
fields: { tests },
|
fields: { tests },
|
||||||
title,
|
title,
|
||||||
challengeType
|
challengeType,
|
||||||
|
helpCategory
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pageContext: { challengeMeta }
|
pageContext: { challengeMeta }
|
||||||
} = this.props;
|
} = this.props;
|
||||||
initConsole();
|
initConsole();
|
||||||
initTests(tests);
|
initTests(tests);
|
||||||
updateChallengeMeta({ ...challengeMeta, title, challengeType });
|
updateChallengeMeta({
|
||||||
|
...challengeMeta,
|
||||||
|
title,
|
||||||
|
challengeType,
|
||||||
|
helpCategory
|
||||||
|
});
|
||||||
challengeMounted(challengeMeta.id);
|
challengeMounted(challengeMeta.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +230,7 @@ export const query = graphql`
|
|||||||
description
|
description
|
||||||
instructions
|
instructions
|
||||||
challengeType
|
challengeType
|
||||||
|
helpCategory
|
||||||
fields {
|
fields {
|
||||||
blockName
|
blockName
|
||||||
slug
|
slug
|
||||||
|
@ -55,12 +55,17 @@ export class Project extends Component {
|
|||||||
const {
|
const {
|
||||||
challengeMounted,
|
challengeMounted,
|
||||||
data: {
|
data: {
|
||||||
challengeNode: { title, challengeType }
|
challengeNode: { title, challengeType, helpCategory }
|
||||||
},
|
},
|
||||||
pageContext: { challengeMeta },
|
pageContext: { challengeMeta },
|
||||||
updateChallengeMeta
|
updateChallengeMeta
|
||||||
} = this.props;
|
} = this.props;
|
||||||
updateChallengeMeta({ ...challengeMeta, title, challengeType });
|
updateChallengeMeta({
|
||||||
|
...challengeMeta,
|
||||||
|
title,
|
||||||
|
challengeType,
|
||||||
|
helpCategory
|
||||||
|
});
|
||||||
challengeMounted(challengeMeta.id);
|
challengeMounted(challengeMeta.id);
|
||||||
this._container.focus();
|
this._container.focus();
|
||||||
}
|
}
|
||||||
@ -74,7 +79,7 @@ export class Project extends Component {
|
|||||||
const {
|
const {
|
||||||
challengeMounted,
|
challengeMounted,
|
||||||
data: {
|
data: {
|
||||||
challengeNode: { title: currentTitle, challengeType }
|
challengeNode: { title: currentTitle, challengeType, helpCategory }
|
||||||
},
|
},
|
||||||
pageContext: { challengeMeta },
|
pageContext: { challengeMeta },
|
||||||
updateChallengeMeta
|
updateChallengeMeta
|
||||||
@ -83,7 +88,8 @@ export class Project extends Component {
|
|||||||
updateChallengeMeta({
|
updateChallengeMeta({
|
||||||
...challengeMeta,
|
...challengeMeta,
|
||||||
title: currentTitle,
|
title: currentTitle,
|
||||||
challengeType
|
challengeType,
|
||||||
|
helpCategory
|
||||||
});
|
});
|
||||||
challengeMounted(challengeMeta.id);
|
challengeMounted(challengeMeta.id);
|
||||||
}
|
}
|
||||||
@ -161,6 +167,7 @@ export const query = graphql`
|
|||||||
title
|
title
|
||||||
description
|
description
|
||||||
challengeType
|
challengeType
|
||||||
|
helpCategory
|
||||||
fields {
|
fields {
|
||||||
blockName
|
blockName
|
||||||
slug
|
slug
|
||||||
|
@ -7,7 +7,6 @@ import {
|
|||||||
challengeMetaSelector
|
challengeMetaSelector
|
||||||
} from '../redux';
|
} from '../redux';
|
||||||
import { tap, mapTo } from 'rxjs/operators';
|
import { tap, mapTo } from 'rxjs/operators';
|
||||||
import { helpCategory } from '../../../../utils/challengeTypes';
|
|
||||||
import { forumLocation } from '../../../../../config/env.json';
|
import { forumLocation } from '../../../../../config/env.json';
|
||||||
|
|
||||||
function filesToMarkdown(files = {}) {
|
function filesToMarkdown(files = {}) {
|
||||||
@ -29,7 +28,9 @@ function createQuestionEpic(action$, state$, { window }) {
|
|||||||
tap(() => {
|
tap(() => {
|
||||||
const state = state$.value;
|
const state = state$.value;
|
||||||
const files = challengeFilesSelector(state);
|
const files = challengeFilesSelector(state);
|
||||||
const { block, title: challengeTitle } = challengeMetaSelector(state);
|
const { title: challengeTitle, helpCategory } = challengeMetaSelector(
|
||||||
|
state
|
||||||
|
);
|
||||||
const {
|
const {
|
||||||
navigator: { userAgent },
|
navigator: { userAgent },
|
||||||
location: { href }
|
location: { href }
|
||||||
@ -69,13 +70,13 @@ function createQuestionEpic(action$, state$, { window }) {
|
|||||||
\`\`\`
|
\`\`\`
|
||||||
|
|
||||||
Replace these two sentences with your copied code.
|
Replace these two sentences with your copied code.
|
||||||
Please leave the \`\`\` line above and the \`\`\` line below,
|
Please leave the \`\`\` line above and the \`\`\` line below,
|
||||||
because they allow your code to properly format in the post.
|
because they allow your code to properly format in the post.
|
||||||
|
|
||||||
\`\`\`\n${endingText}`
|
\`\`\`\n${endingText}`
|
||||||
);
|
);
|
||||||
|
|
||||||
const category = window.encodeURIComponent(helpCategory[block] || 'Help');
|
const category = window.encodeURIComponent(helpCategory || 'Help');
|
||||||
|
|
||||||
const studentCode = window.encodeURIComponent(textMessage);
|
const studentCode = window.encodeURIComponent(textMessage);
|
||||||
const altStudentCode = window.encodeURIComponent(altTextMessage);
|
const altStudentCode = window.encodeURIComponent(altTextMessage);
|
||||||
|
@ -85,12 +85,17 @@ export class Project extends Component {
|
|||||||
const {
|
const {
|
||||||
challengeMounted,
|
challengeMounted,
|
||||||
data: {
|
data: {
|
||||||
challengeNode: { title, challengeType }
|
challengeNode: { title, challengeType, helpCategory }
|
||||||
},
|
},
|
||||||
pageContext: { challengeMeta },
|
pageContext: { challengeMeta },
|
||||||
updateChallengeMeta
|
updateChallengeMeta
|
||||||
} = this.props;
|
} = this.props;
|
||||||
updateChallengeMeta({ ...challengeMeta, title, challengeType });
|
updateChallengeMeta({
|
||||||
|
...challengeMeta,
|
||||||
|
title,
|
||||||
|
challengeType,
|
||||||
|
helpCategory
|
||||||
|
});
|
||||||
challengeMounted(challengeMeta.id);
|
challengeMounted(challengeMeta.id);
|
||||||
this._container.focus();
|
this._container.focus();
|
||||||
}
|
}
|
||||||
@ -104,7 +109,7 @@ export class Project extends Component {
|
|||||||
const {
|
const {
|
||||||
challengeMounted,
|
challengeMounted,
|
||||||
data: {
|
data: {
|
||||||
challengeNode: { title: currentTitle, challengeType }
|
challengeNode: { title: currentTitle, challengeType, helpCategory }
|
||||||
},
|
},
|
||||||
pageContext: { challengeMeta },
|
pageContext: { challengeMeta },
|
||||||
updateChallengeMeta
|
updateChallengeMeta
|
||||||
@ -113,7 +118,8 @@ export class Project extends Component {
|
|||||||
updateChallengeMeta({
|
updateChallengeMeta({
|
||||||
...challengeMeta,
|
...challengeMeta,
|
||||||
title: currentTitle,
|
title: currentTitle,
|
||||||
challengeType
|
challengeType,
|
||||||
|
helpCategory
|
||||||
});
|
});
|
||||||
challengeMounted(challengeMeta.id);
|
challengeMounted(challengeMeta.id);
|
||||||
}
|
}
|
||||||
@ -305,6 +311,7 @@ export const query = graphql`
|
|||||||
title
|
title
|
||||||
description
|
description
|
||||||
challengeType
|
challengeType
|
||||||
|
helpCategory
|
||||||
fields {
|
fields {
|
||||||
blockName
|
blockName
|
||||||
slug
|
slug
|
||||||
|
@ -76,7 +76,7 @@ exports.submitTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// determine which help forum questions should be posted to
|
// determine which help forum questions should be posted to
|
||||||
exports.helpCategory = {
|
exports.helpCategoryMap = {
|
||||||
'basic-html-and-html5': 'HTML-CSS',
|
'basic-html-and-html5': 'HTML-CSS',
|
||||||
'basic-css': 'HTML-CSS',
|
'basic-css': 'HTML-CSS',
|
||||||
'applied-visual-design': 'HTML-CSS',
|
'applied-visual-design': 'HTML-CSS',
|
||||||
@ -84,7 +84,7 @@ exports.helpCategory = {
|
|||||||
'responsive-web-design-principles': 'HTML-CSS',
|
'responsive-web-design-principles': 'HTML-CSS',
|
||||||
'css-flexbox': 'HTML-CSS',
|
'css-flexbox': 'HTML-CSS',
|
||||||
'css-grid': 'HTML-CSS',
|
'css-grid': 'HTML-CSS',
|
||||||
'responsive-web-design-projects': 'Certification Projects',
|
'responsive-web-design-projects': 'HTML-CSS',
|
||||||
'basic-javascript': 'JavaScript',
|
'basic-javascript': 'JavaScript',
|
||||||
es6: 'JavaScript',
|
es6: 'JavaScript',
|
||||||
'regular-expressions': 'JavaScript',
|
'regular-expressions': 'JavaScript',
|
||||||
@ -94,38 +94,37 @@ exports.helpCategory = {
|
|||||||
'object-oriented-programming': 'JavaScript',
|
'object-oriented-programming': 'JavaScript',
|
||||||
'functional-programming': 'JavaScript',
|
'functional-programming': 'JavaScript',
|
||||||
'intermediate-algorithm-scripting': 'JavaScript',
|
'intermediate-algorithm-scripting': 'JavaScript',
|
||||||
'javascript-algorithms-and-data-structures-projects':
|
'javascript-algorithms-and-data-structures-projects': 'JavaScript',
|
||||||
'Certification Projects',
|
|
||||||
bootstrap: 'HTML-CSS',
|
bootstrap: 'HTML-CSS',
|
||||||
jquery: 'JavaScript',
|
jquery: 'JavaScript',
|
||||||
sass: 'HTML-CSS',
|
sass: 'HTML-CSS',
|
||||||
react: 'JavaScript',
|
react: 'JavaScript',
|
||||||
redux: 'JavaScript',
|
redux: 'JavaScript',
|
||||||
'react-and-redux': 'JavaScript',
|
'react-and-redux': 'JavaScript',
|
||||||
'front-end-libraries-projects': 'Certification Projects',
|
'front-end-libraries-projects': 'JavaScript',
|
||||||
'data-visualization-with-d3': 'JavaScript',
|
'data-visualization-with-d3': 'JavaScript',
|
||||||
'json-apis-and-ajax': 'JavaScript',
|
'json-apis-and-ajax': 'JavaScript',
|
||||||
'data-visualization-projects': 'Certification Projects',
|
'data-visualization-projects': 'JavaScript',
|
||||||
'managing-packages-with-npm': 'JavaScript',
|
'managing-packages-with-npm': 'JavaScript',
|
||||||
'basic-node-and-express': 'JavaScript',
|
'basic-node-and-express': 'JavaScript',
|
||||||
'mongodb-and-mongoose': 'JavaScript',
|
'mongodb-and-mongoose': 'JavaScript',
|
||||||
'apis-and-microservices-projects': 'Certification Projects',
|
'apis-and-microservices-projects': 'JavaScript',
|
||||||
'information-security-with-helmetjs': 'JavaScript',
|
'information-security-with-helmetjs': 'JavaScript',
|
||||||
'quality-assurance-and-testing-with-chai': 'JavaScript',
|
'quality-assurance-and-testing-with-chai': 'JavaScript',
|
||||||
'advanced-node-and-express': 'JavaScript',
|
'advanced-node-and-express': 'JavaScript',
|
||||||
'quality-assurance-projects': 'Certification Projects',
|
'quality-assurance-projects': 'JavaScript',
|
||||||
'information-security-projects': 'Certification Projects',
|
'information-security-projects': 'JavaScript',
|
||||||
algorithms: 'JavaScript',
|
algorithms: 'JavaScript',
|
||||||
'data-structures': 'JavaScript',
|
'data-structures': 'JavaScript',
|
||||||
'take-home-projects': 'Certification Projects',
|
'take-home-projects': 'JavaScript',
|
||||||
'rosetta-code': 'JavaScript',
|
'rosetta-code': 'JavaScript',
|
||||||
'project-euler': 'JavaScript',
|
'project-euler': 'JavaScript',
|
||||||
'scientific-computing-with-python': 'Python',
|
'scientific-computing-with-python': 'Python',
|
||||||
'scientific-computing-with-python-projects': 'Certification Projects',
|
'scientific-computing-with-python-projects': 'Python',
|
||||||
'data-analysis-with-python': 'Python',
|
'data-analysis-with-python': 'Python',
|
||||||
'data-analysis-with-python-projects': 'Certification Projects',
|
'data-analysis-with-python-projects': 'Python',
|
||||||
'machine-learning-with-python': 'Python',
|
'machine-learning-with-python': 'Python',
|
||||||
'machine-learning-with-python-projects': 'Certification Projects',
|
'machine-learning-with-python-projects': 'Python',
|
||||||
'python-for-everybody': 'Python',
|
'python-for-everybody': 'Python',
|
||||||
tensorflow: 'Python',
|
tensorflow: 'Python',
|
||||||
'how-neural-networks-work': 'Python',
|
'how-neural-networks-work': 'Python',
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
id: 5e46f979ac417301a38fb932
|
id: 5e46f979ac417301a38fb932
|
||||||
title: Port Scanner
|
title: Port Scanner
|
||||||
challengeType: 10
|
challengeType: 10
|
||||||
|
helpCategory: Python
|
||||||
---
|
---
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
id: 5e46f983ac417301a38fb933
|
id: 5e46f983ac417301a38fb933
|
||||||
title: SHA-1 Password Cracker
|
title: SHA-1 Password Cracker
|
||||||
challengeType: 10
|
challengeType: 10
|
||||||
|
helpCategory: Python
|
||||||
---
|
---
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
@ -16,6 +16,7 @@ const { dasherize, nameify } = require('../utils/slugs');
|
|||||||
const { createPoly } = require('../utils/polyvinyl');
|
const { createPoly } = require('../utils/polyvinyl');
|
||||||
const { blockNameify } = require('../utils/block-nameify');
|
const { blockNameify } = require('../utils/block-nameify');
|
||||||
const { supportedLangs } = require('./utils');
|
const { supportedLangs } = require('./utils');
|
||||||
|
const { helpCategoryMap } = require('../client/utils/challengeTypes');
|
||||||
|
|
||||||
const access = util.promisify(fs.access);
|
const access = util.promisify(fs.access);
|
||||||
|
|
||||||
@ -275,6 +276,8 @@ ${getFullPath('english')}
|
|||||||
challenge.required = required.concat(challenge.required || []);
|
challenge.required = required.concat(challenge.required || []);
|
||||||
challenge.template = template;
|
challenge.template = template;
|
||||||
challenge.time = time;
|
challenge.time = time;
|
||||||
|
challenge.helpCategory =
|
||||||
|
challenge.helpCategory || helpCategoryMap[dasherize(blockName)];
|
||||||
|
|
||||||
return prepareChallenge(challenge);
|
return prepareChallenge(challenge);
|
||||||
};
|
};
|
||||||
|
@ -17,89 +17,92 @@ const fileJoi = Joi.object().keys({
|
|||||||
history: [Joi.array().items(Joi.string().allow('')), Joi.string().allow('')]
|
history: [Joi.array().items(Joi.string().allow('')), Joi.string().allow('')]
|
||||||
});
|
});
|
||||||
|
|
||||||
const schema = Joi.object().keys({
|
const schema = Joi.object()
|
||||||
block: Joi.string(),
|
.keys({
|
||||||
blockId: Joi.objectId(),
|
block: Joi.string(),
|
||||||
challengeOrder: Joi.number(),
|
blockId: Joi.objectId(),
|
||||||
challengeType: Joi.number()
|
challengeOrder: Joi.number(),
|
||||||
.min(0)
|
challengeType: Joi.number()
|
||||||
.max(11)
|
.min(0)
|
||||||
.required(),
|
.max(11)
|
||||||
checksum: Joi.number(),
|
|
||||||
dashedName: Joi.string(),
|
|
||||||
description: Joi.when('challengeType', {
|
|
||||||
is: Joi.only([challengeTypes.step, challengeTypes.video]),
|
|
||||||
then: Joi.string().allow(''),
|
|
||||||
otherwise: Joi.string().required()
|
|
||||||
}),
|
|
||||||
fileName: Joi.string(),
|
|
||||||
files: Joi.object().keys({
|
|
||||||
indexcss: fileJoi,
|
|
||||||
indexhtml: fileJoi,
|
|
||||||
indexjs: fileJoi,
|
|
||||||
indexjsx: fileJoi
|
|
||||||
}),
|
|
||||||
guideUrl: Joi.string().uri({ scheme: 'https' }),
|
|
||||||
videoUrl: Joi.string().allow(''),
|
|
||||||
forumTopicId: Joi.number(),
|
|
||||||
helpRoom: Joi.string(),
|
|
||||||
id: Joi.objectId().required(),
|
|
||||||
instructions: Joi.string().allow(''),
|
|
||||||
isComingSoon: Joi.bool(),
|
|
||||||
isLocked: Joi.bool(),
|
|
||||||
isPrivate: Joi.bool(),
|
|
||||||
name: Joi.string(),
|
|
||||||
order: Joi.number(),
|
|
||||||
// video challenges only:
|
|
||||||
videoId: Joi.when('challengeType', {
|
|
||||||
is: challengeTypes.video,
|
|
||||||
then: Joi.string().required()
|
|
||||||
}),
|
|
||||||
question: Joi.object().keys({
|
|
||||||
text: Joi.string().required(),
|
|
||||||
answers: Joi.array()
|
|
||||||
.items(Joi.string())
|
|
||||||
.required(),
|
.required(),
|
||||||
solution: Joi.number().required()
|
checksum: Joi.number(),
|
||||||
}),
|
dashedName: Joi.string(),
|
||||||
required: Joi.array().items(
|
description: Joi.when('challengeType', {
|
||||||
Joi.object().keys({
|
is: Joi.only([challengeTypes.step, challengeTypes.video]),
|
||||||
link: Joi.string(),
|
then: Joi.string().allow(''),
|
||||||
raw: Joi.bool(),
|
otherwise: Joi.string().required()
|
||||||
src: Joi.string(),
|
}),
|
||||||
crossDomain: Joi.bool()
|
fileName: Joi.string(),
|
||||||
})
|
files: Joi.object().keys({
|
||||||
),
|
|
||||||
solutions: Joi.array().items(
|
|
||||||
Joi.object().keys({
|
|
||||||
indexcss: fileJoi,
|
indexcss: fileJoi,
|
||||||
indexhtml: fileJoi,
|
indexhtml: fileJoi,
|
||||||
indexjs: fileJoi,
|
indexjs: fileJoi,
|
||||||
indexjsx: fileJoi,
|
indexjsx: fileJoi
|
||||||
indexpy: fileJoi
|
|
||||||
})
|
|
||||||
),
|
|
||||||
superBlock: Joi.string(),
|
|
||||||
superOrder: Joi.number(),
|
|
||||||
suborder: Joi.number(),
|
|
||||||
tests: Joi.array().items(
|
|
||||||
// public challenges
|
|
||||||
Joi.object().keys({
|
|
||||||
text: Joi.string().required(),
|
|
||||||
testString: Joi.string()
|
|
||||||
.allow('')
|
|
||||||
.required()
|
|
||||||
}),
|
}),
|
||||||
// our tests used in certification verification
|
guideUrl: Joi.string().uri({ scheme: 'https' }),
|
||||||
Joi.object().keys({
|
helpCategory: Joi.only(['JavaScript', 'HTML-CSS', 'Python']),
|
||||||
id: Joi.string().required(),
|
videoUrl: Joi.string().allow(''),
|
||||||
title: Joi.string().required()
|
forumTopicId: Joi.number(),
|
||||||
})
|
helpRoom: Joi.string(),
|
||||||
),
|
id: Joi.objectId().required(),
|
||||||
template: Joi.string().allow(''),
|
instructions: Joi.string().allow(''),
|
||||||
time: Joi.string().allow(''),
|
isComingSoon: Joi.bool(),
|
||||||
title: Joi.string().required()
|
isLocked: Joi.bool(),
|
||||||
});
|
isPrivate: Joi.bool(),
|
||||||
|
name: Joi.string(),
|
||||||
|
order: Joi.number(),
|
||||||
|
// video challenges only:
|
||||||
|
videoId: Joi.when('challengeType', {
|
||||||
|
is: challengeTypes.video,
|
||||||
|
then: Joi.string().required()
|
||||||
|
}),
|
||||||
|
question: Joi.object().keys({
|
||||||
|
text: Joi.string().required(),
|
||||||
|
answers: Joi.array()
|
||||||
|
.items(Joi.string())
|
||||||
|
.required(),
|
||||||
|
solution: Joi.number().required()
|
||||||
|
}),
|
||||||
|
required: Joi.array().items(
|
||||||
|
Joi.object().keys({
|
||||||
|
link: Joi.string(),
|
||||||
|
raw: Joi.bool(),
|
||||||
|
src: Joi.string(),
|
||||||
|
crossDomain: Joi.bool()
|
||||||
|
})
|
||||||
|
),
|
||||||
|
solutions: Joi.array().items(
|
||||||
|
Joi.object().keys({
|
||||||
|
indexcss: fileJoi,
|
||||||
|
indexhtml: fileJoi,
|
||||||
|
indexjs: fileJoi,
|
||||||
|
indexjsx: fileJoi,
|
||||||
|
indexpy: fileJoi
|
||||||
|
})
|
||||||
|
),
|
||||||
|
superBlock: Joi.string(),
|
||||||
|
superOrder: Joi.number(),
|
||||||
|
suborder: Joi.number(),
|
||||||
|
tests: Joi.array().items(
|
||||||
|
// public challenges
|
||||||
|
Joi.object().keys({
|
||||||
|
text: Joi.string().required(),
|
||||||
|
testString: Joi.string()
|
||||||
|
.allow('')
|
||||||
|
.required()
|
||||||
|
}),
|
||||||
|
// our tests used in certification verification
|
||||||
|
Joi.object().keys({
|
||||||
|
id: Joi.string().required(),
|
||||||
|
title: Joi.string().required()
|
||||||
|
})
|
||||||
|
),
|
||||||
|
template: Joi.string().allow(''),
|
||||||
|
time: Joi.string().allow(''),
|
||||||
|
title: Joi.string().required()
|
||||||
|
})
|
||||||
|
.xor('helpCategory', 'isPrivate');
|
||||||
|
|
||||||
exports.challengeSchemaValidator = () => {
|
exports.challengeSchemaValidator = () => {
|
||||||
return challenge => Joi.validate(challenge, schema);
|
return challenge => Joi.validate(challenge, schema);
|
||||||
|
@ -42,10 +42,7 @@ const {
|
|||||||
const MongoIds = require('./utils/mongoIds');
|
const MongoIds = require('./utils/mongoIds');
|
||||||
const ChallengeTitles = require('./utils/challengeTitles');
|
const ChallengeTitles = require('./utils/challengeTitles');
|
||||||
const { challengeSchemaValidator } = require('../schema/challengeSchema');
|
const { challengeSchemaValidator } = require('../schema/challengeSchema');
|
||||||
const {
|
const { challengeTypes } = require('../../client/utils/challengeTypes');
|
||||||
challengeTypes,
|
|
||||||
helpCategory
|
|
||||||
} = require('../../client/utils/challengeTypes');
|
|
||||||
|
|
||||||
const { dasherize } = require('../../utils/slugs');
|
const { dasherize } = require('../../utils/slugs');
|
||||||
const { toSortedArray } = require('../../utils/sort-files');
|
const { toSortedArray } = require('../../utils/sort-files');
|
||||||
@ -249,15 +246,6 @@ async function getChallenges(lang) {
|
|||||||
return sortChallenges(challenges);
|
return sortChallenges(challenges);
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateBlock(challenge) {
|
|
||||||
const dashedBlock = dasherize(challenge.block);
|
|
||||||
if (!helpCategory.hasOwnProperty(dashedBlock)) {
|
|
||||||
return `'${dashedBlock}' block not found as a helpCategory in client/utils/challengeTypes.js file for the '${challenge.title}' challenge`;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function populateTestsForLang({ lang, challenges, meta }) {
|
function populateTestsForLang({ lang, challenges, meta }) {
|
||||||
const mongoIds = new MongoIds();
|
const mongoIds = new MongoIds();
|
||||||
const challengeTitles = new ChallengeTitles();
|
const challengeTitles = new ChallengeTitles();
|
||||||
@ -285,14 +273,10 @@ function populateTestsForLang({ lang, challenges, meta }) {
|
|||||||
|
|
||||||
it('Common checks', function() {
|
it('Common checks', function() {
|
||||||
const result = validateChallenge(challenge);
|
const result = validateChallenge(challenge);
|
||||||
const invalidBlock = validateBlock(challenge);
|
|
||||||
|
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
throw new AssertionError(result.error);
|
throw new AssertionError(result.error);
|
||||||
}
|
}
|
||||||
if (challenge.challengeType !== 7 && invalidBlock) {
|
|
||||||
throw new Error(invalidBlock);
|
|
||||||
}
|
|
||||||
const { id, title, block, dashedName } = challenge;
|
const { id, title, block, dashedName } = challenge;
|
||||||
const dashedBlock = dasherize(block);
|
const dashedBlock = dasherize(block);
|
||||||
const pathAndTitle = `${dashedBlock}/${dashedName}`;
|
const pathAndTitle = `${dashedBlock}/${dashedName}`;
|
||||||
|
Reference in New Issue
Block a user