Skip to content

Commit 97549c1

Browse files
Merge pull request #724 from freeCodeCamp/main
Create a new pull request by comparing changes across two branches
2 parents a295715 + 8e968ea commit 97549c1

File tree

271 files changed

+18390
-1210
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

271 files changed

+18390
-1210
lines changed

api/__mocks__/env-exam.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,9 +343,7 @@ export const exam: EnvExam = {
343343
};
344344

345345
export async function seedEnvExam() {
346-
await fastifyTestInstance.prisma.envExamAttempt.deleteMany({});
347-
await fastifyTestInstance.prisma.envGeneratedExam.deleteMany({});
348-
await fastifyTestInstance.prisma.envExam.deleteMany({});
346+
await clearEnvExam();
349347

350348
await fastifyTestInstance.prisma.envExam.create({
351349
data: exam
@@ -369,3 +367,15 @@ export async function seedEnvExam() {
369367
// }
370368
// }
371369
}
370+
371+
export async function clearEnvExam() {
372+
await fastifyTestInstance.prisma.envExamAttempt.deleteMany({});
373+
await fastifyTestInstance.prisma.envGeneratedExam.deleteMany({});
374+
await fastifyTestInstance.prisma.envExam.deleteMany({});
375+
}
376+
377+
export async function seedEnvExamAttempt() {
378+
await fastifyTestInstance.prisma.envExamAttempt.create({
379+
data: examAttempt
380+
});
381+
}

api/prisma/schema.prisma

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ model EnvExamAttempt {
277277
needsRetake Boolean
278278
279279
// Relations
280-
user user @relation(fields: [userId], references: [id])
280+
user user @relation(fields: [userId], references: [id], onDelete: Cascade)
281281
exam EnvExam @relation(fields: [examId], references: [id])
282282
generatedExam EnvGeneratedExam @relation(fields: [generatedExamId], references: [id])
283283
}

api/src/exam-environment/routes/exam-environment.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ describe('/exam-environment/', () => {
4242
res.body.examEnvironmentAuthorizationToken;
4343
});
4444

45+
afterAll(async () => {
46+
await mock.clearEnvExam();
47+
});
48+
4549
describe('POST /exam-environment/exam/attempt', () => {
4650
afterEach(async () => {
4751
await fastifyTestInstance.prisma.envExamAttempt.deleteMany();

api/src/routes/protected/user.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ import {
1616
createSuperRequest
1717
} from '../../../jest.utils';
1818
import { JWT_SECRET } from '../../utils/env';
19+
import {
20+
clearEnvExam,
21+
seedEnvExam,
22+
seedEnvExamAttempt
23+
} from '../../../__mocks__/env-exam';
1924
import { getMsTranscriptApiUrl } from './user';
2025

2126
const mockedFetch = jest.fn();
@@ -336,13 +341,18 @@ describe('userRoutes', () => {
336341
});
337342

338343
describe('/account/delete', () => {
344+
beforeEach(async () => {
345+
await seedEnvExam();
346+
await seedEnvExamAttempt();
347+
});
339348
afterEach(async () => {
340349
await fastifyTestInstance.prisma.userToken.deleteMany({
341350
where: { OR: [{ userId: defaultUserId }, { userId: otherUserId }] }
342351
});
343352
await fastifyTestInstance.prisma.msUsername.deleteMany({
344353
where: { OR: [{ userId: defaultUserId }, { userId: otherUserId }] }
345354
});
355+
await clearEnvExam();
346356
});
347357

348358
test('POST returns 200 status code with empty object', async () => {
@@ -398,6 +408,18 @@ describe('userRoutes', () => {
398408
);
399409
expect(setCookie).toHaveLength(3);
400410
});
411+
412+
test("POST deletes all the user's exam attempts", async () => {
413+
const examAttempts =
414+
await fastifyTestInstance.prisma.envExamAttempt.findMany();
415+
expect(examAttempts).toHaveLength(1);
416+
417+
await superPost('/account/delete');
418+
419+
const examAttemptsAfter =
420+
await fastifyTestInstance.prisma.envExamAttempt.findMany();
421+
expect(examAttemptsAfter).toHaveLength(0);
422+
});
401423
});
402424

403425
describe('/account/reset-progress', () => {

client/i18n/locales/chinese-traditional/intro.json

Lines changed: 40 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,12 @@
15611561
"intro": [
15621562
"This course will provide you with ways to explain things to other people while assisting them."
15631563
]
1564+
},
1565+
"a2-english-for-developers-certification-exam": {
1566+
"title": "A2 English for Developers Certification Exam",
1567+
"intro": [
1568+
"This exam is required to claim the A2 English for Developers Certification."
1569+
]
15641570
}
15651571
}
15661572
},
@@ -1756,9 +1762,11 @@
17561762
"The following quiz will test your knowledge of the basic HTML concepts you have learned so far."
17571763
]
17581764
},
1759-
"evdc": {
1760-
"title": "11",
1761-
"intro": []
1765+
"lecture-importance-of-semantic-html": {
1766+
"title": "Importance of Semantic HTML",
1767+
"intro": [
1768+
"In these lecture videos, you will learn about semantic HTML and the importance of using it."
1769+
]
17621770
},
17631771
"workshop-blog-page": {
17641772
"title": "Build a Cat Blog Page",
@@ -1786,9 +1794,11 @@
17861794
"The following quiz will test your knowledge on semantic HTML concepts you have learned so far."
17871795
]
17881796
},
1789-
"cfgp": {
1790-
"title": "16",
1791-
"intro": []
1797+
"lecture-working-with-forms": {
1798+
"title": "Working with Forms",
1799+
"intro": [
1800+
"In these lecture videos, you will learn about working with forms in HTML."
1801+
]
17921802
},
17931803
"workshop-hotel-feedback-form": {
17941804
"title": "Build a Hotel Feedback Form",
@@ -1804,9 +1814,9 @@
18041814
"This lab will give you the opportunity to practice working with the <code>label</code> element, the different <code>input</code> elements, the <code>required</code> attribute, and more. "
18051815
]
18061816
},
1807-
"wgot": {
1808-
"title": "19",
1809-
"intro": []
1817+
"lecture-working-with-tables": {
1818+
"title": "Working with Tables",
1819+
"intro": ["In these lecture videos, you will learn about HTML tables."]
18101820
},
18111821
"workshop-final-exams-table": {
18121822
"title": "Build a Final Exams Table",
@@ -1821,9 +1831,11 @@
18211831
"This lab will give you an opportunity to practice working with the different table components like the <code>Table Head</code>, <code>Table Row</code> and <code>Table Data Cell</code> elements."
18221832
]
18231833
},
1824-
"rsve": {
1825-
"title": "22",
1826-
"intro": []
1834+
"lecture-working-with-html-tools": {
1835+
"title": "Working with HTML Tools",
1836+
"intro": [
1837+
"In these lecture videos, you will learn about working with HTML tools."
1838+
]
18271839
},
18281840
"review-html-tables-and-forms": {
18291841
"title": "HTML Tables and Forms Review",
@@ -1838,9 +1850,11 @@
18381850
"The following quiz will test your knowledge of HTML tables and forms."
18391851
]
18401852
},
1841-
"ghoc": {
1842-
"title": "25",
1843-
"intro": []
1853+
"lecture-importance-of-accessibility-and-good-html-structure": {
1854+
"title": "Importance of Accessibility and Good HTML Structure",
1855+
"intro": [
1856+
"In these lecture videos, you will learn about importance of accessibility and using good HTML structure."
1857+
]
18441858
},
18451859
"lab-checkout-page": {
18461860
"title": "Build a Checkout Page",
@@ -2163,7 +2177,8 @@
21632177
"review-css-typography": {
21642178
"title": "CSS Typography Review",
21652179
"intro": [
2166-
"Review the CSS Typography concepts to prepare for the upcoming quiz."
2180+
"Before you are quizzed on the fundamentals of typography, you first need to review.",
2181+
"Open up this page to review concepts like web safe fonts, the <code>font-family</code> property and more."
21672182
]
21682183
},
21692184
"quiz-css-typography": {
@@ -2230,7 +2245,7 @@
22302245
"title": "Build a Cat Painting",
22312246
"intro": [
22322247
"Mastering CSS positioning is essential for creating visually appealing and responsive web layouts.",
2233-
"In this workshop, you will build a cat painting. You'll learn about how to work with absolute positioning, the z-index property, and the transform property."
2248+
"In this workshop, you will build a cat painting. You'll learn about how to work with absolute positioning, the <code>z-index</code> property, and the <code>transform</code> property."
22342249
]
22352250
},
22362251
"lab-house-painting": {
@@ -2368,9 +2383,9 @@
23682383
]
23692384
},
23702385
"review-css-animations": {
2371-
"title": "CSS Amimations Review",
2386+
"title": "CSS Animations Review",
23722387
"intro": [
2373-
"Review the CSS Amimations concepts to prepare for the upcoming quiz."
2388+
"Review the CSS Animations concepts to prepare for the upcoming quiz."
23742389
]
23752390
},
23762391
"quiz-css-animations": {
@@ -3067,9 +3082,12 @@
30673082
"title": "251",
30683083
"intro": []
30693084
},
3070-
"byqx": {
3071-
"title": "252",
3072-
"intro": []
3085+
"workshop-fcc-authors-page": {
3086+
"title": "Build an fCC Authors Page",
3087+
"intro": [
3088+
"One common aspect of web development is learning how to fetch data from an external API, then work with asynchronous JavaScript.",
3089+
"In this workshop you will practice how to use the fetch method, dynamically update the DOM to display the fetched data and paginate your data so you can load results in batches."
3090+
]
30733091
},
30743092
"alda": {
30753093
"title": "253",
@@ -3617,58 +3635,14 @@
36173635
"title": "368",
36183636
"intro": []
36193637
},
3620-
"workshop-npm-packages": {
3621-
"title": "Managing Packages with npm",
3622-
"intro": [
3623-
"npm (Node Package Manager), is a command line tool to install, create, and share packages of JavaScript code written for Node.js. There are many open source packages available on npm, so before starting a project, take some time to explore so you don't end up recreating the wheel for things like working with dates or fetching data from an API.",
3624-
"In this workshop, you'll learn the basics of using npm, including how to work with the <code>package.json</code> file and how to manage your installed dependencies."
3625-
]
3626-
},
36273638
"hjku": {
36283639
"title": "370",
36293640
"intro": []
36303641
},
3631-
"workshop-node-and-express": {
3632-
"title": "Basic Node and Express",
3633-
"intro": [
3634-
"Node.js is a JavaScript runtime that allows developers to write backend (server-side) programs in JavaScript. Node.js comes with a handful of built-in modules — small, independent programs — that help with this. Some of the core modules include HTTP, which acts like a server, and File System, a module to read and modify files.",
3635-
"In the last set of courses you learned to install and manage packages from npm, which are collections of smaller modules. These packages can help you build larger, more complex applications.",
3636-
"Express is a lightweight web application framework, and is one of the most popular packages on npm. Express makes it much easier to create a server and handle routing for your application, which handles things like directing people to the correct page when they visit a certain endpoint like <pre>/blog</pre>.",
3637-
"In this course, you'll learn the basics of Node and Express including how to create a server, serve different files, and handle different requests from the browser."
3638-
]
3639-
},
3640-
"lab-timestamp-microservice": {
3641-
"title": "Build a Timestamp Microservice",
3642-
"intro": ["In this lab you will build a timestamp microservice"]
3643-
},
3644-
"lab-request-header-parser-microservice": {
3645-
"title": "Build a Request Header Parser Microservice",
3646-
"intro": [
3647-
"In this lab, you will build a request header parser microservice"
3648-
]
3649-
},
3650-
"lab-url-shortener-microservice": {
3651-
"title": "Build a URL Shortener Microservice",
3652-
"intro": ["In this lab, you will build a URL Shortener Microservice"]
3653-
},
3654-
"lab-exercise-tracker": {
3655-
"title": "Build an Exercise Tracker",
3656-
"intro": ["In this lab, you will build an exercise tracker"]
3657-
},
3658-
"lab-file-metadata-microservice": {
3659-
"title": "Build a File Metadata Microservice",
3660-
"intro": ["For this lab you will build a file metadata microservice"]
3661-
},
36623642
"kegi": {
36633643
"title": "377",
36643644
"intro": []
36653645
},
3666-
"quiz-backend-javascript": {
3667-
"title": "Backend JavaScript Quiz",
3668-
"intro": [
3669-
"Test what you've learned in this quiz on Backend JavaScript."
3670-
]
3671-
},
36723646
"vnfu": {
36733647
"title": "379",
36743648
"intro": []
@@ -3685,12 +3659,6 @@
36853659
"title": "382",
36863660
"intro": []
36873661
},
3688-
"quiz-tooling-and-deployment": {
3689-
"title": "Tooling and Deployment Quiz",
3690-
"intro": [
3691-
"Test what you've learned in this quiz of tooling and deployment"
3692-
]
3693-
},
36943662
"nkjt": {
36953663
"title": "384",
36963664
"intro": []

client/i18n/locales/chinese-traditional/translations.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@
9696
"exit": "退出",
9797
"finish-exam": "完成考試",
9898
"finish": "完成",
99+
"exit-quiz": "Exit the quiz",
100+
"finish-quiz": "Finish the quiz",
99101
"submit-exam-results": "提交我的結果",
100102
"verify-trophy": "驗證獎盃",
101103
"link-account": "關聯賬戶",
@@ -518,7 +520,15 @@
518520
"correct-answer": "Correct!",
519521
"incorrect-answer": "Incorrect.",
520522
"unanswered-questions": "The following questions are unanswered: {{ unansweredQuestions }}. You must answer all questions.",
521-
"have-n-correct-questions": "You have {{ correctAnswerCount }} out of {{ total }} questions correct."
523+
"have-n-correct-questions": "You have {{ correctAnswerCount }} out of {{ total }} questions correct.",
524+
"finish-modal-header": "Finish Quiz",
525+
"finish-modal-body": "Are you sure you want to finish the quiz? You will not be able to change any answers.",
526+
"finish-modal-yes": "Yes, I am finished",
527+
"finish-modal-no": "No, I would like to continue the quiz",
528+
"exit-modal-header": "Exit Quiz",
529+
"exit-modal-body": "Are you sure you want to leave the quiz? You will lose any progress you have made.",
530+
"exit-modal-yes": "Yes, I want to leave the quiz",
531+
"exit-modal-no": "No, I would like to continue the quiz"
522532
},
523533
"exam": {
524534
"qualified": "恭喜,你已經完成了考試資格的所有要求。",
@@ -770,6 +780,7 @@
770780
"heart": "愛心",
771781
"initial": "初始",
772782
"input-reset": "清除搜索條件",
783+
"input-search": "Submit search terms",
773784
"info": "介紹信息",
774785
"spacer": "間隔",
775786
"toggle": "切換選中標記",

0 commit comments

Comments
 (0)