feat(learn): split InforSec and QA into individual certs (#38347)

Co-authored-by: Mrugesh Mohapatra <me@raisedadead.com>
Co-authored-by: Kris Koishigawa <scissorsneedfoodtoo@gmail.com>
This commit is contained in:
Beau Carnes
2020-04-23 09:08:50 -04:00
committed by Mrugesh Mohapatra
parent c75d212831
commit 256ed00fb9
25 changed files with 251 additions and 160 deletions

View File

@ -107,11 +107,12 @@ Once you have earned all 6 of these certifications, you'll be able to claim your
#### Legacy Certifications #### Legacy Certifications
We also have 3 legacy certifications from our 2015 curriculum, which are still available. All of the required projects for these legacy certifications will remain available on freeCodeCamp.org. We also have 4 legacy certifications dating back to our 2015 curriculum, which are still available. All of the required projects for these legacy certifications will remain available on freeCodeCamp.org.
- Legacy Front End Development Certification - Legacy Front End Development Certification
- Legacy Data Visualization Certification - Legacy Data Visualization Certification
- Legacy Back End Development Certification - Legacy Back End Development Certification
- Legacy Information Security and Quality Assurance Certification
### The Learning Platform ### The Learning Platform

View File

@ -79,10 +79,28 @@ const legacyDataVisProjects = {
superBlock: 'legacy-data-visualization' superBlock: 'legacy-data-visualization'
}; };
const legacyInfosecQaProjects = {
challenges: [
// metric-imperial-converter
'587d8249367417b2b2512c41',
// issue-tracker
'587d8249367417b2b2512c42',
// personal-library
'587d824a367417b2b2512c43',
// stock-price-checker
'587d824a367417b2b2512c44',
// anonymous-message-board
'587d824a367417b2b2512c45'
],
title: 'Legacy Information Security and Quality Assurance Projects',
superBlock: 'legacy-information-security-and-quality-assurance'
};
const legacyProjects = [ const legacyProjects = [
legacyFrontEndProjects, legacyFrontEndProjects,
legacyBackEndProjects, legacyBackEndProjects,
legacyDataVisProjects legacyDataVisProjects,
legacyInfosecQaProjects
]; ];
export default legacyProjects; export default legacyProjects;

View File

