chore(deps): upgrade eslint, prettier & related packages
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
0a53a1d7f0
commit
6c91f81b0e
@@ -1,4 +1,3 @@
|
|||||||
**/node_modules/**
|
|
||||||
client/.cache/**
|
client/.cache/**
|
||||||
client/static/**
|
client/static/**
|
||||||
client/public/**
|
client/public/**
|
||||||
|
@@ -7,8 +7,18 @@
|
|||||||
},
|
},
|
||||||
"parser": "babel-eslint",
|
"parser": "babel-eslint",
|
||||||
"root": true,
|
"root": true,
|
||||||
"extends": ["./.eslintrc-base.json", "prettier", "prettier/react"],
|
"extends": [
|
||||||
"plugins": ["react", "import", "prefer-object-spread", "prettier", "react-hooks", "jsx-a11y"],
|
"./.eslintrc-base.json",
|
||||||
|
"prettier"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"react",
|
||||||
|
"import",
|
||||||
|
"prefer-object-spread",
|
||||||
|
"prettier",
|
||||||
|
"react-hooks",
|
||||||
|
"jsx-a11y"
|
||||||
|
],
|
||||||
"globals": {
|
"globals": {
|
||||||
"Promise": true,
|
"Promise": true,
|
||||||
"window": true,
|
"window": true,
|
||||||
@@ -20,8 +30,14 @@
|
|||||||
"settings": {
|
"settings": {
|
||||||
"react": {
|
"react": {
|
||||||
"version": "16.4.2",
|
"version": "16.4.2",
|
||||||
"import/ignore": ["node_modules", "\\.json$"],
|
"import/ignore": [
|
||||||
"import/extensions": [".js", ".jsx"]
|
"node_modules",
|
||||||
|
"\\.json$"
|
||||||
|
],
|
||||||
|
"import/extensions": [
|
||||||
|
".js",
|
||||||
|
".jsx"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,5 +4,6 @@
|
|||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"jsxSingleQuote": true,
|
"jsxSingleQuote": true,
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"trailingComma": "none"
|
"trailingComma": "none",
|
||||||
|
"arrowParens": "avoid"
|
||||||
}
|
}
|
||||||
|
@@ -41,9 +41,9 @@ export default function donateBoot(app, done) {
|
|||||||
metadata: {
|
metadata: {
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
sb_service: `freeCodeCamp.org`,
|
sb_service: `freeCodeCamp.org`,
|
||||||
sb_tier: `${
|
sb_tier: `${donationSubscriptionConfig.duration[duration]} $${
|
||||||
donationSubscriptionConfig.duration[duration]
|
amount / 100
|
||||||
} $${amount / 100} Donation`
|
} Donation`
|
||||||
/* eslint-enable camelcase */
|
/* eslint-enable camelcase */
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -77,9 +77,7 @@ function refetchCompletedChallenges(req, res, next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const updateMyEmailValidators = [
|
const updateMyEmailValidators = [
|
||||||
check('email')
|
check('email').isEmail().withMessage('Email format is invalid.')
|
||||||
.isEmail()
|
|
||||||
.withMessage('Email format is invalid.')
|
|
||||||
];
|
];
|
||||||
|
|
||||||
function updateMyEmail(req, res, next) {
|
function updateMyEmail(req, res, next) {
|
||||||
@@ -117,9 +115,7 @@ function updateMyCurrentChallenge(req, res, next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const updateMyThemeValidators = [
|
const updateMyThemeValidators = [
|
||||||
check('theme')
|
check('theme').isIn(Object.keys(themes)).withMessage('Theme is invalid.')
|
||||||
.isIn(Object.keys(themes))
|
|
||||||
.withMessage('Theme is invalid.')
|
|
||||||
];
|
];
|
||||||
|
|
||||||
function updateMyTheme(req, res, next) {
|
function updateMyTheme(req, res, next) {
|
||||||
|
@@ -64,7 +64,10 @@ boot(app, __dirname, err => {
|
|||||||
setupPassport(app);
|
setupPassport(app);
|
||||||
|
|
||||||
const { db } = app.datasources;
|
const { db } = app.datasources;
|
||||||
db.on('connected', _.once(() => log('db connected')));
|
db.on(
|
||||||
|
'connected',
|
||||||
|
_.once(() => log('db connected'))
|
||||||
|
);
|
||||||
app.start = _.once(function () {
|
app.start = _.once(function () {
|
||||||
const server = app.listen(app.get('port'), function () {
|
const server = app.listen(app.get('port'), function () {
|
||||||
app.emit('started');
|
app.emit('started');
|
||||||
|
@@ -3,14 +3,8 @@ import moment from 'moment-timezone';
|
|||||||
// day count between two epochs (inclusive)
|
// day count between two epochs (inclusive)
|
||||||
export function dayCount([head, tail], timezone = 'UTC') {
|
export function dayCount([head, tail], timezone = 'UTC') {
|
||||||
return Math.ceil(
|
return Math.ceil(
|
||||||
moment(
|
moment(moment(head).tz(timezone).endOf('day')).diff(
|
||||||
moment(head)
|
moment(tail).tz(timezone).startOf('day'),
|
||||||
.tz(timezone)
|
|
||||||
.endOf('day')
|
|
||||||
).diff(
|
|
||||||
moment(tail)
|
|
||||||
.tz(timezone)
|
|
||||||
.startOf('day'),
|
|
||||||
'days',
|
'days',
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
@@ -49,9 +49,7 @@ export function timeCache(time, unit) {
|
|||||||
// set new expire time in MS and create new subscription to source
|
// set new expire time in MS and create new subscription to source
|
||||||
if (!expireCacheAt || expireCacheAt < Date.now()) {
|
if (!expireCacheAt || expireCacheAt < Date.now()) {
|
||||||
// set expire in ms;
|
// set expire in ms;
|
||||||
expireCacheAt = moment()
|
expireCacheAt = moment().add(time, unit).valueOf();
|
||||||
.add(time, unit)
|
|
||||||
.valueOf();
|
|
||||||
cache = new AsyncSubject();
|
cache = new AsyncSubject();
|
||||||
source.subscribe(cache);
|
source.subscribe(cache);
|
||||||
}
|
}
|
||||||
|
@@ -25,36 +25,23 @@ export function prepUniqueDaysByHours(cals, tz = 'UTC') {
|
|||||||
data.push(cur);
|
data.push(cur);
|
||||||
prev = cur;
|
prev = cur;
|
||||||
} else if (
|
} else if (
|
||||||
moment(cur)
|
moment(cur).tz(tz).diff(moment(prev).tz(tz).startOf('day'), 'hours') >=
|
||||||
.tz(tz)
|
hoursDay
|
||||||
.diff(
|
|
||||||
moment(prev)
|
|
||||||
.tz(tz)
|
|
||||||
.startOf('day'),
|
|
||||||
'hours'
|
|
||||||
) >= hoursDay
|
|
||||||
) {
|
) {
|
||||||
data.push(cur);
|
data.push(cur);
|
||||||
prev = cur;
|
prev = cur;
|
||||||
}
|
}
|
||||||
}, []),
|
}, []),
|
||||||
sortBy(e => e),
|
sortBy(e => e),
|
||||||
map(ts =>
|
map(ts => moment(ts).tz(tz).startOf('hours').valueOf())
|
||||||
moment(ts)
|
|
||||||
.tz(tz)
|
|
||||||
.startOf('hours')
|
|
||||||
.valueOf()
|
|
||||||
)
|
|
||||||
)(cals);
|
)(cals);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calcCurrentStreak(cals, tz = 'UTC') {
|
export function calcCurrentStreak(cals, tz = 'UTC') {
|
||||||
let prev = last(cals);
|
let prev = last(cals);
|
||||||
if (
|
if (
|
||||||
moment()
|
moment().tz(tz).startOf('day').diff(moment(prev).tz(tz), 'hours') >
|
||||||
.tz(tz)
|
hoursBetween
|
||||||
.startOf('day')
|
|
||||||
.diff(moment(prev).tz(tz), 'hours') > hoursBetween
|
|
||||||
) {
|
) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -62,10 +49,8 @@ export function calcCurrentStreak(cals, tz = 'UTC') {
|
|||||||
let streakContinues = true;
|
let streakContinues = true;
|
||||||
forEachRight(cur => {
|
forEachRight(cur => {
|
||||||
if (
|
if (
|
||||||
moment(prev)
|
moment(prev).tz(tz).startOf('day').diff(moment(cur).tz(tz), 'hours') <=
|
||||||
.tz(tz)
|
hoursBetween
|
||||||
.startOf('day')
|
|
||||||
.diff(moment(cur).tz(tz), 'hours') <= hoursBetween
|
|
||||||
) {
|
) {
|
||||||
prev = cur;
|
prev = cur;
|
||||||
currentStreak++;
|
currentStreak++;
|
||||||
@@ -86,10 +71,8 @@ export function calcLongestStreak(cals, tz = 'UTC') {
|
|||||||
const last = cals[index === 0 ? 0 : index - 1];
|
const last = cals[index === 0 ? 0 : index - 1];
|
||||||
// is streak broken
|
// is streak broken
|
||||||
if (
|
if (
|
||||||
moment(head)
|
moment(head).tz(tz).startOf('day').diff(moment(last).tz(tz), 'hours') >
|
||||||
.tz(tz)
|
hoursBetween
|
||||||
.startOf('day')
|
|
||||||
.diff(moment(last).tz(tz), 'hours') > hoursBetween
|
|
||||||
) {
|
) {
|
||||||
tail = head;
|
tail = head;
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,8 @@ function createChallengeNode(challenge, reporter) {
|
|||||||
// sections.
|
// sections.
|
||||||
if (
|
if (
|
||||||
typeof challenge.description !== 'string' &&
|
typeof challenge.description !== 'string' &&
|
||||||
(challenge.challengeType !== 11 && challenge.challengeType !== 7)
|
challenge.challengeType !== 11 &&
|
||||||
|
challenge.challengeType !== 7
|
||||||
) {
|
) {
|
||||||
reporter.warn(`
|
reporter.warn(`
|
||||||
|
|
||||||
|
@@ -298,8 +298,9 @@ const ShowCertification = props => {
|
|||||||
bsSize='lg'
|
bsSize='lg'
|
||||||
bsStyle='primary'
|
bsStyle='primary'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
href={`https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&name=${certTitle}&organizationId=4831032&issueYear=${certYear}&issueMonth=${certMonth +
|
href={`https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&name=${certTitle}&organizationId=4831032&issueYear=${certYear}&issueMonth=${
|
||||||
1}&certUrl=${certURL}`}
|
certMonth + 1
|
||||||
|
}&certUrl=${certURL}`}
|
||||||
>
|
>
|
||||||
{t('profile.add-linkedin')}
|
{t('profile.add-linkedin')}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -399,7 +400,4 @@ const ShowCertification = props => {
|
|||||||
ShowCertification.displayName = 'ShowCertification';
|
ShowCertification.displayName = 'ShowCertification';
|
||||||
ShowCertification.propTypes = propTypes;
|
ShowCertification.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps)(ShowCertification);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(ShowCertification);
|
|
||||||
|
@@ -211,7 +211,4 @@ export function ShowSettings(props) {
|
|||||||
ShowSettings.displayName = 'ShowSettings';
|
ShowSettings.displayName = 'ShowSettings';
|
||||||
ShowSettings.propTypes = propTypes;
|
ShowSettings.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps)(ShowSettings);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(ShowSettings);
|
|
||||||
|
@@ -155,8 +155,5 @@ ShowUser.displayName = 'ShowUser';
|
|||||||
ShowUser.propTypes = propTypes;
|
ShowUser.propTypes = propTypes;
|
||||||
|
|
||||||
export default withTranslation()(
|
export default withTranslation()(
|
||||||
connect(
|
connect(mapStateToProps, mapDispatchToProps)(ShowUser)
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(ShowUser)
|
|
||||||
);
|
);
|
||||||
|
@@ -24,7 +24,4 @@ AppMountNotifier.propTypes = {
|
|||||||
render: PropTypes.func.isRequired
|
render: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps)(AppMountNotifier);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(AppMountNotifier);
|
|
||||||
|
@@ -163,7 +163,4 @@ function DonateModal({
|
|||||||
DonateModal.displayName = 'DonateModal';
|
DonateModal.displayName = 'DonateModal';
|
||||||
DonateModal.propTypes = propTypes;
|
DonateModal.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps)(DonateModal);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(DonateModal);
|
|
||||||
|
@@ -10,12 +10,9 @@ import { apiLocation, homeLocation } from '../../../../../config/env.json';
|
|||||||
|
|
||||||
import './login.css';
|
import './login.css';
|
||||||
|
|
||||||
const mapStateToProps = createSelector(
|
const mapStateToProps = createSelector(isSignedInSelector, isSignedIn => ({
|
||||||
isSignedInSelector,
|
|
||||||
isSignedIn => ({
|
|
||||||
isSignedIn
|
isSignedIn
|
||||||
})
|
}));
|
||||||
);
|
|
||||||
|
|
||||||
function Login(props) {
|
function Login(props) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@@ -207,7 +207,4 @@ export class NavLinks extends Component {
|
|||||||
NavLinks.propTypes = propTypes;
|
NavLinks.propTypes = propTypes;
|
||||||
NavLinks.displayName = 'NavLinks';
|
NavLinks.displayName = 'NavLinks';
|
||||||
|
|
||||||
export default connect(
|
export default connect(null, mapDispatchToProps)(withTranslation()(NavLinks));
|
||||||
null,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(withTranslation()(NavLinks));
|
|
||||||
|
@@ -7,10 +7,7 @@ const createLanguageRedirect = ({ clientLocale, lang }) => {
|
|||||||
.filter(item => (item !== clientLocale && item !== lang ? item : ''))
|
.filter(item => (item !== clientLocale && item !== lang ? item : ''))
|
||||||
.join('/');
|
.join('/');
|
||||||
|
|
||||||
const hostTail = window?.location?.host
|
const hostTail = window?.location?.host.split('.').slice(1).join('.');
|
||||||
.split('.')
|
|
||||||
.slice(1)
|
|
||||||
.join('.');
|
|
||||||
const nextClient = lang !== 'chinese' ? 'www' : 'chinese';
|
const nextClient = lang !== 'chinese' ? 'www' : 'chinese';
|
||||||
const nextLocation = `${window?.location?.protocol}//${nextClient}.${hostTail}`;
|
const nextLocation = `${window?.location?.protocol}//${nextClient}.${hostTail}`;
|
||||||
|
|
||||||
|
@@ -6,12 +6,9 @@ import { fetchUser, isSignedInSelector, executeGA } from '../../redux';
|
|||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
|
|
||||||
const mapStateToProps = createSelector(
|
const mapStateToProps = createSelector(isSignedInSelector, isSignedIn => ({
|
||||||
isSignedInSelector,
|
|
||||||
isSignedIn => ({
|
|
||||||
isSignedIn
|
isSignedIn
|
||||||
})
|
}));
|
||||||
);
|
|
||||||
|
|
||||||
const mapDispatchToProps = { fetchUser, executeGA };
|
const mapDispatchToProps = { fetchUser, executeGA };
|
||||||
|
|
||||||
|
@@ -90,7 +90,4 @@ LearnLayout.propTypes = {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps)(LearnLayout);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(LearnLayout);
|
|
||||||
|
@@ -336,9 +336,17 @@ function useIdToNameMap() {
|
|||||||
certPath: getPathFromID(id)
|
certPath: getPathFromID(id)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
edges.forEach(({ node: { id, title, fields: { slug } } }) => {
|
edges.forEach(
|
||||||
|
({
|
||||||
|
node: {
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
fields: { slug }
|
||||||
|
}
|
||||||
|
}) => {
|
||||||
idToNameMap.set(id, { challengeTitle: title, challengePath: slug });
|
idToNameMap.set(id, { challengeTitle: title, challengePath: slug });
|
||||||
});
|
}
|
||||||
|
);
|
||||||
return idToNameMap;
|
return idToNameMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -386,9 +386,7 @@ export class CertificationSettings extends Component {
|
|||||||
newChallengeFound = true;
|
newChallengeFound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const valuesSaved = values(formChalObj)
|
const valuesSaved = values(formChalObj).filter(Boolean).filter(isString);
|
||||||
.filter(Boolean)
|
|
||||||
.filter(isString);
|
|
||||||
|
|
||||||
const isProjectSectionComplete = valuesSaved.length === oldSubmissions;
|
const isProjectSectionComplete = valuesSaved.length === oldSubmissions;
|
||||||
|
|
||||||
|
@@ -14,12 +14,9 @@ import Spacer from '../helpers/Spacer';
|
|||||||
import ToggleSetting from './ToggleSetting';
|
import ToggleSetting from './ToggleSetting';
|
||||||
import SectionHeader from './SectionHeader';
|
import SectionHeader from './SectionHeader';
|
||||||
|
|
||||||
const mapStateToProps = createSelector(
|
const mapStateToProps = createSelector(userSelector, user => ({
|
||||||
userSelector,
|
|
||||||
user => ({
|
|
||||||
user
|
user
|
||||||
})
|
}));
|
||||||
);
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch =>
|
const mapDispatchToProps = dispatch =>
|
||||||
bindActionCreators({ submitProfileUI }, dispatch);
|
bindActionCreators({ submitProfileUI }, dispatch);
|
||||||
|
@@ -45,7 +45,4 @@ class SearchPage extends Component {
|
|||||||
SearchPage.displayName = 'SearchPage';
|
SearchPage.displayName = 'SearchPage';
|
||||||
SearchPage.propTypes = propTypes;
|
SearchPage.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(null, mapDispatchToProps)(withTranslation()(SearchPage));
|
||||||
null,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(withTranslation()(SearchPage));
|
|
||||||
|
@@ -971,9 +971,6 @@ Editor.propTypes = propTypes;
|
|||||||
|
|
||||||
// NOTE: withRef gets replaced by forwardRef in react-redux 6,
|
// NOTE: withRef gets replaced by forwardRef in react-redux 6,
|
||||||
// https://github.com/reduxjs/react-redux/releases/tag/v6.0.0
|
// https://github.com/reduxjs/react-redux/releases/tag/v6.0.0
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps, null, {
|
||||||
mapStateToProps,
|
withRef: true
|
||||||
mapDispatchToProps,
|
})(Editor);
|
||||||
null,
|
|
||||||
{ withRef: true }
|
|
||||||
)(Editor);
|
|
||||||
|
@@ -86,7 +86,4 @@ class EditorTabs extends Component {
|
|||||||
EditorTabs.displayName = 'EditorTabs';
|
EditorTabs.displayName = 'EditorTabs';
|
||||||
EditorTabs.propTypes = propTypes;
|
EditorTabs.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps)(EditorTabs);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(EditorTabs);
|
|
||||||
|
@@ -101,7 +101,4 @@ class MobileLayout extends Component {
|
|||||||
MobileLayout.displayName = 'MobileLayout';
|
MobileLayout.displayName = 'MobileLayout';
|
||||||
MobileLayout.propTypes = propTypes;
|
MobileLayout.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps)(MobileLayout);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(MobileLayout);
|
|
||||||
|
@@ -274,9 +274,6 @@ MultifileEditor.propTypes = propTypes;
|
|||||||
|
|
||||||
// NOTE: withRef gets replaced by forwardRef in react-redux 6,
|
// NOTE: withRef gets replaced by forwardRef in react-redux 6,
|
||||||
// https://github.com/reduxjs/react-redux/releases/tag/v6.0.0
|
// https://github.com/reduxjs/react-redux/releases/tag/v6.0.0
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps, null, {
|
||||||
mapStateToProps,
|
withRef: true
|
||||||
mapDispatchToProps,
|
})(MultifileEditor);
|
||||||
null,
|
|
||||||
{ withRef: true }
|
|
||||||
)(MultifileEditor);
|
|
||||||
|
@@ -90,7 +90,4 @@ function Hotkeys({
|
|||||||
Hotkeys.displayName = 'Hotkeys';
|
Hotkeys.displayName = 'Hotkeys';
|
||||||
Hotkeys.propTypes = propTypes;
|
Hotkeys.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps)(Hotkeys);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(Hotkeys);
|
|
||||||
|
@@ -63,7 +63,4 @@ class Preview extends Component {
|
|||||||
Preview.displayName = 'Preview';
|
Preview.displayName = 'Preview';
|
||||||
Preview.propTypes = propTypes;
|
Preview.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(null, mapDispatchToProps)(withTranslation()(Preview));
|
||||||
null,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(withTranslation()(Preview));
|
|
||||||
|
@@ -18,12 +18,9 @@ const propTypes = {
|
|||||||
reset: PropTypes.func.isRequired
|
reset: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = createSelector(
|
const mapStateToProps = createSelector(isResetModalOpenSelector, isOpen => ({
|
||||||
isResetModalOpenSelector,
|
|
||||||
isOpen => ({
|
|
||||||
isOpen
|
isOpen
|
||||||
})
|
}));
|
||||||
);
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch =>
|
const mapDispatchToProps = dispatch =>
|
||||||
bindActionCreators(
|
bindActionCreators(
|
||||||
@@ -80,7 +77,4 @@ function ResetModal({ reset, close, isOpen }) {
|
|||||||
ResetModal.displayName = 'ResetModal';
|
ResetModal.displayName = 'ResetModal';
|
||||||
ResetModal.propTypes = propTypes;
|
ResetModal.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps)(ResetModal);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(ResetModal);
|
|
||||||
|
@@ -47,7 +47,10 @@ export class SidePanel extends Component {
|
|||||||
// users navigate from another challenge
|
// users navigate from another challenge
|
||||||
MathJax.Hub.Config({
|
MathJax.Hub.Config({
|
||||||
tex2jax: {
|
tex2jax: {
|
||||||
inlineMath: [['$', '$'], ['\\(', '\\)']],
|
inlineMath: [
|
||||||
|
['$', '$'],
|
||||||
|
['\\(', '\\)']
|
||||||
|
],
|
||||||
processEscapes: true,
|
processEscapes: true,
|
||||||
processClass: 'rosetta-code|project-euler'
|
processClass: 'rosetta-code|project-euler'
|
||||||
}
|
}
|
||||||
|
@@ -105,7 +105,4 @@ function ToolPanel({
|
|||||||
ToolPanel.displayName = 'ToolPanel';
|
ToolPanel.displayName = 'ToolPanel';
|
||||||
ToolPanel.propTypes = propTypes;
|
ToolPanel.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps)(ToolPanel);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(ToolPanel);
|
|
||||||
|
@@ -43,11 +43,7 @@ const padContentWithCssCatch = partial(compileHeadTail, cssCatch);
|
|||||||
export const jsToHtml = cond([
|
export const jsToHtml = cond([
|
||||||
[
|
[
|
||||||
matchesProperty('ext', 'js'),
|
matchesProperty('ext', 'js'),
|
||||||
flow(
|
flow(padContentWithJsCatch, wrapInScript, setExtToHTML)
|
||||||
padContentWithJsCatch,
|
|
||||||
wrapInScript,
|
|
||||||
setExtToHTML
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
[stubTrue, identity]
|
[stubTrue, identity]
|
||||||
]);
|
]);
|
||||||
@@ -55,11 +51,7 @@ export const jsToHtml = cond([
|
|||||||
export const cssToHtml = cond([
|
export const cssToHtml = cond([
|
||||||
[
|
[
|
||||||
matchesProperty('ext', 'css'),
|
matchesProperty('ext', 'css'),
|
||||||
flow(
|
flow(padContentWithCssCatch, wrapInStyle, setExtToHTML)
|
||||||
padContentWithCssCatch,
|
|
||||||
wrapInStyle,
|
|
||||||
setExtToHTML
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
[stubTrue, identity]
|
[stubTrue, identity]
|
||||||
]);
|
]);
|
||||||
|
@@ -3,10 +3,7 @@ import { ofType } from 'redux-observable';
|
|||||||
import { types, unlockCode } from './';
|
import { types, unlockCode } from './';
|
||||||
|
|
||||||
function codeLockEpic(action$) {
|
function codeLockEpic(action$) {
|
||||||
return action$.pipe(
|
return action$.pipe(ofType(types.updateFile), map(unlockCode));
|
||||||
ofType(types.updateFile),
|
|
||||||
map(unlockCode)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default codeLockEpic;
|
export default codeLockEpic;
|
||||||
|
@@ -58,9 +58,11 @@ function createQuestionEpic(action$, state$, { window }) {
|
|||||||
? `**Your project link(s)**\n`
|
? `**Your project link(s)**\n`
|
||||||
: `**Your code so far**`
|
: `**Your code so far**`
|
||||||
}
|
}
|
||||||
${projectFormValues
|
${
|
||||||
|
projectFormValues
|
||||||
?.map(([key, val]) => `${key}: ${val}\n`)
|
?.map(([key, val]) => `${key}: ${val}\n`)
|
||||||
?.join('') || filesToMarkdown(files)}
|
?.join('') || filesToMarkdown(files)
|
||||||
|
}
|
||||||
|
|
||||||
${endingText}`
|
${endingText}`
|
||||||
);
|
);
|
||||||
|
@@ -74,9 +74,9 @@ export function* executeChallengeSaga({
|
|||||||
yield put(initLogs());
|
yield put(initLogs());
|
||||||
yield put(initConsole(i18next.t('learn.running-tests')));
|
yield put(initConsole(i18next.t('learn.running-tests')));
|
||||||
// reset tests to initial state
|
// reset tests to initial state
|
||||||
const tests = (yield select(challengeTestsSelector)).map(
|
const tests = (yield select(
|
||||||
({ text, testString }) => ({ text, testString })
|
challengeTestsSelector
|
||||||
);
|
)).map(({ text, testString }) => ({ text, testString }));
|
||||||
yield put(updateTests(tests));
|
yield put(updateTests(tests));
|
||||||
|
|
||||||
yield fork(takeEveryLog, consoleProxy);
|
yield fork(takeEveryLog, consoleProxy);
|
||||||
|
@@ -18,12 +18,9 @@ const propTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
return createSelector(
|
return createSelector(userSelector, user => ({
|
||||||
userSelector,
|
|
||||||
user => ({
|
|
||||||
user
|
user
|
||||||
})
|
}))(state);
|
||||||
)(state);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export class CertChallenge extends Component {
|
export class CertChallenge extends Component {
|
||||||
|
@@ -11,12 +11,9 @@ import GreenPass from '../../../assets/icons/GreenPass';
|
|||||||
import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted';
|
import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
return createSelector(
|
return createSelector(completedChallengesSelector, completedChallenges => ({
|
||||||
completedChallengesSelector,
|
|
||||||
completedChallenges => ({
|
|
||||||
completedChallenges: completedChallenges.map(({ id }) => id)
|
completedChallenges: completedChallenges.map(({ id }) => id)
|
||||||
})
|
}))(state);
|
||||||
)(state);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch =>
|
const mapDispatchToProps = dispatch =>
|
||||||
|
@@ -16,12 +16,7 @@ function prototyper(str) {
|
|||||||
.map(str => {
|
.map(str => {
|
||||||
if (prototypeRE.test(str)) {
|
if (prototypeRE.test(str)) {
|
||||||
if (str.length > 9) {
|
if (str.length > 9) {
|
||||||
return prototyper(
|
return prototyper(str.trim().split('prototype').join('-prototype-'));
|
||||||
str
|
|
||||||
.trim()
|
|
||||||
.split('prototype')
|
|
||||||
.join('-prototype-')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@@ -39,12 +34,7 @@ function prototyper(str) {
|
|||||||
return `${titleify(first)}.prototype.${finalSecond}`;
|
return `${titleify(first)}.prototype.${finalSecond}`;
|
||||||
}
|
}
|
||||||
if (noProto.length === 1) {
|
if (noProto.length === 1) {
|
||||||
return prototyper(
|
return prototyper(noProto[0].toLowerCase().split('.').join('-'));
|
||||||
noProto[0]
|
|
||||||
.toLowerCase()
|
|
||||||
.split('.')
|
|
||||||
.join('-')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return titleify(str, true);
|
return titleify(str, true);
|
||||||
}
|
}
|
||||||
|
@@ -53,22 +53,22 @@ const donationSubscriptionConfig = {
|
|||||||
const paypalConfigTypes = {
|
const paypalConfigTypes = {
|
||||||
live: {
|
live: {
|
||||||
month: {
|
month: {
|
||||||
'500': { planId: 'P-1L11422374370240ULZKX3PA' },
|
500: { planId: 'P-1L11422374370240ULZKX3PA' },
|
||||||
'1000': { planId: 'P-61K21421WY874920PL6E36YI' },
|
1000: { planId: 'P-61K21421WY874920PL6E36YI' },
|
||||||
'2000': { planId: 'P-31999436LF709112VL6E374A' },
|
2000: { planId: 'P-31999436LF709112VL6E374A' },
|
||||||
'3000': { planId: 'P-1KY930839N8045117L6E4BKY' },
|
3000: { planId: 'P-1KY930839N8045117L6E4BKY' },
|
||||||
'4000': { planId: 'P-0JW4843250567551AL6E4CAI' },
|
4000: { planId: 'P-0JW4843250567551AL6E4CAI' },
|
||||||
'5000': { planId: 'P-0WR49877YD949401BL6E4CTA' }
|
5000: { planId: 'P-0WR49877YD949401BL6E4CTA' }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
staging: {
|
staging: {
|
||||||
month: {
|
month: {
|
||||||
'500': { planId: 'P-37N14480BW163382FLZYPVMA' },
|
500: { planId: 'P-37N14480BW163382FLZYPVMA' },
|
||||||
'1000': { planId: 'P-28B62039J8092810UL6E3FXA' },
|
1000: { planId: 'P-28B62039J8092810UL6E3FXA' },
|
||||||
'2000': { planId: 'P-7HR706961M9170433L6HI5VI' },
|
2000: { planId: 'P-7HR706961M9170433L6HI5VI' },
|
||||||
'3000': { planId: 'P-35V33574BU596924JL6HI6XY' },
|
3000: { planId: 'P-35V33574BU596924JL6HI6XY' },
|
||||||
'4000': { planId: 'P-45M45060289267734L6HJSXA' },
|
4000: { planId: 'P-45M45060289267734L6HJSXA' },
|
||||||
'5000': { planId: 'P-0MD70861FY4172444L6HJTUQ' }
|
5000: { planId: 'P-0MD70861FY4172444L6HJTUQ' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -25,10 +25,7 @@ const schema = Joi.object()
|
|||||||
block: Joi.string().regex(slugRE),
|
block: Joi.string().regex(slugRE),
|
||||||
blockId: Joi.objectId(),
|
blockId: Joi.objectId(),
|
||||||
challengeOrder: Joi.number(),
|
challengeOrder: Joi.number(),
|
||||||
challengeType: Joi.number()
|
challengeType: Joi.number().min(0).max(11).required(),
|
||||||
.min(0)
|
|
||||||
.max(11)
|
|
||||||
.required(),
|
|
||||||
checksum: Joi.number(),
|
checksum: Joi.number(),
|
||||||
// TODO: require this only for normal challenges, not certs
|
// TODO: require this only for normal challenges, not certs
|
||||||
dashedName: Joi.string().regex(slugRE),
|
dashedName: Joi.string().regex(slugRE),
|
||||||
@@ -62,9 +59,7 @@ const schema = Joi.object()
|
|||||||
}),
|
}),
|
||||||
question: Joi.object().keys({
|
question: Joi.object().keys({
|
||||||
text: Joi.string().required(),
|
text: Joi.string().required(),
|
||||||
answers: Joi.array()
|
answers: Joi.array().items(Joi.string()).required(),
|
||||||
.items(Joi.string())
|
|
||||||
.required(),
|
|
||||||
solution: Joi.number().required()
|
solution: Joi.number().required()
|
||||||
}),
|
}),
|
||||||
required: Joi.array().items(
|
required: Joi.array().items(
|
||||||
@@ -92,9 +87,7 @@ const schema = Joi.object()
|
|||||||
Joi.object().keys({
|
Joi.object().keys({
|
||||||
id: Joi.string().allow(''),
|
id: Joi.string().allow(''),
|
||||||
text: Joi.string().required(),
|
text: Joi.string().required(),
|
||||||
testString: Joi.string()
|
testString: Joi.string().allow('').required()
|
||||||
.allow('')
|
|
||||||
.required()
|
|
||||||
}),
|
}),
|
||||||
// our tests used in certification verification
|
// our tests used in certification verification
|
||||||
Joi.object().keys({
|
Joi.object().keys({
|
||||||
|
@@ -198,9 +198,9 @@ async function setup() {
|
|||||||
for (const challenge of challenges) {
|
for (const challenge of challenges) {
|
||||||
const dashedBlockName = challenge.block;
|
const dashedBlockName = challenge.block;
|
||||||
if (!meta[dashedBlockName]) {
|
if (!meta[dashedBlockName]) {
|
||||||
meta[dashedBlockName] = (await getMetaForBlock(
|
meta[dashedBlockName] = (
|
||||||
dashedBlockName
|
await getMetaForBlock(dashedBlockName)
|
||||||
)).challengeOrder;
|
).challengeOrder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -475,7 +475,9 @@ function populateTestsForLang({ lang, challenges, meta }) {
|
|||||||
|
|
||||||
describe('Check tests against solutions', function () {
|
describe('Check tests against solutions', function () {
|
||||||
solutions.forEach((solution, index) => {
|
solutions.forEach((solution, index) => {
|
||||||
it(`Solution ${index + 1} must pass the tests`, async function() {
|
it(`Solution ${
|
||||||
|
index + 1
|
||||||
|
} must pass the tests`, async function () {
|
||||||
this.timeout(5000 * tests.length + 2000);
|
this.timeout(5000 * tests.length + 2000);
|
||||||
const testRunner = await createTestRunner(
|
const testRunner = await createTestRunner(
|
||||||
challenge,
|
challenge,
|
||||||
|
@@ -43,43 +43,28 @@ describe('Landing page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Has 5 brand logos', () => {
|
it('Has 5 brand logos', () => {
|
||||||
cy.get('.logo-row')
|
cy.get('.logo-row').children().its('length').should('eq', 5);
|
||||||
.children()
|
|
||||||
.its('length')
|
|
||||||
.should('eq', 5);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Has `as seens as` section', () => {
|
it('Has `as seens as` section', () => {
|
||||||
cy.contains('Build projects.').should('be.visible');
|
cy.contains('Build projects.').should('be.visible');
|
||||||
cy.get('.big-heading')
|
cy.get('.big-heading').siblings().get('svg');
|
||||||
.siblings()
|
|
||||||
.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Has a visible large image on large viewports', function () {
|
it('Has a visible large image on large viewports', function () {
|
||||||
cy.viewport(1200, 660)
|
cy.viewport(1200, 660).get(selectors.landingPageImage).should('be.visible');
|
||||||
.get(selectors.landingPageImage)
|
|
||||||
.should('be.visible');
|
|
||||||
|
|
||||||
cy.viewport(1199, 660)
|
cy.viewport(1199, 660).get(selectors.landingPageImage).should('not.exist');
|
||||||
.get(selectors.landingPageImage)
|
|
||||||
.should('not.exist');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Has links to all the certifications', function () {
|
it('Has links to all the certifications', function () {
|
||||||
cy.get(selectors.certifications)
|
cy.get(selectors.certifications).children().its('length').should('eq', 10);
|
||||||
.children()
|
|
||||||
.its('length')
|
|
||||||
.should('eq', 10);
|
|
||||||
cy.wrap(certifications).each(cert => {
|
cy.wrap(certifications).each(cert => {
|
||||||
cy.get(selectors.certifications).contains(cert);
|
cy.get(selectors.certifications).contains(cert);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Has 3 testimonial cards', function () {
|
it('Has 3 testimonial cards', function () {
|
||||||
cy.get(selectors.testimonials)
|
cy.get(selectors.testimonials).children().its('length').should('eq', 3);
|
||||||
.children()
|
|
||||||
.its('length')
|
|
||||||
.should('eq', 3);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -68,9 +68,7 @@ describe('Navbar', () => {
|
|||||||
() => {
|
() => {
|
||||||
cy.get(selectors.menuButton).click();
|
cy.get(selectors.menuButton).click();
|
||||||
cy.get(selectors.navigationLinks).contains('Forum');
|
cy.get(selectors.navigationLinks).contains('Forum');
|
||||||
cy.get(selectors.navigationLinks)
|
cy.get(selectors.navigationLinks).contains('Curriculum').click();
|
||||||
.contains('Curriculum')
|
|
||||||
.click();
|
|
||||||
cy.url().should('include', '/learn');
|
cy.url().should('include', '/learn');
|
||||||
cy.get(selectors.navigationLinks).contains('Curriculum');
|
cy.get(selectors.navigationLinks).contains('Curriculum');
|
||||||
cy.get(selectors.navigationLinks).contains('Forum');
|
cy.get(selectors.navigationLinks).contains('Forum');
|
||||||
@@ -84,9 +82,7 @@ describe('Navbar', () => {
|
|||||||
() => {
|
() => {
|
||||||
cy.contains(selectors.smallCallToAction, 'Sign in');
|
cy.contains(selectors.smallCallToAction, 'Sign in');
|
||||||
cy.get(selectors.menuButton).click();
|
cy.get(selectors.menuButton).click();
|
||||||
cy.get(selectors.navigationLinks)
|
cy.get(selectors.navigationLinks).contains('Curriculum').click();
|
||||||
.contains('Curriculum')
|
|
||||||
.click();
|
|
||||||
cy.contains(selectors.smallCallToAction, 'Sign in');
|
cy.contains(selectors.smallCallToAction, 'Sign in');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -95,9 +91,7 @@ describe('Navbar', () => {
|
|||||||
cy.login();
|
cy.login();
|
||||||
cy.get('a[href*="/settings"]').should('be.visible');
|
cy.get('a[href*="/settings"]').should('be.visible');
|
||||||
cy.get(selectors.menuButton).click();
|
cy.get(selectors.menuButton).click();
|
||||||
cy.get(selectors.navigationLinks)
|
cy.get(selectors.navigationLinks).contains('Profile').click();
|
||||||
.contains('Profile')
|
|
||||||
.click();
|
|
||||||
cy.url().should('include', '/developmentuser');
|
cy.url().should('include', '/developmentuser');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -30,17 +30,13 @@ describe('Search bar', () => {
|
|||||||
it('Should accept input and display hits', () => {
|
it('Should accept input and display hits', () => {
|
||||||
search('freeCodeCamp');
|
search('freeCodeCamp');
|
||||||
|
|
||||||
cy.get('.ais-Hits-list')
|
cy.get('.ais-Hits-list').children().should('to.have.length.of.at.least', 1);
|
||||||
.children()
|
|
||||||
.should('to.have.length.of.at.least', 1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should clear hits when input is cleared', () => {
|
it('Should clear hits when input is cleared', () => {
|
||||||
search('freeCodeCamp');
|
search('freeCodeCamp');
|
||||||
|
|
||||||
cy.get('.ais-Hits-list')
|
cy.get('.ais-Hits-list').children().should('to.have.length.of.at.least', 1);
|
||||||
.children()
|
|
||||||
.should('to.have.length.of.at.least', 1);
|
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
@@ -52,9 +48,7 @@ describe('Search bar', () => {
|
|||||||
|
|
||||||
search('freeCodeCamp');
|
search('freeCodeCamp');
|
||||||
|
|
||||||
cy.get('.ais-Hits-list')
|
cy.get('.ais-Hits-list').children().should('to.have.length.of', 8);
|
||||||
.children()
|
|
||||||
.should('to.have.length.of', 8);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should show up to 5 hits when height < 768px', () => {
|
it('Should show up to 5 hits when height < 768px', () => {
|
||||||
@@ -62,17 +56,13 @@ describe('Search bar', () => {
|
|||||||
|
|
||||||
search('freeCodeCamp');
|
search('freeCodeCamp');
|
||||||
|
|
||||||
cy.get('.ais-Hits-list')
|
cy.get('.ais-Hits-list').children().should('to.have.length.of', 5);
|
||||||
.children()
|
|
||||||
.should('to.have.length.of', 5);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should show no hits for queries that do not exist in the Algolia index', () => {
|
it('Should show no hits for queries that do not exist in the Algolia index', () => {
|
||||||
search('testtttt');
|
search('testtttt');
|
||||||
|
|
||||||
cy.get('.ais-Hits-list')
|
cy.get('.ais-Hits-list').children().should('to.have.length.of', 0);
|
||||||
.children()
|
|
||||||
.should('to.have.length.of', 0);
|
|
||||||
|
|
||||||
cy.contains('No tutorials found');
|
cy.contains('No tutorials found');
|
||||||
});
|
});
|
||||||
|
@@ -96,9 +96,7 @@ describe('Username input field', () => {
|
|||||||
'the URL to your profile and your certifications.'
|
'the URL to your profile and your certifications.'
|
||||||
).should('not.exist');
|
).should('not.exist');
|
||||||
|
|
||||||
cy.get('@usernameForm')
|
cy.get('@usernameForm').contains('Save').should('be.disabled');
|
||||||
.contains('Save')
|
|
||||||
.should('be.disabled');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should not show anything if user types their current name', () => {
|
it('Should not show anything if user types their current name', () => {
|
||||||
@@ -106,9 +104,7 @@ describe('Username input field', () => {
|
|||||||
.clear({ force: true })
|
.clear({ force: true })
|
||||||
.type('developmentuser', { force: true });
|
.type('developmentuser', { force: true });
|
||||||
|
|
||||||
cy.get('@usernameForm')
|
cy.get('@usernameForm').contains('Save').should('be.disabled');
|
||||||
.contains('Save')
|
|
||||||
.should('be.disabled');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
@@ -117,9 +113,7 @@ describe('Username input field', () => {
|
|||||||
.clear({ force: true })
|
.clear({ force: true })
|
||||||
.type('developmentuser', { force: true });
|
.type('developmentuser', { force: true });
|
||||||
|
|
||||||
cy.get('@usernameForm')
|
cy.get('@usernameForm').contains('Save').should('be.disabled');
|
||||||
.contains('Save')
|
|
||||||
.should('be.disabled');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should show warning if username includes invalid character', () => {
|
it('Should show warning if username includes invalid character', () => {
|
||||||
@@ -141,9 +135,7 @@ describe('Username input field', () => {
|
|||||||
.clear({ force: true })
|
.clear({ force: true })
|
||||||
.type('Quincy Larson', { force: true });
|
.type('Quincy Larson', { force: true });
|
||||||
|
|
||||||
cy.get('@usernameForm')
|
cy.get('@usernameForm').contains('Save').should('be.disabled');
|
||||||
.contains('Save')
|
|
||||||
.should('be.disabled');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should change username if `Save` button is clicked', () => {
|
it('Should change username if `Save` button is clicked', () => {
|
||||||
@@ -153,9 +145,7 @@ describe('Username input field', () => {
|
|||||||
|
|
||||||
cy.contains('Username is available');
|
cy.contains('Username is available');
|
||||||
|
|
||||||
cy.get('@usernameForm')
|
cy.get('@usernameForm').contains('Save').click({ force: true });
|
||||||
.contains('Save')
|
|
||||||
.click({ force: true });
|
|
||||||
cy.contains('Account Settings for quincy').should('be.visible');
|
cy.contains('Account Settings for quincy').should('be.visible');
|
||||||
|
|
||||||
cy.resetUsername();
|
cy.resetUsername();
|
||||||
|
1746
package-lock.json
generated
1746
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -71,8 +71,8 @@
|
|||||||
"cypress": "^6.6.0",
|
"cypress": "^6.6.0",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"docsify-cli": "^4.4.3",
|
"docsify-cli": "^4.4.3",
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^7.21.0",
|
||||||
"eslint-config-prettier": "^6.12.0",
|
"eslint-config-prettier": "^8.1.0",
|
||||||
"eslint-plugin-babel": "^5.3.1",
|
"eslint-plugin-babel": "^5.3.1",
|
||||||
"eslint-plugin-import": "^2.22.1",
|
"eslint-plugin-import": "^2.22.1",
|
||||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
"markdownlint": "^0.21.0",
|
"markdownlint": "^0.21.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"ora": "^3.4.0",
|
"ora": "^3.4.0",
|
||||||
"prettier": "^1.18.2",
|
"prettier": "^2.2.1",
|
||||||
"prismjs": "^1.23.0",
|
"prismjs": "^1.23.0",
|
||||||
"readdirp-walk": "^1.7.0",
|
"readdirp-walk": "^1.7.0",
|
||||||
"shx": "^0.3.3",
|
"shx": "^0.3.3",
|
||||||
|
@@ -24,8 +24,10 @@ if (
|
|||||||
start < 1 ||
|
start < 1 ||
|
||||||
start !== end - 1
|
start !== end - 1
|
||||||
) {
|
) {
|
||||||
throw 'Step not created. Steps specified must be' +
|
throw (
|
||||||
' consecutive numbers and start step must be greater than 0.';
|
'Step not created. Steps specified must be' +
|
||||||
|
' consecutive numbers and start step must be greater than 0.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingSteps = getExistingStepNums(projectPath);
|
const existingSteps = getExistingStepNums(projectPath);
|
||||||
|
@@ -73,14 +73,8 @@ const reorderSteps = () => {
|
|||||||
const projectPath = getProjectPath();
|
const projectPath = getProjectPath();
|
||||||
|
|
||||||
const projectName = process.env.CALLING_DIR
|
const projectName = process.env.CALLING_DIR
|
||||||
? process.env.CALLING_DIR.split(path.sep)
|
? process.env.CALLING_DIR.split(path.sep).slice(-1).toString()
|
||||||
.slice(-1)
|
: process.cwd().split(path.sep).slice(-1).toString();
|
||||||
.toString()
|
|
||||||
: process
|
|
||||||
.cwd()
|
|
||||||
.split(path.sep)
|
|
||||||
.slice(-1)
|
|
||||||
.toString();
|
|
||||||
|
|
||||||
const curriculumPath = process.env.CALLING_DIR
|
const curriculumPath = process.env.CALLING_DIR
|
||||||
? ''
|
? ''
|
||||||
@@ -187,8 +181,10 @@ const getExistingStepNums = projectPath => {
|
|||||||
) {
|
) {
|
||||||
let stepNum = fileName.split('.')[0].split('-')[1];
|
let stepNum = fileName.split('.')[0].split('-')[1];
|
||||||
if (!/^\d{3}$/.test(stepNum)) {
|
if (!/^\d{3}$/.test(stepNum)) {
|
||||||
throw `Step not created. File ${fileName} has a step number containing non-digits.` +
|
throw (
|
||||||
' Please run reorder-steps script first.';
|
`Step not created. File ${fileName} has a step number containing non-digits.` +
|
||||||
|
' Please run reorder-steps script first.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
stepNum = parseInt(stepNum, 10);
|
stepNum = parseInt(stepNum, 10);
|
||||||
stepNums.push(stepNum);
|
stepNums.push(stepNum);
|
||||||
|
@@ -90,14 +90,16 @@ function validateEditableMarkers({ value, position }) {
|
|||||||
lines.forEach((line, index) => {
|
lines.forEach((line, index) => {
|
||||||
if (line.match(twoMarkersRE)) {
|
if (line.match(twoMarkersRE)) {
|
||||||
throw Error(
|
throw Error(
|
||||||
`Line ${baseLineNumber +
|
`Line ${
|
||||||
index} has two markers. Each line should only have one.`
|
baseLineNumber + index
|
||||||
|
} has two markers. Each line should only have one.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (line.match(formattedMarkerRE)) {
|
if (line.match(formattedMarkerRE)) {
|
||||||
throw Error(
|
throw Error(
|
||||||
`Line ${baseLineNumber +
|
`Line ${
|
||||||
index} has a malformed marker. It should be --fcc-editable-region--`
|
baseLineNumber + index
|
||||||
|
} has a malformed marker. It should be --fcc-editable-region--`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -11,9 +11,7 @@ const { editableRegionMarker } = require('./add-seed');
|
|||||||
const tableAndStrikeThrough = require('./table-and-strikethrough');
|
const tableAndStrikeThrough = require('./table-and-strikethrough');
|
||||||
|
|
||||||
async function parse(file) {
|
async function parse(file) {
|
||||||
return await remark()
|
return await remark().use(tableAndStrikeThrough).parse(file);
|
||||||
.use(tableAndStrikeThrough)
|
|
||||||
.parse(file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin() {
|
function plugin() {
|
||||||
|
@@ -12,7 +12,7 @@ const usernameIsHttpStatusCode = {
|
|||||||
const isNumeric = num => !isNaN(num);
|
const isNumeric = num => !isNaN(num);
|
||||||
const validCharsRE = /^[a-zA-Z0-9\-_+]*$/;
|
const validCharsRE = /^[a-zA-Z0-9\-_+]*$/;
|
||||||
const isHttpStatusCode = str =>
|
const isHttpStatusCode = str =>
|
||||||
isNumeric(str) && (parseInt(str, 10) >= 100 && parseInt(str, 10) <= 599);
|
isNumeric(str) && parseInt(str, 10) >= 100 && parseInt(str, 10) <= 599;
|
||||||
const isValidUsername = str => {
|
const isValidUsername = str => {
|
||||||
if (!validCharsRE.test(str)) return invalidCharError;
|
if (!validCharsRE.test(str)) return invalidCharError;
|
||||||
if (str.length < 3) return usernameTooShort;
|
if (str.length < 3) return usernameTooShort;
|
||||||
|
Reference in New Issue
Block a user