From 12b5905c6031e6742824178d941f02bfa4b2bf33 Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Wed, 27 Aug 2025 19:15:36 +0200 Subject: [PATCH] refactor: remove isPrivate (#61952) --- client/src/__mocks__/challenge-nodes.ts | 14 - client/src/redux/prop-types.ts | 1 - .../Introduction/components/block.test.tsx | 1 - client/utils/build-challenges.js | 1 - client/utils/gatsby/challenge-page-creator.js | 2 - curriculum/build-superblock.js | 1 - .../a1-professional-chinese.yml | 3 +- .../a2-english-for-developers.yml | 1 - .../a2-professional-chinese.yml | 1 - .../a2-professional-spanish.yml | 1 - .../b1-english-for-developers.yml | 1 - .../back-end-development-and-apis.yml | 1 - .../college-algebra-with-python.yml | 3 +- .../data-analysis-with-python.yml | 1 - .../certifications/data-visualization.yml | 1 - .../foundational-c-sharp-with-microsoft.yml | 1 - .../front-end-development-libraries.yml | 1 - .../certifications/full-stack-developer.yml | 1 - .../certifications/information-security.yml | 1 - ...ript-algorithms-and-data-structures-v8.yml | 1 - ...ascript-algorithms-and-data-structures.yml | 1 - .../certifications/legacy-back-end.yml | 1 - .../legacy-data-visualization.yml | 1 - .../certifications/legacy-front-end.yml | 1 - .../certifications/legacy-full-stack.yml | 1 - ...rmation-security-and-quality-assurance.yml | 1 - .../machine-learning-with-python.yml | 1 - .../certifications/quality-assurance.yml | 1 - .../certifications/relational-database.yml | 1 - .../certifications/responsive-web-design.yml | 1 - .../scientific-computing-with-python.yml | 1 - curriculum/schema/challenge-schema.js | 413 +++++++++--------- e2e/projects.spec.ts | 1 - tools/scripts/seed/__mocks__/curriculum.json | 3 +- 34 files changed, 208 insertions(+), 258 deletions(-) diff --git a/client/src/__mocks__/challenge-nodes.ts b/client/src/__mocks__/challenge-nodes.ts index 6f5bf58eb26..674af565418 100644 --- a/client/src/__mocks__/challenge-nodes.ts +++ b/client/src/__mocks__/challenge-nodes.ts @@ -7,7 +7,6 @@ interface MockChallengeNodes { id: string; block: string; title: string; - isPrivate: boolean; superBlock: string; dashedName: string; }; @@ -23,7 +22,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'a', block: 'block-a', title: 'Challenge One', - isPrivate: false, superBlock: 'super-block-one', dashedName: 'challenge-one' } @@ -37,7 +35,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'b', block: 'block-a', title: 'Challenge Two', - isPrivate: false, superBlock: 'super-block-one', dashedName: 'challenge-two' } @@ -51,7 +48,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'c', block: 'block-b', title: 'Challenge One', - isPrivate: false, superBlock: 'super-block-one', dashedName: 'challenge-one' } @@ -66,7 +62,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'd', block: 'block-b', title: 'Challenge Two', - isPrivate: false, superBlock: 'super-block-one', dashedName: 'challenge-two' } @@ -80,7 +75,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'e', block: 'block-c', title: 'Challenge One', - isPrivate: true, superBlock: 'super-block-one', dashedName: 'challenge-one' } @@ -94,7 +88,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'f', block: 'block-a', title: 'Challenge One', - isPrivate: false, superBlock: 'super-block-two', dashedName: 'challenge-one' } @@ -108,7 +101,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'g', block: 'block-a', title: 'Challenge Two', - isPrivate: false, superBlock: 'super-block-two', dashedName: 'challenge-two' } @@ -122,7 +114,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'h', block: 'block-b', title: 'Challenge One', - isPrivate: false, superBlock: 'super-block-two', dashedName: 'challenge-one' } @@ -136,7 +127,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'i', block: 'block-b', title: 'Challenge Two', - isPrivate: false, superBlock: 'super-block-two', dashedName: 'challenge-two' } @@ -150,7 +140,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'j', block: 'block-a', title: 'Challenge One', - isPrivate: false, superBlock: 'super-block-three', dashedName: 'challenge-one' } @@ -164,7 +153,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'k', block: 'block-c', title: 'Challenge Two', - isPrivate: false, superBlock: 'super-block-three', dashedName: 'challenge-two' } @@ -178,7 +166,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'l', block: 'block-c', title: 'Challenge Three', - isPrivate: false, superBlock: 'super-block-three', dashedName: 'challenge-three' } @@ -192,7 +179,6 @@ const mockChallengeNodes: MockChallengeNodes[] = [ id: 'm', block: 'block-a', title: 'Challenge One', - isPrivate: false, superBlock: 'super-block-four', dashedName: 'challenge-one' } diff --git a/client/src/redux/prop-types.ts b/client/src/redux/prop-types.ts index b268ace2b0a..52406aefdd9 100644 --- a/client/src/redux/prop-types.ts +++ b/client/src/redux/prop-types.ts @@ -210,7 +210,6 @@ export type ChallengeNode = { notes: string; prerequisites: PrerequisiteChallenge[]; isLocked: boolean; - isPrivate: boolean; order: number; questions: Question[]; quizzes: Quiz[]; diff --git a/client/src/templates/Introduction/components/block.test.tsx b/client/src/templates/Introduction/components/block.test.tsx index a071c65f974..95dfad52475 100644 --- a/client/src/templates/Introduction/components/block.test.tsx +++ b/client/src/templates/Introduction/components/block.test.tsx @@ -63,7 +63,6 @@ const defaultProps = { notes: 'mockNotes', prerequisites: [] as PrerequisiteChallenge[], isLocked: false, - isPrivate: false, order: 1, questions: [] as Question[], assignments: ['mockAssignment'], diff --git a/client/utils/build-challenges.js b/client/utils/build-challenges.js index 629b6ce10e6..193a0c4a116 100644 --- a/client/utils/build-challenges.js +++ b/client/utils/build-challenges.js @@ -45,7 +45,6 @@ exports.buildChallenges = async function buildChallenges() { }, []); const builtChallenges = blocks - .filter(block => !block.isPrivate) .map(({ challenges }) => challenges) .reduce((accu, current) => accu.concat(current), []); return builtChallenges; diff --git a/client/utils/gatsby/challenge-page-creator.js b/client/utils/gatsby/challenge-page-creator.js index b2c35b936e6..17178a00dff 100644 --- a/client/utils/gatsby/challenge-page-creator.js +++ b/client/utils/gatsby/challenge-page-creator.js @@ -102,8 +102,6 @@ exports.createChallengePages = function ( id, isLastChallengeInBlock } = node.challenge; - // TODO: challengeType === 7 and isPrivate are the same, right? If so, we - // should remove one of them. createPage({ path: slug, diff --git a/curriculum/build-superblock.js b/curriculum/build-superblock.js index fe5fcb8d717..fe2087c48a2 100644 --- a/curriculum/build-superblock.js +++ b/curriculum/build-superblock.js @@ -147,7 +147,6 @@ function addMetaToChallenge(challenge, meta) { challenge.superOrder = meta.superOrder; challenge.challengeOrder = challengeOrderIndex; challenge.isLastChallengeInBlock = isLastChallengeInBlock; - challenge.isPrivate = challenge.isPrivate || meta.isPrivate; challenge.required = (meta.required || []).concat(challenge.required || []); challenge.template = meta.template; challenge.helpCategory = challenge.helpCategory || meta.helpCategory; diff --git a/curriculum/challenges/english/certifications/a1-professional-chinese.yml b/curriculum/challenges/english/certifications/a1-professional-chinese.yml index 5182b2ca4ce..c65a94c73bb 100644 --- a/curriculum/challenges/english/certifications/a1-professional-chinese.yml +++ b/curriculum/challenges/english/certifications/a1-professional-chinese.yml @@ -3,7 +3,6 @@ id: 688f1daf0133dbe2a36b140b title: A1 Professional Chinese Certification certification: a1-professional-chinese-certification challengeType: 7 -isPrivate: true tests: - id: 688f1daf0133dbe2a36b140b - title: "Dialogue 1: PLACEHOLDER" \ No newline at end of file + title: "Dialogue 1: PLACEHOLDER" diff --git a/curriculum/challenges/english/certifications/a2-english-for-developers.yml b/curriculum/challenges/english/certifications/a2-english-for-developers.yml index ff2aaa785d3..8d6cc52f23c 100644 --- a/curriculum/challenges/english/certifications/a2-english-for-developers.yml +++ b/curriculum/challenges/english/certifications/a2-english-for-developers.yml @@ -3,7 +3,6 @@ id: 651dd7e01d697d0aab7833b7 title: A2 English for Developers Certification certification: a2-english-for-developers challengeType: 7 -isPrivate: true tests: - id: 6721db5d9f0c116e6a0fe25a title: A2 English for Developers Certification Exam diff --git a/curriculum/challenges/english/certifications/a2-professional-chinese.yml b/curriculum/challenges/english/certifications/a2-professional-chinese.yml index 8293e289d15..10c76ddfa80 100644 --- a/curriculum/challenges/english/certifications/a2-professional-chinese.yml +++ b/curriculum/challenges/english/certifications/a2-professional-chinese.yml @@ -3,7 +3,6 @@ id: 682c3153086dd7cabe7f48bc title: A2 Professional Chinese Certification certification: a2-professional-chinese-certification challengeType: 7 -isPrivate: true tests: - id: 682c2753317b88f1ecdad894 title: "Dialogue 1: PLACEHOLDER" diff --git a/curriculum/challenges/english/certifications/a2-professional-spanish.yml b/curriculum/challenges/english/certifications/a2-professional-spanish.yml index 6f5d5886198..e29f461d655 100644 --- a/curriculum/challenges/english/certifications/a2-professional-spanish.yml +++ b/curriculum/challenges/english/certifications/a2-professional-spanish.yml @@ -3,7 +3,6 @@ id: 681a6b22e5a782fe3459984a title: A2 Professional Spanish Certification certification: a2-professional-spanish-certification challengeType: 7 -isPrivate: true tests: - id: 681a8796e5a782fe3459984b title: "Dialogue 1: PLACEHOLDER" diff --git a/curriculum/challenges/english/certifications/b1-english-for-developers.yml b/curriculum/challenges/english/certifications/b1-english-for-developers.yml index 87122f5ae4e..721dc3489f6 100644 --- a/curriculum/challenges/english/certifications/b1-english-for-developers.yml +++ b/curriculum/challenges/english/certifications/b1-english-for-developers.yml @@ -3,7 +3,6 @@ id: 66607e53317411dd5e8aae21 title: B1 English for Developers Certification certification: b1-english-for-developers challengeType: 7 -isPrivate: true tests: - id: 66607e5b317411dd5e8aae22 title: "Dialogue 1: I'm Tom" diff --git a/curriculum/challenges/english/certifications/back-end-development-and-apis.yml b/curriculum/challenges/english/certifications/back-end-development-and-apis.yml index 7f5e0d2ddf5..27fd7636000 100644 --- a/curriculum/challenges/english/certifications/back-end-development-and-apis.yml +++ b/curriculum/challenges/english/certifications/back-end-development-and-apis.yml @@ -3,7 +3,6 @@ id: 561add10cb82ac38a17523bc title: Back End Development and APIs Certification certification: back-end-development-and-apis challengeType: 7 -isPrivate: true tests: - id: bd7158d8c443edefaeb5bdef title: Timestamp Microservice diff --git a/curriculum/challenges/english/certifications/college-algebra-with-python.yml b/curriculum/challenges/english/certifications/college-algebra-with-python.yml index 67c48ceb609..fc1ccc90c6a 100644 --- a/curriculum/challenges/english/certifications/college-algebra-with-python.yml +++ b/curriculum/challenges/english/certifications/college-algebra-with-python.yml @@ -3,7 +3,6 @@ id: 61531b20cc9dfa2741a5b800 title: College Algebra with Python Certification certification: college-algebra-with-python challengeType: 7 -isPrivate: true tests: - id: 63d83ff239c73468b059cd3f title: Build a Multi-Function Calculator @@ -14,4 +13,4 @@ tests: - id: 63d8401e39c73468b059cd42 title: Build a Financial Calculator - id: 63d8402e39c73468b059cd43 - title: Build a Data Graph Explorer \ No newline at end of file + title: Build a Data Graph Explorer diff --git a/curriculum/challenges/english/certifications/data-analysis-with-python.yml b/curriculum/challenges/english/certifications/data-analysis-with-python.yml index e4c1a13ad03..7d227f677eb 100644 --- a/curriculum/challenges/english/certifications/data-analysis-with-python.yml +++ b/curriculum/challenges/english/certifications/data-analysis-with-python.yml @@ -2,7 +2,6 @@ id: 5e46fc95ac417301a38fb934 title: Data Analysis with Python Certification certification: data-analysis-with-python challengeType: 7 -isPrivate: true tests: - id: 5e46f7e5ac417301a38fb928 title: Mean-Variance-Standard Deviation Calculator diff --git a/curriculum/challenges/english/certifications/data-visualization.yml b/curriculum/challenges/english/certifications/data-visualization.yml index 2ec1d9efe61..7fb99015782 100644 --- a/curriculum/challenges/english/certifications/data-visualization.yml +++ b/curriculum/challenges/english/certifications/data-visualization.yml @@ -2,7 +2,6 @@ id: 5a553ca864b52e1d8bceea14 title: Data Visualization Certification certification: data-visualization challengeType: 7 -isPrivate: true tests: - id: bd7168d8c242eddfaeb5bd13 title: Visualize Data with a Bar Chart diff --git a/curriculum/challenges/english/certifications/foundational-c-sharp-with-microsoft.yml b/curriculum/challenges/english/certifications/foundational-c-sharp-with-microsoft.yml index e9a6c51d0fe..72cc306852c 100644 --- a/curriculum/challenges/english/certifications/foundational-c-sharp-with-microsoft.yml +++ b/curriculum/challenges/english/certifications/foundational-c-sharp-with-microsoft.yml @@ -3,7 +3,6 @@ id: 647f7da207d29547b3bee1ba title: Foundational C# with Microsoft Certification certification: foundational-c-sharp-with-microsoft challengeType: 7 -isPrivate: true tests: - id: 647e22d18acb466c97ccbef8 title: Foundational C# with Microsoft Certification Exam diff --git a/curriculum/challenges/english/certifications/front-end-development-libraries.yml b/curriculum/challenges/english/certifications/front-end-development-libraries.yml index 408e57078d9..21915a79ac4 100644 --- a/curriculum/challenges/english/certifications/front-end-development-libraries.yml +++ b/curriculum/challenges/english/certifications/front-end-development-libraries.yml @@ -3,7 +3,6 @@ id: 561acd10cb82ac38a17513bc title: Front End Development Libraries Certification certification: front-end-development-libraries challengeType: 7 -isPrivate: true tests: - id: bd7158d8c442eddfaeb5bd13 title: Build a Random Quote Machine diff --git a/curriculum/challenges/english/certifications/full-stack-developer.yml b/curriculum/challenges/english/certifications/full-stack-developer.yml index 3228db92602..e5a3ba97af5 100644 --- a/curriculum/challenges/english/certifications/full-stack-developer.yml +++ b/curriculum/challenges/english/certifications/full-stack-developer.yml @@ -3,7 +3,6 @@ id: 64514fda6c245de4d11eb7bb title: Certified Full Stack Developer certification: full-stack-developer challengeType: 7 -isPrivate: true tests: - id: 645147516c245de4d11eb7ba title: Certified Full Stack Developer Exam diff --git a/curriculum/challenges/english/certifications/information-security.yml b/curriculum/challenges/english/certifications/information-security.yml index 8997cfbb352..7a69a6345ee 100644 --- a/curriculum/challenges/english/certifications/information-security.yml +++ b/curriculum/challenges/english/certifications/information-security.yml @@ -2,7 +2,6 @@ id: 5e6021435ac9d0ecd8b94b00 title: Information Security Certification certification: information-security challengeType: 7 -isPrivate: true tests: - id: 587d824a367417b2b2512c44 title: Stock Price Checker diff --git a/curriculum/challenges/english/certifications/javascript-algorithms-and-data-structures-v8.yml b/curriculum/challenges/english/certifications/javascript-algorithms-and-data-structures-v8.yml index 769c0db6d9b..5b92ae8ac30 100644 --- a/curriculum/challenges/english/certifications/javascript-algorithms-and-data-structures-v8.yml +++ b/curriculum/challenges/english/certifications/javascript-algorithms-and-data-structures-v8.yml @@ -2,7 +2,6 @@ id: 658180220947283cdc0689ce title: JavaScript Algorithms and Data Structures Certification certification: javascript-algorithms-and-data-structures-v8 challengeType: 7 -isPrivate: true tests: - id: 657bdc55a322aae1eac3838f title: Build a Palindrome Checker diff --git a/curriculum/challenges/english/certifications/javascript-algorithms-and-data-structures.yml b/curriculum/challenges/english/certifications/javascript-algorithms-and-data-structures.yml index 4e1c5832a52..d5443d5df55 100644 --- a/curriculum/challenges/english/certifications/javascript-algorithms-and-data-structures.yml +++ b/curriculum/challenges/english/certifications/javascript-algorithms-and-data-structures.yml @@ -2,7 +2,6 @@ id: 561abd10cb81ac38a17513bc title: Legacy JavaScript Algorithms and Data Structures Certification certification: javascript-algorithms-and-data-structures challengeType: 7 -isPrivate: true tests: - id: aaa48de84e1ecc7c742e1124 title: Palindrome Checker diff --git a/curriculum/challenges/english/certifications/legacy-back-end.yml b/curriculum/challenges/english/certifications/legacy-back-end.yml index 8a792c1b393..51d62c28292 100644 --- a/curriculum/challenges/english/certifications/legacy-back-end.yml +++ b/curriculum/challenges/english/certifications/legacy-back-end.yml @@ -2,7 +2,6 @@ id: 660add10cb82ac38a17513be title: Legacy Back End Certification certification: legacy-back-end challengeType: 7 -isPrivate: true tests: - id: bd7158d8c443edefaeb5bdef title: Timestamp Microservice diff --git a/curriculum/challenges/english/certifications/legacy-data-visualization.yml b/curriculum/challenges/english/certifications/legacy-data-visualization.yml index 69845d6c652..074ba356e52 100644 --- a/curriculum/challenges/english/certifications/legacy-data-visualization.yml +++ b/curriculum/challenges/english/certifications/legacy-data-visualization.yml @@ -2,7 +2,6 @@ id: 561add10cb82ac39a17513bc title: Legacy Data Visualization Certification certification: legacy-data-visualization challengeType: 7 -isPrivate: true tests: - id: bd7157d8c242eddfaeb5bd13 title: Build a Markdown Previewer diff --git a/curriculum/challenges/english/certifications/legacy-front-end.yml b/curriculum/challenges/english/certifications/legacy-front-end.yml index 30d49af2d6a..678464df793 100644 --- a/curriculum/challenges/english/certifications/legacy-front-end.yml +++ b/curriculum/challenges/english/certifications/legacy-front-end.yml @@ -2,7 +2,6 @@ id: 561add10cb82ac38a17513be title: Legacy Front End Certification certification: legacy-front-end challengeType: 7 -isPrivate: true tests: - id: bd7158d8c242eddfaeb5bd13 title: Build a Personal Portfolio Webpage diff --git a/curriculum/challenges/english/certifications/legacy-full-stack.yml b/curriculum/challenges/english/certifications/legacy-full-stack.yml index 6ae27ad5eab..9d6b3a28e26 100644 --- a/curriculum/challenges/english/certifications/legacy-full-stack.yml +++ b/curriculum/challenges/english/certifications/legacy-full-stack.yml @@ -2,7 +2,6 @@ id: 561add10cb82ac38a17213bd title: Legacy Full Stack Certification certification: legacy-full-stack challengeType: 7 -isPrivate: true tests: - id: 561add10cb82ac38a17513bc title: Responsive Web Design Certification diff --git a/curriculum/challenges/english/certifications/legacy-information-security-and-quality-assurance.yml b/curriculum/challenges/english/certifications/legacy-information-security-and-quality-assurance.yml index 87b0bef699f..f8eb1608b67 100644 --- a/curriculum/challenges/english/certifications/legacy-information-security-and-quality-assurance.yml +++ b/curriculum/challenges/english/certifications/legacy-information-security-and-quality-assurance.yml @@ -2,7 +2,6 @@ id: 561add10cb82ac38a17213bc title: Legacy Information Security and Quality Assurance Certification certification: legacy-information-security-and-quality-assurance challengeType: 7 -isPrivate: true tests: - id: 587d8249367417b2b2512c41 title: Metric-Imperial Converter diff --git a/curriculum/challenges/english/certifications/machine-learning-with-python.yml b/curriculum/challenges/english/certifications/machine-learning-with-python.yml index 82b664f3642..18a17a3afd8 100644 --- a/curriculum/challenges/english/certifications/machine-learning-with-python.yml +++ b/curriculum/challenges/english/certifications/machine-learning-with-python.yml @@ -2,7 +2,6 @@ id: 5e46fc95ac417301a38fb935 title: Machine Learning with Python Certification certification: machine-learning-with-python challengeType: 7 -isPrivate: true tests: - id: 5e46f8d6ac417301a38fb92d title: Rock Paper Scissors diff --git a/curriculum/challenges/english/certifications/quality-assurance.yml b/curriculum/challenges/english/certifications/quality-assurance.yml index b12e25b5331..f776709db10 100644 --- a/curriculum/challenges/english/certifications/quality-assurance.yml +++ b/curriculum/challenges/english/certifications/quality-assurance.yml @@ -2,7 +2,6 @@ id: 5e611829481575a52dc59c0e title: Quality Assurance Certification certification: quality-assurance challengeType: 7 -isPrivate: true tests: - id: 587d8249367417b2b2512c41 title: Metric-Imperial Converter diff --git a/curriculum/challenges/english/certifications/relational-database.yml b/curriculum/challenges/english/certifications/relational-database.yml index dd82e0c8199..49c206a5158 100644 --- a/curriculum/challenges/english/certifications/relational-database.yml +++ b/curriculum/challenges/english/certifications/relational-database.yml @@ -2,7 +2,6 @@ id: 606243f50267e718b1e755f4 title: Relational Database Certification certification: relational-database challengeType: 7 -isPrivate: true tests: - id: 5f1a4ef5d5d6b5ab580fc6ae title: Celestial Bodies Database diff --git a/curriculum/challenges/english/certifications/responsive-web-design.yml b/curriculum/challenges/english/certifications/responsive-web-design.yml index 811d45d6bf5..116dd1396c3 100644 --- a/curriculum/challenges/english/certifications/responsive-web-design.yml +++ b/curriculum/challenges/english/certifications/responsive-web-design.yml @@ -2,7 +2,6 @@ id: 561add10cb82ac38a17513bc title: Responsive Web Design Certification certification: responsive-web-design challengeType: 7 -isPrivate: true tests: - id: bd7158d8c442eddfaeb5bd18 title: Build a Tribute Page diff --git a/curriculum/challenges/english/certifications/scientific-computing-with-python.yml b/curriculum/challenges/english/certifications/scientific-computing-with-python.yml index 24bc6df56e7..ab5d97d12fa 100644 --- a/curriculum/challenges/english/certifications/scientific-computing-with-python.yml +++ b/curriculum/challenges/english/certifications/scientific-computing-with-python.yml @@ -2,7 +2,6 @@ id: 5e44431b903586ffb414c951 title: Scientific Computing with Python Certification certification: scientific-computing-with-python challengeType: 7 -isPrivate: true tests: - id: 5e44412c903586ffb414c94c title: Arithmetic Formatter diff --git a/curriculum/schema/challenge-schema.js b/curriculum/schema/challenge-schema.js index a2b49baa36d..ce400780f11 100644 --- a/curriculum/schema/challenge-schema.js +++ b/curriculum/schema/challenge-schema.js @@ -126,219 +126,216 @@ const quizJoi = Joi.object().keys({ .required() }); -const schema = Joi.object() - .keys({ - block: Joi.string().regex(slugRE).required(), - blockId: Joi.objectId(), - blockType: Joi.when('superBlock', { - is: [...chapterBasedSuperBlocks, ...catalogSuperBlocks], - then: Joi.valid( - 'workshop', - 'lab', - 'lecture', - 'review', - 'quiz', - 'exam' - ).required(), - otherwise: Joi.valid(null) - }), - blockLayout: Joi.valid( - 'challenge-list', - 'challenge-grid', - 'dialogue-grid', - 'link', - 'project-list', - 'legacy-challenge-list', - 'legacy-link', - 'legacy-challenge-grid' +const schema = Joi.object().keys({ + block: Joi.string().regex(slugRE).required(), + blockId: Joi.objectId(), + blockType: Joi.when('superBlock', { + is: [...chapterBasedSuperBlocks, ...catalogSuperBlocks], + then: Joi.valid( + 'workshop', + 'lab', + 'lecture', + 'review', + 'quiz', + 'exam' ).required(), - challengeOrder: Joi.number(), - chapter: Joi.string().when('superBlock', { - is: chapterBasedSuperBlocks, - then: Joi.required(), - otherwise: Joi.optional() - }), - certification: Joi.string().regex(slugWithSlashRE), - challengeType: Joi.number().min(0).max(30).required(), - checksum: Joi.number(), - // TODO: require this only for normal challenges, not certs - dashedName: Joi.string().regex(slugRE), - demoType: Joi.string().valid('onClick', 'onLoad'), - description: Joi.when('challengeType', { - is: [ - challengeTypes.step, - challengeTypes.video, - challengeTypes.multipleChoice, - challengeTypes.fillInTheBlank - ], - then: Joi.string().allow(''), - otherwise: Joi.string().required() - }), - disableLoopProtectTests: Joi.boolean().required(), - disableLoopProtectPreview: Joi.boolean().required(), - explanation: Joi.when('challengeType', { - is: [challengeTypes.multipleChoice, challengeTypes.fillInTheBlank], - then: Joi.string() - }), - challengeFiles: Joi.array().items(fileJoi), - guideUrl: Joi.string().uri({ scheme: 'https' }), - hasEditableBoundaries: Joi.boolean(), - helpCategory: Joi.valid( - 'JavaScript', - 'HTML-CSS', - 'Python', - 'Backend Development', - 'C-Sharp', - 'English', - 'Odin', - 'Euler', - 'Rosetta' - ), - isLastChallengeInBlock: Joi.boolean().required(), - videoUrl: Joi.string().allow(''), - fillInTheBlank: Joi.object().keys({ - sentence: Joi.string().required(), - blanks: Joi.array() - .items( - Joi.object().keys({ - answer: Joi.string().required(), - feedback: Joi.string().allow(null) - }) - ) - .required() - }), - forumTopicId: Joi.number(), - id: Joi.objectId().required(), - instructions: Joi.string().when('challengeType', { - is: [challengeTypes.pythonProject, challengeTypes.codeAllyCert], - then: Joi.string().min(1).required(), - otherwise: Joi.string().allow('') - }), - isComingSoon: Joi.bool(), - isLocked: Joi.bool(), - isPrivate: Joi.bool(), - module: Joi.string().when('superBlock', { - is: chapterBasedSuperBlocks, - then: Joi.required(), - otherwise: Joi.optional() - }), - msTrophyId: Joi.when('challengeType', { - is: [challengeTypes.msTrophy], - then: Joi.string().required() - }), - notes: Joi.string().allow(''), - order: Joi.number(), - prerequisites: Joi.when('challengeType', { - is: [challengeTypes.exam], - then: Joi.array().items(prerequisitesJoi) - }), - // video challenges only: - videoId: Joi.when('challengeType', { - is: [challengeTypes.video], - then: Joi.string().required() - }), - videoLocaleIds: Joi.when('challengeType', { - is: challengeTypes.video, - then: Joi.object().keys({ - espanol: Joi.string(), - italian: Joi.string(), - portuguese: Joi.string() - }) - }), - bilibiliIds: Joi.when('challengeType', { - is: challengeTypes.video, - then: Joi.object().keys({ - aid: Joi.number().required(), - bvid: Joi.string().required(), - cid: Joi.number().required() - }) - }), - questions: Joi.when('challengeType', { - is: [ - challengeTypes.video, - challengeTypes.multipleChoice, - challengeTypes.theOdinProject - ], - then: Joi.array().items(questionJoi).min(1).required(), - otherwise: Joi.array().length(0) - }), - quizzes: Joi.when('challengeType', { - is: challengeTypes.quiz, - then: Joi.array().items(quizJoi).min(1).required(), - otherwise: Joi.forbidden() - }), - required: Joi.array().items( - Joi.object().keys({ - link: Joi.string(), - raw: Joi.bool(), - src: Joi.string(), - crossDomain: Joi.bool() - }) - ), - assignments: Joi.when('challengeType', { - is: challengeTypes.dialogue, - then: Joi.array().items(Joi.string()).required(), - otherwise: Joi.array().items(Joi.string()) - }), - scene: Joi.object().keys({ - setup: setupJoi.required(), - commands: Joi.array() - .items(commandJoi) - .unique( - (a, b) => - a.dialogue && - b.dialogue && - !( - (a.startTime < b.startTime && - a.finishTime < b.finishTime && - a.finishTime <= b.startTime) || - (b.startTime < a.startTime && - b.finishTime < a.finishTime && - b.finishTime <= a.startTime) - ) - ) - .messages({ - 'array.unique': 'Dialogues must not have overlapping times.' - }) - }), - solutions: Joi.array().items(Joi.array().items(fileJoi).min(1)), - superBlock: Joi.string().regex(slugWithSlashRE), - superOrder: Joi.number(), - suborder: Joi.number(), - hooks: Joi.object().keys({ - beforeAll: Joi.string().allow(''), - beforeEach: Joi.string().allow(''), - afterEach: Joi.string().allow('') - }), - tests: Joi.array() + otherwise: Joi.valid(null) + }), + blockLayout: Joi.valid( + 'challenge-list', + 'challenge-grid', + 'dialogue-grid', + 'link', + 'project-list', + 'legacy-challenge-list', + 'legacy-link', + 'legacy-challenge-grid' + ).required(), + challengeOrder: Joi.number(), + chapter: Joi.string().when('superBlock', { + is: chapterBasedSuperBlocks, + then: Joi.required(), + otherwise: Joi.optional() + }), + certification: Joi.string().regex(slugWithSlashRE), + challengeType: Joi.number().min(0).max(30).required(), + checksum: Joi.number(), + // TODO: require this only for normal challenges, not certs + dashedName: Joi.string().regex(slugRE), + demoType: Joi.string().valid('onClick', 'onLoad'), + description: Joi.when('challengeType', { + is: [ + challengeTypes.step, + challengeTypes.video, + challengeTypes.multipleChoice, + challengeTypes.fillInTheBlank + ], + then: Joi.string().allow(''), + otherwise: Joi.string().required() + }), + disableLoopProtectTests: Joi.boolean().required(), + disableLoopProtectPreview: Joi.boolean().required(), + explanation: Joi.when('challengeType', { + is: [challengeTypes.multipleChoice, challengeTypes.fillInTheBlank], + then: Joi.string() + }), + challengeFiles: Joi.array().items(fileJoi), + guideUrl: Joi.string().uri({ scheme: 'https' }), + hasEditableBoundaries: Joi.boolean(), + helpCategory: Joi.valid( + 'JavaScript', + 'HTML-CSS', + 'Python', + 'Backend Development', + 'C-Sharp', + 'English', + 'Odin', + 'Euler', + 'Rosetta' + ).required(), + isLastChallengeInBlock: Joi.boolean().required(), + videoUrl: Joi.string().allow(''), + fillInTheBlank: Joi.object().keys({ + sentence: Joi.string().required(), + blanks: Joi.array() .items( - // public challenges Joi.object().keys({ - id: Joi.string().allow(''), - text: Joi.string().required(), - testString: Joi.string().allow('').required() - }), - // our tests used in certification verification - Joi.object().keys({ - id: Joi.string().required(), - title: Joi.string().required() + answer: Joi.string().required(), + feedback: Joi.string().allow(null) }) ) - .required(), - template: Joi.string().allow(''), - title: Joi.string().required(), - transcript: Joi.when('challengeType', { - is: [challengeTypes.generic, challengeTypes.video], - then: Joi.string() - }), - translationPending: Joi.bool().required(), - url: Joi.when('challengeType', { - is: [challengeTypes.codeAllyPractice, challengeTypes.codeAllyCert], - then: Joi.string().required() - }), - usesMultifileEditor: Joi.boolean() - }) - .xor('helpCategory', 'isPrivate'); + .required() + }), + forumTopicId: Joi.number(), + id: Joi.objectId().required(), + instructions: Joi.string().when('challengeType', { + is: [challengeTypes.pythonProject, challengeTypes.codeAllyCert], + then: Joi.string().min(1).required(), + otherwise: Joi.string().allow('') + }), + isComingSoon: Joi.bool(), + isLocked: Joi.bool(), + module: Joi.string().when('superBlock', { + is: chapterBasedSuperBlocks, + then: Joi.required(), + otherwise: Joi.optional() + }), + msTrophyId: Joi.when('challengeType', { + is: [challengeTypes.msTrophy], + then: Joi.string().required() + }), + notes: Joi.string().allow(''), + order: Joi.number(), + prerequisites: Joi.when('challengeType', { + is: [challengeTypes.exam], + then: Joi.array().items(prerequisitesJoi) + }), + // video challenges only: + videoId: Joi.when('challengeType', { + is: [challengeTypes.video], + then: Joi.string().required() + }), + videoLocaleIds: Joi.when('challengeType', { + is: challengeTypes.video, + then: Joi.object().keys({ + espanol: Joi.string(), + italian: Joi.string(), + portuguese: Joi.string() + }) + }), + bilibiliIds: Joi.when('challengeType', { + is: challengeTypes.video, + then: Joi.object().keys({ + aid: Joi.number().required(), + bvid: Joi.string().required(), + cid: Joi.number().required() + }) + }), + questions: Joi.when('challengeType', { + is: [ + challengeTypes.video, + challengeTypes.multipleChoice, + challengeTypes.theOdinProject + ], + then: Joi.array().items(questionJoi).min(1).required(), + otherwise: Joi.array().length(0) + }), + quizzes: Joi.when('challengeType', { + is: challengeTypes.quiz, + then: Joi.array().items(quizJoi).min(1).required(), + otherwise: Joi.forbidden() + }), + required: Joi.array().items( + Joi.object().keys({ + link: Joi.string(), + raw: Joi.bool(), + src: Joi.string(), + crossDomain: Joi.bool() + }) + ), + assignments: Joi.when('challengeType', { + is: challengeTypes.dialogue, + then: Joi.array().items(Joi.string()).required(), + otherwise: Joi.array().items(Joi.string()) + }), + scene: Joi.object().keys({ + setup: setupJoi.required(), + commands: Joi.array() + .items(commandJoi) + .unique( + (a, b) => + a.dialogue && + b.dialogue && + !( + (a.startTime < b.startTime && + a.finishTime < b.finishTime && + a.finishTime <= b.startTime) || + (b.startTime < a.startTime && + b.finishTime < a.finishTime && + b.finishTime <= a.startTime) + ) + ) + .messages({ + 'array.unique': 'Dialogues must not have overlapping times.' + }) + }), + solutions: Joi.array().items(Joi.array().items(fileJoi).min(1)), + superBlock: Joi.string().regex(slugWithSlashRE), + superOrder: Joi.number(), + suborder: Joi.number(), + hooks: Joi.object().keys({ + beforeAll: Joi.string().allow(''), + beforeEach: Joi.string().allow(''), + afterEach: Joi.string().allow('') + }), + tests: Joi.array() + .items( + // public challenges + Joi.object().keys({ + id: Joi.string().allow(''), + text: Joi.string().required(), + testString: Joi.string().allow('').required() + }), + // our tests used in certification verification + Joi.object().keys({ + id: Joi.string().required(), + title: Joi.string().required() + }) + ) + .required(), + template: Joi.string().allow(''), + title: Joi.string().required(), + transcript: Joi.when('challengeType', { + is: [challengeTypes.generic, challengeTypes.video], + then: Joi.string() + }), + translationPending: Joi.bool().required(), + url: Joi.when('challengeType', { + is: [challengeTypes.codeAllyPractice, challengeTypes.codeAllyCert], + then: Joi.string().required() + }), + usesMultifileEditor: Joi.boolean() +}); exports.challengeSchemaValidator = () => { return challenge => schema.validate(challenge); diff --git a/e2e/projects.spec.ts b/e2e/projects.spec.ts index 06d894ba88d..30bb978e7c2 100644 --- a/e2e/projects.spec.ts +++ b/e2e/projects.spec.ts @@ -27,7 +27,6 @@ interface Challenge { superBlock: string; dashedName: string; solutions: Solution[]; - isPrivate?: boolean; } interface block { diff --git a/tools/scripts/seed/__mocks__/curriculum.json b/tools/scripts/seed/__mocks__/curriculum.json index d958d357938..6962ebce196 100644 --- a/tools/scripts/seed/__mocks__/curriculum.json +++ b/tools/scripts/seed/__mocks__/curriculum.json @@ -61,8 +61,7 @@ { "title": "Challenge Nine", "block": "Block One", - "superBlock": "super-block-b", - "isPrivate": true + "superBlock": "super-block-b" }, { "title": "Challenge Ten",