mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2025-12-19 18:18:27 -05:00
feat: add a2-english cert and exam (#62855)
This commit is contained in:
@@ -105,6 +105,7 @@ model user {
|
||||
emailVerifyTTL DateTime? // Null | Undefined
|
||||
externalId String
|
||||
githubProfile String? // Undefined
|
||||
isA2EnglishCert Boolean? // Undefined
|
||||
isApisMicroservicesCert Boolean? // Undefined
|
||||
isBackEndCert Boolean? // Undefined
|
||||
isBanned Boolean? // Undefined
|
||||
|
||||
@@ -28,6 +28,7 @@ export const newUser = (email: string) => ({
|
||||
id: expect.stringMatching(mongodbIdRe),
|
||||
is2018DataVisCert: false,
|
||||
is2018FullStackCert: false,
|
||||
isA2EnglishCert: false,
|
||||
isApisMicroservicesCert: false,
|
||||
isBackEndCert: false,
|
||||
isBanned: false,
|
||||
|
||||
@@ -7,6 +7,7 @@ import { pick, omit } from 'lodash-es';
|
||||
const nullableFlags = [
|
||||
'is2018DataVisCert',
|
||||
'is2018FullStackCert',
|
||||
'isA2EnglishCert',
|
||||
'isApisMicroservicesCert',
|
||||
'isBackEndCert',
|
||||
'isCheater',
|
||||
|
||||
@@ -292,6 +292,7 @@ describe('certificate routes', () => {
|
||||
}
|
||||
},
|
||||
isCertMap: {
|
||||
isA2EnglishCert: false,
|
||||
isRespWebDesignCert: true,
|
||||
isRespWebDesignCertV9: false,
|
||||
isJavascriptCertV9: false,
|
||||
|
||||
@@ -21,6 +21,7 @@ import { SHOW_UPCOMING_CHANGES } from '../../utils/env.js';
|
||||
import { isKnownCertSlug } from '../helpers/certificate-utils.js';
|
||||
|
||||
const {
|
||||
a2EnglishId,
|
||||
legacyFrontEndChallengeId,
|
||||
legacyBackEndChallengeId,
|
||||
legacyDataVisId,
|
||||
@@ -160,13 +161,15 @@ function createCertTypeIds(challenges: ReturnType<typeof getChallenges>) {
|
||||
challenges
|
||||
),
|
||||
[certTypes.javascriptV9]: getCertById(javascriptV9Id, challenges),
|
||||
[certTypes.respWebDesignV9]: getCertById(respWebDesignV9Id, challenges)
|
||||
[certTypes.respWebDesignV9]: getCertById(respWebDesignV9Id, challenges),
|
||||
|
||||
// upcoming
|
||||
[certTypes.a2English]: getCertById(a2EnglishId, challenges)
|
||||
};
|
||||
}
|
||||
|
||||
interface CertI {
|
||||
isA2EnglishCert?: boolean;
|
||||
isRespWebDesignCert?: boolean;
|
||||
isJsAlgoDataStructCert?: boolean;
|
||||
isJsAlgoDataStructCertV8?: boolean;
|
||||
@@ -192,6 +195,7 @@ interface CertI {
|
||||
|
||||
function getUserIsCertMap(user: CertI) {
|
||||
const {
|
||||
isA2EnglishCert = false,
|
||||
isRespWebDesignCert = false,
|
||||
isJsAlgoDataStructCert = false,
|
||||
isJsAlgoDataStructCertV8 = false,
|
||||
@@ -216,6 +220,7 @@ function getUserIsCertMap(user: CertI) {
|
||||
} = user;
|
||||
|
||||
return {
|
||||
isA2EnglishCert,
|
||||
isRespWebDesignCert,
|
||||
isJsAlgoDataStructCert,
|
||||
isJsAlgoDataStructCertV8,
|
||||
@@ -383,6 +388,7 @@ export const protectedCertificateRoutes: FastifyPluginCallbackTypebox = (
|
||||
completedChallenges: true,
|
||||
is2018DataVisCert: true,
|
||||
is2018FullStackCert: true,
|
||||
isA2EnglishCert: true,
|
||||
isApisMicroservicesCert: true,
|
||||
isBackEndCert: true,
|
||||
isDataVisCert: true,
|
||||
|
||||
@@ -274,6 +274,7 @@ const publicUserData = {
|
||||
githubProfile: testUserData.githubProfile,
|
||||
is2018DataVisCert: testUserData.is2018DataVisCert,
|
||||
is2018FullStackCert: testUserData.is2018FullStackCert, // TODO: should this be returned? The client doesn't use it at the moment.
|
||||
isA2EnglishCert: testUserData.isA2EnglishCert,
|
||||
isApisMicroservicesCert: testUserData.isApisMicroservicesCert,
|
||||
isBackEndCert: testUserData.isBackEndCert,
|
||||
isCheater: testUserData.isCheater,
|
||||
@@ -326,6 +327,7 @@ const sessionUserData = {
|
||||
|
||||
const baseProgressData = {
|
||||
currentChallengeId: '',
|
||||
isA2EnglishCert: false,
|
||||
isRespWebDesignCert: false,
|
||||
is2018DataVisCert: false,
|
||||
isFrontEndLibsCert: false,
|
||||
@@ -998,6 +1000,7 @@ describe('userRoutes', () => {
|
||||
yearsTopContributor: [],
|
||||
is2018DataVisCert: false,
|
||||
is2018FullStackCert: false,
|
||||
isA2EnglishCert: false,
|
||||
isApisMicroservicesCert: false,
|
||||
isBackEndCert: false,
|
||||
isCheater: false,
|
||||
|
||||
@@ -667,6 +667,7 @@ export const userGetRoutes: FastifyPluginCallbackTypebox = (
|
||||
id: true,
|
||||
is2018DataVisCert: true,
|
||||
is2018FullStackCert: true,
|
||||
isA2EnglishCert: true,
|
||||
isApisMicroservicesCert: true,
|
||||
isBackEndCert: true,
|
||||
isCheater: true,
|
||||
|
||||
@@ -60,6 +60,7 @@ export const unprotectedCertificateRoutes: FastifyPluginCallbackTypebox = (
|
||||
select: {
|
||||
isBanned: true,
|
||||
isCheater: true,
|
||||
isA2EnglishCert: true,
|
||||
isFrontEndCert: true,
|
||||
isBackEndCert: true,
|
||||
isFullStackCert: true,
|
||||
|
||||
@@ -187,6 +187,7 @@ const publicUserData = {
|
||||
githubProfile: testUserData.githubProfile,
|
||||
is2018DataVisCert: testUserData.is2018DataVisCert,
|
||||
is2018FullStackCert: testUserData.is2018FullStackCert, // TODO: should this be returned? The client doesn't use it at the moment.
|
||||
isA2EnglishCert: testUserData.isA2EnglishCert,
|
||||
isApisMicroservicesCert: testUserData.isApisMicroservicesCert,
|
||||
isBackEndCert: testUserData.isBackEndCert,
|
||||
isCheater: testUserData.isCheater,
|
||||
|
||||
@@ -6,6 +6,7 @@ export const genericError = Type.Object({
|
||||
});
|
||||
|
||||
export const isCertMap = Type.Object({
|
||||
isA2EnglishCert: Type.Boolean(),
|
||||
isRespWebDesignCert: Type.Boolean(),
|
||||
isRespWebDesignCertV9: Type.Boolean(),
|
||||
isJavascriptCertV9: Type.Boolean(),
|
||||
|
||||
@@ -68,6 +68,7 @@ export const getSessionUser = {
|
||||
id: Type.String(),
|
||||
is2018DataVisCert: Type.Boolean(),
|
||||
is2018FullStackCert: Type.Boolean(),
|
||||
isA2EnglishCert: Type.Boolean(),
|
||||
isApisMicroservicesCert: Type.Boolean(),
|
||||
isBackEndCert: Type.Boolean(),
|
||||
isCheater: Type.Boolean(),
|
||||
|
||||
@@ -52,6 +52,7 @@ export const getPublicProfile = {
|
||||
githubProfile: Type.Optional(Type.String()),
|
||||
is2018DataVisCert: Type.Boolean(),
|
||||
is2018FullStackCert: Type.Boolean(),
|
||||
isA2EnglishCert: Type.Boolean(),
|
||||
isApisMicroservicesCert: Type.Boolean(),
|
||||
isBackEndCert: Type.Boolean(),
|
||||
isCheater: Type.Boolean(),
|
||||
|
||||
@@ -16,6 +16,7 @@ export const createResetProperties = () => ({
|
||||
currentChallengeId: '',
|
||||
is2018DataVisCert: false,
|
||||
is2018FullStackCert: false,
|
||||
isA2EnglishCert: false,
|
||||
isApisMicroservicesCert: false,
|
||||
isBackEndCert: false,
|
||||
isCollegeAlgebraPyCertV8: false,
|
||||
|
||||
@@ -903,7 +903,7 @@ const allStandardCerts = [
|
||||
certSlug: Certification.A2English,
|
||||
projects: [
|
||||
{
|
||||
id: '651dd3e06ffb500e3f2ce478',
|
||||
id: '6721db5d9f0c116e6a0fe25a',
|
||||
title: 'A2 English for Developers Certification Exam',
|
||||
link: `${a2EnglishBase}/a2-english-for-developers-certification-exam/a2-english-for-developers-certification-exam`,
|
||||
certSlug: Certification.A2English
|
||||
|
||||
@@ -122,6 +122,7 @@ export function ShowSettings(props: ShowSettingsProps): JSX.Element {
|
||||
completedChallenges,
|
||||
email,
|
||||
is2018DataVisCert,
|
||||
isA2EnglishCert,
|
||||
isApisMicroservicesCert,
|
||||
isJavascriptCertV9,
|
||||
isJsAlgoDataStructCert,
|
||||
@@ -190,6 +191,7 @@ export function ShowSettings(props: ShowSettingsProps): JSX.Element {
|
||||
completedChallenges={completedChallenges}
|
||||
createFlashMessage={createFlashMessage}
|
||||
is2018DataVisCert={is2018DataVisCert}
|
||||
isA2EnglishCert={isA2EnglishCert}
|
||||
isApisMicroservicesCert={isApisMicroservicesCert}
|
||||
isBackEndCert={isBackEndCert}
|
||||
isDataAnalysisPyCertV7={isDataAnalysisPyCertV7}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { User } from '../../../../redux/prop-types';
|
||||
|
||||
export const getCertifications = (user: User) => {
|
||||
const {
|
||||
isA2EnglishCert,
|
||||
isRespWebDesignCert,
|
||||
isRespWebDesignCertV9,
|
||||
is2018DataVisCert,
|
||||
@@ -28,6 +29,7 @@ export const getCertifications = (user: User) => {
|
||||
|
||||
return {
|
||||
hasModernCert:
|
||||
isA2EnglishCert ||
|
||||
isRespWebDesignCert ||
|
||||
isRespWebDesignCertV9 ||
|
||||
is2018DataVisCert ||
|
||||
@@ -52,6 +54,11 @@ export const getCertifications = (user: User) => {
|
||||
isInfosecQaCert,
|
||||
isFullStackCert,
|
||||
currentCerts: [
|
||||
{
|
||||
show: isA2EnglishCert,
|
||||
title: 'A2 English for Developers Certification',
|
||||
certSlug: Certification.A2English
|
||||
},
|
||||
{
|
||||
show: isRespWebDesignCert,
|
||||
title: 'Responsive Web Design Certification',
|
||||
|
||||
@@ -54,6 +54,7 @@ const userProps = {
|
||||
yearsTopContributor: [],
|
||||
isDonating: false,
|
||||
is2018DataVisCert: true,
|
||||
isA2EnglishCert: true,
|
||||
isApisMicroservicesCert: true,
|
||||
isBackEndCert: true,
|
||||
isDataVisCert: true,
|
||||
|
||||
@@ -262,6 +262,7 @@ const defaultTestProps = {
|
||||
],
|
||||
createFlashMessage: createFlashMessage,
|
||||
is2018DataVisCert: false,
|
||||
isA2EnglishCert: false,
|
||||
isApisMicroservicesCert: false,
|
||||
isBackEndCert: false,
|
||||
isDataVisCert: true,
|
||||
|
||||
@@ -47,6 +47,7 @@ const mapDispatchToProps = {
|
||||
|
||||
const createCertifiedMap = ({
|
||||
is2018DataVisCert,
|
||||
isA2EnglishCert,
|
||||
isApisMicroservicesCert,
|
||||
isJavascriptCertV9,
|
||||
isJsAlgoDataStructCert,
|
||||
@@ -97,7 +98,7 @@ const createCertifiedMap = ({
|
||||
[Certification.PythonV9]: false,
|
||||
[Certification.RelationalDbV9]: false,
|
||||
[Certification.BackEndDevApisV9]: false,
|
||||
[Certification.A2English]: false,
|
||||
[Certification.A2English]: isA2EnglishCert,
|
||||
[Certification.B1English]: false,
|
||||
[Certification.A2Spanish]: false,
|
||||
[Certification.A2Chinese]: false,
|
||||
|
||||
@@ -432,6 +432,7 @@ export type ProfileUI = {
|
||||
|
||||
export type ClaimedCertifications = {
|
||||
is2018DataVisCert: boolean;
|
||||
isA2EnglishCert: boolean;
|
||||
isApisMicroservicesCert: boolean;
|
||||
isBackEndCert: boolean;
|
||||
isDataVisCert: boolean;
|
||||
|
||||
@@ -22,7 +22,8 @@ const idToPath = new Map(
|
||||
'68e008aa5f80c6099d47b3a2': Certification.FrontEndDevLibsV9,
|
||||
'68e6bd5020effa1586e79855': Certification.PythonV9,
|
||||
'68e6bd5120effa1586e79856': Certification.RelationalDbV9,
|
||||
'68e6bd5120effa1586e79857': Certification.BackEndDevApisV9
|
||||
'68e6bd5120effa1586e79857': Certification.BackEndDevApisV9,
|
||||
'651dd7e01d697d0aab7833b7': Certification.A2English
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
---
|
||||
id: 651dd7e01d697d0aab7833b7
|
||||
title: A2 English for Developers Certification
|
||||
certification: a2-english-for-developers
|
||||
|
||||
@@ -119,7 +119,8 @@ export const certTypes = {
|
||||
collegeAlgebraPyV8: 'isCollegeAlgebraPyCertV8',
|
||||
foundationalCSharpV8: 'isFoundationalCSharpCertV8',
|
||||
jsAlgoDataStructV8: 'isJsAlgoDataStructCertV8',
|
||||
javascriptV9: 'isJavascriptCertV9'
|
||||
javascriptV9: 'isJavascriptCertV9',
|
||||
a2English: 'isA2EnglishCert'
|
||||
} as const;
|
||||
|
||||
export const certIds = {
|
||||
@@ -147,7 +148,8 @@ export const certIds = {
|
||||
frontEndLibsV9Id: '68e008aa5f80c6099d47b3a2',
|
||||
pythonV9Id: '68e6bd5020effa1586e79855',
|
||||
relationalDbV9Id: '68e6bd5120effa1586e79856',
|
||||
backEndDevApisV9Id: '68e6bd5120effa1586e79857'
|
||||
backEndDevApisV9Id: '68e6bd5120effa1586e79857',
|
||||
a2EnglishId: '651dd7e01d697d0aab7833b7'
|
||||
};
|
||||
|
||||
export const completionHours = {
|
||||
@@ -171,7 +173,8 @@ export const completionHours = {
|
||||
[certTypes.collegeAlgebraPyV8]: 300,
|
||||
[certTypes.foundationalCSharpV8]: 300,
|
||||
[certTypes.jsAlgoDataStructV8]: 300,
|
||||
[certTypes.javascriptV9]: 300
|
||||
[certTypes.javascriptV9]: 300,
|
||||
[certTypes.a2English]: 300
|
||||
};
|
||||
|
||||
export const certSlugTypeMap = {
|
||||
@@ -200,7 +203,8 @@ export const certSlugTypeMap = {
|
||||
|
||||
// upcoming
|
||||
[Certification.RespWebDesignV9]: certTypes.respWebDesignV9,
|
||||
[Certification.JsV9]: certTypes.javascriptV9
|
||||
[Certification.JsV9]: certTypes.javascriptV9,
|
||||
[Certification.A2English]: certTypes.a2English
|
||||
};
|
||||
|
||||
export const superBlockCertTypeMap = {
|
||||
@@ -229,9 +233,10 @@ export const superBlockCertTypeMap = {
|
||||
|
||||
// post-modern
|
||||
// TODO: use enum
|
||||
[SuperBlocks.RespWebDesignNew]: certTypes.respWebDesign
|
||||
[SuperBlocks.RespWebDesignNew]: certTypes.respWebDesign,
|
||||
|
||||
// upcoming
|
||||
[SuperBlocks.A2English]: certTypes.a2English
|
||||
};
|
||||
|
||||
export const certTypeIdMap = {
|
||||
@@ -255,7 +260,8 @@ export const certTypeIdMap = {
|
||||
[certTypes.collegeAlgebraPyV8]: certIds.collegeAlgebraPyV8Id,
|
||||
[certTypes.foundationalCSharpV8]: certIds.foundationalCSharpV8Id,
|
||||
[certTypes.jsAlgoDataStructV8]: certIds.jsAlgoDataStructV8Id,
|
||||
[certTypes.javascriptV9]: certIds.javascriptV9Id
|
||||
[certTypes.javascriptV9]: certIds.javascriptV9Id,
|
||||
[certTypes.a2English]: certIds.a2EnglishId
|
||||
};
|
||||
|
||||
export const certTypeTitleMap = {
|
||||
@@ -280,7 +286,8 @@ export const certTypeTitleMap = {
|
||||
[certTypes.collegeAlgebraPyV8]: 'College Algebra with Python',
|
||||
[certTypes.foundationalCSharpV8]: 'Foundational C# with Microsoft',
|
||||
[certTypes.jsAlgoDataStructV8]: 'JavaScript Algorithms and Data Structures',
|
||||
[certTypes.javascriptV9]: 'JavaScript'
|
||||
[certTypes.javascriptV9]: 'JavaScript',
|
||||
[certTypes.a2English]: 'A2 English for Developers'
|
||||
};
|
||||
|
||||
export const superBlockToCertMap: {
|
||||
|
||||
@@ -220,6 +220,7 @@ module.exports.fullyCertifiedUser = {
|
||||
sendQuincyEmail: null,
|
||||
currentChallengeId: '',
|
||||
isHonest: true,
|
||||
isA2EnglishCert: true,
|
||||
isFrontEndCert: true,
|
||||
isDataVisCert: true,
|
||||
isBackEndCert: true,
|
||||
|
||||
Reference in New Issue
Block a user