+
+
+ {title}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+MsTrophy.displayName = 'MsTrophy';
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(withTranslation()(MsTrophy));
+
+export const query = graphql`
+ query MsTrophyChallenge($slug: String!) {
+ challengeNode(challenge: { fields: { slug: { eq: $slug } } }) {
+ challenge {
+ title
+ description
+ instructions
+ challengeType
+ superBlock
+ block
+ translationPending
+ }
+ }
+ }
+`;
diff --git a/client/src/templates/Challenges/projects/frontend/show.tsx b/client/src/templates/Challenges/projects/frontend/show.tsx
index f120121a0a1..2f12cbc12aa 100644
--- a/client/src/templates/Challenges/projects/frontend/show.tsx
+++ b/client/src/templates/Challenges/projects/frontend/show.tsx
@@ -28,7 +28,6 @@ import { isChallengeCompletedSelector } from '../../redux/selectors';
import { getGuideUrl } from '../../utils';
import SolutionForm from '../solution-form';
import ProjectToolPanel from '../tool-panel';
-import { challengeTypes } from '../../../../../../config/challenge-types';
// Redux Setup
const mapStateToProps = createSelector(
@@ -192,11 +191,9 @@ class Project extends Component {
onSubmit={this.handleSubmit}
updateSolutionForm={updateSolutionFormValues}
/>
- {challengeType !== challengeTypes.msTrophyUrl && (
-
- )}
+
diff --git a/client/src/templates/Challenges/projects/solution-form.tsx b/client/src/templates/Challenges/projects/solution-form.tsx
index 12ae2ae23cd..50979e35774 100644
--- a/client/src/templates/Challenges/projects/solution-form.tsx
+++ b/client/src/templates/Challenges/projects/solution-form.tsx
@@ -53,7 +53,6 @@ export class SolutionForm extends Component {
{ name: 'solution', label: t('learn.solution-link') },
{ name: 'githubLink', label: t('learn.github-link') }
];
- const msTrophyField = [{ name: 'solution', label: t('learn.ms-link') }];
const buttonCopy = t('learn.i-completed');
@@ -64,8 +63,7 @@ export class SolutionForm extends Component {
},
required: ['solution'],
isEditorLinkAllowed: false,
- isLocalLinkAllowed: false,
- isMicrosoftLearnLink: false
+ isLocalLinkAllowed: false
};
let formFields = solutionField;
@@ -108,14 +106,6 @@ export class SolutionForm extends Component {
solutionLink = solutionLink + 'https://your-git-repo.url/files';
break;
- case challengeTypes.msTrophyUrl:
- formFields = msTrophyField;
- options.isMicrosoftLearnLink = true;
- solutionLink =
- solutionLink +
- 'https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-1.trophy?username=you';
- break;
-
default:
formFields = solutionField;
solutionLink =
diff --git a/client/src/templates/Challenges/redux/completion-epic.js b/client/src/templates/Challenges/redux/completion-epic.js
index e93873c8bf0..da73bbedb89 100644
--- a/client/src/templates/Challenges/redux/completion-epic.js
+++ b/client/src/templates/Challenges/redux/completion-epic.js
@@ -13,7 +13,8 @@ import {
import { createFlashMessage } from '../../../components/Flash/redux';
import {
standardErrorMessage,
- trophyMissingMessage
+ msTrophyError,
+ msTrophyVerified
} from '../../../utils/error-messages';
import {
challengeTypes,
@@ -23,6 +24,7 @@ import {
import { actionTypes as submitActionTypes } from '../../../redux/action-types';
import {
allowBlockDonationRequests,
+ setIsProcessing,
setRenderStartTime,
submitComplete,
updateComplete,
@@ -50,10 +52,13 @@ import {
} from './selectors';
function postChallenge(update, username) {
+ const {
+ payload: { challengeType }
+ } = update;
const saveChallenge = postUpdate$(update).pipe(
retry(3),
switchMap(({ data }) => {
- const { savedChallenges, points, isTrophyMissing, examResults } = data;
+ const { savedChallenges, points, type, examResults } = data;
const payloadWithClientProperties = {
...omit(update.payload, ['files'])
};
@@ -66,7 +71,7 @@ function postChallenge(update, username) {
);
}
- const actions = [
+ let actions = [
submitComplete({
submittedChallenge: {
username,
@@ -79,9 +84,13 @@ function postChallenge(update, username) {
updateComplete(),
submitChallengeComplete()
];
- // TODO(Post-MVP): separate endpoint for trophy submission?
- if (isTrophyMissing)
- actions.push(createFlashMessage(trophyMissingMessage));
+
+ if (challengeType === challengeTypes.msTrophy && type === 'error') {
+ actions = [createFlashMessage(msTrophyError), submitChallengeError()];
+ } else if (challengeType === challengeTypes.msTrophy) {
+ actions.push(createFlashMessage(msTrophyVerified));
+ }
+
return of(...actions);
}),
catchError(() => of(updateFailed(update), submitChallengeError()))
@@ -176,7 +185,8 @@ const submitters = {
backend: submitBackendChallenge,
'project.frontEnd': submitProject,
'project.backEnd': submitProject,
- exam: submitExam
+ exam: submitExam,
+ msTrophy: submitMsTrophy
};
function submitExam(type, state) {
@@ -197,6 +207,22 @@ function submitExam(type, state) {
return empty();
}
+function submitMsTrophy(type, state) {
+ if (type === actionTypes.submitChallenge) {
+ const { id, challengeType } = challengeMetaSelector(state);
+
+ const { username } = userSelector(state);
+ const challengeInfo = { id, challengeType };
+
+ const update = {
+ endpoint: '/ms-trophy-challenge-completed',
+ payload: challengeInfo
+ };
+ return postChallenge(update, username);
+ }
+ return empty();
+}
+
export default function completionEpic(action$, state$) {
return action$.pipe(
ofType(actionTypes.submitChallenge),
@@ -238,7 +264,9 @@ export default function completionEpic(action$, state$) {
action.type === submitActionTypes.submitComplete;
return submitter(type, state).pipe(
- concat(of(setIsAdvancing(!lastChallengeInBlock))),
+ concat(
+ of(setIsAdvancing(!lastChallengeInBlock), setIsProcessing(false))
+ ),
mergeMap(x =>
canAllowDonationRequest(state, x)
? of(x, allowBlockDonationRequests({ superBlock, block }))
diff --git a/client/src/utils/ajax.ts b/client/src/utils/ajax.ts
index 7e92fbc1f74..314a986bba9 100644
--- a/client/src/utils/ajax.ts
+++ b/client/src/utils/ajax.ts
@@ -271,6 +271,12 @@ export function postUserToken(): Promise> {
return post('/user/user-token', {});
}
+export function postMsUsername(body: {
+ msTranscriptUrl: string;
+}): Promise> {
+ return post('/user/ms-username', body);
+}
+
export function postSaveChallenge(body: {
id: string;
files: ChallengeFiles;
@@ -368,3 +374,7 @@ export function putVerifyCert(
export function deleteUserToken(): Promise> {
return deleteRequest('/user/user-token', {});
}
+
+export function deleteMsUsername(): Promise> {
+ return deleteRequest('/user/ms-username', {});
+}
diff --git a/client/src/utils/error-messages.ts b/client/src/utils/error-messages.ts
index 238d479d5be..9d755a0085e 100644
--- a/client/src/utils/error-messages.ts
+++ b/client/src/utils/error-messages.ts
@@ -5,9 +5,9 @@ export const standardErrorMessage = {
message: FlashMessages.WentWrong
};
-export const trophyMissingMessage = {
+export const msTrophyError = {
type: 'danger',
- message: FlashMessages.MSTrophyMissing
+ message: FlashMessages.MsTrophyErr
};
export const reallyWeirdErrorMessage = {
@@ -24,3 +24,8 @@ export const certificateMissingErrorMessage = {
type: 'danger',
message: FlashMessages.CertificateMissing
};
+
+export const msTrophyVerified = {
+ type: 'success',
+ message: FlashMessages.MsTrophyVerified
+};
diff --git a/client/src/utils/tone/index.ts b/client/src/utils/tone/index.ts
index 7cf38103f97..179c6a45c6b 100644
--- a/client/src/utils/tone/index.ts
+++ b/client/src/utils/tone/index.ts
@@ -63,7 +63,12 @@ const toneUrls = {
[FlashMessages.WrongName]: TRY_AGAIN,
[FlashMessages.WrongUpdating]: TRY_AGAIN,
[FlashMessages.WentWrong]: TRY_AGAIN,
- [FlashMessages.MSTrophyMissing]: TRY_AGAIN
+ [FlashMessages.MsTrophyErr]: TRY_AGAIN,
+ [FlashMessages.MsTrophyVerified]: CHAL_COMP,
+ [FlashMessages.MsLinked]: CHAL_COMP,
+ [FlashMessages.MsLinkErr]: TRY_AGAIN,
+ [FlashMessages.MsUnlinked]: CHAL_COMP,
+ [FlashMessages.MsUnlinkErr]: TRY_AGAIN
} as const;
type ToneStates = keyof typeof toneUrls;
diff --git a/client/utils/gatsby/challenge-page-creator.js b/client/utils/gatsby/challenge-page-creator.js
index 19f03e964f6..8e8f5bc37ce 100644
--- a/client/utils/gatsby/challenge-page-creator.js
+++ b/client/utils/gatsby/challenge-page-creator.js
@@ -44,6 +44,11 @@ const exam = path.resolve(
'../../src/templates/Challenges/exam/show.tsx'
);
+const msTrophy = path.resolve(
+ __dirname,
+ '../../src/templates/Challenges/ms-trophy/show.tsx'
+);
+
const views = {
backend,
classic,
@@ -52,7 +57,8 @@ const views = {
video,
codeAlly,
odin,
- exam
+ exam,
+ msTrophy
// quiz: Quiz
};
diff --git a/config/challenge-types.ts b/config/challenge-types.ts
index caecbfc4332..b9cceeb2fc8 100644
--- a/config/challenge-types.ts
+++ b/config/challenge-types.ts
@@ -17,7 +17,7 @@ const multifileCertProject = 14;
const theOdinProject = 15;
const colab = 16;
const exam = 17;
-const msTrophyUrl = 18;
+const msTrophy = 18;
const multipleChoice = 19;
const python = 20;
@@ -41,7 +41,7 @@ export const challengeTypes = {
theOdinProject,
colab,
exam,
- msTrophyUrl,
+ msTrophy,
multipleChoice,
python
};
@@ -92,7 +92,7 @@ export const viewTypes = {
[theOdinProject]: 'odin',
[colab]: 'frontend',
[exam]: 'exam',
- [msTrophyUrl]: 'frontend',
+ [msTrophy]: 'msTrophy',
[multipleChoice]: 'video',
[python]: 'modern'
};
@@ -120,7 +120,7 @@ export const submitTypes = {
[theOdinProject]: 'tests',
[colab]: 'project.backEnd',
[exam]: 'exam',
- [msTrophyUrl]: 'project.frontEnd',
+ [msTrophy]: 'msTrophy',
[multipleChoice]: 'tests',
[python]: 'tests'
};
diff --git a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/add-logic-to-c-sharp-console-applications/evaluate-boolean-expressions-to-make-decisions-in-c-sharp.md b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/add-logic-to-c-sharp-console-applications/evaluate-boolean-expressions-to-make-decisions-in-c-sharp.md
index 3d48e953996..47a0c486d1c 100644
--- a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/add-logic-to-c-sharp-console-applications/evaluate-boolean-expressions-to-make-decisions-in-c-sharp.md
+++ b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/add-logic-to-c-sharp-console-applications/evaluate-boolean-expressions-to-make-decisions-in-c-sharp.md
@@ -20,15 +20,15 @@ Which of the following lines of code is a valid use of the conditional operator?
## --answers--
-`int value = amount >= 10? 10: 20;`
+`int value = amount >= 10 ? 10 : 20;`
---
-`int value = amount >= 10: 10? 20;`
+`int value = amount >= 10 : 10 ? 20;`
---
-`int value = amount >= 10? 10| 20;`
+`int value = amount >= 10 ? 10 | 20;`
## --video-solution--
diff --git a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/add-logic-to-c-sharp-console-applications/trophy-add-logic-to-c-sharp-console-applications.md b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/add-logic-to-c-sharp-console-applications/trophy-add-logic-to-c-sharp-console-applications.md
index 24f758c359d..709027461cd 100644
--- a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/add-logic-to-c-sharp-console-applications/trophy-add-logic-to-c-sharp-console-applications.md
+++ b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/add-logic-to-c-sharp-console-applications/trophy-add-logic-to-c-sharp-console-applications.md
@@ -3,21 +3,11 @@ id: 647f882207d29547b3bee1c0
title: Trophy - Add Logic to C# Console Applications
challengeType: 18
dashedName: trophy-add-logic-to-c-sharp-console-applications
+msTrophyId: learn.wwl.get-started-c-sharp-part-3.trophy
---
# --description--
-Now that you've completed all of the "Add Logic to C# Console Applications" modules on Microsoft's learn platform, submit the URL to your trophy below.
+Now that you've completed all of the "Add Logic to C# Console Applications" challenges, you should have earned a trophy for it on Microsoft's learning platform.
-Follow these instructions to find your trophy URL:
-
-1. Go to https://learn.microsoft.com/users/me/achievements#badges-section using a browser you are logged into Microsoft with
-1. Find the trophy for "Add Logic to C# Console Applications" and click the "share" icon next to it
-1. Click the "Copy URL" button
-1. Paste the URL into the input below
-
-The URL should look similar to this:
-
-`https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-3.trophy?username=your-username&sharingId=your-sharing-id`
-
-This trophy is required to qualify to take the certification exam.
+Link your Microsoft username to your freeCodeCamp account and click the "Verify Trophy" button below to complete the challenge. This trophy is required to qualify to take the certification exam.
diff --git a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-and-run-simple-c-sharp-console-applications/trophy-create-and-run-simple-c-sharp-console-applications.md b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-and-run-simple-c-sharp-console-applications/trophy-create-and-run-simple-c-sharp-console-applications.md
index 79faabc35ec..1f2d2911618 100644
--- a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-and-run-simple-c-sharp-console-applications/trophy-create-and-run-simple-c-sharp-console-applications.md
+++ b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-and-run-simple-c-sharp-console-applications/trophy-create-and-run-simple-c-sharp-console-applications.md
@@ -3,21 +3,11 @@ id: 647f87dc07d29547b3bee1bf
title: Trophy - Create and Run Simple C# Console Applications
challengeType: 18
dashedName: trophy-create-and-run-simple-c-sharp-console-applications
+msTrophyId: learn.wwl.get-started-c-sharp-part-2.trophy
---
# --description--
-Now that you've completed all of the "Create and Run Simple C# Console Applications" modules on Microsoft's learn platform, submit the URL to your trophy below.
+Now that you've completed all of the "Create and Run Simple C# Console Applications" challenges, you should have earned a trophy for it on Microsoft's learning platform.
-Follow these instructions to find your trophy URL:
-
-1. Go to https://learn.microsoft.com/users/me/achievements#badges-section using a browser you are logged into Microsoft with
-1. Find the trophy for "Create and Run Simple C# Console Applications" and click the "share" icon next to it
-1. Click the "Copy URL" button
-1. Paste the URL into the input below
-
-The URL should look similar to this:
-
-`https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-2.trophy?username=your-username&sharingId=your-sharing-id`
-
-This trophy is required to qualify to take the certification exam.
+Link your Microsoft username to your freeCodeCamp account and click the "Verify Trophy" button below to complete the challenge. This trophy is required to qualify to take the certification exam.
diff --git a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-methods-in-c-sharp-console-applications/create-c-sharp-methods-with-parameters.md b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-methods-in-c-sharp-console-applications/create-c-sharp-methods-with-parameters.md
index d0ea7e05106..deef4a96635 100644
--- a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-methods-in-c-sharp-console-applications/create-c-sharp-methods-with-parameters.md
+++ b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-methods-in-c-sharp-console-applications/create-c-sharp-methods-with-parameters.md
@@ -18,9 +18,11 @@ This challenge will be partially completed on Microsoft's learn platform. Follow
Given the method signature,
-`void Print(string name, string number = "", bool member = false)`,
+```clike
+void Print(string name, string number = "", bool member = false)
+```
-which of the following options correctly uses named and optional arguments?
+Which of the following options correctly uses named and optional arguments?
## --answers--
diff --git a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-methods-in-c-sharp-console-applications/trophy-create-methods-in-c-sharp-console-applications.md b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-methods-in-c-sharp-console-applications/trophy-create-methods-in-c-sharp-console-applications.md
index 1ccee355dd3..a2fa4877ce6 100644
--- a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-methods-in-c-sharp-console-applications/trophy-create-methods-in-c-sharp-console-applications.md
+++ b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/create-methods-in-c-sharp-console-applications/trophy-create-methods-in-c-sharp-console-applications.md
@@ -3,21 +3,11 @@ id: 647f877f07d29547b3bee1be
title: Trophy - Create Methods in C# Console Applications
challengeType: 18
dashedName: trophy-create-methods-in-c-sharp-console-applications
+msTrophyId: learn.wwl.get-started-c-sharp-part-5.trophy
---
# --description--
-Now that you've completed all of the "Create Methods in C# Console Applications" modules on Microsoft's learn platform, submit the URL to your trophy below.
+Now that you've completed all of the "Create Methods in C# Console Applications" challenges, you should have earned a trophy for it on Microsoft's learning platform.
-Follow these instructions to find your trophy URL:
-
-1. Go to https://learn.microsoft.com/users/me/achievements#badges-section using a browser you are logged into Microsoft with
-1. Find the trophy for "Create Methods in C# Console Applications" and click the "share" icon next to it
-1. Click the "Copy URL" button
-1. Paste the URL into the input below
-
-The URL should look similar to this:
-
-`https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-5.trophy?username=your-username&sharingId=your-sharing-id`
-
-This trophy is required to qualify to take the certification exam.
+Link your Microsoft username to your freeCodeCamp account and click the "Verify Trophy" button below to complete the challenge. This trophy is required to qualify to take the certification exam.
diff --git a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/debug-c-sharp-console-applications/trophy-debug-c-sharp-console-applications.md b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/debug-c-sharp-console-applications/trophy-debug-c-sharp-console-applications.md
index ade2bde35ed..0ad0629cd57 100644
--- a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/debug-c-sharp-console-applications/trophy-debug-c-sharp-console-applications.md
+++ b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/debug-c-sharp-console-applications/trophy-debug-c-sharp-console-applications.md
@@ -3,21 +3,11 @@ id: 647f86ff07d29547b3bee1bd
title: Trophy - Debug C# Console Applications
challengeType: 18
dashedName: trophy-debug-c-sharp-console-applications
+msTrophyId: learn.wwl.get-started-c-sharp-part-6.trophy
---
# --description--
-Now that you've completed all of the "Debug C# Console Applications" modules on Microsoft's learn platform, submit the URL to your trophy below.
+Now that you've completed all of the "Debug C# Console Applications" challenges, you should have earned a trophy for it on Microsoft's learning platform.
-Follow these instructions to find your trophy URL:
-
-1. Go to https://learn.microsoft.com/users/me/achievements#badges-section using a browser you are logged into Microsoft with
-1. Find the trophy for "Debug C# Console Applications" and click the "share" icon next to it
-1. Click the "Copy URL" button
-1. Paste the URL into the input below
-
-The URL should look similar to this:
-
-`https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-6.trophy?username=your-username&sharingId=your-sharing-id`
-
-This trophy is required to qualify to take the certification exam.
+Link your Microsoft username to your freeCodeCamp account and click the "Verify Trophy" button below to complete the challenge. This trophy is required to qualify to take the certification exam.
diff --git a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/work-with-variable-data-in-c-sharp-console-applications/trophy-work-with-variable-data-in-c-sharp-console-applications.md b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/work-with-variable-data-in-c-sharp-console-applications/trophy-work-with-variable-data-in-c-sharp-console-applications.md
index 03b7a62a073..d556dae8bb6 100644
--- a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/work-with-variable-data-in-c-sharp-console-applications/trophy-work-with-variable-data-in-c-sharp-console-applications.md
+++ b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/work-with-variable-data-in-c-sharp-console-applications/trophy-work-with-variable-data-in-c-sharp-console-applications.md
@@ -3,21 +3,11 @@ id: 647f867a07d29547b3bee1bc
title: Trophy - Work with Variable Data in C# Console Applications
challengeType: 18
dashedName: trophy-work-with-variable-data-in-c-sharp-console-applications
+msTrophyId: learn.wwl.get-started-c-sharp-part-4.trophy
---
# --description--
-Now that you've completed all of the "Work with Variable Data in C# Console Applications" modules on Microsoft's learn platform, submit the URL to your trophy below.
+Now that you've completed all of the "Work with Variable Data in C# Console Applications" challenges, you should have earned a trophy for it on Microsoft's learning platform.
-Follow these instructions to find your trophy URL:
-
-1. Go to https://learn.microsoft.com/users/me/achievements#badges-section using a browser you are logged into Microsoft with
-1. Find the trophy for "Work with Variable Data in C# Console Applications" and click the "share" icon next to it
-1. Click the "Copy URL" button
-1. Paste the URL into the input below
-
-The URL should look similar to this:
-
-`https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-4.trophy?username=your-username&sharingId=your-sharing-id`
-
-This trophy is required to qualify to take the certification exam.
+Link your Microsoft username to your freeCodeCamp account and click the "Verify Trophy" button below to complete the challenge. This trophy is required to qualify to take the certification exam.
diff --git a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/guided-project-calculate-and-print-student-grades.md b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/guided-project-calculate-and-print-student-grades.md
index 8e2307255b1..d7980f1b170 100644
--- a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/guided-project-calculate-and-print-student-grades.md
+++ b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/guided-project-calculate-and-print-student-grades.md
@@ -18,7 +18,10 @@ This challenge will be partially completed on Microsoft's learn platform. Follow
What is wrong with the following code?
-`int sophiaSum; Console.WriteLine("Sophia: " + sophiaSum);`
+```clike
+int sophiaSum;
+Console.WriteLine("Sophia: " + sophiaSum);
+```
## --answers--
diff --git a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/perform-basic-operations-on-numbers-in-c-sharp.md b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/perform-basic-operations-on-numbers-in-c-sharp.md
index 9b11808405d..80398319ef8 100644
--- a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/perform-basic-operations-on-numbers-in-c-sharp.md
+++ b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/perform-basic-operations-on-numbers-in-c-sharp.md
@@ -18,7 +18,9 @@ This challenge will be partially completed on Microsoft's learn platform. Follow
What is the value of the following result?
-`int result = 3 + 1 * 5 / 2;`
+```clike
+int result = 3 + 1 * 5 / 2;
+```
## --answers--
diff --git a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/perform-basic-string-formatting-in-c-sharp.md b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/perform-basic-string-formatting-in-c-sharp.md
index 82ef2c897b0..177487051ef 100644
--- a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/perform-basic-string-formatting-in-c-sharp.md
+++ b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/perform-basic-string-formatting-in-c-sharp.md
@@ -20,15 +20,15 @@ Which of the following lines of code correctly uses string interpolation assumin
## --answers--
-'`Console.WriteLine(@"My value: {value}");`'
+`Console.WriteLine(@"My value: {value}");`
---
-'`Console.WriteLine($"My value: {value}");`'
+`Console.WriteLine($"My value: {value}");`
---
-'`Console.WriteLine(@"My value: [value]");`'
+`Console.WriteLine(@"My value: [value]");`
## --video-solution--
diff --git a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/trophy-write-your-first-code-using-c-sharp.md b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/trophy-write-your-first-code-using-c-sharp.md
index fa0299b12b6..4a0d15770c2 100644
--- a/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/trophy-write-your-first-code-using-c-sharp.md
+++ b/curriculum/challenges/english/19-foundational-c-sharp-with-microsoft/write-your-first-code-using-c-sharp/trophy-write-your-first-code-using-c-sharp.md
@@ -3,21 +3,11 @@ id: 647f85d407d29547b3bee1bb
title: Trophy - Write Your First Code Using C#
challengeType: 18
dashedName: trophy-write-your-first-code-using-c-sharp
+msTrophyId: learn.wwl.get-started-c-sharp-part-1.trophy
---
# --description--
-Now that you've completed all of the "Write Your First Code Using C#" modules on Microsoft's learn platform, submit the URL to your trophy below.
+Now that you've completed all of the "Write Your First Code Using C#" challenges, you should have earned a trophy for it on Microsoft's learning platform.
-Follow these instructions to find your trophy URL:
-
-1. Go to https://learn.microsoft.com/users/me/achievements#badges-section using a browser you are logged into Microsoft with
-1. Find the trophy for "Write Your First Code Using C#" and click the "share" icon next to it
-1. Click the "Copy URL" button
-1. Paste the URL into the input below
-
-The URL should look similar to this:
-
-`https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-1.trophy?username=your-username&sharingId=your-sharing-id`
-
-This trophy is required to qualify to take the certification exam.
+Link your Microsoft username to your freeCodeCamp account and click the "Verify Trophy" button below to complete the challenge. This trophy is required to qualify to take the certification exam.
diff --git a/curriculum/schema/challenge-schema.js b/curriculum/schema/challenge-schema.js
index 69bc8e84830..ee9ee91ad92 100644
--- a/curriculum/schema/challenge-schema.js
+++ b/curriculum/schema/challenge-schema.js
@@ -58,6 +58,10 @@ const schema = Joi.object()
isComingSoon: Joi.bool(),
isLocked: Joi.bool(),
isPrivate: Joi.bool(),
+ msTrophyId: Joi.when('challengeType', {
+ is: [challengeTypes.msTrophy],
+ then: Joi.string().required()
+ }),
notes: Joi.string().allow(''),
order: Joi.number(),
prerequisites: Joi.when('challengeType', {
diff --git a/utils/validate.test.ts b/utils/validate.test.ts
index 40626bc39a7..9ed026e2ef5 100644
--- a/utils/validate.test.ts
+++ b/utils/validate.test.ts
@@ -3,8 +3,7 @@ import {
usernameTooShort,
validationSuccess,
usernameIsHttpStatusCode,
- invalidCharError,
- isMicrosoftLearnLink
+ invalidCharError
} from './validate';
function inRange(num: number, range: number[]) {
@@ -57,65 +56,3 @@ describe('isValidUsername', () => {
}
});
});
-
-const baseUrl =
- 'https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-1.trophy';
-describe('form-validators', () => {
- describe('isMicrosoftLearnLink', () => {
- it('should reject links to domains other than learn.microsoft.com', () => {
- {
- expect(isMicrosoftLearnLink('https://lean.microsoft.com')).toBe(false);
- expect(isMicrosoftLearnLink('https://learn.microsft.com')).toBe(false);
- }
- });
-
- it('should reject links without a sharingId', () => {
- expect(isMicrosoftLearnLink(`${baseUrl}?username=moT01`)).toBe(false);
-
- expect(isMicrosoftLearnLink(`${baseUrl}?username=moT01&sharingId=`)).toBe(
- false
- );
- });
-
- it('should reject links without a username', () => {
- expect(isMicrosoftLearnLink(`${baseUrl}?sharingId=Whatever`)).toBe(false);
- expect(isMicrosoftLearnLink(`${baseUrl}?sharingId=123&username=`)).toBe(
- false
- );
- });
-
- it('should reject links without the /training/achievements/ subpath', () => {
- expect(
- isMicrosoftLearnLink(
- 'https://learn.microsoft.com/en-us/achievements/learn.wwl.get-started-c-sharp-part-1.trophy?username=moT01&sharingId=E2EF453C1F9208B8'
- )
- ).toBe(false);
- });
-
- it('should reject links with the wrong trophy subpath', () => {
- // missing .trophy
- expect(
- isMicrosoftLearnLink(
- 'https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-1?username=moT01&sharingId=E2EF453C1F9208B8'
- )
- ).toBe(false);
- // no number
- expect(
- isMicrosoftLearnLink(
- 'https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-a.trophy?username=moT01&sharingId=E2EF453C1F9208B8'
- )
- ).toBe(false);
- });
-
- it.each(['en-us', 'fr-fr', 'lang-country'])(
- 'should accept links with the %s locale',
- locale => {
- expect(
- isMicrosoftLearnLink(
- `https://learn.microsoft.com/${locale}/training/achievements/learn.wwl.get-started-c-sharp-part-1.trophy?username=moT01&sharingId=E2EF453C1F9208B8`
- )
- ).toBe(true);
- }
- );
- });
-});
diff --git a/utils/validate.ts b/utils/validate.ts
index dd4e01439a8..12a1fa76019 100644
--- a/utils/validate.ts
+++ b/utils/validate.ts
@@ -36,21 +36,3 @@ export const isValidUsername = (str: string): Validated => {
if (isHttpStatusCode(str)) return usernameIsHttpStatusCode;
return validationSuccess;
};
-
-// example link: https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-1.trophy?username=moT01&sharingId=E2EF453C1F9208B8
-export const isMicrosoftLearnLink = (value: string): boolean => {
- let url;
- try {
- url = new URL(value);
- } catch {
- return false;
- }
-
- const correctDomain = url.hostname === 'learn.microsoft.com';
- const correctPath = !!url.pathname.match(
- /^\/[^/]+\/training\/achievements\/learn\.wwl\.get-started-c-sharp-part-\d\.trophy$/
- );
- const hasSharingId = !!url.searchParams.get('sharingId');
- const hasUsername = !!url.searchParams.get('username');
- return correctDomain && correctPath && hasSharingId && hasUsername;
-};