mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00: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
|
||||
is2018FullStackCert 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.
|
||||
keyboardShortcuts Boolean? // Undefined
|
||||
linkedin String? // Null | Undefined
|
||||
|
||||
@@ -56,6 +56,13 @@ export const newUser = (email: string) => ({
|
||||
isRespWebDesignCert: false,
|
||||
isRespWebDesignCertV9: false,
|
||||
isSciCompPyCertV7: false,
|
||||
isFrontEndLibsCertV9: false,
|
||||
isBackEndDevApisCertV9: false,
|
||||
isFullStackDeveloperCertV9: false,
|
||||
isB1EnglishCert: false,
|
||||
isA2SpanishCert: false,
|
||||
isA2ChineseCert: false,
|
||||
isA1ChineseCert: false,
|
||||
keyboardShortcuts: false,
|
||||
linkedin: null,
|
||||
location: '',
|
||||
|
||||
@@ -21,9 +21,7 @@ const fullStackCertificateIds = [
|
||||
* @param certSlug - The certification slug to check.
|
||||
* @returns True if the certification slug is known, otherwise false.
|
||||
*/
|
||||
export function isKnownCertSlug(
|
||||
certSlug: string
|
||||
): certSlug is keyof typeof certSlugTypeMap {
|
||||
export function isKnownCertSlug(certSlug: string): certSlug is Certification {
|
||||
return certSlug in certSlugTypeMap;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,13 @@ const nullableFlags = [
|
||||
'isRespWebDesignCertV9',
|
||||
'isSciCompPyCertV7',
|
||||
'isDataAnalysisPyCertV7',
|
||||
'isFrontEndLibsCertV9',
|
||||
'isBackEndDevApisCertV9',
|
||||
'isFullStackDeveloperCertV9',
|
||||
'isB1EnglishCert',
|
||||
'isA2SpanishCert',
|
||||
'isA2ChineseCert',
|
||||
'isA1ChineseCert',
|
||||
// isUpcomingPythonCertV8 exists in the db, but is not returned by the api-server
|
||||
// TODO(Post-MVP): delete it from the db?
|
||||
'keyboardShortcuts'
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
defaultUserEmail,
|
||||
defaultUserId,
|
||||
devLogin,
|
||||
resetDefaultUser,
|
||||
setupServer,
|
||||
superRequest
|
||||
} from '../../../vitest.utils.js';
|
||||
@@ -35,30 +36,13 @@ describe('certificate routes', () => {
|
||||
|
||||
describe('PUT /certificate/verify', () => {
|
||||
beforeEach(async () => {
|
||||
await resetDefaultUser();
|
||||
await fastifyTestInstance.prisma.user.updateMany({
|
||||
where: { email: defaultUserEmail },
|
||||
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',
|
||||
username: 'fcc'
|
||||
username: 'fcc',
|
||||
completedChallenges: []
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -174,7 +158,6 @@ describe('certificate routes', () => {
|
||||
await fastifyTestInstance.prisma.user.updateMany({
|
||||
where: { email: defaultUserEmail },
|
||||
data: {
|
||||
completedChallenges: [],
|
||||
isRespWebDesignCert: true
|
||||
}
|
||||
});
|
||||
@@ -309,29 +292,37 @@ describe('certificate routes', () => {
|
||||
}
|
||||
},
|
||||
isCertMap: {
|
||||
is2018DataVisCert: false,
|
||||
isA1ChineseCert: false,
|
||||
isA2ChineseCert: false,
|
||||
isA2EnglishCert: false,
|
||||
isRespWebDesignCert: true,
|
||||
isRespWebDesignCertV9: false,
|
||||
isA2SpanishCert: 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,
|
||||
isJsAlgoDataStructCert: false,
|
||||
isFrontEndLibsCert: false,
|
||||
is2018DataVisCert: false,
|
||||
isApisMicroservicesCert: false,
|
||||
isInfosecQaCert: false,
|
||||
isQaCertV7: false,
|
||||
isInfosecCertV7: false,
|
||||
isFrontEndCert: false,
|
||||
isBackEndCert: false,
|
||||
isDataVisCert: false,
|
||||
isFullStackCert: false,
|
||||
isSciCompPyCertV7: false,
|
||||
isDataAnalysisPyCertV7: false,
|
||||
isJsAlgoDataStructCertV8: false,
|
||||
isMachineLearningPyCertV7: false,
|
||||
isRelationalDatabaseCertV8: false,
|
||||
isCollegeAlgebraPyCertV8: false,
|
||||
isFoundationalCSharpCertV8: false,
|
||||
isPythonCertV9: false,
|
||||
isRelationalDatabaseCertV9: false
|
||||
isQaCertV7: false,
|
||||
isRelationalDatabaseCertV8: false,
|
||||
isRelationalDatabaseCertV9: false,
|
||||
isRespWebDesignCert: true,
|
||||
isRespWebDesignCertV9: false,
|
||||
isSciCompPyCertV7: false
|
||||
},
|
||||
completedChallenges: [
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebo
|
||||
import { challenges, getChallenges } from '../../utils/get-challenges.js';
|
||||
import {
|
||||
Certification,
|
||||
type CertificationFlags,
|
||||
certSlugTypeMap,
|
||||
certToIdMap,
|
||||
certToTitleMap,
|
||||
@@ -121,45 +122,26 @@ export function createCertLookup(
|
||||
return certLookup;
|
||||
}
|
||||
|
||||
interface CertI {
|
||||
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) {
|
||||
function getUserIsCertMap(user: Partial<CertificationFlags>) {
|
||||
const {
|
||||
is2018DataVisCert = false,
|
||||
isA1ChineseCert = false,
|
||||
isA2ChineseCert = false,
|
||||
isA2EnglishCert = false,
|
||||
isA2SpanishCert = false,
|
||||
isApisMicroservicesCert = false,
|
||||
isB1EnglishCert = false,
|
||||
isBackEndCert = false,
|
||||
isBackEndDevApisCertV9 = false,
|
||||
isCollegeAlgebraPyCertV8 = false,
|
||||
isDataAnalysisPyCertV7 = false,
|
||||
isDataVisCert = false,
|
||||
isFoundationalCSharpCertV8 = false,
|
||||
isFrontEndCert = false,
|
||||
isFrontEndLibsCert = false,
|
||||
isFoundationalCSharpCertV8 = false,
|
||||
isFrontEndLibsCertV9 = false,
|
||||
isFullStackCert = false,
|
||||
isFullStackDeveloperCertV9 = false,
|
||||
isInfosecCertV7 = false,
|
||||
isInfosecQaCert = false,
|
||||
isJavascriptCertV9 = false,
|
||||
@@ -172,21 +154,28 @@ function getUserIsCertMap(user: CertI) {
|
||||
isRelationalDatabaseCertV9 = false,
|
||||
isRespWebDesignCert = false,
|
||||
isRespWebDesignCertV9 = false,
|
||||
isSciCompPyCertV7 = false,
|
||||
is2018DataVisCert = false
|
||||
isSciCompPyCertV7 = false
|
||||
} = user;
|
||||
|
||||
return {
|
||||
is2018DataVisCert,
|
||||
isA1ChineseCert,
|
||||
isA2ChineseCert,
|
||||
isA2EnglishCert,
|
||||
isA2SpanishCert,
|
||||
isApisMicroservicesCert,
|
||||
isB1EnglishCert,
|
||||
isBackEndCert,
|
||||
isBackEndDevApisCertV9,
|
||||
isCollegeAlgebraPyCertV8,
|
||||
isDataAnalysisPyCertV7,
|
||||
isDataVisCert,
|
||||
isFoundationalCSharpCertV8,
|
||||
isFrontEndCert,
|
||||
isFrontEndLibsCert,
|
||||
isFoundationalCSharpCertV8,
|
||||
isFrontEndLibsCertV9,
|
||||
isFullStackCert,
|
||||
isFullStackDeveloperCertV9,
|
||||
isInfosecCertV7,
|
||||
isInfosecQaCert,
|
||||
isJavascriptCertV9,
|
||||
@@ -199,8 +188,7 @@ function getUserIsCertMap(user: CertI) {
|
||||
isRelationalDatabaseCertV9,
|
||||
isRespWebDesignCert,
|
||||
isRespWebDesignCertV9,
|
||||
isSciCompPyCertV7,
|
||||
is2018DataVisCert
|
||||
isSciCompPyCertV7
|
||||
};
|
||||
}
|
||||
|
||||
@@ -346,16 +334,23 @@ export const protectedCertificateRoutes: FastifyPluginCallbackTypebox = (
|
||||
username: true,
|
||||
is2018DataVisCert: true,
|
||||
is2018FullStackCert: true,
|
||||
isA1ChineseCert: true,
|
||||
isA2ChineseCert: true,
|
||||
isA2EnglishCert: true,
|
||||
isA2SpanishCert: true,
|
||||
isApisMicroservicesCert: true,
|
||||
isB1EnglishCert: true,
|
||||
isBackEndCert: true,
|
||||
isBackEndDevApisCertV9: true,
|
||||
isCollegeAlgebraPyCertV8: true,
|
||||
isDataAnalysisPyCertV7: true,
|
||||
isDataVisCert: true,
|
||||
isFoundationalCSharpCertV8: true,
|
||||
isFrontEndCert: true,
|
||||
isFrontEndLibsCert: true,
|
||||
isFrontEndLibsCertV9: true,
|
||||
isFullStackCert: true,
|
||||
isFullStackDeveloperCertV9: true,
|
||||
isInfosecCertV7: true,
|
||||
isInfosecQaCert: true,
|
||||
isJavascriptCertV9: true,
|
||||
|
||||
@@ -300,6 +300,13 @@ const publicUserData = {
|
||||
isRespWebDesignCert: testUserData.isRespWebDesignCert,
|
||||
isRespWebDesignCertV9: testUserData.isRespWebDesignCertV9,
|
||||
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,
|
||||
location: testUserData.location,
|
||||
name: testUserData.name,
|
||||
@@ -1029,6 +1036,13 @@ describe('userRoutes', () => {
|
||||
isRespWebDesignCert: false,
|
||||
isRespWebDesignCertV9: false,
|
||||
isSciCompPyCertV7: false,
|
||||
isFrontEndLibsCertV9: false,
|
||||
isBackEndDevApisCertV9: false,
|
||||
isFullStackDeveloperCertV9: false,
|
||||
isB1EnglishCert: false,
|
||||
isA2SpanishCert: false,
|
||||
isA2ChineseCert: false,
|
||||
isA1ChineseCert: false,
|
||||
keyboardShortcuts: false,
|
||||
location: '',
|
||||
name: '',
|
||||
|
||||
@@ -708,6 +708,13 @@ export const userGetRoutes: FastifyPluginCallbackTypebox = (
|
||||
isRespWebDesignCert: true,
|
||||
isRespWebDesignCertV9: true,
|
||||
isSciCompPyCertV7: true,
|
||||
isFrontEndLibsCertV9: true,
|
||||
isBackEndDevApisCertV9: true,
|
||||
isFullStackDeveloperCertV9: true,
|
||||
isB1EnglishCert: true,
|
||||
isA2SpanishCert: true,
|
||||
isA2ChineseCert: true,
|
||||
isA1ChineseCert: true,
|
||||
keyboardShortcuts: true,
|
||||
linkedin: true,
|
||||
location: true,
|
||||
|
||||
@@ -84,6 +84,13 @@ export const unprotectedCertificateRoutes: FastifyPluginCallbackTypebox = (
|
||||
isRelationalDatabaseCertV9: true,
|
||||
isCollegeAlgebraPyCertV8: true,
|
||||
isFoundationalCSharpCertV8: true,
|
||||
isFrontEndLibsCertV9: true,
|
||||
isBackEndDevApisCertV9: true,
|
||||
isFullStackDeveloperCertV9: true,
|
||||
isB1EnglishCert: true,
|
||||
isA2SpanishCert: true,
|
||||
isA2ChineseCert: true,
|
||||
isA1ChineseCert: true,
|
||||
isHonest: true,
|
||||
username: true,
|
||||
name: true,
|
||||
|
||||
@@ -28,7 +28,15 @@ export const isCertMap = Type.Object({
|
||||
isRelationalDatabaseCertV8: Type.Boolean(),
|
||||
isRelationalDatabaseCertV9: 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({
|
||||
|
||||
@@ -93,6 +93,13 @@ export const getSessionUser = {
|
||||
isRespWebDesignCert: Type.Boolean(),
|
||||
isRespWebDesignCertV9: 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(),
|
||||
linkedin: Type.Optional(Type.String()),
|
||||
location: Type.String(),
|
||||
|
||||
@@ -39,6 +39,13 @@ export const createResetProperties = () => ({
|
||||
isRespWebDesignCert: false,
|
||||
isRespWebDesignCertV9: false,
|
||||
isSciCompPyCertV7: false,
|
||||
isFrontEndLibsCertV9: false,
|
||||
isBackEndDevApisCertV9: false,
|
||||
isFullStackDeveloperCertV9: false,
|
||||
isB1EnglishCert: false,
|
||||
isA2SpanishCert: false,
|
||||
isA2ChineseCert: false,
|
||||
isA1ChineseCert: false,
|
||||
needsModeration: false,
|
||||
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?
|
||||
|
||||
Reference in New Issue
Block a user