fix:(api): send full stack email for v9 (#64751)

Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>
This commit is contained in:
Ahmad Abdolsaheb
2026-02-17 17:24:32 +03:00
committed by GitHub
parent 8e7edb9f3d
commit 4a11c4fdf5
3 changed files with 8 additions and 65 deletions

View File

@@ -211,7 +211,7 @@ describe('certificate routes', () => {
});
// Note: Email does not actually send (work) in development, but status should still be 200.
test('should send the certified email, if all current certifications are met', async () => {
test('should send the certified email when full stack developer v9 is claimed', async () => {
await fastifyTestInstance.prisma.user.updateMany({
where: { email: defaultUserEmail },
data: {
@@ -222,25 +222,7 @@ describe('certificate routes', () => {
{ id: '587d78b0367417b2b2512b05', completedDate: 123456789 },
{ id: 'bd7158d8c242eddfaeb5bd13', completedDate: 123456789 }
],
is2018DataVisCert: true,
isA2EnglishCert: true,
isB1EnglishCert: true,
isApisMicroservicesCert: true,
isCollegeAlgebraPyCertV8: true,
isDataAnalysisPyCertV7: true,
isFoundationalCSharpCertV8: true,
isFrontEndLibsCert: true,
isInfosecCertV7: true,
isJavascriptCertV9: true,
isJsAlgoDataStructCertV8: true,
isMachineLearningPyCertV7: true,
isPythonCertV9: true,
isQaCertV7: true,
isRelationalDatabaseCertV8: true,
isRelationalDatabaseCertV9: true,
isRespWebDesignCert: false,
isRespWebDesignCertV9: true,
isSciCompPyCertV7: true
isFullStackDeveloperCertV9: true
}
});

View File

@@ -44,14 +44,12 @@ function renderCertifiedEmail({
}) {
const certifiedEmailTemplate = `Hi ${name || username},
Congratulations on completing all of the freeCodeCamp certifications!
Congratulations on completing the Certified Full Stack Developer Curriculum!
All of your certifications are now live at: https://www.freecodecamp.org/${username}
Please tell me a bit more about you and your near-term goals.
Are you interested in contributing to our open source projects used by nonprofits?
Also, check out https://contribute.freecodecamp.org/ for some fun and convenient ways you can contribute to the community.
Happy coding,
@@ -372,18 +370,17 @@ export const protectedCertificateRoutes: FastifyPluginCallbackTypebox = (
const updatedIsCertMap = getUserIsCertMap(updatedUserSansNull);
// TODO(POST-MVP): Consider sending email based on `user.isEmailVerified` as well
const hasCompletedAllCerts = currentCertifications
.map(x => certSlugTypeMap[x])
.every(certType => updatedIsCertMap[certType]);
const fullStackV9Claimed = updatedIsCertMap.isFullStackDeveloperCertV9;
const shouldSendCertifiedEmailToCamper =
email && validator.default.isEmail(email) && hasCompletedAllCerts;
email && validator.default.isEmail(email) && fullStackV9Claimed;
if (shouldSendCertifiedEmailToCamper) {
const notifyUser = {
to: email,
from: 'quincy@freecodecamp.org',
subject:
'Congratulations on completing all of the freeCodeCamp certifications!',
'Congratulations on completing the Certified Full Stack Developer Curriculum!',
text: renderCertifiedEmail({
username: updatedUser.username,
// Safety: `user.name` is required to exist earlier. TODO: Assert

View File

@@ -1,44 +1,8 @@
import { execSync } from 'child_process';
import { test, expect, Page } from '@playwright/test';
import translations from '../client/i18n/locales/english/translations.json';
import { alertToBeVisible } from './utils/alerts';
import {
deleteAllEmails,
getAllEmails,
getFirstEmail,
getSubject
} from './utils/email';
test.describe('Claim a certification - almost certified user', () => {
test.beforeEach(async () => {
await deleteAllEmails();
execSync('node ../tools/scripts/seed/seed-demo-user --unclaimed-user');
});
test.afterAll(() => {
execSync('node ../tools/scripts/seed/seed-demo-user --certified-user');
});
test.use({ storageState: 'playwright/.auth/certified-user.json' });
test('User receives a congratulations email on completing all certs', async ({
page
}) => {
await page.goto('/settings#cert-front-end-development-libraries');
await page
.getByRole('button', {
name: 'Claim Certification Front End Development Libraries V8'
})
.click();
// verify that an email is sent
await expect(async () => {
const emails = await getAllEmails();
expect(emails.messages).toHaveLength(1);
expect(getSubject(getFirstEmail(emails))).toBe(
'Congratulations on completing all of the freeCodeCamp certifications!'
);
}).toPass();
});
});
// TODO: Include fullstack emails when claiming fullstack is implemented.
test.describe('Certification page - Non Microsoft', () => {
test.beforeEach(async ({ page }) => {