mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-09-01 15:02:09 +08:00
fix(client): show correct lab progress on resubmission (#67894)
This commit is contained in:
@@ -84,6 +84,22 @@ describe('get-completion-percentage', () => {
|
||||
|
||||
expect(result).toBe(33);
|
||||
});
|
||||
|
||||
it('reports 100% when resubmitting an already-completed single-challenge lab block', () => {
|
||||
// Regression test for #67867: a completed lab whose block contains only
|
||||
// the lab itself should read 100%, not 0%, on resubmission.
|
||||
const labId = 'lab-challenge';
|
||||
const completedChallengesIds = [labId];
|
||||
const currentBlockIds = [labId];
|
||||
|
||||
const result = getCompletedPercentage(
|
||||
completedChallengesIds,
|
||||
currentBlockIds,
|
||||
labId
|
||||
);
|
||||
|
||||
expect(result).toBe(100);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getCompletedChallengesInBlock', () => {
|
||||
@@ -251,6 +267,40 @@ describe('get-completion-percentage', () => {
|
||||
expect(result).toEqual(['project-1', 'project-2']);
|
||||
});
|
||||
|
||||
// Regression test for #67867: labs are project-based but each is its own
|
||||
// standalone block, so they must use their block IDs rather than the
|
||||
// certification's tests (otherwise resubmitting a completed lab reads 0%).
|
||||
it('returns block IDs for labs even when a certificate is available', () => {
|
||||
const allChallengesInfo: AllChallengesInfo = {
|
||||
challengeNodes: [
|
||||
{
|
||||
challenge: {
|
||||
id: 'lab-challenge',
|
||||
block: 'lab-all-true-property-validator',
|
||||
certification: Certification.JsV9
|
||||
}
|
||||
} as Partial<ChallengeNode> as ChallengeNode
|
||||
],
|
||||
certificateNodes: [
|
||||
{
|
||||
challenge: {
|
||||
certification: Certification.JsV9,
|
||||
tests: [{ id: 'javascript-certification-exam' }]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const result = getCurrentBlockIds(
|
||||
allChallengesInfo,
|
||||
'lab-all-true-property-validator',
|
||||
Certification.JsV9,
|
||||
challengeTypes.jsLab
|
||||
);
|
||||
|
||||
expect(result).toEqual(['lab-challenge']);
|
||||
});
|
||||
|
||||
it('returns empty array when no matching challenges found', () => {
|
||||
const allChallengesInfo: AllChallengesInfo = {
|
||||
challengeNodes: [
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { type Certification } from '@freecodecamp/shared/config/certification-settings';
|
||||
import { getIsLabChallenge } from '@freecodecamp/shared/config/challenge-types';
|
||||
import { AllChallengesInfo } from '../redux/prop-types';
|
||||
import { isProjectBased } from './curriculum-layout';
|
||||
|
||||
@@ -53,7 +54,10 @@ export const getCurrentBlockIds = (
|
||||
)
|
||||
.map(node => node.challenge.id);
|
||||
|
||||
if (isProjectBased(challengeType)) {
|
||||
// Labs are project-based, but each lab is its own standalone block rather than
|
||||
// part of a certification's project list. Excluding them keeps the progress bar
|
||||
// accurate (otherwise an already-completed lab reads 0% on resubmit). See #67867.
|
||||
if (isProjectBased(challengeType) && !getIsLabChallenge(challengeType)) {
|
||||
return currentCertificateIds.length > 0
|
||||
? currentCertificateIds
|
||||
: currentBlockIds;
|
||||
|
||||
@@ -178,6 +178,15 @@ const dailyCodingChallengeTypes = [
|
||||
export const getIsDailyCodingChallenge = (challengeType: number): boolean =>
|
||||
dailyCodingChallengeTypes.includes(challengeType);
|
||||
|
||||
const labChallengeTypes = [
|
||||
challengeTypes.lab,
|
||||
challengeTypes.jsLab,
|
||||
challengeTypes.pyLab
|
||||
];
|
||||
|
||||
export const getIsLabChallenge = (challengeType: number): boolean =>
|
||||
labChallengeTypes.includes(challengeType);
|
||||
|
||||
const dailyCodingChallengeLanguages = {
|
||||
[challengeTypes.dailyChallengeJs]: 'javascript',
|
||||
[challengeTypes.dailyChallengePy]: 'python'
|
||||
|
||||
Reference in New Issue
Block a user