mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2025-12-19 18:18:27 -05:00
feat: add user flags for all certifications (#64338)
Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>
This commit is contained in:
committed by
GitHub
parent
4558096cee
commit
44f5cd6cfc
@@ -134,6 +134,13 @@ model user {
|
|||||||
is2018DataVisCert Boolean? // Undefined
|
is2018DataVisCert Boolean? // Undefined
|
||||||
is2018FullStackCert Boolean? // Undefined
|
is2018FullStackCert Boolean? // Undefined
|
||||||
isCollegeAlgebraPyCertV8 Boolean? // Undefined
|
isCollegeAlgebraPyCertV8 Boolean? // Undefined
|
||||||
|
isFrontEndLibsCertV9 Boolean? // Undefined
|
||||||
|
isBackEndDevApisCertV9 Boolean? // Undefined
|
||||||
|
isFullStackDeveloperCertV9 Boolean? // Undefined
|
||||||
|
isB1EnglishCert Boolean? // Undefined
|
||||||
|
isA2SpanishCert Boolean? // Undefined
|
||||||
|
isA2ChineseCert Boolean? // Undefined
|
||||||
|
isA1ChineseCert Boolean? // Undefined
|
||||||
// isUpcomingPythonCertV8 Boolean? // Undefined. It is in the db but has never been used.
|
// isUpcomingPythonCertV8 Boolean? // Undefined. It is in the db but has never been used.
|
||||||
keyboardShortcuts Boolean? // Undefined
|
keyboardShortcuts Boolean? // Undefined
|
||||||
linkedin String? // Null | Undefined
|
linkedin String? // Null | Undefined
|
||||||
|
|||||||
@@ -56,6 +56,13 @@ export const newUser = (email: string) => ({
|
|||||||
isRespWebDesignCert: false,
|
isRespWebDesignCert: false,
|
||||||
isRespWebDesignCertV9: false,
|
isRespWebDesignCertV9: false,
|
||||||
isSciCompPyCertV7: false,
|
isSciCompPyCertV7: false,
|
||||||
|
isFrontEndLibsCertV9: false,
|
||||||
|
isBackEndDevApisCertV9: false,
|
||||||
|
isFullStackDeveloperCertV9: false,
|
||||||
|
isB1EnglishCert: false,
|
||||||
|
isA2SpanishCert: false,
|
||||||
|
isA2ChineseCert: false,
|
||||||
|
isA1ChineseCert: false,
|
||||||
keyboardShortcuts: false,
|
keyboardShortcuts: false,
|
||||||
linkedin: null,
|
linkedin: null,
|
||||||
location: '',
|
location: '',
|
||||||
|
|||||||
@@ -21,9 +21,7 @@ const fullStackCertificateIds = [
|
|||||||
* @param certSlug - The certification slug to check.
|
* @param certSlug - The certification slug to check.
|
||||||
* @returns True if the certification slug is known, otherwise false.
|
* @returns True if the certification slug is known, otherwise false.
|
||||||
*/
|
*/
|
||||||
export function isKnownCertSlug(
|
export function isKnownCertSlug(certSlug: string): certSlug is Certification {
|
||||||
certSlug: string
|
|
||||||
): certSlug is keyof typeof certSlugTypeMap {
|
|
||||||
return certSlug in certSlugTypeMap;
|
return certSlug in certSlugTypeMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,13 @@ const nullableFlags = [
|
|||||||
'isRespWebDesignCertV9',
|
'isRespWebDesignCertV9',
|
||||||
'isSciCompPyCertV7',
|
'isSciCompPyCertV7',
|
||||||
'isDataAnalysisPyCertV7',
|
'isDataAnalysisPyCertV7',
|
||||||
|
'isFrontEndLibsCertV9',
|
||||||
|
'isBackEndDevApisCertV9',
|
||||||
|
'isFullStackDeveloperCertV9',
|
||||||
|
'isB1EnglishCert',
|
||||||
|
'isA2SpanishCert',
|
||||||
|
'isA2ChineseCert',
|
||||||
|
'isA1ChineseCert',
|
||||||
// isUpcomingPythonCertV8 exists in the db, but is not returned by the api-server
|
// isUpcomingPythonCertV8 exists in the db, but is not returned by the api-server
|
||||||
// TODO(Post-MVP): delete it from the db?
|
// TODO(Post-MVP): delete it from the db?
|
||||||
'keyboardShortcuts'
|
'keyboardShortcuts'
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
defaultUserEmail,
|
defaultUserEmail,
|
||||||
defaultUserId,
|
defaultUserId,
|
||||||
devLogin,
|
devLogin,
|
||||||
|
resetDefaultUser,
|
||||||
setupServer,
|
setupServer,
|
||||||
superRequest
|
superRequest
|
||||||
} from '../../../vitest.utils.js';
|
} from '../../../vitest.utils.js';
|
||||||
@@ -35,30 +36,13 @@ describe('certificate routes', () => {
|
|||||||
|
|
||||||
describe('PUT /certificate/verify', () => {
|
describe('PUT /certificate/verify', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
await resetDefaultUser();
|
||||||
await fastifyTestInstance.prisma.user.updateMany({
|
await fastifyTestInstance.prisma.user.updateMany({
|
||||||
where: { email: defaultUserEmail },
|
where: { email: defaultUserEmail },
|
||||||
data: {
|
data: {
|
||||||
completedChallenges: [],
|
|
||||||
is2018DataVisCert: false,
|
|
||||||
isA2EnglishCert: false,
|
|
||||||
isApisMicroservicesCert: false,
|
|
||||||
isCollegeAlgebraPyCertV8: false,
|
|
||||||
isDataAnalysisPyCertV7: false,
|
|
||||||
isFoundationalCSharpCertV8: false,
|
|
||||||
isFrontEndLibsCert: false,
|
|
||||||
isInfosecCertV7: false,
|
|
||||||
isJsAlgoDataStructCert: false,
|
|
||||||
isJavascriptCertV9: false,
|
|
||||||
isMachineLearningPyCertV7: false,
|
|
||||||
isPythonCertV9: false,
|
|
||||||
isQaCertV7: false,
|
|
||||||
isRelationalDatabaseCertV8: false,
|
|
||||||
isRelationalDatabaseCertV9: false,
|
|
||||||
isRespWebDesignCert: false,
|
|
||||||
isRespWebDesignCertV9: false,
|
|
||||||
isSciCompPyCertV7: false,
|
|
||||||
name: 'fcc',
|
name: 'fcc',
|
||||||
username: 'fcc'
|
username: 'fcc',
|
||||||
|
completedChallenges: []
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -174,7 +158,6 @@ describe('certificate routes', () => {
|
|||||||
await fastifyTestInstance.prisma.user.updateMany({
|
await fastifyTestInstance.prisma.user.updateMany({
|
||||||
where: { email: defaultUserEmail },
|
where: { email: defaultUserEmail },
|
||||||
data: {
|
data: {
|
||||||
completedChallenges: [],
|
|
||||||
isRespWebDesignCert: true
|
isRespWebDesignCert: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -309,29 +292,37 @@ describe('certificate routes', () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
isCertMap: {
|
isCertMap: {
|
||||||
|
is2018DataVisCert: false,
|
||||||
|
isA1ChineseCert: false,
|
||||||
|
isA2ChineseCert: false,
|
||||||
isA2EnglishCert: false,
|
isA2EnglishCert: false,
|
||||||
isRespWebDesignCert: true,
|
isA2SpanishCert: false,
|
||||||
isRespWebDesignCertV9: false,
|
isApisMicroservicesCert: false,
|
||||||
|
isB1EnglishCert: false,
|
||||||
|
isBackEndCert: false,
|
||||||
|
isBackEndDevApisCertV9: false,
|
||||||
|
isCollegeAlgebraPyCertV8: false,
|
||||||
|
isDataAnalysisPyCertV7: false,
|
||||||
|
isDataVisCert: false,
|
||||||
|
isFoundationalCSharpCertV8: false,
|
||||||
|
isFrontEndCert: false,
|
||||||
|
isFrontEndLibsCert: false,
|
||||||
|
isFrontEndLibsCertV9: false,
|
||||||
|
isFullStackCert: false,
|
||||||
|
isFullStackDeveloperCertV9: false,
|
||||||
|
isInfosecCertV7: false,
|
||||||
|
isInfosecQaCert: false,
|
||||||
isJavascriptCertV9: false,
|
isJavascriptCertV9: false,
|
||||||
isJsAlgoDataStructCert: false,
|
isJsAlgoDataStructCert: false,
|
||||||
isFrontEndLibsCert: false,
|
isJsAlgoDataStructCertV8: false,
|
||||||
is2018DataVisCert: false,
|
|
||||||
isApisMicroservicesCert: false,
|
|
||||||
isInfosecQaCert: false,
|
|
||||||
isQaCertV7: false,
|
|
||||||
isInfosecCertV7: false,
|
|
||||||
isFrontEndCert: false,
|
|
||||||
isBackEndCert: false,
|
|
||||||
isDataVisCert: false,
|
|
||||||
isFullStackCert: false,
|
|
||||||
isSciCompPyCertV7: false,
|
|
||||||
isDataAnalysisPyCertV7: false,
|
|
||||||
isMachineLearningPyCertV7: false,
|
isMachineLearningPyCertV7: false,
|
||||||
isRelationalDatabaseCertV8: false,
|
|
||||||
isCollegeAlgebraPyCertV8: false,
|
|
||||||
isFoundationalCSharpCertV8: false,
|
|
||||||
isPythonCertV9: false,
|
isPythonCertV9: false,
|
||||||
isRelationalDatabaseCertV9: false
|
isQaCertV7: false,
|
||||||
|
isRelationalDatabaseCertV8: false,
|
||||||
|
isRelationalDatabaseCertV9: false,
|
||||||
|
isRespWebDesignCert: true,
|
||||||
|
isRespWebDesignCertV9: false,
|
||||||
|
isSciCompPyCertV7: false
|
||||||
},
|
},
|
||||||
completedChallenges: [
|
completedChallenges: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type { FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebo
|
|||||||
import { challenges, getChallenges } from '../../utils/get-challenges.js';
|
import { challenges, getChallenges } from '../../utils/get-challenges.js';
|
||||||
import {
|
import {
|
||||||
Certification,
|
Certification,
|
||||||
|
type CertificationFlags,
|
||||||
certSlugTypeMap,
|
certSlugTypeMap,
|
||||||
certToIdMap,
|
certToIdMap,
|
||||||
certToTitleMap,
|
certToTitleMap,
|
||||||
@@ -121,45 +122,26 @@ export function createCertLookup(
|
|||||||
return certLookup;
|
return certLookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CertI {
|
function getUserIsCertMap(user: Partial<CertificationFlags>) {
|
||||||
isA2EnglishCert?: boolean;
|
|
||||||
isApisMicroservicesCert?: boolean;
|
|
||||||
isBackEndCert?: boolean;
|
|
||||||
isCollegeAlgebraPyCertV8?: boolean;
|
|
||||||
isDataAnalysisPyCertV7?: boolean;
|
|
||||||
isDataVisCert?: boolean;
|
|
||||||
isFrontEndCert?: boolean;
|
|
||||||
isFrontEndLibsCert?: boolean;
|
|
||||||
isFoundationalCSharpCertV8?: boolean;
|
|
||||||
isFullStackCert?: boolean;
|
|
||||||
isInfosecCertV7?: boolean;
|
|
||||||
isInfosecQaCert?: boolean;
|
|
||||||
isJavascriptCertV9?: boolean;
|
|
||||||
isJsAlgoDataStructCert?: boolean;
|
|
||||||
isJsAlgoDataStructCertV8?: boolean;
|
|
||||||
isMachineLearningPyCertV7?: boolean;
|
|
||||||
isPythonCertV9?: boolean;
|
|
||||||
isQaCertV7?: boolean;
|
|
||||||
isRelationalDatabaseCertV8?: boolean;
|
|
||||||
isRelationalDatabaseCertV9?: boolean;
|
|
||||||
isRespWebDesignCert?: boolean;
|
|
||||||
isRespWebDesignCertV9?: boolean;
|
|
||||||
isSciCompPyCertV7?: boolean;
|
|
||||||
is2018DataVisCert?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getUserIsCertMap(user: CertI) {
|
|
||||||
const {
|
const {
|
||||||
|
is2018DataVisCert = false,
|
||||||
|
isA1ChineseCert = false,
|
||||||
|
isA2ChineseCert = false,
|
||||||
isA2EnglishCert = false,
|
isA2EnglishCert = false,
|
||||||
|
isA2SpanishCert = false,
|
||||||
isApisMicroservicesCert = false,
|
isApisMicroservicesCert = false,
|
||||||
|
isB1EnglishCert = false,
|
||||||
isBackEndCert = false,
|
isBackEndCert = false,
|
||||||
|
isBackEndDevApisCertV9 = false,
|
||||||
isCollegeAlgebraPyCertV8 = false,
|
isCollegeAlgebraPyCertV8 = false,
|
||||||
isDataAnalysisPyCertV7 = false,
|
isDataAnalysisPyCertV7 = false,
|
||||||
isDataVisCert = false,
|
isDataVisCert = false,
|
||||||
|
isFoundationalCSharpCertV8 = false,
|
||||||
isFrontEndCert = false,
|
isFrontEndCert = false,
|
||||||
isFrontEndLibsCert = false,
|
isFrontEndLibsCert = false,
|
||||||
isFoundationalCSharpCertV8 = false,
|
isFrontEndLibsCertV9 = false,
|
||||||
isFullStackCert = false,
|
isFullStackCert = false,
|
||||||
|
isFullStackDeveloperCertV9 = false,
|
||||||
isInfosecCertV7 = false,
|
isInfosecCertV7 = false,
|
||||||
isInfosecQaCert = false,
|
isInfosecQaCert = false,
|
||||||
isJavascriptCertV9 = false,
|
isJavascriptCertV9 = false,
|
||||||
@@ -172,21 +154,28 @@ function getUserIsCertMap(user: CertI) {
|
|||||||
isRelationalDatabaseCertV9 = false,
|
isRelationalDatabaseCertV9 = false,
|
||||||
isRespWebDesignCert = false,
|
isRespWebDesignCert = false,
|
||||||
isRespWebDesignCertV9 = false,
|
isRespWebDesignCertV9 = false,
|
||||||
isSciCompPyCertV7 = false,
|
isSciCompPyCertV7 = false
|
||||||
is2018DataVisCert = false
|
|
||||||
} = user;
|
} = user;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
is2018DataVisCert,
|
||||||
|
isA1ChineseCert,
|
||||||
|
isA2ChineseCert,
|
||||||
isA2EnglishCert,
|
isA2EnglishCert,
|
||||||
|
isA2SpanishCert,
|
||||||
isApisMicroservicesCert,
|
isApisMicroservicesCert,
|
||||||
|
isB1EnglishCert,
|
||||||
isBackEndCert,
|
isBackEndCert,
|
||||||
|
isBackEndDevApisCertV9,
|
||||||
isCollegeAlgebraPyCertV8,
|
isCollegeAlgebraPyCertV8,
|
||||||
isDataAnalysisPyCertV7,
|
isDataAnalysisPyCertV7,
|
||||||
isDataVisCert,
|
isDataVisCert,
|
||||||
|
isFoundationalCSharpCertV8,
|
||||||
isFrontEndCert,
|
isFrontEndCert,
|
||||||
isFrontEndLibsCert,
|
isFrontEndLibsCert,
|
||||||
isFoundationalCSharpCertV8,
|
isFrontEndLibsCertV9,
|
||||||
isFullStackCert,
|
isFullStackCert,
|
||||||
|
isFullStackDeveloperCertV9,
|
||||||
isInfosecCertV7,
|
isInfosecCertV7,
|
||||||
isInfosecQaCert,
|
isInfosecQaCert,
|
||||||
isJavascriptCertV9,
|
isJavascriptCertV9,
|
||||||
@@ -199,8 +188,7 @@ function getUserIsCertMap(user: CertI) {
|
|||||||
isRelationalDatabaseCertV9,
|
isRelationalDatabaseCertV9,
|
||||||
isRespWebDesignCert,
|
isRespWebDesignCert,
|
||||||
isRespWebDesignCertV9,
|
isRespWebDesignCertV9,
|
||||||
isSciCompPyCertV7,
|
isSciCompPyCertV7
|
||||||
is2018DataVisCert
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,16 +334,23 @@ export const protectedCertificateRoutes: FastifyPluginCallbackTypebox = (
|
|||||||
username: true,
|
username: true,
|
||||||
is2018DataVisCert: true,
|
is2018DataVisCert: true,
|
||||||
is2018FullStackCert: true,
|
is2018FullStackCert: true,
|
||||||
|
isA1ChineseCert: true,
|
||||||
|
isA2ChineseCert: true,
|
||||||
isA2EnglishCert: true,
|
isA2EnglishCert: true,
|
||||||
|
isA2SpanishCert: true,
|
||||||
isApisMicroservicesCert: true,
|
isApisMicroservicesCert: true,
|
||||||
|
isB1EnglishCert: true,
|
||||||
isBackEndCert: true,
|
isBackEndCert: true,
|
||||||
|
isBackEndDevApisCertV9: true,
|
||||||
isCollegeAlgebraPyCertV8: true,
|
isCollegeAlgebraPyCertV8: true,
|
||||||
isDataAnalysisPyCertV7: true,
|
isDataAnalysisPyCertV7: true,
|
||||||
isDataVisCert: true,
|
isDataVisCert: true,
|
||||||
isFoundationalCSharpCertV8: true,
|
isFoundationalCSharpCertV8: true,
|
||||||
isFrontEndCert: true,
|
isFrontEndCert: true,
|
||||||
isFrontEndLibsCert: true,
|
isFrontEndLibsCert: true,
|
||||||
|
isFrontEndLibsCertV9: true,
|
||||||
isFullStackCert: true,
|
isFullStackCert: true,
|
||||||
|
isFullStackDeveloperCertV9: true,
|
||||||
isInfosecCertV7: true,
|
isInfosecCertV7: true,
|
||||||
isInfosecQaCert: true,
|
isInfosecQaCert: true,
|
||||||
isJavascriptCertV9: true,
|
isJavascriptCertV9: true,
|
||||||
|
|||||||
@@ -300,6 +300,13 @@ const publicUserData = {
|
|||||||
isRespWebDesignCert: testUserData.isRespWebDesignCert,
|
isRespWebDesignCert: testUserData.isRespWebDesignCert,
|
||||||
isRespWebDesignCertV9: testUserData.isRespWebDesignCertV9,
|
isRespWebDesignCertV9: testUserData.isRespWebDesignCertV9,
|
||||||
isSciCompPyCertV7: testUserData.isSciCompPyCertV7,
|
isSciCompPyCertV7: testUserData.isSciCompPyCertV7,
|
||||||
|
isFrontEndLibsCertV9: testUserData.isFrontEndLibsCertV9,
|
||||||
|
isBackEndDevApisCertV9: testUserData.isBackEndDevApisCertV9,
|
||||||
|
isFullStackDeveloperCertV9: testUserData.isFullStackDeveloperCertV9,
|
||||||
|
isB1EnglishCert: testUserData.isB1EnglishCert,
|
||||||
|
isA2SpanishCert: testUserData.isA2SpanishCert,
|
||||||
|
isA2ChineseCert: testUserData.isA2ChineseCert,
|
||||||
|
isA1ChineseCert: testUserData.isA1ChineseCert,
|
||||||
linkedin: testUserData.linkedin,
|
linkedin: testUserData.linkedin,
|
||||||
location: testUserData.location,
|
location: testUserData.location,
|
||||||
name: testUserData.name,
|
name: testUserData.name,
|
||||||
@@ -1029,6 +1036,13 @@ describe('userRoutes', () => {
|
|||||||
isRespWebDesignCert: false,
|
isRespWebDesignCert: false,
|
||||||
isRespWebDesignCertV9: false,
|
isRespWebDesignCertV9: false,
|
||||||
isSciCompPyCertV7: false,
|
isSciCompPyCertV7: false,
|
||||||
|
isFrontEndLibsCertV9: false,
|
||||||
|
isBackEndDevApisCertV9: false,
|
||||||
|
isFullStackDeveloperCertV9: false,
|
||||||
|
isB1EnglishCert: false,
|
||||||
|
isA2SpanishCert: false,
|
||||||
|
isA2ChineseCert: false,
|
||||||
|
isA1ChineseCert: false,
|
||||||
keyboardShortcuts: false,
|
keyboardShortcuts: false,
|
||||||
location: '',
|
location: '',
|
||||||
name: '',
|
name: '',
|
||||||
|
|||||||
@@ -708,6 +708,13 @@ export const userGetRoutes: FastifyPluginCallbackTypebox = (
|
|||||||
isRespWebDesignCert: true,
|
isRespWebDesignCert: true,
|
||||||
isRespWebDesignCertV9: true,
|
isRespWebDesignCertV9: true,
|
||||||
isSciCompPyCertV7: true,
|
isSciCompPyCertV7: true,
|
||||||
|
isFrontEndLibsCertV9: true,
|
||||||
|
isBackEndDevApisCertV9: true,
|
||||||
|
isFullStackDeveloperCertV9: true,
|
||||||
|
isB1EnglishCert: true,
|
||||||
|
isA2SpanishCert: true,
|
||||||
|
isA2ChineseCert: true,
|
||||||
|
isA1ChineseCert: true,
|
||||||
keyboardShortcuts: true,
|
keyboardShortcuts: true,
|
||||||
linkedin: true,
|
linkedin: true,
|
||||||
location: true,
|
location: true,
|
||||||
|
|||||||
@@ -84,6 +84,13 @@ export const unprotectedCertificateRoutes: FastifyPluginCallbackTypebox = (
|
|||||||
isRelationalDatabaseCertV9: true,
|
isRelationalDatabaseCertV9: true,
|
||||||
isCollegeAlgebraPyCertV8: true,
|
isCollegeAlgebraPyCertV8: true,
|
||||||
isFoundationalCSharpCertV8: true,
|
isFoundationalCSharpCertV8: true,
|
||||||
|
isFrontEndLibsCertV9: true,
|
||||||
|
isBackEndDevApisCertV9: true,
|
||||||
|
isFullStackDeveloperCertV9: true,
|
||||||
|
isB1EnglishCert: true,
|
||||||
|
isA2SpanishCert: true,
|
||||||
|
isA2ChineseCert: true,
|
||||||
|
isA1ChineseCert: true,
|
||||||
isHonest: true,
|
isHonest: true,
|
||||||
username: true,
|
username: true,
|
||||||
name: true,
|
name: true,
|
||||||
|
|||||||
@@ -28,7 +28,15 @@ export const isCertMap = Type.Object({
|
|||||||
isRelationalDatabaseCertV8: Type.Boolean(),
|
isRelationalDatabaseCertV8: Type.Boolean(),
|
||||||
isRelationalDatabaseCertV9: Type.Boolean(),
|
isRelationalDatabaseCertV9: Type.Boolean(),
|
||||||
isCollegeAlgebraPyCertV8: Type.Boolean(),
|
isCollegeAlgebraPyCertV8: Type.Boolean(),
|
||||||
isFoundationalCSharpCertV8: Type.Boolean()
|
isFoundationalCSharpCertV8: Type.Boolean(),
|
||||||
|
isJsAlgoDataStructCertV8: Type.Boolean(),
|
||||||
|
isA1ChineseCert: Type.Boolean(),
|
||||||
|
isA2ChineseCert: Type.Boolean(),
|
||||||
|
isA2SpanishCert: Type.Boolean(),
|
||||||
|
isB1EnglishCert: Type.Boolean(),
|
||||||
|
isBackEndDevApisCertV9: Type.Boolean(),
|
||||||
|
isFullStackDeveloperCertV9: Type.Boolean(),
|
||||||
|
isFrontEndLibsCertV9: Type.Boolean()
|
||||||
});
|
});
|
||||||
|
|
||||||
export const file = Type.Object({
|
export const file = Type.Object({
|
||||||
|
|||||||
@@ -93,6 +93,13 @@ export const getSessionUser = {
|
|||||||
isRespWebDesignCert: Type.Boolean(),
|
isRespWebDesignCert: Type.Boolean(),
|
||||||
isRespWebDesignCertV9: Type.Boolean(),
|
isRespWebDesignCertV9: Type.Boolean(),
|
||||||
isSciCompPyCertV7: Type.Boolean(),
|
isSciCompPyCertV7: Type.Boolean(),
|
||||||
|
isFrontEndLibsCertV9: Type.Boolean(),
|
||||||
|
isBackEndDevApisCertV9: Type.Boolean(),
|
||||||
|
isFullStackDeveloperCertV9: Type.Boolean(),
|
||||||
|
isB1EnglishCert: Type.Boolean(),
|
||||||
|
isA2SpanishCert: Type.Boolean(),
|
||||||
|
isA2ChineseCert: Type.Boolean(),
|
||||||
|
isA1ChineseCert: Type.Boolean(),
|
||||||
keyboardShortcuts: Type.Boolean(),
|
keyboardShortcuts: Type.Boolean(),
|
||||||
linkedin: Type.Optional(Type.String()),
|
linkedin: Type.Optional(Type.String()),
|
||||||
location: Type.String(),
|
location: Type.String(),
|
||||||
|
|||||||
@@ -39,6 +39,13 @@ export const createResetProperties = () => ({
|
|||||||
isRespWebDesignCert: false,
|
isRespWebDesignCert: false,
|
||||||
isRespWebDesignCertV9: false,
|
isRespWebDesignCertV9: false,
|
||||||
isSciCompPyCertV7: false,
|
isSciCompPyCertV7: false,
|
||||||
|
isFrontEndLibsCertV9: false,
|
||||||
|
isBackEndDevApisCertV9: false,
|
||||||
|
isFullStackDeveloperCertV9: false,
|
||||||
|
isB1EnglishCert: false,
|
||||||
|
isA2SpanishCert: false,
|
||||||
|
isA2ChineseCert: false,
|
||||||
|
isA1ChineseCert: false,
|
||||||
needsModeration: false,
|
needsModeration: false,
|
||||||
partiallyCompletedChallenges: [], // TODO(Post-MVP): Omit this from the document? (prisma will always return [])
|
partiallyCompletedChallenges: [], // TODO(Post-MVP): Omit this from the document? (prisma will always return [])
|
||||||
progressTimestamps: [Date.now()], // TODO(Post-MVP): This may need normalising before we can omit it. Also, does it need to start with a timestamp?
|
progressTimestamps: [Date.now()], // TODO(Post-MVP): This may need normalising before we can omit it. Also, does it need to start with a timestamp?
|
||||||
|
|||||||
@@ -163,6 +163,13 @@ export function ShowSettings(props: ShowSettingsProps): JSX.Element {
|
|||||||
isCollegeAlgebraPyCertV8,
|
isCollegeAlgebraPyCertV8,
|
||||||
isFoundationalCSharpCertV8,
|
isFoundationalCSharpCertV8,
|
||||||
isJsAlgoDataStructCertV8,
|
isJsAlgoDataStructCertV8,
|
||||||
|
isFrontEndLibsCertV9,
|
||||||
|
isBackEndDevApisCertV9,
|
||||||
|
isFullStackDeveloperCertV9,
|
||||||
|
isB1EnglishCert,
|
||||||
|
isA2SpanishCert,
|
||||||
|
isA2ChineseCert,
|
||||||
|
isA1ChineseCert,
|
||||||
isEmailVerified,
|
isEmailVerified,
|
||||||
isHonest,
|
isHonest,
|
||||||
sendQuincyEmail,
|
sendQuincyEmail,
|
||||||
@@ -251,9 +258,15 @@ export function ShowSettings(props: ShowSettingsProps): JSX.Element {
|
|||||||
isRespWebDesignCertV9={isRespWebDesignCertV9}
|
isRespWebDesignCertV9={isRespWebDesignCertV9}
|
||||||
isSciCompPyCertV7={isSciCompPyCertV7}
|
isSciCompPyCertV7={isSciCompPyCertV7}
|
||||||
isJsAlgoDataStructCertV8={isJsAlgoDataStructCertV8}
|
isJsAlgoDataStructCertV8={isJsAlgoDataStructCertV8}
|
||||||
|
isFrontEndLibsCertV9={isFrontEndLibsCertV9}
|
||||||
|
isBackEndDevApisCertV9={isBackEndDevApisCertV9}
|
||||||
|
isFullStackDeveloperCertV9={isFullStackDeveloperCertV9}
|
||||||
|
isB1EnglishCert={isB1EnglishCert}
|
||||||
|
isA2SpanishCert={isA2SpanishCert}
|
||||||
|
isA2ChineseCert={isA2ChineseCert}
|
||||||
|
isA1ChineseCert={isA1ChineseCert}
|
||||||
username={username}
|
username={username}
|
||||||
verifyCert={verifyCert}
|
verifyCert={verifyCert}
|
||||||
isEmailVerified={isEmailVerified}
|
|
||||||
/>
|
/>
|
||||||
<Spacer size='m' />
|
<Spacer size='m' />
|
||||||
</ScrollElement>
|
</ScrollElement>
|
||||||
|
|||||||
@@ -286,6 +286,13 @@ const defaultTestProps = {
|
|||||||
isRelationalDatabaseCertV9: false,
|
isRelationalDatabaseCertV9: false,
|
||||||
isCollegeAlgebraPyCertV8: false,
|
isCollegeAlgebraPyCertV8: false,
|
||||||
isFoundationalCSharpCertV8: false,
|
isFoundationalCSharpCertV8: false,
|
||||||
|
isFrontEndLibsCertV9: false,
|
||||||
|
isBackEndDevApisCertV9: false,
|
||||||
|
isFullStackDeveloperCertV9: false,
|
||||||
|
isB1EnglishCert: false,
|
||||||
|
isA2SpanishCert: false,
|
||||||
|
isA2ChineseCert: false,
|
||||||
|
isA1ChineseCert: false,
|
||||||
username: 'developmentuser',
|
username: 'developmentuser',
|
||||||
verifyCert: verifyCert,
|
verifyCert: verifyCert,
|
||||||
isEmailVerified: false
|
isEmailVerified: false
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ import {
|
|||||||
Certification,
|
Certification,
|
||||||
currentCertifications,
|
currentCertifications,
|
||||||
legacyCertifications,
|
legacyCertifications,
|
||||||
upcomingCertifications
|
upcomingCertifications,
|
||||||
|
type CertificationFlags
|
||||||
} from '../../../../shared-dist/config/certification-settings';
|
} from '../../../../shared-dist/config/certification-settings';
|
||||||
import env from '../../../config/env.json';
|
import env from '../../../config/env.json';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ChallengeData,
|
ChallengeData,
|
||||||
ClaimedCertifications,
|
|
||||||
CompletedChallenge,
|
CompletedChallenge,
|
||||||
GeneratedExamResults,
|
GeneratedExamResults,
|
||||||
User
|
User
|
||||||
@@ -66,7 +66,7 @@ const createCertifiedMap = ({
|
|||||||
isCollegeAlgebraPyCertV8,
|
isCollegeAlgebraPyCertV8,
|
||||||
isFoundationalCSharpCertV8,
|
isFoundationalCSharpCertV8,
|
||||||
isJsAlgoDataStructCertV8
|
isJsAlgoDataStructCertV8
|
||||||
}: ClaimedCertifications): Record<
|
}: CertificationFlags): Record<
|
||||||
Exclude<Certification, Certification.LegacyFullStack>,
|
Exclude<Certification, Certification.LegacyFullStack>,
|
||||||
boolean
|
boolean
|
||||||
> => ({
|
> => ({
|
||||||
@@ -115,7 +115,7 @@ type CertificationSettingsProps = {
|
|||||||
t: TFunction;
|
t: TFunction;
|
||||||
verifyCert: typeof verifyCert;
|
verifyCert: typeof verifyCert;
|
||||||
openModal: typeof openModal;
|
openModal: typeof openModal;
|
||||||
} & ClaimedCertifications &
|
} & CertificationFlags &
|
||||||
Pick<User, 'completedChallenges' | 'isHonest' | 'username'>;
|
Pick<User, 'completedChallenges' | 'isHonest' | 'username'>;
|
||||||
|
|
||||||
const LegacyFullStack = (props: CertificationSettingsProps) => {
|
const LegacyFullStack = (props: CertificationSettingsProps) => {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { HandlerProps } from 'react-reflex';
|
import { HandlerProps } from 'react-reflex';
|
||||||
import {
|
import type {
|
||||||
ChallengeLang,
|
ChallengeLang,
|
||||||
SuperBlocks
|
SuperBlocks
|
||||||
} from '../../../shared-dist/config/curriculum';
|
} from '../../../shared-dist/config/curriculum';
|
||||||
|
import type { CertificationFlags } from '../../../shared-dist/config/certification-settings';
|
||||||
import type { Chapter } from '../../../shared-dist/config/chapters';
|
import type { Chapter } from '../../../shared-dist/config/chapters';
|
||||||
import { BlockLayouts, BlockLabel } from '../../../shared-dist/config/blocks';
|
import { BlockLayouts, BlockLabel } from '../../../shared-dist/config/blocks';
|
||||||
import type { ChallengeFile, Ext } from '../../../shared-dist/utils/polyvinyl';
|
import type { ChallengeFile, Ext } from '../../../shared-dist/utils/polyvinyl';
|
||||||
@@ -424,6 +425,7 @@ export type User = {
|
|||||||
email: string;
|
email: string;
|
||||||
emailVerified: boolean;
|
emailVerified: boolean;
|
||||||
githubProfile: string;
|
githubProfile: string;
|
||||||
|
isEmailVerified: boolean;
|
||||||
isBanned: boolean;
|
isBanned: boolean;
|
||||||
isCheater: boolean;
|
isCheater: boolean;
|
||||||
isDonating: boolean;
|
isDonating: boolean;
|
||||||
@@ -447,7 +449,7 @@ export type User = {
|
|||||||
username: string;
|
username: string;
|
||||||
website: string;
|
website: string;
|
||||||
yearsTopContributor: string[];
|
yearsTopContributor: string[];
|
||||||
} & ClaimedCertifications;
|
} & CertificationFlags;
|
||||||
|
|
||||||
export type ProfileUI = {
|
export type ProfileUI = {
|
||||||
isLocked: boolean;
|
isLocked: boolean;
|
||||||
@@ -462,34 +464,6 @@ export type ProfileUI = {
|
|||||||
showTimeLine: boolean;
|
showTimeLine: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ClaimedCertifications = {
|
|
||||||
is2018DataVisCert: boolean;
|
|
||||||
isA2EnglishCert: boolean;
|
|
||||||
isApisMicroservicesCert: boolean;
|
|
||||||
isBackEndCert: boolean;
|
|
||||||
isDataVisCert: boolean;
|
|
||||||
isEmailVerified: boolean;
|
|
||||||
isCollegeAlgebraPyCertV8: boolean;
|
|
||||||
isFoundationalCSharpCertV8: boolean;
|
|
||||||
isFrontEndCert: boolean;
|
|
||||||
isFrontEndLibsCert: boolean;
|
|
||||||
isFullStackCert: boolean;
|
|
||||||
isInfosecQaCert: boolean;
|
|
||||||
isJavascriptCertV9: boolean;
|
|
||||||
isPythonCertV9: boolean;
|
|
||||||
isQaCertV7: boolean;
|
|
||||||
isInfosecCertV7: boolean;
|
|
||||||
isJsAlgoDataStructCert: boolean;
|
|
||||||
isRelationalDatabaseCertV8: boolean;
|
|
||||||
isRelationalDatabaseCertV9: boolean;
|
|
||||||
isRespWebDesignCert: boolean;
|
|
||||||
isRespWebDesignCertV9: boolean;
|
|
||||||
isSciCompPyCertV7: boolean;
|
|
||||||
isDataAnalysisPyCertV7: boolean;
|
|
||||||
isMachineLearningPyCertV7: boolean;
|
|
||||||
isJsAlgoDataStructCertV8: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SavedChallenges = SavedChallenge[];
|
type SavedChallenges = SavedChallenge[];
|
||||||
|
|
||||||
export type SavedChallenge = {
|
export type SavedChallenge = {
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import {
|
|||||||
import type { CertTitle } from '../../../../config/cert-and-project-map';
|
import type { CertTitle } from '../../../../config/cert-and-project-map';
|
||||||
import type {
|
import type {
|
||||||
ChapterBasedSuperBlockStructure,
|
ChapterBasedSuperBlockStructure,
|
||||||
ClaimedCertifications,
|
|
||||||
User
|
User
|
||||||
} from '../../../redux/prop-types';
|
} from '../../../redux/prop-types';
|
||||||
import type {
|
import type {
|
||||||
@@ -146,11 +145,7 @@ export const SuperBlockMap = ({
|
|||||||
const requirementLink = `/learn/${requirement}/`;
|
const requirementLink = `/learn/${requirement}/`;
|
||||||
|
|
||||||
const certSlug = superBlockToCertMap[requirement];
|
const certSlug = superBlockToCertMap[requirement];
|
||||||
const certFlagLookup = certSlugTypeMap as Record<
|
const certFlagKey = certSlug ? certSlugTypeMap[certSlug] : undefined;
|
||||||
string,
|
|
||||||
keyof ClaimedCertifications
|
|
||||||
>;
|
|
||||||
const certFlagKey = certSlug ? certFlagLookup[certSlug] : undefined;
|
|
||||||
const isRequirementComplete = Boolean(
|
const isRequirementComplete = Boolean(
|
||||||
certFlagKey && user?.[certFlagKey]
|
certFlagKey && user?.[certFlagKey]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
id: 68f1268149f045a650d4229e
|
id: 68f1268149f045a650d4229e
|
||||||
title: A1 Professional Chinese Certification
|
title: A1 Professional Chinese Certification
|
||||||
certification: a1-professional-chinese-v8
|
certification: a1-professional-chinese
|
||||||
challengeType: 7
|
challengeType: 7
|
||||||
tests:
|
tests:
|
||||||
- id: 688f1daf0133dbe2a36b140b
|
- id: 688f1daf0133dbe2a36b140b
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
id: 682c3153086dd7cabe7f48bc
|
id: 682c3153086dd7cabe7f48bc
|
||||||
title: A2 Professional Chinese Certification
|
title: A2 Professional Chinese Certification
|
||||||
certification: a2-professional-chinese-v8
|
certification: a2-professional-chinese
|
||||||
challengeType: 7
|
challengeType: 7
|
||||||
tests:
|
tests:
|
||||||
- id: 682c2753317b88f1ecdad894
|
- id: 682c2753317b88f1ecdad894
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
id: 681a6b22e5a782fe3459984a
|
id: 681a6b22e5a782fe3459984a
|
||||||
title: A2 Professional Spanish Certification
|
title: A2 Professional Spanish Certification
|
||||||
certification: a2-professional-spanish-v8
|
certification: a2-professional-spanish
|
||||||
challengeType: 7
|
challengeType: 7
|
||||||
tests:
|
tests:
|
||||||
- id: 681a8796e5a782fe3459984b
|
- id: 681a8796e5a782fe3459984b
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
id: 66607e53317411dd5e8aae21
|
id: 66607e53317411dd5e8aae21
|
||||||
title: B1 English for Developers Certification
|
title: B1 English for Developers Certification
|
||||||
certification: b1-english-for-developers-v8
|
certification: b1-english-for-developers
|
||||||
challengeType: 7
|
challengeType: 7
|
||||||
tests:
|
tests:
|
||||||
- id: 66607e5b317411dd5e8aae22
|
- id: 66607e5b317411dd5e8aae22
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ describe('certToIdMap', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('certSlugTypeMap', () => {
|
describe('certSlugTypeMap', () => {
|
||||||
it.todo('should contain a value for all certifications', () => {
|
it('should contain a value for all certifications', () => {
|
||||||
const allCertifications = Object.values(Certification).sort();
|
const allCertifications = Object.values(Certification).sort();
|
||||||
const certSlugTypeMapKeys = Object.keys(certSlugTypeMap).sort();
|
const certSlugTypeMapKeys = Object.keys(certSlugTypeMap).sort();
|
||||||
|
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ export enum Certification {
|
|||||||
BackEndDevApisV9 = 'back-end-development-and-apis-v9',
|
BackEndDevApisV9 = 'back-end-development-and-apis-v9',
|
||||||
A2English = 'a2-english-for-developers',
|
A2English = 'a2-english-for-developers',
|
||||||
FullStackDeveloperV9 = 'full-stack-developer-v9',
|
FullStackDeveloperV9 = 'full-stack-developer-v9',
|
||||||
B1English = 'b1-english-for-developers-v8',
|
B1English = 'b1-english-for-developers',
|
||||||
A2Spanish = 'a2-professional-spanish-v8',
|
A2Spanish = 'a2-professional-spanish',
|
||||||
A2Chinese = 'a2-professional-chinese-v8',
|
A2Chinese = 'a2-professional-chinese',
|
||||||
A1Chinese = 'a1-professional-chinese-v8',
|
A1Chinese = 'a1-professional-chinese',
|
||||||
// Legacy certifications
|
// Legacy certifications
|
||||||
LegacyFrontEnd = 'legacy-front-end',
|
LegacyFrontEnd = 'legacy-front-end',
|
||||||
JsAlgoDataStruct = 'javascript-algorithms-and-data-structures',
|
JsAlgoDataStruct = 'javascript-algorithms-and-data-structures',
|
||||||
@@ -175,7 +175,40 @@ export const completionHours: Record<Certification, number> = {
|
|||||||
[Certification.A1Chinese]: 300
|
[Certification.A1Chinese]: 300
|
||||||
};
|
};
|
||||||
|
|
||||||
export const certSlugTypeMap = {
|
type UserCertFlag =
|
||||||
|
| 'isFrontEndCert'
|
||||||
|
| 'isJsAlgoDataStructCert'
|
||||||
|
| 'isBackEndCert'
|
||||||
|
| 'isDataVisCert'
|
||||||
|
| 'isInfosecQaCert'
|
||||||
|
| 'isFullStackCert'
|
||||||
|
| 'isRespWebDesignCert'
|
||||||
|
| 'isJsAlgoDataStructCertV8'
|
||||||
|
| 'isFrontEndLibsCert'
|
||||||
|
| 'is2018DataVisCert'
|
||||||
|
| 'isApisMicroservicesCert'
|
||||||
|
| 'isQaCertV7'
|
||||||
|
| 'isInfosecCertV7'
|
||||||
|
| 'isSciCompPyCertV7'
|
||||||
|
| 'isDataAnalysisPyCertV7'
|
||||||
|
| 'isMachineLearningPyCertV7'
|
||||||
|
| 'isRelationalDatabaseCertV8'
|
||||||
|
| 'isCollegeAlgebraPyCertV8'
|
||||||
|
| 'isFoundationalCSharpCertV8'
|
||||||
|
| 'isA2EnglishCert'
|
||||||
|
| 'isRespWebDesignCertV9'
|
||||||
|
| 'isJavascriptCertV9'
|
||||||
|
| 'isFrontEndLibsCertV9'
|
||||||
|
| 'isPythonCertV9'
|
||||||
|
| 'isRelationalDatabaseCertV9'
|
||||||
|
| 'isBackEndDevApisCertV9'
|
||||||
|
| 'isFullStackDeveloperCertV9'
|
||||||
|
| 'isB1EnglishCert'
|
||||||
|
| 'isA2SpanishCert'
|
||||||
|
| 'isA2ChineseCert'
|
||||||
|
| 'isA1ChineseCert';
|
||||||
|
|
||||||
|
export const certSlugTypeMap: Record<Certification, UserCertFlag> = {
|
||||||
// legacy
|
// legacy
|
||||||
[Certification.LegacyFrontEnd]: 'isFrontEndCert',
|
[Certification.LegacyFrontEnd]: 'isFrontEndCert',
|
||||||
[Certification.JsAlgoDataStruct]: 'isJsAlgoDataStructCert',
|
[Certification.JsAlgoDataStruct]: 'isJsAlgoDataStructCert',
|
||||||
@@ -202,9 +235,21 @@ export const certSlugTypeMap = {
|
|||||||
[Certification.PythonV9]: 'isPythonCertV9',
|
[Certification.PythonV9]: 'isPythonCertV9',
|
||||||
[Certification.RelationalDbV9]: 'isRelationalDatabaseCertV9',
|
[Certification.RelationalDbV9]: 'isRelationalDatabaseCertV9',
|
||||||
[Certification.RespWebDesignV9]: 'isRespWebDesignCertV9',
|
[Certification.RespWebDesignV9]: 'isRespWebDesignCertV9',
|
||||||
[Certification.JsV9]: 'isJavascriptCertV9'
|
[Certification.JsV9]: 'isJavascriptCertV9',
|
||||||
|
|
||||||
// upcoming
|
// upcoming
|
||||||
} as const;
|
[Certification.FrontEndDevLibsV9]: 'isFrontEndLibsCertV9',
|
||||||
|
[Certification.BackEndDevApisV9]: 'isBackEndDevApisCertV9',
|
||||||
|
[Certification.FullStackDeveloperV9]: 'isFullStackDeveloperCertV9',
|
||||||
|
[Certification.B1English]: 'isB1EnglishCert',
|
||||||
|
[Certification.A2Spanish]: 'isA2SpanishCert',
|
||||||
|
[Certification.A2Chinese]: 'isA2ChineseCert',
|
||||||
|
[Certification.A1Chinese]: 'isA1ChineseCert'
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CertificationFlags = {
|
||||||
|
[key in UserCertFlag]: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: use i18n keys instead of hardcoded titles
|
// TODO: use i18n keys instead of hardcoded titles
|
||||||
export const certToTitleMap: Record<Certification, string> = {
|
export const certToTitleMap: Record<Certification, string> = {
|
||||||
|
|||||||
Reference in New Issue
Block a user