({ lang, challenges, meta })
| 166 | } |
| 167 | |
| 168 | async function populateTestsForLang({ lang, challenges, meta }) { |
| 169 | // We have to dynamically import this because otherwise it will not be mocked. |
| 170 | // Presumably this is because we import from_this file in the generated block |
| 171 | // test files and that happens before the mock is applied. |
| 172 | const { buildChallenge } = |
| 173 | await import('@freecodecamp/challenge-builder/build'); |
| 174 | const validateChallenge = challengeSchemaValidator(); |
| 175 | |
| 176 | describe(`Language: ${lang}`, function () { |
| 177 | const challengeTitles = new ChallengeTitles(); |
| 178 | const mongoIds = new MongoIds(); |
| 179 | |
| 180 | challenges.forEach((challenge, id) => { |
| 181 | // When testing single challenge, in project based curriculum, |
| 182 | // challenge to test (current challenge) might not have solution. |
| 183 | // Instead seed from next challenge is tested against tests from |
| 184 | // current challenge. Next challenge is skipped from testing. |
| 185 | if (FCC_CHALLENGE_ID && id > 0) return; |
| 186 | |
| 187 | const dashedBlockName = challenge.block; |
| 188 | // TODO: once certifications are not included in the list of challenges, |
| 189 | // stop returning early here. |
| 190 | if (typeof dashedBlockName === 'undefined') return; |
| 191 | describe(`Block: ${challenge.block}`, function () { |
| 192 | describe(`Title: ${challenge.title}`, function () { |
| 193 | describe(`ID: ${challenge.id}`, function () { |
| 194 | // Note: the title in meta.json are purely for human readability and |
| 195 | // do not include translations, so we do not validate against them. |
| 196 | it(`Matches an ID in ${challenge.block}.json`, function () { |
| 197 | const index = meta[dashedBlockName]?.challengeOrder?.findIndex( |
| 198 | ({ id }) => id === challenge.id |
| 199 | ); |
| 200 | expect( |
| 201 | index, |
| 202 | `Cannot find ID "${challenge.id}" in ${challenge.block}.json file for block "${dashedBlockName}"` |
| 203 | ).toBeGreaterThanOrEqual(0); |
| 204 | }); |
| 205 | |
| 206 | it('Common checks', function () { |
| 207 | const result = validateChallenge(challenge); |
| 208 | |
| 209 | expect(result.error).toBeUndefined(); |
| 210 | const { id, block, dashedName } = challenge; |
| 211 | |
| 212 | expect(dashedName).toBeDefined(); |
| 213 | |
| 214 | const pathAndTitle = `${block}/${dashedName}`; |
| 215 | const idVerificationMessage = mongoIds.check(id, block); |
| 216 | expect(idVerificationMessage).toBeNull(); |
| 217 | const dupeTitleCheck = challengeTitles.check(dashedName, block); |
| 218 | expect( |
| 219 | dupeTitleCheck, |
| 220 | `All challenges within a block must have a unique dashed name. ${dashedName} (at ${pathAndTitle}) is already assigned` |
| 221 | ).toBeTruthy(); |
| 222 | }); |
| 223 | |
| 224 | const { challengeType } = challenge; |
| 225 |
no test coverage detected