Feat/graphql challenge map readme/tests update#578
Conversation
NewtonLC
left a comment
There was a problem hiding this comment.
I tested this out in a Windows environment and originally, upon running node scripts/build-challenge-map-graphql.mjs, there was an issue with the pathing of the challenge map. I updated the file path to use the fileURLToPath() function and it should now work on all machines!
Aside from that, this PR looks ready for review.
| 8. Run `npm run mock-fcc-data` | ||
| 9. Run `npx prisma studio` | ||
|
|
||
| ### Challenge map (FCC Proper) |
There was a problem hiding this comment.
Can you add some explanation about the purpose of the Challenge Map? Why does does Classroom App need it? How is it consumed/transformed?
There was a problem hiding this comment.
I added additional notation in the readme about the purpose of the Challenge Map and how it works so that the functionality is not lost going forward as well as specifics in the file itself and the Utils file explaining how the breakdown works so that if anyone addresses the functions in the future they have context.
| const name = mapEntry.name; | ||
| const certification = | ||
| mapEntry.certification || (mapEntry.superblocks || [])[0]; | ||
| const block = mapEntry.block || (mapEntry.blocks || [])[0]; |
There was a problem hiding this comment.
Why do we need to check for both cases mapEntry.certification AND mapEntry.superblocks? Are we not sure what the actual property name is? Is the property name sometimes "certification" and at other times "superblocks"? Same question for "block" vs. "blocks" -- is it sometimes one vs. the other?
There was a problem hiding this comment.
Short answer: that code was dead and has been removed. It was a transition artifact — the build script originally wrote singular fields (certification, block), then was updated to write arrays (superblocks, blocks). The conditional mapEntry.certification || (mapEntry.superblocks || [])[0] was the bridge during that migration and was never cleaned up. Now that the build script always emits arrays, we replaced the whole inline expression with getCanonicalChallengeMapLocation(mapEntry) from challengeMapHelpers.js, which only reads from the arrays. I removed the additional code as it is no longer needed and it makes the code much simpler and straightforward.
| mapEntry.certification || (mapEntry.superblocks || [])[0]; | ||
| const block = mapEntry.block || (mapEntry.blocks || [])[0]; |
There was a problem hiding this comment.
2nd time this code is duplicated. Can we prevent the code duplication?
There was a problem hiding this comment.
I created a util/challengeMapHelpers.js file to consolidate the duplicated logic. This now uses the util/challengeMapHelpers.js file.
| mapEntry.certification || (mapEntry.superblocks || [])[0]; | ||
| const block = mapEntry.block || (mapEntry.blocks || [])[0]; |
There was a problem hiding this comment.
This code gets duplicated below. Is there a way to prevent the duplication of this code?
There was a problem hiding this comment.
This now uses the util/challengeMapHelpers.js file.
- Add scripts/build-challenge-map-graphql.mjs to generate challengeMap.json
* Fetches curriculum from FCC GraphQL API
* Builds flat map with { certification, block, name } structure
* Output: data/challengeMap.json with 12,847 unique challenges
* Run: node scripts/build-challenge-map-graphql.mjs
- Add util/challengeMapUtils.js for transforming student data
* resolveAllStudentsToDashboardFormat() - converts FCC Proper student data to dashboard format
* buildStudentDashboardData() - groups challenges by certification and block
- Update .gitignore to exclude generated data/challengeMap.json
…C Proper/sync tests to their feature PR
… and tests - Extract getCanonicalChallengeMapLocation into util/challengeMapHelpers.js so the "first element wins" canonical rule lives in one place - Remove dead mapEntry.certification fallback from challengeMapUtils.js (was a schema-migration artifact; build script only emits arrays now) - Lazy-load challengeMap.json to fix Babel/CJS __dirname collision under Jest - Expand README Challenge Map section: purpose, why-canonical design reasoning, generate/test commands - Refactor tests: remove jest.mock(fs/path) and duplicate implementations; import real functions; add real-map suite that reads data/challengeMap.json Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8dca44a to
0f4bbca
Compare
Checklist:
Update index.md)Summary
This PR extends the work merged in #574 by:
challengeMap.jsonand recommending a weekly refresh.challengeMap.json(when present) to validate that FCC Proper output is digestible by Classroom.Co-authored-by: Newton Chung <NewtonLC@users.noreply.github.com>
Why keep both synthetic and real-map tests?
Synthetic tests validate the transformation logic in isolation (stable, deterministic).
Real-map tests validate that the actual FCC Proper map format is compatible with Classroom. This is important since the upstream map can change over time.
This aligns with the feedback:
“Tests should run against the actual challengeMap.json from FCC Proper … If the file does not exist, the test should fail and tell the user to generate it.”
New real-map test descriptions
loads a non-empty challenge map
Confirms
challengeMap.jsonexists, parses, and has entries. Prevents downstream logic from running on empty or missing data.builds dashboard data using the first valid map entry
Verifies the map’s real structure can be transformed into the expected nested dashboard shape.
skips unknown challenge IDs
Ensures the logic ignores unknown/missing IDs safely (no crashes or mis-grouping).
resolves multiple students against the current map
Validates per-student transformation with real map data and the expected output shape.
Fail example (missing map):
Pass example (map generated):
Testing:
npm run test:challenge-mapTesting / CI Note
Local dev: If
challengeMap.jsonis missing, the real‑map suite fails with a clear error and guidance to run node scripts/build-challenge-map-graphql.mjs.CI: When CI=true and the map is missing, the real‑map suite is skipped to keep the pipeline green. Synthetic tests still run.