diff --git a/client/config/cert-and-project-map.ts b/client/config/cert-and-project-map.ts index 85a5065937e..083275afe08 100644 --- a/client/config/cert-and-project-map.ts +++ b/client/config/cert-and-project-map.ts @@ -793,7 +793,7 @@ const allStandardCerts = [ ] }, { - id: '647e3159823e0ef219c7359b', + id: '647f7da207d29547b3bee1ba', title: 'Foundational C# with Microsoft', certSlug: Certification.FoundationalCSharp, projects: [ @@ -952,12 +952,12 @@ const allStandardCerts = [ ] }, { - id: '682c3153086dd7cabe7f48bc', + id: '68f1268149f045a650d4229e', title: 'A1 Professional Chinese', certSlug: Certification.A1Chinese, projects: [ { - id: '682c2753317b88f1ecdad894', + id: '688f1daf0133dbe2a36b140b', title: 'Dialogue 1: PLACEHOLDER', link: `${a1ChineseBase}/learn-essential-courtesies-at-the-office /text-1`, @@ -1008,6 +1008,12 @@ const upcomingCerts = allStandardCerts.filter((cert): cert is UpcomingCert => const liveCerts = showUpcomingChanges ? [...currentCerts, ...legacyCerts, fullstackCert, ...upcomingCerts] : [...currentCerts, ...legacyCerts, fullstackCert]; +const allCerts = [ + ...currentCerts, + ...legacyCerts, + fullstackCert, + ...upcomingCerts +]; type CertsToProjects = Record< (typeof allStandardCerts)[number]['certSlug'], @@ -1025,4 +1031,4 @@ export type CertTitle = | (typeof liveCerts)[number]['title'] | 'Legacy Full Stack'; -export { liveCerts, certsToProjects }; +export { liveCerts, certsToProjects, allCerts }; diff --git a/curriculum/build-certification.test.js b/curriculum/build-certification.test.js new file mode 100644 index 00000000000..aea6b9a7efa --- /dev/null +++ b/curriculum/build-certification.test.js @@ -0,0 +1,94 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import { describe, test, expect } from 'vitest'; + +import { allCerts } from '../client/config/cert-and-project-map.js'; +import { buildCertification } from './build-certification.js'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +describe('build-certification', () => { + const certificationsDir = path.join( + __dirname, + 'challenges/english/certifications' + ); + const yamlFiles = fs + .readdirSync(certificationsDir) + .filter(file => file.endsWith('.yml')); + + yamlFiles.forEach(file => { + describe(`${file} file`, () => { + const filePath = path.join(certificationsDir, file); + const result = buildCertification(filePath); + + test('should have the correct properties', () => { + expect(result).toHaveProperty('challenges'); + expect(Array.isArray(result.challenges)).toBe(true); + expect(result.challenges).toHaveLength(1); + + const certData = result.challenges[0]; + expect(certData).toHaveProperty('id'); + expect(certData).toHaveProperty('title'); + expect(certData).toHaveProperty('certification'); + expect(certData).toHaveProperty('challengeType'); + expect(certData).toHaveProperty('tests'); + expect(Array.isArray(certData.tests)).toBe(true); + }); + + test('Should have matching items in cert-and-project-map', () => { + const certData = result.challenges[0]; + const certTests = certData.tests; + + const matchingCert = allCerts.find(cert => cert.id === certData.id); + + expect( + matchingCert, + `Cert ID ${certData.id} not found in allCerts.` + ).toBeDefined(); + expect( + matchingCert, + `Matching cert has no 'projects' property` + ).toHaveProperty('projects'); + + // skip legacy-full-stack as it has no projects + if (file !== 'legacy-full-stack.yml') { + expect( + Array.isArray(matchingCert.projects), + `Matching cert 'projects' is not an array` + ).toBe(true); + + const certProjects = matchingCert.projects; + + expect( + certProjects.length, + `Project count mismatch: allCerts has ${certProjects.length} projects, YAML has ${certTests.length} tests` + ).toBe(certTests.length); + + certTests.forEach((test, i) => { + expect( + test, + `Test at index ${i} in missing id property` + ).toHaveProperty('id'); + expect( + test, + `Test at index ${i} missing title property` + ).toHaveProperty('title'); + + const matchingProject = certProjects[i]; + + expect( + matchingProject, + `No project found at index ${i} for test ${test.id}` + ).toBeDefined(); + expect( + matchingProject.id, + `Project ID mismatch at index ${i}: allCerts has "${matchingProject.id}", YAML has "${test.id}"` + ).toBe(test.id); + }); + } + }); + }); + }); +}); diff --git a/curriculum/challenges/english/certifications/a1-professional-chinese.yml b/curriculum/challenges/english/certifications/a1-professional-chinese.yml index c65a94c73bb..1c9a35159a6 100644 --- a/curriculum/challenges/english/certifications/a1-professional-chinese.yml +++ b/curriculum/challenges/english/certifications/a1-professional-chinese.yml @@ -1,5 +1,5 @@ --- -id: 688f1daf0133dbe2a36b140b +id: 68f1268149f045a650d4229e title: A1 Professional Chinese Certification certification: a1-professional-chinese-certification challengeType: 7 diff --git a/curriculum/challenges/english/certifications/responsive-web-design.yml b/curriculum/challenges/english/certifications/responsive-web-design.yml index 116dd1396c3..a0eb0de9884 100644 --- a/curriculum/challenges/english/certifications/responsive-web-design.yml +++ b/curriculum/challenges/english/certifications/responsive-web-design.yml @@ -3,13 +3,13 @@ title: Responsive Web Design Certification certification: responsive-web-design challengeType: 7 tests: - - id: bd7158d8c442eddfaeb5bd18 - title: Build a Tribute Page - id: 587d78af367417b2b2512b03 title: Build a Survey Form - - id: 587d78af367417b2b2512b04 - title: Build a Product Landing Page + - id: bd7158d8c442eddfaeb5bd18 + title: Build a Tribute Page - id: 587d78b0367417b2b2512b05 title: Build a Technical Documentation Page + - id: 587d78af367417b2b2512b04 + title: Build a Product Landing Page - id: bd7158d8c242eddfaeb5bd13 title: Build a Personal Portfolio Webpage