feat(client/curriclum): make C# live (#51354)

This commit is contained in:
Tom
2023-08-27 08:00:57 -05:00
committed by GitHub
parent f1ccccfee6
commit 4ed95973d2
35 changed files with 158 additions and 106 deletions
+7 -5
View File
@@ -41,7 +41,7 @@ const {
machineLearningPyV7Id, machineLearningPyV7Id,
relationalDatabaseV8Id, relationalDatabaseV8Id,
collegeAlgebraPyV8Id, collegeAlgebraPyV8Id,
foundationalCSharpId foundationalCSharpV8Id
} = certIds; } = certIds;
const log = debug('fcc:certification'); const log = debug('fcc:certification');
@@ -134,8 +134,8 @@ function createCertTypeIds(allChallenges) {
collegeAlgebraPyV8Id, collegeAlgebraPyV8Id,
allChallenges allChallenges
), ),
[certTypes.foundationalCSharp]: getCertById( [certTypes.foundationalCSharpV8]: getCertById(
foundationalCSharpId, foundationalCSharpV8Id,
allChallenges allChallenges
) )
}; };
@@ -174,7 +174,8 @@ function sendCertifiedEmail(
isDataAnalysisPyCertV7, isDataAnalysisPyCertV7,
isMachineLearningPyCertV7, isMachineLearningPyCertV7,
isRelationalDatabaseCertV8, isRelationalDatabaseCertV8,
isCollegeAlgebraPyCertV8 isCollegeAlgebraPyCertV8,
isFoundationalCSharpCertV8
}, },
send$ send$
) { ) {
@@ -191,7 +192,8 @@ function sendCertifiedEmail(
!isDataAnalysisPyCertV7 || !isDataAnalysisPyCertV7 ||
!isMachineLearningPyCertV7 || !isMachineLearningPyCertV7 ||
!isRelationalDatabaseCertV8 || !isRelationalDatabaseCertV8 ||
!isCollegeAlgebraPyCertV8 !isCollegeAlgebraPyCertV8 ||
!isFoundationalCSharpCertV8
) { ) {
return Observable.just(false); return Observable.just(false);
} }
+1
View File
@@ -366,6 +366,7 @@ function postResetProgress(req, res, next) {
isMachineLearningPyCertV7: false, isMachineLearningPyCertV7: false,
isRelationalDatabaseCertV8: false, isRelationalDatabaseCertV8: false,
isCollegeAlgebraPyCertV8: false, isCollegeAlgebraPyCertV8: false,
isFoundationalCSharpCertV8: false,
completedChallenges: [], completedChallenges: [],
completedExams: [], completedExams: [],
savedChallenges: [], savedChallenges: [],
+2 -1
View File
@@ -15,5 +15,6 @@
"machineLearningPyV7": "isMachineLearningPyCertV7", "machineLearningPyV7": "isMachineLearningPyCertV7",
"fullStack": "isFullStackCert", "fullStack": "isFullStackCert",
"relationalDatabaseV8": "isRelationalDatabaseV8", "relationalDatabaseV8": "isRelationalDatabaseV8",
"collegeAlgebraPyV8": "isCollegeAlgebraPyCertV8" "collegeAlgebraPyV8": "isCollegeAlgebraPyCertV8",
"foundationalCSharpV8": "isFoundationalCSharpCertV8"
} }
+1 -1
View File
@@ -747,7 +747,6 @@ const allStandardCerts = [
} }
] ]
}, },
// Upcoming Certifications
{ {
id: '647e3159823e0ef219c7359b', id: '647e3159823e0ef219c7359b',
title: 'Foundational C# with Microsoft', title: 'Foundational C# with Microsoft',
@@ -761,6 +760,7 @@ const allStandardCerts = [
} }
] ]
}, },
// Upcoming Certifications
{ {
id: '64514fda6c245de4d11eb7bb', id: '64514fda6c245de4d11eb7bb',
title: 'Example Certification', title: 'Example Certification',
+1 -1
View File
@@ -1017,7 +1017,7 @@
} }
}, },
"foundational-c-sharp-with-microsoft": { "foundational-c-sharp-with-microsoft": {
"title": "Foundational C# with Microsoft", "title": "(New) Foundational C# with Microsoft",
"intro": [ "intro": [
"This course offers a comprehensive introduction to C# programming, covering its core concepts, syntax, and practical application in software development.", "This course offers a comprehensive introduction to C# programming, covering its core concepts, syntax, and practical application in software development.",
"Through hands-on exercises and projects, you will learn the fundamentals of C#, including variables, data types, control structures, and object-oriented programming principles.", "Through hands-on exercises and projects, you will learn the fundamentals of C#, including variables, data types, control structures, and object-oriented programming principles.",
@@ -116,6 +116,9 @@
} }
}, },
"certification-heading": "Earn free verified certifications in:", "certification-heading": "Earn free verified certifications in:",
"core-certs-heading": "Earn free verified certifications with freeCodeCamp's core curriculum:",
"professional-certs-heading": "Earn free professional certifications:",
"interview-prep-heading": "Prepare for the developer interview job search:",
"faq": "Frequently asked questions:", "faq": "Frequently asked questions:",
"faqs": [ "faqs": [
{ {
@@ -303,7 +303,7 @@ const ShowCertification = (props: ShowCertificationProps): JSX.Element => {
); );
const isMicrosoftCert = const isMicrosoftCert =
certTitle === certTypeTitleMap[certTypes.foundationalCSharp]; certTitle === certTypeTitleMap[certTypes.foundationalCSharpV8];
return ( return (
<Container className='certificate-outer-wrapper'> <Container className='certificate-outer-wrapper'>
@@ -213,6 +213,7 @@ export function ShowSettings(props: ShowSettingsProps): JSX.Element {
isDataAnalysisPyCertV7={isDataAnalysisPyCertV7} isDataAnalysisPyCertV7={isDataAnalysisPyCertV7}
isDataVisCert={isDataVisCert} isDataVisCert={isDataVisCert}
isCollegeAlgebraPyCertV8={isCollegeAlgebraPyCertV8} isCollegeAlgebraPyCertV8={isCollegeAlgebraPyCertV8}
isFoundationalCSharpCertV8={isFoundationalCSharpCertV8}
isFrontEndCert={isFrontEndCert} isFrontEndCert={isFrontEndCert}
isFrontEndLibsCert={isFrontEndLibsCert} isFrontEndLibsCert={isFrontEndLibsCert}
isFullStackCert={isFullStackCert} isFullStackCert={isFullStackCert}
@@ -225,7 +226,6 @@ export function ShowSettings(props: ShowSettingsProps): JSX.Element {
isRelationalDatabaseCertV8={isRelationalDatabaseCertV8} isRelationalDatabaseCertV8={isRelationalDatabaseCertV8}
isRespWebDesignCert={isRespWebDesignCert} isRespWebDesignCert={isRespWebDesignCert}
isSciCompPyCertV7={isSciCompPyCertV7} isSciCompPyCertV7={isSciCompPyCertV7}
isFoundationalCSharpCertV8={isFoundationalCSharpCertV8}
username={username} username={username}
verifyCert={verifyCert} verifyCert={verifyCert}
/> />
+34 -7
View File
@@ -1,10 +1,12 @@
import i18next from 'i18next'; import i18next from 'i18next';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next';
import { import {
SuperBlockStages,
SuperBlocks, SuperBlocks,
createFlatSuperBlockMap, getFirstNotAuditedSuperBlock,
getFirstNotAuditedSuperBlock superBlockOrder
} from '../../../../config/superblocks'; } from '../../../../config/superblocks';
import { generateIconComponent } from '../../assets/icons'; import { generateIconComponent } from '../../assets/icons';
import LinkButton from '../../assets/icons/link-button'; import LinkButton from '../../assets/icons/link-button';
@@ -29,16 +31,18 @@ const linkSpacingStyle = {
gap: '15px' gap: '15px'
}; };
const flatSuperBlockMap = createFlatSuperBlockMap({
showNewCurriculum,
showUpcomingChanges
});
const firstNotAuditedSuperBlock = getFirstNotAuditedSuperBlock({ const firstNotAuditedSuperBlock = getFirstNotAuditedSuperBlock({
language: curriculumLocale, language: curriculumLocale,
showNewCurriculum, showNewCurriculum,
showUpcomingChanges showUpcomingChanges
}); });
const coreCurriculum = [
...superBlockOrder[SuperBlockStages.FrontEnd],
...superBlockOrder[SuperBlockStages.Backend],
...superBlockOrder[SuperBlockStages.Python]
];
function MapLi({ function MapLi({
superBlock, superBlock,
landing = false landing = false
@@ -81,10 +85,33 @@ function MapLi({
} }
function Map({ forLanding = false }: MapProps): React.ReactElement { function Map({ forLanding = false }: MapProps): React.ReactElement {
const { t } = useTranslation();
return ( return (
<div className='map-ui' data-test-label='curriculum-map'> <div className='map-ui' data-test-label='curriculum-map'>
<h1 className={forLanding ? 'big-heading' : ''}>
{t('landing.core-certs-heading')}
</h1>
<ul> <ul>
{flatSuperBlockMap.map((superBlock, i) => ( {coreCurriculum.map((superBlock, i) => (
<MapLi key={i} superBlock={superBlock} landing={forLanding} />
))}
</ul>
<Spacer size='medium' />
<h1 className={forLanding ? 'big-heading' : ''}>
{t('landing.professional-certs-heading')}
</h1>
<ul>
{superBlockOrder[SuperBlockStages.Professional].map((superBlock, i) => (
<MapLi key={i} superBlock={superBlock} landing={forLanding} />
))}
</ul>
<Spacer size='medium' />
<h1 className={forLanding ? 'big-heading' : ''}>
{t('landing.interview-prep-heading')}
</h1>
<ul>
{superBlockOrder[SuperBlockStages.Extra].map((superBlock, i) => (
<MapLi key={i} superBlock={superBlock} landing={forLanding} /> <MapLi key={i} superBlock={superBlock} landing={forLanding} />
))} ))}
</ul> </ul>
@@ -1,13 +1,10 @@
import { Col } from '@freecodecamp/react-bootstrap'; import { Col } from '@freecodecamp/react-bootstrap';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next';
import Map from '../../Map/index'; import Map from '../../Map/index';
import { Spacer } from '../../helpers'; import { Spacer } from '../../helpers';
import BigCallToAction from './big-call-to-action'; import BigCallToAction from './big-call-to-action';
const Certifications = (): JSX.Element => { const Certifications = (): JSX.Element => {
const { t } = useTranslation();
return ( return (
<Col <Col
className='certification-section' className='certification-section'
@@ -17,7 +14,6 @@ const Certifications = (): JSX.Element => {
smOffset={1} smOffset={1}
xs={12} xs={12}
> >
<h1 className='big-heading'>{t('landing.certification-heading')}</h1>
<Map forLanding={true} /> <Map forLanding={true} />
<Spacer size='medium' /> <Spacer size='medium' />
<BigCallToAction /> <BigCallToAction />
@@ -66,7 +66,8 @@ const userProps = {
isDataAnalysisPyCertV7: true, isDataAnalysisPyCertV7: true,
isMachineLearningPyCertV7: true, isMachineLearningPyCertV7: true,
isRelationalDatabaseCertV8: true, isRelationalDatabaseCertV8: true,
isCollegeAlgebraPyCertV8: true isCollegeAlgebraPyCertV8: true,
isFoundationalCSharpVertV8: true
}, },
// eslint-disable-next-line @typescript-eslint/no-empty-function // eslint-disable-next-line @typescript-eslint/no-empty-function
navigate: () => {} navigate: () => {}
@@ -276,6 +276,7 @@ const defaultTestProps = {
isMachineLearningPyCertV7: false, isMachineLearningPyCertV7: false,
isRelationalDatabaseCertV8: false, isRelationalDatabaseCertV8: false,
isCollegeAlgebraPyCertV8: false, isCollegeAlgebraPyCertV8: false,
isFoundationalCSharpCertV8: false,
username: 'developmentuser', username: 'developmentuser',
verifyCert: verifyCert, verifyCert: verifyCert,
isEmailVerified: false isEmailVerified: false
@@ -122,11 +122,11 @@ const isCertMapSelector = createSelector(
'Machine Learning with Python': isMachineLearningPyCertV7, 'Machine Learning with Python': isMachineLearningPyCertV7,
'Relational Database': isRelationalDatabaseCertV8, 'Relational Database': isRelationalDatabaseCertV8,
'College Algebra with Python': isCollegeAlgebraPyCertV8, 'College Algebra with Python': isCollegeAlgebraPyCertV8,
'Foundational C# with Microsoft': isFoundationalCSharpCertV8,
'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, 'Legacy Information Security and Quality Assurance': isInfosecQaCert,
'Foundational C# with Microsoft': isFoundationalCSharpCertV8,
// TODO: remove Example Certification? Also, include Upcoming Python // TODO: remove Example Certification? Also, include Upcoming Python
// Certification. // Certification.
'Example Certification': false, 'Example Certification': false,
+3 -2
View File
@@ -125,14 +125,15 @@
.certification-namespace .dual-logo svg { .certification-namespace .dual-logo svg {
max-width: 70%; max-width: 70%;
height: auto;
} }
.certification-namespace .fcc-logo svg { .certification-namespace .fcc-logo svg {
max-width: 350px; width: 350px;
} }
.certification-namespace .ms-logo svg { .certification-namespace .ms-logo svg {
max-width: 300px; width: 300px;
} }
.certification-namespace .information { .certification-namespace .information {
+31 -19
View File
@@ -317,26 +317,38 @@ export const reducer = handleActions(
submittedchallenges = submittedChallenge.challArray; submittedchallenges = submittedChallenge.challArray;
} }
const { appUsername } = state; const { appUsername } = state;
return {
...state, return examResults && !examResults.passed
completionCount: state.completionCount + 1, ? {
user: { ...state,
...state.user, user: {
[appUsername]: { ...state.user,
...state.user[appUsername], [appUsername]: {
completedChallenges: uniqBy( ...state.user[appUsername],
[ examResults
...submittedchallenges, }
...state.user[appUsername].completedChallenges }
],
'id'
),
savedChallenges:
savedChallenges ?? savedChallengesSelector(state[MainApp]),
examResults
} }
} : {
}; ...state,
completionCount: state.completionCount + 1,
user: {
...state.user,
[appUsername]: {
...state.user[appUsername],
completedChallenges: uniqBy(
[
...submittedchallenges,
...state.user[appUsername].completedChallenges
],
'id'
),
savedChallenges:
savedChallenges ?? savedChallengesSelector(state[MainApp]),
examResults
}
}
};
}, },
[actionTypes.setMsUsername]: (state, { payload }) => { [actionTypes.setMsUsername]: (state, { payload }) => {
const { appUsername } = state; const { appUsername } = state;
+1 -1
View File
@@ -253,6 +253,7 @@ export type ClaimedCertifications = {
isDataVisCert: boolean; isDataVisCert: boolean;
isEmailVerified: boolean; isEmailVerified: boolean;
isCollegeAlgebraPyCertV8: boolean; isCollegeAlgebraPyCertV8: boolean;
isFoundationalCSharpCertV8: boolean;
isFrontEndCert: boolean; isFrontEndCert: boolean;
isFrontEndLibsCert: boolean; isFrontEndLibsCert: boolean;
isFullStackCert: boolean; isFullStackCert: boolean;
@@ -265,7 +266,6 @@ export type ClaimedCertifications = {
isSciCompPyCertV7: boolean; isSciCompPyCertV7: boolean;
isDataAnalysisPyCertV7: boolean; isDataAnalysisPyCertV7: boolean;
isMachineLearningPyCertV7: boolean; isMachineLearningPyCertV7: boolean;
isFoundationalCSharpCertV8: boolean;
}; };
type SavedChallenges = SavedChallenge[]; type SavedChallenges = SavedChallenge[];
+9 -2
View File
@@ -124,7 +124,8 @@ export const certificatesByNameSelector = username => state => {
isDataAnalysisPyCertV7, isDataAnalysisPyCertV7,
isMachineLearningPyCertV7, isMachineLearningPyCertV7,
isRelationalDatabaseCertV8, isRelationalDatabaseCertV8,
isCollegeAlgebraPyCertV8 isCollegeAlgebraPyCertV8,
isFoundationalCSharpCertV8
} = userByNameSelector(username)(state); } = userByNameSelector(username)(state);
return { return {
hasModernCert: hasModernCert:
@@ -140,7 +141,8 @@ export const certificatesByNameSelector = username => state => {
isDataAnalysisPyCertV7 || isDataAnalysisPyCertV7 ||
isMachineLearningPyCertV7 || isMachineLearningPyCertV7 ||
isRelationalDatabaseCertV8 || isRelationalDatabaseCertV8 ||
isCollegeAlgebraPyCertV8, isCollegeAlgebraPyCertV8 ||
isFoundationalCSharpCertV8,
hasLegacyCert: hasLegacyCert:
isFrontEndCert || isBackEndCert || isDataVisCert || isInfosecQaCert, isFrontEndCert || isBackEndCert || isDataVisCert || isInfosecQaCert,
isFullStackCert, isFullStackCert,
@@ -204,6 +206,11 @@ export const certificatesByNameSelector = username => state => {
show: isCollegeAlgebraPyCertV8, show: isCollegeAlgebraPyCertV8,
title: 'College Algebra with Python Certification', title: 'College Algebra with Python Certification',
certSlug: Certification.CollegeAlgebraPy certSlug: Certification.CollegeAlgebraPy
},
{
show: isFoundationalCSharpCertV8,
title: 'Foundational C# with Microsoft Certification',
certSlug: Certification.FoundationalCSharp
} }
], ],
legacyCerts: [ legacyCerts: [
+11 -13
View File
@@ -24,8 +24,8 @@ export enum Certification {
InfoSec = 'information-security-v7', InfoSec = 'information-security-v7',
MachineLearningPy = 'machine-learning-with-python-v7', MachineLearningPy = 'machine-learning-with-python-v7',
CollegeAlgebraPy = 'college-algebra-with-python-v8', CollegeAlgebraPy = 'college-algebra-with-python-v8',
// Upcoming certifications
FoundationalCSharp = 'foundational-c-sharp-with-microsoft', FoundationalCSharp = 'foundational-c-sharp-with-microsoft',
// Upcoming certifications
UpcomingPython = 'upcoming-python-v8', UpcomingPython = 'upcoming-python-v8',
// Legacy certifications // Legacy certifications
LegacyFrontEnd = 'legacy-front-end', LegacyFrontEnd = 'legacy-front-end',
@@ -49,7 +49,8 @@ export const currentCertifications = [
Certification.DataAnalysisPy, Certification.DataAnalysisPy,
Certification.InfoSec, Certification.InfoSec,
Certification.MachineLearningPy, Certification.MachineLearningPy,
Certification.CollegeAlgebraPy Certification.CollegeAlgebraPy,
Certification.FoundationalCSharp
] as const; ] as const;
// "Legacy" certifications are another class of standard certifications. They're // "Legacy" certifications are another class of standard certifications. They're
@@ -63,10 +64,7 @@ export const legacyCertifications = [
// "Upcoming" certifications are standard certifications that are not live unless // "Upcoming" certifications are standard certifications that are not live unless
// showUpcomingChanges is true. // showUpcomingChanges is true.
export const upcomingCertifications = [ export const upcomingCertifications = [Certification.UpcomingPython] as const;
Certification.UpcomingPython,
Certification.FoundationalCSharp
] as const;
export const certTypes = { export const certTypes = {
frontEnd: 'isFrontEndCert', frontEnd: 'isFrontEndCert',
@@ -86,7 +84,7 @@ export const certTypes = {
fullStack: 'isFullStackCert', fullStack: 'isFullStackCert',
relationalDatabaseV8: 'isRelationalDatabaseCertV8', relationalDatabaseV8: 'isRelationalDatabaseCertV8',
collegeAlgebraPyV8: 'isCollegeAlgebraPyCertV8', collegeAlgebraPyV8: 'isCollegeAlgebraPyCertV8',
foundationalCSharp: 'isFoundationalCSharpCertV8' foundationalCSharpV8: 'isFoundationalCSharpCertV8'
} as const; } as const;
export const certIds = { export const certIds = {
@@ -107,7 +105,7 @@ export const certIds = {
machineLearningPyV7Id: '5e46fc95ac417301a38fb935', machineLearningPyV7Id: '5e46fc95ac417301a38fb935',
relationalDatabaseV8Id: '606243f50267e718b1e755f4', relationalDatabaseV8Id: '606243f50267e718b1e755f4',
collegeAlgebraPyV8Id: '61531b20cc9dfa2741a5b800', collegeAlgebraPyV8Id: '61531b20cc9dfa2741a5b800',
foundationalCSharpId: '647f7da207d29547b3bee1ba' foundationalCSharpV8Id: '647f7da207d29547b3bee1ba'
}; };
export const completionHours = { export const completionHours = {
@@ -128,7 +126,7 @@ export const completionHours = {
[certTypes.machineLearningPyV7]: 300, [certTypes.machineLearningPyV7]: 300,
[certTypes.relationalDatabaseV8]: 300, [certTypes.relationalDatabaseV8]: 300,
[certTypes.collegeAlgebraPyV8]: 300, [certTypes.collegeAlgebraPyV8]: 300,
[certTypes.foundationalCSharp]: 300 [certTypes.foundationalCSharpV8]: 300
}; };
export const certSlugTypeMap = { export const certSlugTypeMap = {
@@ -152,7 +150,7 @@ export const certSlugTypeMap = {
[Certification.MachineLearningPy]: certTypes.machineLearningPyV7, [Certification.MachineLearningPy]: certTypes.machineLearningPyV7,
[Certification.RelationalDb]: certTypes.relationalDatabaseV8, [Certification.RelationalDb]: certTypes.relationalDatabaseV8,
[Certification.CollegeAlgebraPy]: certTypes.collegeAlgebraPyV8, [Certification.CollegeAlgebraPy]: certTypes.collegeAlgebraPyV8,
[Certification.FoundationalCSharp]: certTypes.foundationalCSharp [Certification.FoundationalCSharp]: certTypes.foundationalCSharpV8
}; };
export const superBlockCertTypeMap = { export const superBlockCertTypeMap = {
@@ -176,7 +174,7 @@ export const superBlockCertTypeMap = {
[SuperBlocks.MachineLearningPy]: certTypes.machineLearningPyV7, [SuperBlocks.MachineLearningPy]: certTypes.machineLearningPyV7,
[SuperBlocks.RelationalDb]: certTypes.relationalDatabaseV8, [SuperBlocks.RelationalDb]: certTypes.relationalDatabaseV8,
[SuperBlocks.CollegeAlgebraPy]: certTypes.collegeAlgebraPyV8, [SuperBlocks.CollegeAlgebraPy]: certTypes.collegeAlgebraPyV8,
[SuperBlocks.FoundationalCSharp]: certTypes.foundationalCSharp, [SuperBlocks.FoundationalCSharp]: certTypes.foundationalCSharpV8,
// post-modern // post-modern
// TODO: use enum // TODO: use enum
@@ -202,7 +200,7 @@ export const certTypeIdMap = {
[certTypes.machineLearningPyV7]: certIds.machineLearningPyV7Id, [certTypes.machineLearningPyV7]: certIds.machineLearningPyV7Id,
[certTypes.relationalDatabaseV8]: certIds.relationalDatabaseV8Id, [certTypes.relationalDatabaseV8]: certIds.relationalDatabaseV8Id,
[certTypes.collegeAlgebraPyV8]: certIds.collegeAlgebraPyV8Id, [certTypes.collegeAlgebraPyV8]: certIds.collegeAlgebraPyV8Id,
[certTypes.foundationalCSharp]: certIds.foundationalCSharpId [certTypes.foundationalCSharpV8]: certIds.foundationalCSharpV8Id
}; };
export const certTypeTitleMap = { export const certTypeTitleMap = {
@@ -223,7 +221,7 @@ export const certTypeTitleMap = {
[certTypes.machineLearningPyV7]: 'Machine Learning with Python', [certTypes.machineLearningPyV7]: 'Machine Learning with Python',
[certTypes.relationalDatabaseV8]: 'Relational Database', [certTypes.relationalDatabaseV8]: 'Relational Database',
[certTypes.collegeAlgebraPyV8]: 'College Algebra with Python', [certTypes.collegeAlgebraPyV8]: 'College Algebra with Python',
[certTypes.foundationalCSharp]: 'Foundational C# with Microsoft' [certTypes.foundationalCSharpV8]: 'Foundational C# with Microsoft'
}; };
export const oldDataVizId = '561add10cb82ac38a17513b3'; export const oldDataVizId = '561add10cb82ac38a17513b3';
+12 -11
View File
@@ -35,6 +35,7 @@ export enum SuperBlockStages {
FrontEnd, FrontEnd,
Backend, Backend,
Python, Python,
Professional,
Extra, Extra,
Legacy, Legacy,
New, New,
@@ -66,6 +67,7 @@ export const superBlockOrder: SuperBlockOrder = {
SuperBlocks.MachineLearningPy, SuperBlocks.MachineLearningPy,
SuperBlocks.CollegeAlgebraPy SuperBlocks.CollegeAlgebraPy
], ],
[SuperBlockStages.Professional]: [SuperBlocks.FoundationalCSharp],
[SuperBlockStages.Extra]: [ [SuperBlockStages.Extra]: [
SuperBlocks.CodingInterviewPrep, SuperBlocks.CodingInterviewPrep,
SuperBlocks.ProjectEuler SuperBlocks.ProjectEuler
@@ -75,7 +77,6 @@ export const superBlockOrder: SuperBlockOrder = {
[SuperBlockStages.Upcoming]: [ [SuperBlockStages.Upcoming]: [
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.TheOdinProject, SuperBlocks.TheOdinProject,
SuperBlocks.FoundationalCSharp,
SuperBlocks.ExampleCertification, SuperBlocks.ExampleCertification,
SuperBlocks.UpcomingPython SuperBlocks.UpcomingPython
] ]
@@ -95,55 +96,55 @@ export const notAuditedSuperBlocks: NotAuditedSuperBlocks = {
SuperBlocks.InfoSec, SuperBlocks.InfoSec,
SuperBlocks.MachineLearningPy, SuperBlocks.MachineLearningPy,
SuperBlocks.CollegeAlgebraPy, SuperBlocks.CollegeAlgebraPy,
SuperBlocks.FoundationalCSharp,
SuperBlocks.CodingInterviewPrep, SuperBlocks.CodingInterviewPrep,
SuperBlocks.ProjectEuler, SuperBlocks.ProjectEuler,
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.TheOdinProject, SuperBlocks.TheOdinProject,
SuperBlocks.FoundationalCSharp,
SuperBlocks.UpcomingPython SuperBlocks.UpcomingPython
], ],
[Languages.Chinese]: [ [Languages.Chinese]: [
SuperBlocks.CollegeAlgebraPy, SuperBlocks.CollegeAlgebraPy,
SuperBlocks.FoundationalCSharp,
SuperBlocks.CodingInterviewPrep, SuperBlocks.CodingInterviewPrep,
SuperBlocks.ProjectEuler, SuperBlocks.ProjectEuler,
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.TheOdinProject, SuperBlocks.TheOdinProject,
SuperBlocks.FoundationalCSharp,
SuperBlocks.UpcomingPython SuperBlocks.UpcomingPython
], ],
[Languages.ChineseTraditional]: [ [Languages.ChineseTraditional]: [
SuperBlocks.CollegeAlgebraPy, SuperBlocks.CollegeAlgebraPy,
SuperBlocks.FoundationalCSharp,
SuperBlocks.CodingInterviewPrep, SuperBlocks.CodingInterviewPrep,
SuperBlocks.ProjectEuler, SuperBlocks.ProjectEuler,
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.TheOdinProject, SuperBlocks.TheOdinProject,
SuperBlocks.FoundationalCSharp,
SuperBlocks.UpcomingPython SuperBlocks.UpcomingPython
], ],
[Languages.Italian]: [ [Languages.Italian]: [
SuperBlocks.FoundationalCSharp,
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.TheOdinProject, SuperBlocks.TheOdinProject,
SuperBlocks.FoundationalCSharp,
SuperBlocks.UpcomingPython SuperBlocks.UpcomingPython
], ],
[Languages.Portuguese]: [ [Languages.Portuguese]: [
SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.FoundationalCSharp, SuperBlocks.FoundationalCSharp,
SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.UpcomingPython SuperBlocks.UpcomingPython
], ],
[Languages.Ukrainian]: [ [Languages.Ukrainian]: [
SuperBlocks.FoundationalCSharp,
SuperBlocks.CodingInterviewPrep, SuperBlocks.CodingInterviewPrep,
SuperBlocks.ProjectEuler, SuperBlocks.ProjectEuler,
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.FoundationalCSharp,
SuperBlocks.UpcomingPython SuperBlocks.UpcomingPython
], ],
[Languages.Japanese]: [ [Languages.Japanese]: [
SuperBlocks.CollegeAlgebraPy, SuperBlocks.CollegeAlgebraPy,
SuperBlocks.FoundationalCSharp,
SuperBlocks.ProjectEuler, SuperBlocks.ProjectEuler,
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.TheOdinProject, SuperBlocks.TheOdinProject,
SuperBlocks.FoundationalCSharp,
SuperBlocks.UpcomingPython SuperBlocks.UpcomingPython
], ],
[Languages.German]: [ [Languages.German]: [
@@ -157,11 +158,11 @@ export const notAuditedSuperBlocks: NotAuditedSuperBlocks = {
SuperBlocks.InfoSec, SuperBlocks.InfoSec,
SuperBlocks.MachineLearningPy, SuperBlocks.MachineLearningPy,
SuperBlocks.CollegeAlgebraPy, SuperBlocks.CollegeAlgebraPy,
SuperBlocks.FoundationalCSharp,
SuperBlocks.CodingInterviewPrep, SuperBlocks.CodingInterviewPrep,
SuperBlocks.ProjectEuler, SuperBlocks.ProjectEuler,
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.TheOdinProject, SuperBlocks.TheOdinProject,
SuperBlocks.FoundationalCSharp,
SuperBlocks.UpcomingPython SuperBlocks.UpcomingPython
], ],
[Languages.Arabic]: [ [Languages.Arabic]: [
@@ -174,11 +175,11 @@ export const notAuditedSuperBlocks: NotAuditedSuperBlocks = {
SuperBlocks.InfoSec, SuperBlocks.InfoSec,
SuperBlocks.MachineLearningPy, SuperBlocks.MachineLearningPy,
SuperBlocks.CollegeAlgebraPy, SuperBlocks.CollegeAlgebraPy,
SuperBlocks.FoundationalCSharp,
SuperBlocks.CodingInterviewPrep, SuperBlocks.CodingInterviewPrep,
SuperBlocks.ProjectEuler, SuperBlocks.ProjectEuler,
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.TheOdinProject, SuperBlocks.TheOdinProject,
SuperBlocks.FoundationalCSharp,
SuperBlocks.UpcomingPython SuperBlocks.UpcomingPython
], ],
[Languages.Swahili]: [ [Languages.Swahili]: [
@@ -191,10 +192,10 @@ export const notAuditedSuperBlocks: NotAuditedSuperBlocks = {
SuperBlocks.InfoSec, SuperBlocks.InfoSec,
SuperBlocks.MachineLearningPy, SuperBlocks.MachineLearningPy,
SuperBlocks.CollegeAlgebraPy, SuperBlocks.CollegeAlgebraPy,
SuperBlocks.FoundationalCSharp,
SuperBlocks.CodingInterviewPrep, SuperBlocks.CodingInterviewPrep,
SuperBlocks.ProjectEuler, SuperBlocks.ProjectEuler,
SuperBlocks.TheOdinProject, SuperBlocks.TheOdinProject,
SuperBlocks.FoundationalCSharp,
SuperBlocks.RespWebDesign, SuperBlocks.RespWebDesign,
SuperBlocks.FrontEndDevLibs, SuperBlocks.FrontEndDevLibs,
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
@@ -1,6 +1,6 @@
{ {
"name": "Add Logic to C# Console Applications", "name": "Add Logic to C# Console Applications",
"isUpcomingChange": true, "isUpcomingChange": false,
"dashedName": "add-logic-to-c-sharp-console-applications", "dashedName": "add-logic-to-c-sharp-console-applications",
"helpCategory": "HTML-CSS", "helpCategory": "HTML-CSS",
"order": 2, "order": 2,
@@ -1,6 +1,6 @@
{ {
"name": "Create and Run Simple C# Console Applications", "name": "Create and Run Simple C# Console Applications",
"isUpcomingChange": true, "isUpcomingChange": false,
"dashedName": "create-and-run-simple-c-sharp-console-applications", "dashedName": "create-and-run-simple-c-sharp-console-applications",
"helpCategory": "HTML-CSS", "helpCategory": "HTML-CSS",
"order": 1, "order": 1,
@@ -1,6 +1,6 @@
{ {
"name": "Create Methods in C# Console Applications", "name": "Create Methods in C# Console Applications",
"isUpcomingChange": true, "isUpcomingChange": false,
"dashedName": "create-methods-in-c-sharp-console-applications", "dashedName": "create-methods-in-c-sharp-console-applications",
"helpCategory": "HTML-CSS", "helpCategory": "HTML-CSS",
"order": 4, "order": 4,
@@ -1,6 +1,6 @@
{ {
"name": "Debug C# Console Applications", "name": "Debug C# Console Applications",
"isUpcomingChange": true, "isUpcomingChange": false,
"dashedName": "debug-c-sharp-console-applications", "dashedName": "debug-c-sharp-console-applications",
"helpCategory": "HTML-CSS", "helpCategory": "HTML-CSS",
"order": 5, "order": 5,
@@ -1,6 +1,6 @@
{ {
"name": "Foundational C# with Microsoft Certification Exam", "name": "Foundational C# with Microsoft Certification Exam",
"isUpcomingChange": true, "isUpcomingChange": false,
"dashedName": "foundational-c-sharp-with-microsoft-certification-exam", "dashedName": "foundational-c-sharp-with-microsoft-certification-exam",
"helpCategory": "HTML-CSS", "helpCategory": "HTML-CSS",
"order": 6, "order": 6,
@@ -1,6 +1,6 @@
{ {
"name": "Work with Variable Data in C# Console Applications", "name": "Work with Variable Data in C# Console Applications",
"isUpcomingChange": true, "isUpcomingChange": false,
"dashedName": "work-with-variable-data-in-c-sharp-console-applications", "dashedName": "work-with-variable-data-in-c-sharp-console-applications",
"helpCategory": "HTML-CSS", "helpCategory": "HTML-CSS",
"order": 3, "order": 3,
@@ -1,6 +1,6 @@
{ {
"name": "Write Your First Code Using C#", "name": "Write Your First Code Using C#",
"isUpcomingChange": true, "isUpcomingChange": false,
"dashedName": "write-your-first-code-using-c-sharp", "dashedName": "write-your-first-code-using-c-sharp",
"helpCategory": "HTML-CSS", "helpCategory": "HTML-CSS",
"order": 0, "order": 0,
+18 -19
View File
@@ -22,12 +22,12 @@ const mockSuperBlocks = [
SuperBlocks.InfoSec, SuperBlocks.InfoSec,
SuperBlocks.MachineLearningPy, SuperBlocks.MachineLearningPy,
SuperBlocks.CollegeAlgebraPy, SuperBlocks.CollegeAlgebraPy,
SuperBlocks.FoundationalCSharp,
SuperBlocks.CodingInterviewPrep, SuperBlocks.CodingInterviewPrep,
SuperBlocks.ProjectEuler, SuperBlocks.ProjectEuler,
SuperBlocks.RespWebDesign, SuperBlocks.RespWebDesign,
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.TheOdinProject, SuperBlocks.TheOdinProject,
SuperBlocks.FoundationalCSharp,
SuperBlocks.ExampleCertification SuperBlocks.ExampleCertification
]; ];
@@ -44,12 +44,12 @@ const fullSuperOrder = {
[SuperBlocks.InfoSec]: 9, [SuperBlocks.InfoSec]: 9,
[SuperBlocks.MachineLearningPy]: 10, [SuperBlocks.MachineLearningPy]: 10,
[SuperBlocks.CollegeAlgebraPy]: 11, [SuperBlocks.CollegeAlgebraPy]: 11,
[SuperBlocks.CodingInterviewPrep]: 12, [SuperBlocks.FoundationalCSharp]: 12,
[SuperBlocks.ProjectEuler]: 13, [SuperBlocks.CodingInterviewPrep]: 13,
[SuperBlocks.RespWebDesign]: 14, [SuperBlocks.ProjectEuler]: 14,
[SuperBlocks.JsAlgoDataStructNew]: 15, [SuperBlocks.RespWebDesign]: 15,
[SuperBlocks.TheOdinProject]: 16, [SuperBlocks.JsAlgoDataStructNew]: 16,
[SuperBlocks.FoundationalCSharp]: 17, [SuperBlocks.TheOdinProject]: 17,
[SuperBlocks.ExampleCertification]: 18 [SuperBlocks.ExampleCertification]: 18
}; };
@@ -93,11 +93,11 @@ describe('getSuperOrder', () => {
process.env.SHOW_NEW_CURRICULUM !== 'true' && process.env.SHOW_NEW_CURRICULUM !== 'true' &&
process.env.SHOW_UPCOMING_CHANGES !== 'true' process.env.SHOW_UPCOMING_CHANGES !== 'true'
) { ) {
expect.assertions(15); expect.assertions(16);
} else if (process.env.SHOW_NEW_CURRICULUM !== 'true') { } else if (process.env.SHOW_NEW_CURRICULUM !== 'true') {
expect.assertions(15); expect.assertions(16);
} else if (process.env.SHOW_UPCOMING_CHANGES !== 'true') { } else if (process.env.SHOW_UPCOMING_CHANGES !== 'true') {
expect.assertions(15); expect.assertions(16);
} else { } else {
expect.assertions(19); expect.assertions(19);
} }
@@ -114,24 +114,23 @@ describe('getSuperOrder', () => {
expect(getSuperOrder(SuperBlocks.InfoSec)).toBe(9); expect(getSuperOrder(SuperBlocks.InfoSec)).toBe(9);
expect(getSuperOrder(SuperBlocks.MachineLearningPy)).toBe(10); expect(getSuperOrder(SuperBlocks.MachineLearningPy)).toBe(10);
expect(getSuperOrder(SuperBlocks.CollegeAlgebraPy)).toBe(11); expect(getSuperOrder(SuperBlocks.CollegeAlgebraPy)).toBe(11);
expect(getSuperOrder(SuperBlocks.CodingInterviewPrep)).toBe(12); expect(getSuperOrder(SuperBlocks.FoundationalCSharp)).toBe(12);
expect(getSuperOrder(SuperBlocks.ProjectEuler)).toBe(13); expect(getSuperOrder(SuperBlocks.CodingInterviewPrep)).toBe(13);
expect(getSuperOrder(SuperBlocks.RespWebDesign)).toBe(14); expect(getSuperOrder(SuperBlocks.ProjectEuler)).toBe(14);
expect(getSuperOrder(SuperBlocks.RespWebDesign)).toBe(15);
if ( if (
process.env.SHOW_NEW_CURRICULUM === 'true' && process.env.SHOW_NEW_CURRICULUM === 'true' &&
process.env.SHOW_UPCOMING_CHANGES === 'true' process.env.SHOW_UPCOMING_CHANGES === 'true'
) { ) {
expect(getSuperOrder(SuperBlocks.JsAlgoDataStructNew)).toBe(15); expect(getSuperOrder(SuperBlocks.JsAlgoDataStructNew)).toBe(16);
expect(getSuperOrder(SuperBlocks.TheOdinProject)).toBe(16); expect(getSuperOrder(SuperBlocks.TheOdinProject)).toBe(17);
expect(getSuperOrder(SuperBlocks.FoundationalCSharp)).toBe(17);
expect(getSuperOrder(SuperBlocks.ExampleCertification)).toBe(18); expect(getSuperOrder(SuperBlocks.ExampleCertification)).toBe(18);
} else if (process.env.SHOW_NEW_CURRICULUM === 'true') { } else if (process.env.SHOW_NEW_CURRICULUM === 'true') {
return; return;
} else if (process.env.SHOW_UPCOMING_CHANGES === 'true') { } else if (process.env.SHOW_UPCOMING_CHANGES === 'true') {
expect(getSuperOrder(SuperBlocks.JsAlgoDataStructNew)).toBe(15); expect(getSuperOrder(SuperBlocks.JsAlgoDataStructNew)).toBe(16);
expect(getSuperOrder(SuperBlocks.TheOdinProject)).toBe(16); expect(getSuperOrder(SuperBlocks.TheOdinProject)).toBe(17);
expect(getSuperOrder(SuperBlocks.FoundationalCSharp)).toBe(17);
expect(getSuperOrder(SuperBlocks.ExampleCertification)).toBe(18); expect(getSuperOrder(SuperBlocks.ExampleCertification)).toBe(18);
} }
}); });
+2 -2
View File
@@ -25,9 +25,9 @@ const superBlocks = [
'Information Security', 'Information Security',
'Machine Learning with Python', 'Machine Learning with Python',
'College Algebra with Python', 'College Algebra with Python',
'(New) Foundational C# with Microsoft',
'Coding Interview Prep', 'Coding Interview Prep',
'Project Euler', 'Project Euler'
'Legacy Responsive Web Design'
]; ];
describe('Landing page', () => { describe('Landing page', () => {
+2 -2
View File
@@ -19,9 +19,9 @@ const superBlockNames = [
'Information Security Certification', 'Information Security Certification',
'Machine Learning with Python Certification', 'Machine Learning with Python Certification',
'College Algebra with Python Certification', 'College Algebra with Python Certification',
'(New) Foundational C# with Microsoft Certification',
'Coding Interview Prep', 'Coding Interview Prep',
'Project Euler', 'Project Euler'
'Legacy Responsive Web Design Challenges'
]; ];
describe('Learn Landing page (not logged in)', () => { describe('Learn Landing page (not logged in)', () => {
@@ -10,7 +10,7 @@ describe('Settings certifications area', () => {
it('Should render the default settings page', () => { it('Should render the default settings page', () => {
cy.visit('/settings/'); cy.visit('/settings/');
cy.findAllByText('Claim Certification').should($btns => { cy.findAllByText('Claim Certification').should($btns => {
expect($btns).to.have.length(17); expect($btns).to.have.length(18);
}); });
cy.findByText('Show Certification').should('not.exist'); cy.findByText('Show Certification').should('not.exist');
cy.contains(`I agree to freeCodeCamp's Academic Honesty Policy.`); cy.contains(`I agree to freeCodeCamp's Academic Honesty Policy.`);
+2 -2
View File
@@ -14,7 +14,7 @@ describe('Public profile certifications', () => {
// The following line is only required if you want to test it in development // The following line is only required if you want to test it in development
//cy.contains('Preview custom 404 page').click(); //cy.contains('Preview custom 404 page').click();
cy.get('[data-cy=claimed-certification]').should('have.length', 17); cy.get('[data-cy=claimed-certification]').should('have.length', 18);
}); });
it('Should show claimed certifications if the username includes uppercase characters', () => { it('Should show claimed certifications if the username includes uppercase characters', () => {
@@ -32,7 +32,7 @@ describe('Public profile certifications', () => {
// The following line is only required if you want to test it in development // The following line is only required if you want to test it in development
//cy.contains('Preview custom 404 page').click(); //cy.contains('Preview custom 404 page').click();
cy.get('[data-cy=claimed-certification]').should('have.length', 17); cy.get('[data-cy=claimed-certification]').should('have.length', 18);
}); });
}); });
+1
View File
@@ -159,6 +159,7 @@ export const notAuditedSuperBlocks: NotAuditedSuperBlocks = {
SuperBlocks.InfoSec, SuperBlocks.InfoSec,
SuperBlocks.MachineLearningPy, SuperBlocks.MachineLearningPy,
SuperBlocks.CollegeAlgebraPy, SuperBlocks.CollegeAlgebraPy,
SuperBlocks.FoundationalCSharp,
SuperBlocks.CodingInterviewPrep, SuperBlocks.CodingInterviewPrep,
SuperBlocks.ProjectEuler, SuperBlocks.ProjectEuler,
SuperBlocks.JsAlgoDataStructNew, SuperBlocks.JsAlgoDataStructNew,
+1
View File
@@ -25,6 +25,7 @@ const superBlocks = [
'Information Security', 'Information Security',
'Machine Learning with Python', 'Machine Learning with Python',
'College Algebra with Python', 'College Algebra with Python',
'Foundational C# with Microsoft',
'Coding Interview Prep', 'Coding Interview Prep',
'Project Euler', 'Project Euler',
'Legacy Responsive Web Design' 'Legacy Responsive Web Design'
@@ -68,7 +68,7 @@ export const superBlockList = [
path: '18-project-euler' path: '18-project-euler'
}, },
{ {
name: 'Foundational C# with Microsoft', name: '(New) Foundational C# with Microsoft',
path: '19-foundational-c-sharp-with-microsoft' path: '19-foundational-c-sharp-with-microsoft'
}, },
{ {
@@ -90,8 +90,8 @@ if (envData.clientLocale == 'english' && !envData.showUpcomingChanges) {
const isUpcoming = [ const isUpcoming = [
'2022/javascript-algorithms-and-data-structures', '2022/javascript-algorithms-and-data-structures',
'college-algebra-with-python', 'college-algebra-with-python',
'the-odin-project',
'foundational-c-sharp-with-microsoft', 'foundational-c-sharp-with-microsoft',
'the-odin-project',
'upcoming-python', 'upcoming-python',
'example-certification' 'example-certification'
]; ];