mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2025-12-19 10:07:46 -05:00
fix(client): fix backend code source submission (#58832)
Co-authored-by: sembauke <semboot699@gmail.com>
This commit is contained in:
@@ -981,7 +981,8 @@
|
||||
"publicly-visible-url": "Remember to submit a publicly visible app URL.",
|
||||
"ms-learn-link": "Please use a valid Microsoft Learn trophy link.",
|
||||
"path-url": "You probably want to submit the root path i.e. https://example.com, not https://example.com/path",
|
||||
"source-code-link-required": "Remember to submit the link to your source code."
|
||||
"source-code-link-required": "Remember to submit the link to your source code.",
|
||||
"source-code-link-public": "Source code link must be publicly visible."
|
||||
},
|
||||
"certification": {
|
||||
"executive": "Executive Director, freeCodeCamp.org",
|
||||
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
fCCValidator,
|
||||
httpValidator,
|
||||
pathValidator,
|
||||
sourceCodeLinkExistsValidator
|
||||
sourceCodeLinkExistsValidator,
|
||||
sourceCodeLinkPublicValidator
|
||||
} from './form-validators';
|
||||
|
||||
export type FormOptions = {
|
||||
@@ -67,8 +68,11 @@ function FormFields({ formFields, options }: FormFieldsProps): JSX.Element {
|
||||
validators.push(pathValidator);
|
||||
}
|
||||
}
|
||||
if (isSourceCodeLinkRequired && name === 'githubLink') {
|
||||
validators.push(sourceCodeLinkExistsValidator);
|
||||
if (name === 'githubLink') {
|
||||
if (isSourceCodeLinkRequired) {
|
||||
validators.push(sourceCodeLinkExistsValidator);
|
||||
}
|
||||
validators.push(sourceCodeLinkPublicValidator);
|
||||
}
|
||||
if (!isLocalLinkAllowed) {
|
||||
validators.push(localhostValidator);
|
||||
|
||||
@@ -41,6 +41,8 @@ export const pathValidator: Validator = value =>
|
||||
export const sourceCodeLinkExistsValidator: Validator = value =>
|
||||
value ? null : <Trans>validation.source-code-link-required</Trans>;
|
||||
|
||||
export const sourceCodeLinkPublicValidator: Validator = value =>
|
||||
isPrivate(value) ? <Trans>validation.source-code-link-public</Trans> : null;
|
||||
export function composeValidators(...validators: Validator[]) {
|
||||
return (value: string): ReturnType<Validator> | null =>
|
||||
validators.reduce(
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
composeValidators,
|
||||
fCCValidator,
|
||||
httpValidator,
|
||||
sourceCodeLinkExistsValidator
|
||||
sourceCodeLinkExistsValidator,
|
||||
sourceCodeLinkPublicValidator
|
||||
} from './form-validators';
|
||||
import FormFields, { FormOptions } from './form-fields';
|
||||
|
||||
@@ -69,8 +70,11 @@ function validateFormValues(
|
||||
if (!isLocalLinkAllowed) {
|
||||
validators.push(localhostValidator);
|
||||
}
|
||||
if (isSourceCodeLinkRequired) {
|
||||
validators.push(sourceCodeLinkExistsValidator);
|
||||
if (key === 'githubLink') {
|
||||
if (isSourceCodeLinkRequired) {
|
||||
validators.push(sourceCodeLinkExistsValidator);
|
||||
}
|
||||
validators.push(sourceCodeLinkPublicValidator);
|
||||
}
|
||||
|
||||
const nullOrWarning = composeValidators(...validators)(value);
|
||||
|
||||
@@ -56,7 +56,7 @@ function postChallenge(update) {
|
||||
const saveChallenge = postUpdate$(update).pipe(
|
||||
retry(3),
|
||||
switchMap(({ data }) => {
|
||||
const { savedChallenges, message, examResults } = data;
|
||||
const { type, savedChallenges, message, examResults } = data;
|
||||
const payloadWithClientProperties = {
|
||||
...omit(update.payload, ['files'])
|
||||
};
|
||||
@@ -79,8 +79,15 @@ function postChallenge(update) {
|
||||
submitChallengeComplete()
|
||||
];
|
||||
|
||||
if (message && challengeType === challengeTypes.msTrophy) {
|
||||
actions = [createFlashMessage(data), submitChallengeError()];
|
||||
if (
|
||||
type === 'error' ||
|
||||
(message && challengeType === challengeTypes.msTrophy)
|
||||
) {
|
||||
actions = [];
|
||||
if (message) {
|
||||
actions.push(createFlashMessage(data));
|
||||
}
|
||||
actions.push(submitChallengeError());
|
||||
} else if (challengeType === challengeTypes.msTrophy) {
|
||||
actions.push(createFlashMessage(msTrophyVerified));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ import { test, expect } from '@playwright/test';
|
||||
const locations = {
|
||||
index:
|
||||
'learn/back-end-development-and-apis/managing-packages-with-npm/' +
|
||||
'how-to-use-package-json-the-core-of-any-node-js-project-or-npm-package'
|
||||
'how-to-use-package-json-the-core-of-any-node-js-project-or-npm-package',
|
||||
project:
|
||||
'/learn/back-end-development-and-apis/back-end-development-and-apis-projects/timestamp-microservice'
|
||||
};
|
||||
|
||||
const unhandledErrorMessage = 'Something is not quite right';
|
||||
@@ -28,3 +30,18 @@ test.describe('Backend challenge', () => {
|
||||
await expect(page.getByText(unhandledErrorMessage)).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Backend project', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(locations.project);
|
||||
});
|
||||
|
||||
test('warns against private source code links', async ({ page }) => {
|
||||
await page.fill('input[name="solution"]', 'https://example.com');
|
||||
await page.fill('input[name="githubLink"]', 'https://localhost:3000');
|
||||
|
||||
await expect(
|
||||
page.getByText('Source code link must be publicly visible.')
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user