@ -13,12 +13,12 @@ import {
legacyFrontEndChallengeId, legacyFrontEndChallengeId,
legacyBackEndChallengeId, legacyBackEndChallengeId,
legacyDataVisId, legacyDataVisId,
legacyInfosecQaId,
respWebDesignId, respWebDesignId,
frontEndLibsId, frontEndLibsId,
jsAlgoDataStructId, jsAlgoDataStructId,
dataVis2018Id, dataVis2018Id,
apisMicroservicesId, apisMicroservicesId,
infosecQaId,
infosecId, infosecId,
qaId, qaId,
fullStackId, fullStackId,
@ -98,6 +98,7 @@ function createCertTypeIds(app) {
[certTypes.frontEnd]: getIdsForCert$(legacyFrontEndChallengeId, Challenge), [certTypes.frontEnd]: getIdsForCert$(legacyFrontEndChallengeId, Challenge),
[certTypes.backEnd]: getIdsForCert$(legacyBackEndChallengeId, Challenge), [certTypes.backEnd]: getIdsForCert$(legacyBackEndChallengeId, Challenge),
[certTypes.dataVis]: getIdsForCert$(legacyDataVisId, Challenge), [certTypes.dataVis]: getIdsForCert$(legacyDataVisId, Challenge),
[certTypes.infosecQa]: getIdsForCert$(legacyInfosecQaId, Challenge),
// modern // modern
[certTypes.respWebDesign]: getIdsForCert$(respWebDesignId, Challenge), [certTypes.respWebDesign]: getIdsForCert$(respWebDesignId, Challenge),
@ -108,7 +109,6 @@ function createCertTypeIds(app) {
apisMicroservicesId, apisMicroservicesId,
Challenge Challenge
), ),
[certTypes.infosecQa]: getIdsForCert$(infosecQaId, Challenge),
[certTypes.qa]: getIdsForCert$(qaId, Challenge), [certTypes.qa]: getIdsForCert$(qaId, Challenge),
[certTypes.infosec]: getIdsForCert$(infosecId, Challenge), [certTypes.infosec]: getIdsForCert$(infosecId, Challenge),
[certTypes.fullStack]: getIdsForCert$(fullStackId, Challenge), [certTypes.fullStack]: getIdsForCert$(fullStackId, Challenge),
@ -131,12 +131,12 @@ const certIds = {
[certTypes.frontEnd]: legacyFrontEndChallengeId, [certTypes.frontEnd]: legacyFrontEndChallengeId,
[certTypes.backEnd]: legacyBackEndChallengeId, [certTypes.backEnd]: legacyBackEndChallengeId,
[certTypes.dataVis]: legacyDataVisId, [certTypes.dataVis]: legacyDataVisId,
[certTypes.infosecQa]: legacyInfosecQaId,
[certTypes.respWebDesign]: respWebDesignId, [certTypes.respWebDesign]: respWebDesignId,
[certTypes.frontEndLibs]: frontEndLibsId, [certTypes.frontEndLibs]: frontEndLibsId,
[certTypes.jsAlgoDataStruct]: jsAlgoDataStructId, [certTypes.jsAlgoDataStruct]: jsAlgoDataStructId,
[certTypes.dataVis2018]: dataVis2018Id, [certTypes.dataVis2018]: dataVis2018Id,
[certTypes.apisMicroservices]: apisMicroservicesId, [certTypes.apisMicroservices]: apisMicroservicesId,
[certTypes.infosecQa]: infosecQaId,
[certTypes.qa]: qaId, [certTypes.qa]: qaId,
[certTypes.infosec]: infosecId, [certTypes.infosec]: infosecId,
[certTypes.fullStack]: fullStackId, [certTypes.fullStack]: fullStackId,
@ -149,13 +149,13 @@ const certText = {
[certTypes.frontEnd]: 'Legacy Front End', [certTypes.frontEnd]: 'Legacy Front End',
[certTypes.backEnd]: 'Legacy Back End', [certTypes.backEnd]: 'Legacy Back End',
[certTypes.dataVis]: 'Legacy Data Visualization', [certTypes.dataVis]: 'Legacy Data Visualization',
[certTypes.infosecQa]: 'Legacy Information Security and Quality Assurance',
[certTypes.fullStack]: 'Full Stack', [certTypes.fullStack]: 'Full Stack',
[certTypes.respWebDesign]: 'Responsive Web Design', [certTypes.respWebDesign]: 'Responsive Web Design',
[certTypes.frontEndLibs]: 'Front End Libraries', [certTypes.frontEndLibs]: 'Front End Libraries',
[certTypes.jsAlgoDataStruct]: 'JavaScript Algorithms and Data Structures', [certTypes.jsAlgoDataStruct]: 'JavaScript Algorithms and Data Structures',
[certTypes.dataVis2018]: 'Data Visualization', [certTypes.dataVis2018]: 'Data Visualization',
[certTypes.apisMicroservices]: 'APIs and Microservices', [certTypes.apisMicroservices]: 'APIs and Microservices',
[certTypes.infosecQa]: 'Information Security and Quality Assurance',
[certTypes.qa]: 'Quality Assurance', [certTypes.qa]: 'Quality Assurance',
[certTypes.infosec]: 'Information Security', [certTypes.infosec]: 'Information Security',
[certTypes.sciCompPy]: 'Scientific Computing with Python', [certTypes.sciCompPy]: 'Scientific Computing with Python',
@ -167,13 +167,13 @@ const completionHours = {
[certTypes.frontEnd]: 400, [certTypes.frontEnd]: 400,
[certTypes.backEnd]: 400, [certTypes.backEnd]: 400,
[certTypes.dataVis]: 400, [certTypes.dataVis]: 400,
[certTypes.infosecQa]: 300,
[certTypes.fullStack]: 1800, [certTypes.fullStack]: 1800,
[certTypes.respWebDesign]: 300, [certTypes.respWebDesign]: 300,
[certTypes.frontEndLibs]: 300, [certTypes.frontEndLibs]: 300,
[certTypes.jsAlgoDataStruct]: 300, [certTypes.jsAlgoDataStruct]: 300,
[certTypes.dataVis2018]: 300, [certTypes.dataVis2018]: 300,
[certTypes.apisMicroservices]: 300, [certTypes.apisMicroservices]: 300,
[certTypes.infosecQa]: 300,
[certTypes.qa]: 300, [certTypes.qa]: 300,
[certTypes.infosec]: 300, [certTypes.infosec]: 300,
[certTypes.sciCompPy]: 400, [certTypes.sciCompPy]: 400,
@ -202,7 +202,6 @@ function sendCertifiedEmail(
isJsAlgoDataStructCert, isJsAlgoDataStructCert,
isDataVisCert, isDataVisCert,
isApisMicroservicesCert, isApisMicroservicesCert,
isInfosecQaCert,
isQaCert, isQaCert,
isInfosecCert, isInfosecCert,
isSciCompPyCert, isSciCompPyCert,
@ -218,7 +217,6 @@ function sendCertifiedEmail(
!isJsAlgoDataStructCert || !isJsAlgoDataStructCert ||
!isDataVisCert || !isDataVisCert ||
!isApisMicroservicesCert || !isApisMicroservicesCert ||
!isInfosecQaCert ||
!isQaCert || !isQaCert ||
!isInfosecCert || !isInfosecCert ||
!isSciCompPyCert || !isSciCompPyCert ||

View File

@ -4,13 +4,13 @@
"legacyFrontEndChallengeId": "561add10cb82ac38a17513be", "legacyFrontEndChallengeId": "561add10cb82ac38a17513be",
"legacyBackEndChallengeId": "660add10cb82ac38a17513be", "legacyBackEndChallengeId": "660add10cb82ac38a17513be",
"legacyDataVisId": "561add10cb82ac39a17513bc", "legacyDataVisId": "561add10cb82ac39a17513bc",
"legacyInfosecQaId": "561add10cb82ac38a17213bc",
"respWebDesignId": "561add10cb82ac38a17513bc", "respWebDesignId": "561add10cb82ac38a17513bc",
"frontEndLibsId": "561acd10cb82ac38a17513bc", "frontEndLibsId": "561acd10cb82ac38a17513bc",
"dataVis2018Id": "5a553ca864b52e1d8bceea14", "dataVis2018Id": "5a553ca864b52e1d8bceea14",
"jsAlgoDataStructId": "561abd10cb81ac38a17513bc", "jsAlgoDataStructId": "561abd10cb81ac38a17513bc",
"apisMicroservicesId": "561add10cb82ac38a17523bc", "apisMicroservicesId": "561add10cb82ac38a17523bc",
"infosecQaId": "561add10cb82ac38a17213bc",
"qaId": "5e611829481575a52dc59c0e", "qaId": "5e611829481575a52dc59c0e",
"infosecId": "5e6021435ac9d0ecd8b94b00", "infosecId": "5e6021435ac9d0ecd8b94b00",
"fullStackId": "561add10cb82ac38a17213bd", "fullStackId": "561add10cb82ac38a17213bd",

View File

@ -3,7 +3,6 @@ function getCompletedCertCount(user) {
'isApisMicroservicesCert', 'isApisMicroservicesCert',
'is2018DataVisCert', 'is2018DataVisCert',
'isFrontEndLibsCert', 'isFrontEndLibsCert',
'isInfosecQaCert',
'isQaCert', 'isQaCert',
'isInfosecCert', 'isInfosecCert',
'isJsAlgoDataStructCert', 'isJsAlgoDataStructCert',
@ -15,10 +14,12 @@ function getCompletedCertCount(user) {
} }
function getLegacyCertCount(user) { function getLegacyCertCount(user) {
return ['isFrontEndCert', 'isBackEndCert', 'isDataVisCert'].reduce( return [
(sum, key) => (user[key] ? sum + 1 : sum), 'isFrontEndCert',
0 'isBackEndCert',
); 'isDataVisCert',
'isInfosecQaCert'
].reduce((sum, key) => (user[key] ? sum + 1 : sum), 0);
} }
export default function populateUser(db, user) { export default function populateUser(db, user) {

View File

@ -5,6 +5,7 @@ const superBlockCertTypeMap = {
'legacy-front-end': certTypes.frontEnd, 'legacy-front-end': certTypes.frontEnd,
'legacy-back-end': certTypes.backEnd, 'legacy-back-end': certTypes.backEnd,
'legacy-data-visualization': certTypes.dataVis, 'legacy-data-visualization': certTypes.dataVis,
'legacy-information-security-and-quality-assurance': certTypes.infosecQa,
// modern // modern
'responsive-web-design': certTypes.respWebDesign, 'responsive-web-design': certTypes.respWebDesign,
@ -12,7 +13,6 @@ const superBlockCertTypeMap = {
'front-end-libraries': certTypes.frontEndLibs, 'front-end-libraries': certTypes.frontEndLibs,
'data-visualization': certTypes.dataVis2018, 'data-visualization': certTypes.dataVis2018,
'apis-and-microservices': certTypes.apisMicroservices, 'apis-and-microservices': certTypes.apisMicroservices,
'information-security-and-quality-assurance': certTypes.infosecQa,
'quality-assurance': certTypes.qa, 'quality-assurance': certTypes.qa,
'information-security': certTypes.infosec, 'information-security': certTypes.infosec,
'full-stack': certTypes.fullStack, 'full-stack': certTypes.fullStack,

View File

@ -142,7 +142,6 @@ function getCompletedCertCount(user) {
'isApisMicroservicesCert', 'isApisMicroservicesCert',
'is2018DataVisCert', 'is2018DataVisCert',
'isFrontEndLibsCert', 'isFrontEndLibsCert',
'isInfosecQaCert',
'isQaCert', 'isQaCert',
'isInfosecCert', 'isInfosecCert',
'isJsAlgoDataStructCert', 'isJsAlgoDataStructCert',
@ -154,8 +153,10 @@ function getCompletedCertCount(user) {
} }
function getLegacyCertCount(user) { function getLegacyCertCount(user) {
return ['isFrontEndCert', 'isBackEndCert', 'isDataVisCert'].reduce( return [
(sum, key) => (user[key] ? sum + 1 : sum), 'isFrontEndCert',
0 'isBackEndCert',
); 'isDataVisCert',
'isInfosecQaCert'
].reduce((sum, key) => (user[key] ? sum + 1 : sum), 0);
} }

View File

@ -121,7 +121,6 @@ const isCertMapSelector = createSelector(
'Front End Libraries': isFrontEndLibsCert, 'Front End Libraries': isFrontEndLibsCert,
'Data Visualization': is2018DataVisCert, 'Data Visualization': is2018DataVisCert,
"API's and Microservices": isApisMicroservicesCert, "API's and Microservices": isApisMicroservicesCert,
'Information Security And Quality Assurance': isInfosecQaCert,
'Quality Assurance': isQaCert, 'Quality Assurance': isQaCert,
'Information Security': isInfosecCert, 'Information Security': isInfosecCert,
'Scientific Computing with Python': isSciCompPyCert, 'Scientific Computing with Python': isSciCompPyCert,
@ -129,7 +128,8 @@ const isCertMapSelector = createSelector(
'Machine Learning with Python': isMachineLearningPyCert, 'Machine Learning with Python': isMachineLearningPyCert,
'Legacy Front End': isFrontEndCert, 'Legacy Front End': isFrontEndCert,
'Legacy Data Visualization': isDataVisCert, 'Legacy Data Visualization': isDataVisCert,
'Legacy Back End': isBackEndCert 'Legacy Back End': isBackEndCert,
'Legacy Information Security And Quality Assurance': isInfosecQaCert
}) })
); );
@ -473,6 +473,7 @@ export class CertificationSettings extends Component {
isApisMicroservicesCert, isApisMicroservicesCert,
isFrontEndLibsCert, isFrontEndLibsCert,
isQaCert, isQaCert,
isInfosecCert,
isJsAlgoDataStructCert, isJsAlgoDataStructCert,
isRespWebDesignCert isRespWebDesignCert
} = this.props; } = this.props;
@ -482,6 +483,7 @@ export class CertificationSettings extends Component {
isApisMicroservicesCert && isApisMicroservicesCert &&
isFrontEndLibsCert && isFrontEndLibsCert &&
isQaCert && isQaCert &&
isInfosecCert &&
isJsAlgoDataStructCert && isJsAlgoDataStructCert &&
isRespWebDesignCert; isRespWebDesignCert;

View File

@ -230,14 +230,14 @@ export const certificatesByNameSelector = username => state => {
isFrontEndLibsCert || isFrontEndLibsCert ||
isJsAlgoDataStructCert || isJsAlgoDataStructCert ||
isApisMicroservicesCert || isApisMicroservicesCert ||
isInfosecQaCert ||
isQaCert || isQaCert ||
isInfosecCert || isInfosecCert ||
isFullStackCert || isFullStackCert ||
isSciCompPyCert || isSciCompPyCert ||
isDataAnalysisPyCert || isDataAnalysisPyCert ||
isMachineLearningPyCert, isMachineLearningPyCert,
hasLegacyCert: isFrontEndCert || isBackEndCert || isDataVisCert, hasLegacyCert:
isFrontEndCert || isBackEndCert || isDataVisCert || isInfosecQaCert,
currentCerts: [ currentCerts: [
{ {
show: isFullStackCert, show: isFullStackCert,
@ -269,11 +269,6 @@ export const certificatesByNameSelector = username => state => {
title: 'APIs and Microservices Certification', title: 'APIs and Microservices Certification',
showURL: 'apis-and-microservices' showURL: 'apis-and-microservices'
}, },
{
show: isInfosecQaCert,
title: 'Information Security and Quality Assurance Certification',
showURL: 'information-security-and-quality-assurance'
},
{ {
show: isQaCert, show: isQaCert,
title: ' Quality Assurance Certification', title: ' Quality Assurance Certification',
@ -315,6 +310,11 @@ export const certificatesByNameSelector = username => state => {
show: isDataVisCert, show: isDataVisCert,
title: 'Data Visualization Certification', title: 'Data Visualization Certification',
showURL: 'legacy-data-visualization' showURL: 'legacy-data-visualization'
},
{
show: isInfosecQaCert,
title: 'Information Security and Quality Assurance Certification',
showURL: 'legacy-information-security-and-quality-assurance'
} }
] ]
}; };

View File

@ -19,6 +19,7 @@ const machineLearningPyBase =
const legacyFrontEndBase = ''; const legacyFrontEndBase = '';
const legacyBackEndBase = ''; const legacyBackEndBase = '';
const legacyDataVisBase = ''; const legacyDataVisBase = '';
const legacyInfosecQaBase = '';
export const legacyProjectMap = { export const legacyProjectMap = {
'Legacy Front End': [ 'Legacy Front End': [
@ -206,6 +207,38 @@ export const legacyProjectMap = {
link: `${legacyDataVisBase}/map-data-across-the-globe`, link: `${legacyDataVisBase}/map-data-across-the-globe`,
superBlock: 'legacy-data-visualization' superBlock: 'legacy-data-visualization'
} }
],
'Legacy Information Security and Quality Assurance': [
{
id: '587d8249367417b2b2512c41',
title: 'Metric-Imperial Converter',
link: `${legacyInfosecQaBase}/metric-imperial-converter`,
superBlock: 'legacy-information-security-and-quality-assurance'
},
{
id: '587d8249367417b2b2512c42',
title: 'Issue Tracker',
link: `${legacyInfosecQaBase}/issue-tracker`,
superBlock: 'legacy-information-security-and-quality-assurance'
},
{
id: '587d824a367417b2b2512c43',
title: 'Personal Library',
link: `${legacyInfosecQaBase}/personal-library`,
superBlock: 'legacy-information-security-and-quality-assurance'
},
{
id: '587d824a367417b2b2512c44',
title: 'Stock Price Checker',
link: `${legacyInfosecQaBase}/stock-price-checker`,
superBlock: 'legacy-information-security-and-quality-assurance'
},
{
id: '587d824a367417b2b2512c45',
title: 'Anonymous Message Board',
link: `${legacyInfosecQaBase}/anonymous-message-board`,
superBlock: 'legacy-information-security-and-quality-assurance'
}
] ]
}; };
@ -429,8 +462,8 @@ export const projectMap = {
}, },
{ {
id: '5e601c775ac9d0ecd8b94aff', id: '5e601c775ac9d0ecd8b94aff',
title: 'Real Time Multiplayer Game', title: 'Secure Real Time Multiplayer Game',
link: `${infoSecBase}/real-time-multiplayer-game`, link: `${infoSecBase}/secure-real-time-multiplayer-game`,
superBlock: 'information-security' superBlock: 'information-security'
} }
], ],

View File

@ -14,12 +14,8 @@ const preFormattedBlockNames = {
'apis-and-microservices': 'APIs and Microservices', 'apis-and-microservices': 'APIs and Microservices',
'apis-and-microservices-projects': 'APIs and Microservices Projects', 'apis-and-microservices-projects': 'APIs and Microservices Projects',
'scientific-computing-with-python': 'Scientific Computing with Python', 'scientific-computing-with-python': 'Scientific Computing with Python',
'scientific-computing-with-python-projects': 'Certification Projects',
'data-analysis-with-python': 'Data Analysis with Python', 'data-analysis-with-python': 'Data Analysis with Python',
'data-analysis-with-python-projects': 'Certification Projects', 'machine-learning-with-python': 'Machine Learning with Python'
'machine-learning-with-python': 'Machine Learning with Python',
'machine-learning-with-python-projects': 'Certification Projects',
'information-security-projects': 'Certification Projects'
}; };
const noFormatting = ['and', 'for', 'of', 'the', 'up', 'with']; const noFormatting = ['and', 'for', 'of', 'the', 'up', 'with'];

View File

@ -4,12 +4,14 @@ export default [
'front-end-libraries', 'front-end-libraries',
'data-visualization', 'data-visualization',
'apis-and-microservices', 'apis-and-microservices',
'information-security-and-quality-assurance',
'full-stack', 'full-stack',
'scientific-computing-with-python', 'scientific-computing-with-python',
'data-analysis-with-python', 'data-analysis-with-python',
'machine-learning-with-python', 'machine-learning-with-python',
'information-security',
'quality-assurance',
'legacy-front-end', 'legacy-front-end',
'legacy-back-end', 'legacy-back-end',
'legacy-data-visualization' 'legacy-data-visualization',
'legacy-information-security-and-quality-assurance'
]; ];

View File

@ -1,34 +0,0 @@
{
"name": "Information Security and Quality Assurance Projects",
"dashedName": "information-security-and-quality-assurance-projects",
"order": 0,
"time": "150 hours",
"template": "",
"required": [],
"superBlock": "information-security-and-quality-assurance",
"superOrder": 13,
"challengeOrder": [
[
"587d8249367417b2b2512c41",
"Metric-Imperial Converter"
],
[
"587d8249367417b2b2512c42",
"Issue Tracker"
],
[
"587d824a367417b2b2512c43",
"Personal Library"
],
[
"587d824a367417b2b2512c44",
"Stock Price Checker"
],
[
"587d824a367417b2b2512c45",
"Anonymous Message Board"
]
],
"helpRoom": "HelpBackend",
"fileName": "12-information-security-and-quality-assurance/quality-assurance-and-information-security-projects.json"
}

View File

@ -18,7 +18,7 @@
], ],
[ [
"5e601c775ac9d0ecd8b94aff", "5e601c775ac9d0ecd8b94aff",
"Real Time Multiplayer Game" "Secure Real Time Multiplayer Game"
], ],
[ [
"5e46f979ac417301a38fb932", "5e46f979ac417301a38fb932",

View File

@ -1,18 +0,0 @@
{
"name": "Information, Securtiy and Quality Assurance Certificate",
"dashedName": "information-securtiy-and-quality-assurance-certificate",
"order": 6,
"time": "",
"template": "",
"required": [],
"superBlock": "certificates",
"superOrder": 12,
"challengeOrder": [
[
"561add10cb82ac38a17213bc",
"Information, Securtiy and Quality Assurance Certificate"
]
],
"isPrivate": true,
"fileName": "12-certificates/information-security-and-quality-assurance-certificate.json"
}

View File

@ -0,0 +1,18 @@
{
"name": "Legacy Information Security and Quality Assurance Certificate",
"dashedName": "legacy-information-security-and-quality-assurance-certificate",
"order": 1,
"time": "",
"template": "",
"required": [],
"superBlock": "certificates",
"superOrder": 12,
"challengeOrder": [
[
"561add10cb82ac38a17213bc",
"Legacy Information Security and Quality Assurance Certificate"
]
],
"isPrivate": true,
"fileName": "12-certificates/legacy-information-security-and-quality-assurance-certificate.json"
}

View File

@ -3,13 +3,15 @@ id: 5e601c0d5ac9d0ecd8b94afe
title: American British Translator title: American British Translator
challengeType: 4 challengeType: 4
isRequired: true isRequired: true
forumTopicId: 301571
--- ---
## Description ## Description
<section id='description'> <section id='description'>
COMING SOON Build a full stack JavaScript app that is functionally similar to this: <a href='add-glitch-link' target='_blank'>add-glitch-link</a>.
Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.
Start this project on Glitch using <a href='https://glitch.com/edit/#!/remix/clone-from-repo?REPO_URL=add-repo-url'>this link</a> or clone <a href='add-repo-url'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!
</section> </section>
## Instructions ## Instructions
@ -22,8 +24,23 @@ COMING SOON
```yml ```yml
tests: tests:
- text: test - text: I can enter a simple sentence into the text area and select whether to translate to British or American English from the dropdown menu.
testString: 'test' testString: ''
- text: When the "Translate" button is pressed, append the translated sentence to the <code>translated-sentence</code> <code>div</code>. See the JavaScript files in <code>/public</code> for the different spelling and terms your application should translate.
testString: ''
- text: Wrap any translated spelling or terms with <code>&lt;span class=&quot;highlight&quot;&gt;...&lt;/span&gt;</code> tags so they appear in green.
testString: ''
- text: If the sentence in the text area has no spelling or terms that should be translated, append the message "Everything looks good to me!" to the <code>translated-sentence</code> <code>div</code>.
testString: ''
- text: |
If there is no text in the text area, append the message "Error: No text to translate." to the <code>error-msg</code> <code>div</code> so the text appears in red.
testString: ''
- text: I can press the "Clear Input" button to remove all text from the text area and the <code>translated-sentence</code> <code>div</code>.
testString: ''
- text: All 12 unit tests are complete and passing.
testString: ''
- text: All 4 functional tests are complete and passing.
testString: ''
``` ```
</section> </section>

View File

@ -3,12 +3,15 @@ id: 5e601bf95ac9d0ecd8b94afd
title: Sudoku Solver title: Sudoku Solver
challengeType: 4 challengeType: 4
isRequired: true isRequired: true
forumTopicId: 301571
--- ---
## Description ## Description
<section id='description'> <section id='description'>
COMING SOON Build a full stack JavaScript app that is functionally similar to this: <a href='add-glitch-link' target='_blank'>add-glitch-link</a>.
Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.
Start this project on Glitch using <a href='https://glitch.com/edit/#!/remix/clone-from-repo?REPO_URL=add-repo-url'>this link</a> or clone <a href='add-repo-url'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!
</section> </section>
## Instructions ## Instructions
@ -21,8 +24,18 @@ COMING SOON
```yml ```yml
tests: tests:
- text: test - text: I can enter a sudoku puzzle by filling in the text area with either a number or period (".") to represent an empty cell. When a valid number is entered in the text area, the same number is applied to the correct cell of the sudoku grid.
testString: 'test' testString: ''
- text: I can enter a sudoku puzzle by adding numbers directly to the sudoku grid. When a valid number is entered in the sudoku grid, the same number appears in the correct position in the text area.
testString: ''
- text: I can solve an incomplete puzzle by clicking the "Solve" button. When a solution is found, the sudoku grid is automatically populated with the correct numbers for each cell.
testString: ''
- text: I can clear the text area and sudoku grid by clicking the "Clear" button.
testString: ''
- text: All 6 unit tests are complete and passing.
testString: ''
- text: All 4 functional tests are complete and passing.
testString: ''
``` ```

View File

@ -1,47 +0,0 @@
---
id: 5e601c775ac9d0ecd8b94aff
title: Real Time Multiplayer Game
challengeType: 4
isRequired: true
forumTopicId: 301572
---
## Description
<section id='description'>
COMING SOON
</section>
## Instructions
<section id='instructions'>
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: test
testString: 'test'
```
</section>
## Challenge Seed
<section id='challengeSeed'>
</section>
## Solution
<section id='solution'>
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```
</section>

View File

@ -0,0 +1,86 @@
---
id: 5e601c775ac9d0ecd8b94aff
title: Secure Real Time Multiplayer Game
challengeType: 4
isRequired: true
---
## Description
<section id='description'>
Develop a 2D real time multiplayer game using the HTML Canvas API and <a href='https://socket.io/' target='_blank'>Socket.io</a> that is functionally similar to this: <a href='add-glitch-url' target='_blank'>add-glitch-url</a>.
Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.
Start this project on Glitch using <a href='https://glitch.com/edit/#!/remix/clone-from-repo?REPO_URL=add-repo-url'>this link</a> or clone <a href='add-repo-url'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!
</section>
## Instructions
<section id='instructions'>
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Multiple players can connect to a server and play.
testString: ''
- text: Each player has an avatar.
testString: ''
- text: Each player is represented by an object created by the <code>Player</code> class in <code>Player.mjs</code>.
testString: ''
- text: At a minimum, each player object should contain a unique <code>id</code>, a <code>score</code>, and <code>x</code> and <code>y</code> coordinates representing the player's current position.
testString: ''
- text: The game has at least one type of collectible item. Complete the <code>Collectible</code> class in <code>Collectible.mjs</code> to implement this.
testString: ''
- text: At a minimum, each collectible item object created by the <code>Collectible</code> class should contain a unique <code>id</code>, a <code>value</code>, and <code>x</code> and <code>y</code> coordinates representing the item's current position.
testString: ''
- text: Players can use the WASD and/or arrow keys to move their avatar. Complete the <code>movePlayer</code> method in <code>Player.mjs</code> to implement this.
testString: ''
- text: |
The <code>movePlayer</code> method should accept two arguments: a string of "up", "down", "left", or "right", and a number for the amount of pixels the player's position should change. <code>movePlayer</code> should adjust the <code>x</code> and <code>y</code> coordinates of the player object it's called from.
testString: ''
- text: The player's score should be used to calculate their rank among the other players. Complete the <code>calculateRank</code> method in the <code>Player</code> class.
testString: ''
- text: |
The <code>calculateRank</code> method should accept an array of objects representing all connected players and return the string <code>Rank: currentRanking/totalPlayers</code>.
testString: ''
- text: Players can collide with a collectible item. Complete the <code>collision</code> method in <code>Player.mjs</code> to implement this.
testString: ''
- text: The <code>collision</code> method should accept a collectible item's object as an argument. If the player's avatar intersects with the item, the <code>collision</code> method should return <code>true</code>.
testString: ''
- text: All players are kept in sync.
testString: ''
- text: Players can disconnect from the game at any time.
testString: ''
- text: Prevent the client from trying to guess / sniff the MIME type.
testString: ''
- text: Prevent cross-site scripting (XSS) attacks.
testString: ''
- text: Nothing from the website is cached in the client.
testString: ''
- text: The headers say that the site is powered by 'PHP 7.4.3' even though it isn't (as a security measure).
testString: ''
```
</section>
## Challenge Seed
<section id='challengeSeed'>
</section>
## Solution
<section id='solution'>
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```
</section>

View File

@ -27,7 +27,7 @@ tests:
- id: 5e46f979ac417301a38fb932 - id: 5e46f979ac417301a38fb932
title: Port Scanner title: Port Scanner
- id: 5e601c775ac9d0ecd8b94aff - id: 5e601c775ac9d0ecd8b94aff
title: Real Time Multiplayer Game title: Secure Real Time Multiplayer Game
- id: 5e46f983ac417301a38fb933 - id: 5e46f983ac417301a38fb933
title: SHA-1 Password Cracker title: SHA-1 Password Cracker
``` ```

View File

@ -1,6 +1,6 @@
--- ---
id: 561add10cb82ac38a17213bc id: 561add10cb82ac38a17213bc
title: 'Information Security and Quality Assurance Certificate' title: Legacy Information Security and Quality Assurance Certificate
challengeType: 7 challengeType: 7
isHidden: false isHidden: false
isPrivate: true isPrivate: true
@ -21,16 +21,17 @@ isPrivate: true
```yml ```yml
tests: tests:
- id: 587d8249367417b2b2512c42
title: Issue Tracker
- id: 587d8249367417b2b2512c41 - id: 587d8249367417b2b2512c41
title: Metric-Imperial Converter title: Metric-Imperial Converter
- id: 587d8249367417b2b2512c42
title: Issue Tracker
- id: 587d824a367417b2b2512c43 - id: 587d824a367417b2b2512c43
title: Personal Library title: Personal Library
- id: 587d824a367417b2b2512c44 - id: 587d824a367417b2b2512c44
title: Stock Price Checker title: Stock Price Checker
- id: 587d824a367417b2b2512c45 - id: 587d824a367417b2b2512c45
title: Anonymous Message Board title: Anonymous Message Board
``` ```
</section> </section>

View File

@ -40,10 +40,11 @@ https://freecodecamp-org.netlify.com/* https://www.freecodecamp.org/:spla
/signup https://api.example.com/signin 200! /signup https://api.example.com/signin 200!
# certification redirects # certification redirects
/:username/front-end-certification /certification/:username/legacy-front-end 301 /:username/front-end-certification /certification/:username/legacy-front-end 301
/:username/data-visualization-certification /certification/:username/legacy-data-visualization 301 /:username/data-visualization-certification /certification/:username/legacy-data-visualization 301
/:username/back-end-certification /certification/:username/legacy-back-end 301 /:username/back-end-certification /certification/:username/legacy-back-end 301
/:username/full-stack-certification /certification/:username/full-stack 301 /:username/information-security-and-quality-assurance /certification/:username/legacy-information-security-and-quality-assurance 301
/:username/full-stack-certification /certification/:username/full-stack 301
# unsubscribe redirects # unsubscribe redirects
/u/* https://api.example.com/u/:splat 200! /u/* https://api.example.com/u/:splat 200!

View File

@ -61,10 +61,11 @@ https://freecodecamp-org.netlify.com/* https://www.freecodecamp.org/:spla
/signup #{{API}}/signin 200! /signup #{{API}}/signin 200!
# certification redirects # certification redirects
/:username/front-end-certification /certification/:username/legacy-front-end 301 /:username/front-end-certification /certification/:username/legacy-front-end 301
/:username/data-visualization-certification /certification/:username/legacy-data-visualization 301 /:username/data-visualization-certification /certification/:username/legacy-data-visualization 301
/:username/back-end-certification /certification/:username/legacy-back-end 301 /:username/back-end-certification /certification/:username/legacy-back-end 301
/:username/full-stack-certification /certification/:username/full-stack 301 /:username/information-security-and-quality-assurance /certification/:username/legacy-information-security-and-quality-assurance 301
/:username/full-stack-certification /certification/:username/full-stack 301
# unsubscribe redirects # unsubscribe redirects
/u/* #{{API}}/u/:splat 200! /u/* #{{API}}/u/:splat 200!

View File

@ -5,7 +5,6 @@ const idToTitle = new Map(
'561add10cb82ac38a17523bc': 'APIs and Microservices', '561add10cb82ac38a17523bc': 'APIs and Microservices',
'5a553ca864b52e1d8bceea14': 'Data Visualization', '5a553ca864b52e1d8bceea14': 'Data Visualization',
'561acd10cb82ac38a17513bc': 'Front End Libraries', '561acd10cb82ac38a17513bc': 'Front End Libraries',
'561add10cb82ac38a17213bc': 'Information Security and Quality Assurance',
'5e611829481575a52dc59c0e': 'Quality Assurance', '5e611829481575a52dc59c0e': 'Quality Assurance',
'5e6021435ac9d0ecd8b94b00': 'Information Security', '5e6021435ac9d0ecd8b94b00': 'Information Security',
'561abd10cb81ac38a17513bc': 'JavaScript Algorithms and Data Structures', '561abd10cb81ac38a17513bc': 'JavaScript Algorithms and Data Structures',
@ -13,6 +12,8 @@ const idToTitle = new Map(
'660add10cb82ac38a17513be': 'Legacy Back End', '660add10cb82ac38a17513be': 'Legacy Back End',
'561add10cb82ac39a17513bc': 'Legacy Data Visualization', '561add10cb82ac39a17513bc': 'Legacy Data Visualization',
'561add10cb82ac38a17513be': 'Legacy Front End', '561add10cb82ac38a17513be': 'Legacy Front End',
'561add10cb82ac38a17213bc':
'Legacy Information Security and Quality Assurance',
'561add10cb82ac38a17213bd': 'Full Stack', '561add10cb82ac38a17213bd': 'Full Stack',
'5e44431b903586ffb414c951': 'Scientific Computing with Python', '5e44431b903586ffb414c951': 'Scientific Computing with Python',
'5e46fc95ac417301a38fb934': 'Data Analysis with Python', '5e46fc95ac417301a38fb934': 'Data Analysis with Python',