diff --git a/api-server/src/server/boot/settings.js b/api-server/src/server/boot/settings.js
index a46b298ff4..d3d02d6c59 100644
--- a/api-server/src/server/boot/settings.js
+++ b/api-server/src/server/boot/settings.js
@@ -28,7 +28,6 @@ export default function settingsController(app) {
updateMyCurrentChallenge
);
api.post('/update-my-portfolio', ifNoUser401, updateMyPortfolio);
- api.post('/update-my-projects', ifNoUser401, updateMyProjects);
api.post(
'/update-my-theme',
ifNoUser401,
@@ -159,16 +158,6 @@ function updateMyProfileUI(req, res, next) {
);
}
-function updateMyProjects(req, res, next) {
- const {
- user,
- body: { projects: project }
- } = req;
- return user
- .updateMyProjects(project)
- .subscribe(message => res.json({ message }), next);
-}
-
function updateMyAbout(req, res, next) {
const {
user,
diff --git a/api-server/src/server/utils/constants.js b/api-server/src/server/utils/constants.js
index db84d7d404..772b1c6ee3 100644
--- a/api-server/src/server/utils/constants.js
+++ b/api-server/src/server/utils/constants.js
@@ -80,7 +80,6 @@ let blocklist = [
'unsubscribed',
'update-my-portfolio',
'update-my-profile-ui',
- 'update-my-projects',
'update-my-theme',
'update-my-username',
'user',
diff --git a/client/src/components/settings/Certification.js b/client/src/components/settings/Certification.js
index ddfd707d9e..5c6d2cd3b4 100644
--- a/client/src/components/settings/Certification.js
+++ b/client/src/components/settings/Certification.js
@@ -1,8 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import { bindActionCreators } from 'redux';
-import { connect } from 'react-redux';
-import { find, first, values, isString } from 'lodash-es';
+import { find, first } from 'lodash-es';
import {
Table,
Button,
@@ -21,16 +19,10 @@ import {
import SectionHeader from './SectionHeader';
import ProjectModal from '../SolutionViewer/ProjectModal';
import { FullWidthRow, Spacer } from '../helpers';
-import { Form } from '../formHelpers';
import { maybeUrlRE } from '../../utils';
-import reallyWeirdErrorMessage from '../../utils/reallyWeirdErrorMessage';
import './certification.css';
-import { updateLegacyCert } from '../../redux/settings';
-
-const mapDispatchToProps = dispatch =>
- bindActionCreators({ updateLegacyCert }, dispatch);
const propTypes = {
completedChallenges: PropTypes.arrayOf(
@@ -61,7 +53,6 @@ const propTypes = {
isRespWebDesignCert: PropTypes.bool,
isSciCompPyCertV7: PropTypes.bool,
t: PropTypes.func.isRequired,
- updateLegacyCert: PropTypes.func.isRequired,
username: PropTypes.string,
verifyCert: PropTypes.func.isRequired
};
@@ -156,7 +147,6 @@ export class CertificationSettings extends Component {
super(props);
this.state = { ...initialState };
- this.handleSubmitLegacy = this.handleSubmitLegacy.bind(this);
}
createHandleLinkButtonClick = to => e => {
@@ -258,9 +248,9 @@ export class CertificationSettings extends Component {
);
};
- renderCertifications = certName => {
+ renderCertifications = (certName, projectsMap) => {
const { t } = this.props;
- const { certSlug } = first(projectMap[certName]);
+ const { certSlug } = first(projectsMap[certName]);
return (
@@ -277,17 +267,18 @@ export class CertificationSettings extends Component {
{this.renderProjectsFor(
certName,
- this.getUserIsCertMap()[certName]
+ this.getUserIsCertMap()[certName],
+ projectsMap
)}
);
};
- renderProjectsFor = (certName, isCert) => {
+ renderProjectsFor = (certName, isCert, projectsMap) => {
const { username, isHonest, createFlashMessage, t, verifyCert } =
this.props;
- const { certSlug } = first(projectMap[certName]);
+ const { certSlug } = first(projectsMap[certName]);
const certLocation = `/certification/${username}/${certSlug}`;
const createClickHandler = certSlug => e => {
e.preventDefault();
@@ -298,7 +289,7 @@ export class CertificationSettings extends Component {
? verifyCert(certSlug)
: createFlashMessage(honestyInfoMessage);
};
- return projectMap[certName]
+ return projectsMap[certName]
.map(({ link, title, id }) => (
@@ -325,160 +316,6 @@ export class CertificationSettings extends Component {
]);
};
- // legacy projects rendering
- handleSubmitLegacy({ values: formChalObj }) {
- const { isHonest, createFlashMessage, verifyCert, updateLegacyCert } =
- this.props;
- let legacyTitle;
- let certSlug;
- let certs = Object.keys(legacyProjectMap);
- let loopBreak = false;
- for (let certTitle of certs) {
- for (let chalTitle of legacyProjectMap[certTitle]) {
- if (chalTitle.title === Object.keys(formChalObj)[0]) {
- certSlug = chalTitle.certSlug;
- loopBreak = true;
- legacyTitle = certTitle;
- break;
- }
- }
- if (loopBreak) {
- break;
- }
- }
-
- // make an object with keys as challenge ids and values as solutions
- let idsToSolutions = {};
- for (let i of Object.keys(formChalObj)) {
- for (let j of legacyProjectMap[legacyTitle]) {
- if (i === j.title) {
- idsToSolutions[j.id] = formChalObj[i];
- break;
- }
- }
- }
-
- // filter the new solutions that need to be updated
- const completedChallenges = this.props.completedChallenges;
- let challengesToUpdate = {};
- let newChallengeFound = true;
- let oldSubmissions = 0;
- for (let submittedChal of Object.keys(idsToSolutions)) {
- for (let i of completedChallenges) {
- if (i.id === submittedChal) {
- if (idsToSolutions[submittedChal] !== i.solution) {
- challengesToUpdate[submittedChal] = idsToSolutions[submittedChal];
- }
- oldSubmissions++;
- newChallengeFound = false;
- break;
- }
- }
- if (newChallengeFound && idsToSolutions[submittedChal] !== '') {
- challengesToUpdate[submittedChal] = idsToSolutions[submittedChal];
- }
- newChallengeFound = true;
- }
-
- const valuesSaved = values(formChalObj).filter(Boolean).filter(isString);
-
- const isProjectSectionComplete = valuesSaved.length === oldSubmissions;
-
- if (isProjectSectionComplete) {
- return isHonest
- ? verifyCert(certSlug)
- : createFlashMessage(honestyInfoMessage);
- }
- return updateLegacyCert({ challengesToUpdate, certSlug });
- }
-
- renderLegacyCertifications = certName => {
- const { username, createFlashMessage, completedChallenges, t } = this.props;
- const { certSlug } = first(legacyProjectMap[certName]);
- const certLocation = `/certification/${username}/${certSlug}`;
- const challengeTitles = legacyProjectMap[certName].map(item => item.title);
- const isCertClaimed = this.getUserIsCertMap()[certName];
- const initialObject = {};
- let filledforms = 0;
- legacyProjectMap[certName].forEach(project => {
- let completedProject = find(completedChallenges, function (challenge) {
- return challenge['id'] === project['id'];
- });
- if (!completedProject) {
- initialObject[project.title] = '';
- } else {
- initialObject[project.title] = completedProject.solution;
- filledforms++;
- }
- });
-
- const options = challengeTitles.reduce(
- (options, current) => {
- options.types[current] = 'url';
- return options;
- },
- { types: {} }
- );
-
- const formFields = challengeTitles.map(title => ({
- name: title,
- label: title
- }));
-
- const fullForm = filledforms === challengeTitles.length;
-
- const createClickHandler = certLocation => e => {
- e.preventDefault();
- if (isCertClaimed) {
- return navigate(certLocation);
- }
- return createFlashMessage(reallyWeirdErrorMessage);
- };
-
- const buttonStyle = {
- marginBottom: '1.45rem'
- };
-
- return (
-
-
-
- {certName}
-
-
- {isCertClaimed ? (
-
-
-
- ) : null}
-
- );
- };
-
renderLegacyFullStack = () => {
const {
isFullStackCert,
@@ -587,10 +424,14 @@ export class CertificationSettings extends Component {
return (
{t('settings.headings.certs')}
- {certifications.map(this.renderCertifications)}
+ {certifications.map(certName =>
+ this.renderCertifications(certName, projectMap)
+ )}
{t('settings.headings.legacy-certs')}
{this.renderLegacyFullStack()}
- {legacyCertifications.map(this.renderLegacyCertifications)}
+ {legacyCertifications.map(certName =>
+ this.renderCertifications(certName, legacyProjectMap)
+ )}
{isOpen ? (
', () => {
);
expect(
- container.querySelector('#button-legacy-data-visualization')
+ container.querySelector(
+ 'a[href="/certification/developmentuser/legacy-data-visualization"]'
+ )
).toHaveTextContent('buttons.show-cert');
});
@@ -32,33 +34,36 @@ describe('', () => {
);
expect(
- container.querySelector('#button-legacy-data-visualization')
- ).toHaveAttribute(
- 'href',
- '/certification/developmentuser/legacy-data-visualization'
- );
+ container.querySelector(
+ 'a[href="/certification/developmentuser/legacy-data-visualization"]'
+ )
+ ).toBeInTheDocument();
});
- // full forms with unclaimed certs should should not shallow render button
- it('Should not render show cert button for unclaimed full form', () => {
+ // full forms with unclaimed certs should not shallow render show cert button
+ it('Should not render show cert button for unclaimed cert with completed projects', () => {
const { container } = renderWithRedux(
);
expect(
- container.querySelector('#button-legacy-back-end')
- ).not.toBeInTheDocument();
+ container.querySelector(
+ 'a[href="/certification/developmentuser/legacy-back-end"]'
+ )
+ ).not.toHaveTextContent('buttons.show-cert');
});
- // empty forms with unclaimed certs should should not shallow render button
- it('Should not render show cert button for empty form', () => {
+ // empty forms with unclaimed certs should not shallow render show cert button
+ it('Should not render show cert button for cert with no completed projects', () => {
const { container } = renderWithRedux(
);
expect(
- container.querySelector('#button-legacy-front-end')
- ).not.toBeInTheDocument();
+ container.querySelector(
+ 'a[href="/certification/developmentuser/legacy-front-end"]'
+ )
+ ).not.toHaveTextContent('buttons.show-cert');
});
it('Render button when only solution is present', () => {
@@ -243,7 +248,6 @@ const defaultTestProps = {
isSciCompPyCertV7: false,
isDataAnalysisPyCertV7: false,
isMachineLearningPyCertV7: false,
- updateLegacyCert: () => {},
username: 'developmentuser',
verifyCert: () => {},
errors: {},
diff --git a/client/src/redux/settings/index.js b/client/src/redux/settings/index.js
index 277f7e508d..9609c90c8a 100644
--- a/client/src/redux/settings/index.js
+++ b/client/src/redux/settings/index.js
@@ -5,10 +5,6 @@ import { createDangerZoneSaga } from './danger-zone-saga';
import { createSettingsSagas } from './settings-sagas';
import { createUpdateMyEmailSaga } from './update-email-saga';
-// prettier-ignore
-import { createUpdateLegacyCertSaga } from
-'./update-legacy-certificate-saga';
-
export const ns = 'settings';
const defaultFetchState = {
@@ -31,7 +27,6 @@ export const types = createTypes(
...createAsyncTypes('submitNewAbout'),
...createAsyncTypes('submitNewUsername'),
...createAsyncTypes('updateMyEmail'),
- ...createAsyncTypes('updateLegacyCert'),
...createAsyncTypes('updateUserFlag'),
...createAsyncTypes('submitProfileUI'),
...createAsyncTypes('verifyCert'),
@@ -44,8 +39,7 @@ export const types = createTypes(
export const sagas = [
...createSettingsSagas(types),
...createUpdateMyEmailSaga(types),
- ...createDangerZoneSaga(types),
- ...createUpdateLegacyCertSaga(types)
+ ...createDangerZoneSaga(types)
];
const checkForSuccessPayload = ({ type, payload }) =>
@@ -78,12 +72,6 @@ export const updateMyEmail = createAction(types.updateMyEmail);
export const updateMyEmailComplete = createAction(types.updateMyEmailComplete);
export const updateMyEmailError = createAction(types.updateMyEmailError);
-export const updateLegacyCert = createAction(types.updateLegacyCert);
-export const updateLegacyCertComplete = createAction(
- types.updateLegacyCertComplete
-);
-export const updateLegacyCertError = createAction(types.updateLegacyCertError);
-
export const updateUserFlag = createAction(types.updateUserFlag);
export const updateUserFlagComplete = createAction(
types.updateUserFlagComplete,
diff --git a/client/src/redux/settings/update-legacy-certificate-saga.js b/client/src/redux/settings/update-legacy-certificate-saga.js
deleted file mode 100644
index 8a1b9c8e0a..0000000000
--- a/client/src/redux/settings/update-legacy-certificate-saga.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { takeEvery, call, put } from 'redux-saga/effects';
-
-import { putUpdateLegacyCert } from '../../utils/ajax';
-import { submitComplete } from '../';
-import { createFlashMessage } from '../../components/Flash/redux';
-import reallyWeirdErrorMessage from '../../utils/reallyWeirdErrorMessage';
-import { updateLegacyCertError } from './';
-
-function* updateLegacyCertSaga({
- payload: { superBlock, challengesToUpdate }
-}) {
- // shape the body of the http call so it is consumable by api
- const body = {
- projects: {
- [superBlock]: challengesToUpdate
- }
- };
- // shape to update completed challenges in redux store
- let reduxShape = [];
- for (let obj in challengesToUpdate) {
- if (challengesToUpdate.hasOwnProperty(obj)) {
- reduxShape.push({ id: obj, solution: challengesToUpdate[obj] });
- }
- }
-
- try {
- const { data: response } = yield call(putUpdateLegacyCert, body);
- yield put(submitComplete({ challArray: reduxShape }));
- yield put(createFlashMessage(response));
- } catch (e) {
- yield put(updateLegacyCertError(e));
- yield put(createFlashMessage(reallyWeirdErrorMessage));
- }
-}
-
-export function createUpdateLegacyCertSaga(types) {
- return [takeEvery(types.updateLegacyCert, updateLegacyCertSaga)];
-}
diff --git a/client/src/resources/certAndProjectMap.js b/client/src/resources/certAndProjectMap.js
index b22cb380c4..ebc7f6ae0a 100644
--- a/client/src/resources/certAndProjectMap.js
+++ b/client/src/resources/certAndProjectMap.js
@@ -16,10 +16,17 @@ const dataAnalysisPyBase =
'/learn/data-analysis-with-python/data-analysis-with-python-projects';
const machineLearningPyBase =
'/learn/machine-learning-with-python/machine-learning-with-python-projects';
-const legacyFrontEndBase = '';
-const legacyBackEndBase = '';
-const legacyDataVisBase = '';
-const legacyInfosecQaBase = '';
+const takeHomeBase = '/learn/coding-interview-prep/take-home-projects';
+const legacyFrontEndBase = feLibsBase;
+const legacyFrontEndResponsiveBase = responsiveWebBase;
+const legacyFrontEndTakeHomeBase = takeHomeBase;
+const legacyBackEndBase = apiMicroBase;
+const legacyBackEndTakeHomeBase = takeHomeBase;
+const legacyDataVisBase = dataVisBase;
+const legacyDataVisFrontEndBase = feLibsBase;
+const legacyDataVisTakeHomeBase = takeHomeBase;
+const legacyInfosecQaQaBase = qaBase;
+const legacyInfosecQaInfosecBase = infoSecBase;
// TODO: generate this automatically in a separate file
// from the md/meta.json files for each cert and projects
@@ -33,7 +40,7 @@ const certMap = [
{
id: 'bd7158d8c242eddfaeb5bd13',
title: 'Build a Personal Portfolio Webpage',
- link: `${legacyFrontEndBase}/build-a-personal-portfolio-webpage`,
+ link: `${legacyFrontEndResponsiveBase}/build-a-personal-portfolio-webpage`,
certSlug: 'legacy-front-end'
},
{
@@ -57,37 +64,37 @@ const certMap = [
{
id: 'bd7158d8c442eddfaeb5bd10',
title: 'Show the Local Weather',
- link: `${legacyFrontEndBase}/show-the-local-weather`,
+ link: `${legacyFrontEndTakeHomeBase}/show-the-local-weather`,
certSlug: 'legacy-front-end'
},
{
id: 'bd7158d8c442eddfaeb5bd1f',
title: 'Use the TwitchTV JSON API',
- link: `${legacyFrontEndBase}/use-the-twitchtv-json-api`,
+ link: `${legacyFrontEndTakeHomeBase}/use-the-twitch-json-api`,
certSlug: 'legacy-front-end'
},
{
id: 'bd7158d8c442eddfaeb5bd18',
- title: 'Stylize Stories on Camper News',
- link: `${legacyFrontEndBase}/stylize-stories-on-camper-news`,
+ title: 'Build a Tribute Page',
+ link: `${legacyFrontEndResponsiveBase}/build-a-tribute-page`,
certSlug: 'legacy-front-end'
},
{
id: 'bd7158d8c442eddfaeb5bd19',
title: 'Build a Wikipedia Viewer',
- link: `${legacyFrontEndBase}/build-a-wikipedia-viewer`,
+ link: `${legacyFrontEndTakeHomeBase}/build-a-wikipedia-viewer`,
certSlug: 'legacy-front-end'
},
{
id: 'bd7158d8c442eedfaeb5bd1c',
title: 'Build a Tic Tac Toe Game',
- link: `${legacyFrontEndBase}/build-a-tic-tac-toe-game`,
+ link: `${legacyFrontEndTakeHomeBase}/build-a-tic-tac-toe-game`,
certSlug: 'legacy-front-end'
},
{
id: 'bd7158d8c442eddfaeb5bd1c',
title: 'Build a Simon Game',
- link: `${legacyFrontEndBase}/build-a-simon-game`,
+ link: `${legacyFrontEndTakeHomeBase}/build-a-simon-game`,
certSlug: 'legacy-front-end'
}
]
@@ -119,7 +126,7 @@ const certMap = [
{
id: 'bd7158d8c443edefaeb5bdee',
title: 'Image Search Abstraction Layer',
- link: `${legacyBackEndBase}/image-search-abstraction-layer`,
+ link: `${legacyBackEndTakeHomeBase}/build-an-image-search-abstraction-layer`,
certSlug: 'legacy-back-end'
},
{
@@ -131,31 +138,31 @@ const certMap = [
{
id: 'bd7158d8c443eddfaeb5bdef',
title: 'Build a Voting App',
- link: `${legacyBackEndBase}/build-a-voting-app`,
+ link: `${legacyBackEndTakeHomeBase}/build-a-voting-app`,
certSlug: 'legacy-back-end'
},
{
id: 'bd7158d8c443eddfaeb5bdff',
title: 'Build a Nightlife Coordination App',
- link: `${legacyBackEndBase}/build-a-nightlife-coordination-app`,
+ link: `${legacyBackEndTakeHomeBase}/build-a-nightlife-coordination-app`,
certSlug: 'legacy-back-end'
},
{
id: 'bd7158d8c443eddfaeb5bd0e',
title: 'Chart the Stock Market',
- link: `${legacyBackEndBase}/chart-the-stock-market`,
+ link: `${legacyBackEndTakeHomeBase}/chart-the-stock-market`,
certSlug: 'legacy-back-end'
},
{
id: 'bd7158d8c443eddfaeb5bd0f',
title: 'Manage a Book Trading Club',
- link: `${legacyBackEndBase}/manage-a-book-trading-club`,
+ link: `${legacyBackEndTakeHomeBase}/manage-a-book-trading-club`,
certSlug: 'legacy-back-end'
},
{
id: 'bd7158d8c443eddfaeb5bdee',
title: 'Build a Pinterest Clone',
- link: `${legacyBackEndBase}/build-a-pinterest-clone`,
+ link: `${legacyBackEndTakeHomeBase}/build-a-pinterest-clone`,
certSlug: 'legacy-back-end'
}
]
@@ -177,31 +184,31 @@ const certMap = [
{
id: 'bd7157d8c242eddfaeb5bd13',
title: 'Build a Markdown Previewer',
- link: `${legacyDataVisBase}/build-a-markdown-previewer`,
+ link: `${legacyDataVisFrontEndBase}/build-a-markdown-previewer`,
certSlug: 'legacy-data-visualization'
},
{
id: 'bd7156d8c242eddfaeb5bd13',
- title: 'Build a Camper Leaderboard',
- link: `${legacyDataVisBase}/build-a-camper-leaderboard`,
+ title: 'Build a freeCodeCamp Forum Homepage',
+ link: `${legacyDataVisTakeHomeBase}/build-a-freecodecamp-forum-homepage`,
certSlug: 'legacy-data-visualization'
},
{
id: 'bd7155d8c242eddfaeb5bd13',
title: 'Build a Recipe Box',
- link: `${legacyDataVisBase}/build-a-recipe-box`,
+ link: `${legacyDataVisTakeHomeBase}/build-a-recipe-box`,
certSlug: 'legacy-data-visualization'
},
{
id: 'bd7154d8c242eddfaeb5bd13',
title: 'Build the Game of Life',
- link: `${legacyDataVisBase}/build-the-game-of-life`,
+ link: `${legacyDataVisTakeHomeBase}/build-the-game-of-life`,
certSlug: 'legacy-data-visualization'
},
{
id: 'bd7153d8c242eddfaeb5bd13',
title: 'Build a Roguelike Dungeon Crawler Game',
- link: `${legacyDataVisBase}/build-a-roguelike-dungeon-crawler-game`,
+ link: `${legacyDataVisTakeHomeBase}/build-a-roguelike-dungeon-crawler-game`,
certSlug: 'legacy-data-visualization'
},
{
@@ -225,13 +232,13 @@ const certMap = [
{
id: 'bd7198d8c242eddfaeb5bd13',
title: 'Show National Contiguity with a Force Directed Graph',
- link: `${legacyDataVisBase}/show-national-contiguity-with-a-force-directed-graph`,
+ link: `${legacyDataVisTakeHomeBase}/show-national-contiguity-with-a-force-directed-graph`,
certSlug: 'legacy-data-visualization'
},
{
id: 'bd7108d8c242eddfaeb5bd13',
title: 'Map Data Across the Globe',
- link: `${legacyDataVisBase}/map-data-across-the-globe`,
+ link: `${legacyDataVisTakeHomeBase}/map-data-across-the-globe`,
certSlug: 'legacy-data-visualization'
}
]
@@ -247,31 +254,31 @@ const certMap = [
{
id: '587d8249367417b2b2512c41',
title: 'Metric-Imperial Converter',
- link: `${legacyInfosecQaBase}/metric-imperial-converter`,
+ link: `${legacyInfosecQaQaBase}/metric-imperial-converter`,
certSlug: 'information-security-and-quality-assurance'
},
{
id: '587d8249367417b2b2512c42',
title: 'Issue Tracker',
- link: `${legacyInfosecQaBase}/issue-tracker`,
+ link: `${legacyInfosecQaQaBase}/issue-tracker`,
certSlug: 'information-security-and-quality-assurance'
},
{
id: '587d824a367417b2b2512c43',
title: 'Personal Library',
- link: `${legacyInfosecQaBase}/personal-library`,
+ link: `${legacyInfosecQaQaBase}/personal-library`,
certSlug: 'information-security-and-quality-assurance'
},
{
id: '587d824a367417b2b2512c44',
title: 'Stock Price Checker',
- link: `${legacyInfosecQaBase}/stock-price-checker`,
+ link: `${legacyInfosecQaInfosecBase}/stock-price-checker`,
certSlug: 'information-security-and-quality-assurance'
},
{
id: '587d824a367417b2b2512c45',
title: 'Anonymous Message Board',
- link: `${legacyInfosecQaBase}/anonymous-message-board`,
+ link: `${legacyInfosecQaInfosecBase}/anonymous-message-board`,
certSlug: 'information-security-and-quality-assurance'
}
]
diff --git a/client/src/utils/ajax.js b/client/src/utils/ajax.js
index d9fb422c02..79c87517bd 100644
--- a/client/src/utils/ajax.js
+++ b/client/src/utils/ajax.js
@@ -65,10 +65,6 @@ export function addDonation(body) {
return post('/donate/add-donation', body);
}
-export function putUpdateLegacyCert(body) {
- return post('/update-my-projects', body);
-}
-
export function postReportUser(body) {
return post('/user/report-user', body);
}
diff --git a/cypress/integration/ShowCertification.js b/cypress/integration/ShowCertification.js
index a1a1f54f85..02084649ff 100644
--- a/cypress/integration/ShowCertification.js
+++ b/cypress/integration/ShowCertification.js
@@ -1,53 +1,79 @@
/* global cy */
+const certificationUrl = '/certification/developmentuser/responsive-web-design';
+const projects = {
+ superBlock: 'responsive-web-design',
+ block: 'responsive-web-design-projects',
+ challenges: [
+ {
+ slug: 'build-a-tribute-page',
+ solution: 'https://codepen.io/moT01/pen/ZpJpKp'
+ },
+ {
+ slug: 'build-a-survey-form',
+ solution: 'https://codepen.io/moT01/pen/LrrjGz?editors=1010'
+ },
+ {
+ slug: 'build-a-product-landing-page',
+ solution: 'https://codepen.io/moT01/full/qKyKYL/'
+ },
+ {
+ slug: 'build-a-technical-documentation-page',
+ solution: 'https://codepen.io/moT01/full/JBvzNL/'
+ },
+ {
+ slug: 'build-a-personal-portfolio-webpage',
+ solution: 'https://codepen.io/moT01/pen/vgOaoJ'
+ }
+ ]
+};
describe('A certification,', function () {
+ before(() => {
+ cy.exec('npm run seed');
+ cy.login();
+
+ // submit projects for certificate
+ const { superBlock, block, challenges } = projects;
+ challenges.forEach(({ slug, solution }) => {
+ const url = `/learn/${superBlock}/${block}/${slug}`;
+ cy.visit(url);
+ cy.get('#dynamic-front-end-form')
+ .get('#solution')
+ .type(solution, { force: true, delay: 0 });
+ cy.contains("I've completed this challenge")
+ .should('not.be.disabled')
+ .click();
+ cy.contains('Submit and go to next challenge').click().wait(1000);
+ });
+
+ cy.visit('/settings');
+
+ // set user settings to public to claim a cert
+ cy.get('label:contains(Public)>input').each(el => {
+ if (!/toggle-active/.test(el[0].parentElement.className)) {
+ cy.wrap(el).click({ force: true });
+ cy.wait(1000);
+ }
+ });
+
+ // if honest policy not accepted
+ cy.get('.honesty-policy button').then(btn => {
+ if (btn[0].innerText === 'Agree') {
+ btn[0].click({ force: true });
+ cy.wait(1000);
+ }
+ });
+
+ // claim certificate
+ cy.get('a[href*="developmentuser/responsive-web-design"]').click({
+ force: true
+ });
+ });
+
describe('while viewing your own,', function () {
before(() => {
cy.login();
- cy.visit('/settings');
-
- // set user settings to public to claim a cert
- cy.get('label:contains(Public)>input').each(el => {
- if (!/toggle-active/.test(el[0].parentElement.className)) {
- cy.wrap(el).click({ force: true });
- cy.wait(1000);
- }
- });
-
- // if honest policy not accepted
- cy.get('.honesty-policy button').then(btn => {
- if (btn[0].innerText === 'Agree') {
- btn[0].click({ force: true });
- cy.wait(1000);
- }
- });
-
- // fill in legacy front end form
- cy.get('#dynamic-legacy-front-end input').each(el => {
- cy.wrap(el)
- .clear({ force: true })
- .type('https://nhl.com', { force: true, delay: 0 });
- });
-
- // if "Save Progress" button exists
- cy.get('#dynamic-legacy-front-end').then(form => {
- if (form[0][10] && form[0][10].innerHTML === 'Save Progress') {
- form[0][10].click({ force: true });
- cy.wait(1000);
- }
- });
-
- // if "Claim Certification" button exists
- cy.get('#dynamic-legacy-front-end').then(form => {
- if (form[0][10] && form[0][10].innerHTML === 'Claim Certification') {
- form[0][10].click({ force: true });
- cy.wait(1000);
- }
- });
-
- cy.get('#button-legacy-front-end')
- .contains('Show Certification')
- .click({ force: true });
+ cy.visit(certificationUrl);
});
it('should render a LinkedIn button', function () {
@@ -56,7 +82,7 @@ describe('A certification,', function () {
.and(
'match',
// eslint-disable-next-line max-len
- /https:\/\/www\.linkedin\.com\/profile\/add\?startTask=CERTIFICATION_NAME&name=Legacy Front End&organizationId=4831032&issueYear=\d\d\d\d&issueMonth=\d\d?&certUrl=https:\/\/freecodecamp\.org\/certification\/developmentuser\/legacy-front-end/
+ /https:\/\/www\.linkedin\.com\/profile\/add\?startTask=CERTIFICATION_NAME&name=Responsive Web Design&organizationId=4831032&issueYear=\d\d\d\d&issueMonth=\d\d?&certUrl=https:\/\/freecodecamp\.org\/certification\/developmentuser\/responsive-web-design/
);
});
@@ -64,7 +90,7 @@ describe('A certification,', function () {
cy.contains('Share this certification on Twitter').should(
'have.attr',
'href',
- 'https://twitter.com/intent/tweet?text=I just earned the Legacy Front End certification @freeCodeCamp! Check it out here: https://freecodecamp.org/certification/developmentuser/legacy-front-end'
+ 'https://twitter.com/intent/tweet?text=I just earned the Responsive Web Design certification @freeCodeCamp! Check it out here: https://freecodecamp.org/certification/developmentuser/responsive-web-design'
);
});
@@ -79,10 +105,14 @@ describe('A certification,', function () {
describe("while viewing someone else's,", function () {
before(() => {
- cy.go('back');
- cy.get('.toggle-button-nav').click();
- cy.get('.nav-list').contains('Sign out').click();
- cy.visit('/certification/developmentuser/legacy-front-end');
+ cy.visit(certificationUrl);
+ });
+
+ it('should display certificate', function () {
+ cy.contains('has successfully completed the freeCodeCamp.org').should(
+ 'exist'
+ );
+ cy.contains('Responsive Web Design').should('exist');
});
it('should not render a LinkedIn button', function () {
diff --git a/cypress/integration/settings/certifications.js b/cypress/integration/settings/certifications.js
index 1facb1d2d3..88edaebe4b 100644
--- a/cypress/integration/settings/certifications.js
+++ b/cypress/integration/settings/certifications.js
@@ -10,9 +10,9 @@ describe('Settings certifications area', () => {
});
describe('initially', () => {
- it('Should render 11 "Claim Certification" buttons', () => {
+ it('Should render 15 "Claim Certification" buttons', () => {
cy.findAllByText('Claim Certification').should($btns => {
- expect($btns).to.have.length(11);
+ expect($btns).to.have.length(15);
});
});
@@ -54,49 +54,6 @@ describe('Settings certifications area', () => {
'It looks like you have not completed the necessary steps. Please complete the required projects to claim the Responsive Web Design Certification'
).should('exist');
});
-
- it('Should show "Your projects have been updated." message after submitting projects', () => {
- cy.get(
- '#dynamic-information-security-and-quality-assurance input'
- ).each(el => {
- cy.wrap(el)
- .clear({ force: true })
- .type('https://nhl.com', { force: true, delay: 0 });
- });
-
- cy.get('#dynamic-information-security-and-quality-assurance').then(
- form => {
- if (form[0][5] && form[0][5].innerHTML === 'Save Progress') {
- form[0][5].click({ force: true });
- cy.wait(1000);
- }
- }
- );
-
- cy.contains('Your projects have been updated.').should('exist');
- });
-
- it('Should render 12 "Claim Certification" buttons after submitting legacy projects', () => {
- cy.findAllByText('Claim Certification').should($btns => {
- expect($btns).to.have.length(12);
- });
- });
-
- it('Should show "congrats" message after claiming a cert', () => {
- cy.get(
- '#dynamic-information-security-and-quality-assurance button'
- ).click();
-
- cy.contains(
- '@developmentuser, you have successfully claimed the Legacy Information Security and Quality Assurance Certification! Congratulations on behalf of the freeCodeCamp.org team!'
- ).should('exist');
- });
-
- it('Should render a "Show Certification" button after submitting enough projects', () => {
- cy.findAllByText('Show Certification').should($btns => {
- expect($btns).to.have.length(1);
- });
- });
});
});
});
|