Merge branch 'staging' of github.com:FreeCodeCamp/freecodecamp into staging
This commit is contained in:
@ -230,7 +230,7 @@
|
|||||||
"permAlone('aab');"
|
"permAlone('aab');"
|
||||||
],
|
],
|
||||||
"tests": [
|
"tests": [
|
||||||
"expect(permAlone('aab')).to.be.a.number;",
|
"expect(permAlone('aab')).to.be.a('number');",
|
||||||
"expect(permAlone('aab')).to.equal(2);",
|
"expect(permAlone('aab')).to.equal(2);",
|
||||||
"expect(permAlone('aaa')).to.equal(0);",
|
"expect(permAlone('aaa')).to.equal(0);",
|
||||||
"expect(permAlone('aabb')).to.equal(8);",
|
"expect(permAlone('aabb')).to.equal(8);",
|
||||||
|
@ -423,6 +423,7 @@
|
|||||||
],
|
],
|
||||||
"tests": [
|
"tests": [
|
||||||
"expect(truncate('A-tisket a-tasket A green and yellow basket', 11)).to.eqls('A-tisket...');",
|
"expect(truncate('A-tisket a-tasket A green and yellow basket', 11)).to.eqls('A-tisket...');",
|
||||||
|
"expect(truncate('Peter Piper picked a peck of pickled peppers', 14)).to.eqls('Peter Piper...');",
|
||||||
"assert(truncate('A-tisket a-tasket A green and yellow basket', 'A-tisket a-tasket A green and yellow basket'.length) === 'A-tisket a-tasket A green and yellow basket', 'should not truncate if string is = length');",
|
"assert(truncate('A-tisket a-tasket A green and yellow basket', 'A-tisket a-tasket A green and yellow basket'.length) === 'A-tisket a-tasket A green and yellow basket', 'should not truncate if string is = length');",
|
||||||
"assert.strictEqual(truncate('A-tisket a-tasket A green and yellow basket', 'A-tisket a-tasket A green and yellow basket'.length + 2), 'A-tisket a-tasket A green and yellow basket', 'should not truncate if string is < length');"
|
"assert.strictEqual(truncate('A-tisket a-tasket A green and yellow basket', 'A-tisket a-tasket A green and yellow basket'.length + 2), 'A-tisket a-tasket A green and yellow basket', 'should not truncate if string is < length');"
|
||||||
],
|
],
|
||||||
@ -657,7 +658,10 @@
|
|||||||
],
|
],
|
||||||
"tests": [
|
"tests": [
|
||||||
"assert.deepEqual(destroyer([1, 2, 3, 1, 2, 3], 2, 3), [1, 1], 'should remove correct values from an array');",
|
"assert.deepEqual(destroyer([1, 2, 3, 1, 2, 3], 2, 3), [1, 1], 'should remove correct values from an array');",
|
||||||
"assert.deepEqual(destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3), [1, 5, 1], 'should remove correct values from an array');"
|
"assert.deepEqual(destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3), [1, 5, 1], 'should remove correct values from an array');",
|
||||||
|
"assert.deepEqual(destroyer([3, 5, 1, 2, 2], 2, 3, 5), [1], 'should accept more than two additional arguments');",
|
||||||
|
"assert.deepEqual(destroyer([2, 3, 2, 3], 2, 3), [], 'should remove correct values from an array');",
|
||||||
|
"assert.deepEqual(destroyer(['tree', 'hamburger', 53], 'tree', 53), ['hamburger'], 'should handle NaN-elements');"
|
||||||
],
|
],
|
||||||
"MDNlinks": [
|
"MDNlinks": [
|
||||||
"Arguments object",
|
"Arguments object",
|
||||||
|
@ -863,7 +863,7 @@
|
|||||||
"description": [
|
"description": [
|
||||||
"<div class=\"col-xs-12 col-sm-10 col-sm-offset-1\">",
|
"<div class=\"col-xs-12 col-sm-10 col-sm-offset-1\">",
|
||||||
" <p class='h2'>Translation is an all-or-nothing proposal.</h2>",
|
" <p class='h2'>Translation is an all-or-nothing proposal.</h2>",
|
||||||
" <p class='large-p'>We won't be able to add new languages to Free Code Camp until all of our challenges are translated into that langauge.</p>",
|
" <p class='large-p'>We won't be able to add new languages to Free Code Camp until all of our challenges are translated into that language.</p>",
|
||||||
" <p class='large-p'>In addition to translating these initially, we'll also need to maintain the translation as the challenges are gradually updated.</p>",
|
" <p class='large-p'>In addition to translating these initially, we'll also need to maintain the translation as the challenges are gradually updated.</p>",
|
||||||
" <p class='large-p'>If you're able to help us, you can join our <a href='https://trello.com/b/m7zhwXka/fcc-translation' target='_blank'>Trello board</a> by sending @quincylarson your email address in Slack.</p>",
|
" <p class='large-p'>If you're able to help us, you can join our <a href='https://trello.com/b/m7zhwXka/fcc-translation' target='_blank'>Trello board</a> by sending @quincylarson your email address in Slack.</p>",
|
||||||
"</div>"
|
"</div>"
|
||||||
|
@ -32,7 +32,9 @@
|
|||||||
|
|
||||||
var R = require('ramda'),
|
var R = require('ramda'),
|
||||||
utils = require('../utils'),
|
utils = require('../utils'),
|
||||||
userMigration = require('../utils/middleware').userMigration;
|
saveUser = require('../utils/rx').saveUser,
|
||||||
|
userMigration = require('../utils/middleware').userMigration,
|
||||||
|
ifNoUserRedirectTo = require('../utils/middleware').ifNoUserRedirectTo;
|
||||||
|
|
||||||
var challengeMapWithNames = utils.getChallengeMapWithNames();
|
var challengeMapWithNames = utils.getChallengeMapWithNames();
|
||||||
var challengeMapWithIds = utils.getChallengeMapWithIds();
|
var challengeMapWithIds = utils.getChallengeMapWithIds();
|
||||||
@ -51,23 +53,30 @@ module.exports = function(app) {
|
|||||||
|
|
||||||
// the follow routes are covered by userMigration
|
// the follow routes are covered by userMigration
|
||||||
router.use(userMigration);
|
router.use(userMigration);
|
||||||
router.get('/challenges/next-challenge', returnNextChallenge);
|
|
||||||
router.get('/challenges/:challengeName', returnIndividualChallenge);
|
|
||||||
router.get('/challenges/', returnCurrentChallenge);
|
|
||||||
router.get('/map', challengeMap);
|
router.get('/map', challengeMap);
|
||||||
|
router.get(
|
||||||
|
'/challenges/next-challenge',
|
||||||
|
ifNoUserRedirectTo('../challenges/learn-how-free-code-camp-works'),
|
||||||
|
returnNextChallenge
|
||||||
|
);
|
||||||
|
|
||||||
|
router.get('/challenges/:challengeName', returnIndividualChallenge);
|
||||||
|
|
||||||
|
router.get(
|
||||||
|
'/challenges/',
|
||||||
|
ifNoUserRedirectTo('../challenges/learn-how-free-code-camp-works'),
|
||||||
|
returnCurrentChallenge
|
||||||
|
);
|
||||||
|
|
||||||
app.use(router);
|
app.use(router);
|
||||||
|
|
||||||
function returnNextChallenge(req, res, next) {
|
function returnNextChallenge(req, res, next) {
|
||||||
if (!req.user) {
|
|
||||||
return res.redirect('../challenges/learn-how-free-code-camp-works');
|
|
||||||
}
|
|
||||||
var completed = req.user.completedChallenges.map(function (elem) {
|
var completed = req.user.completedChallenges.map(function (elem) {
|
||||||
return elem.id;
|
return elem.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
req.user.uncompletedChallenges = utils.allChallengeIds()
|
req.user.uncompletedChallenges = utils.allChallengeIds()
|
||||||
.filter(function (elem) {
|
.filter(function(elem) {
|
||||||
if (completed.indexOf(elem) === -1) {
|
if (completed.indexOf(elem) === -1) {
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
@ -100,18 +109,17 @@ module.exports = function(app) {
|
|||||||
nextChallengeName = R.head(challengeMapWithDashedNames[0].challenges);
|
nextChallengeName = R.head(challengeMapWithDashedNames[0].challenges);
|
||||||
}
|
}
|
||||||
|
|
||||||
req.user.save(function(err) {
|
saveUser(req.user)
|
||||||
if (err) {
|
.subscribe(
|
||||||
return next(err);
|
function() {},
|
||||||
|
next,
|
||||||
|
function() {
|
||||||
|
res.redirect('../challenges/' + nextChallengeName);
|
||||||
}
|
}
|
||||||
return res.redirect('../challenges/' + nextChallengeName);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function returnCurrentChallenge(req, res, next) {
|
function returnCurrentChallenge(req, res, next) {
|
||||||
if (!req.user) {
|
|
||||||
return res.redirect('../challenges/learn-how-free-code-camp-works');
|
|
||||||
}
|
|
||||||
var completed = req.user.completedChallenges.map(function (elem) {
|
var completed = req.user.completedChallenges.map(function (elem) {
|
||||||
return elem.id;
|
return elem.id;
|
||||||
});
|
});
|
||||||
@ -133,12 +141,14 @@ module.exports = function(app) {
|
|||||||
|
|
||||||
var nameString = req.user.currentChallenge.dashedName;
|
var nameString = req.user.currentChallenge.dashedName;
|
||||||
|
|
||||||
req.user.save(function(err) {
|
saveUser(req.user)
|
||||||
if (err) {
|
.subscribe(
|
||||||
return next(err);
|
function() {},
|
||||||
|
next,
|
||||||
|
function() {
|
||||||
|
res.redirect('../challenges/' + nameString);
|
||||||
}
|
}
|
||||||
return res.redirect('../challenges/' + nameString);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function returnIndividualChallenge(req, res, next) {
|
function returnIndividualChallenge(req, res, next) {
|
||||||
@ -152,8 +162,10 @@ module.exports = function(app) {
|
|||||||
// Handle not found
|
// Handle not found
|
||||||
if (!challenge) {
|
if (!challenge) {
|
||||||
req.flash('errors', {
|
req.flash('errors', {
|
||||||
msg: '404: We couldn\'t find a challenge with that name. ' +
|
msg:
|
||||||
'Please double check the name.'
|
'404: We couldn\'t find a challenge with the name `' +
|
||||||
|
dashedName +
|
||||||
|
'` Please double check the name.'
|
||||||
});
|
});
|
||||||
return res.redirect('/challenges');
|
return res.redirect('/challenges');
|
||||||
}
|
}
|
||||||
@ -167,8 +179,9 @@ module.exports = function(app) {
|
|||||||
map(function (key) {
|
map(function (key) {
|
||||||
return challengeMapWithIds[key]
|
return challengeMapWithIds[key]
|
||||||
.filter(function (elem) {
|
.filter(function (elem) {
|
||||||
return String(elem) === String(challenge.id);
|
return String(elem) === challenge.id;
|
||||||
}).map(function () {
|
})
|
||||||
|
.map(function () {
|
||||||
return key;
|
return key;
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -176,13 +189,10 @@ module.exports = function(app) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var challengeType = {
|
var commonLocals = {
|
||||||
0: function() {
|
|
||||||
res.render('coursewares/showHTML', {
|
|
||||||
title: challenge.name,
|
title: challenge.name,
|
||||||
dashedName: dashedName,
|
dashedName: dashedName,
|
||||||
name: challenge.name,
|
name: challenge.name,
|
||||||
brief: challenge.description[0],
|
|
||||||
details: challenge.description.slice(1),
|
details: challenge.description.slice(1),
|
||||||
tests: challenge.tests,
|
tests: challenge.tests,
|
||||||
challengeSeed: challenge.challengeSeed,
|
challengeSeed: challenge.challengeSeed,
|
||||||
@ -190,106 +200,37 @@ module.exports = function(app) {
|
|||||||
phrase: utils.randomPhrase(),
|
phrase: utils.randomPhrase(),
|
||||||
compliment: utils.randomCompliment(),
|
compliment: utils.randomCompliment(),
|
||||||
challengeId: challenge.id,
|
challengeId: challenge.id,
|
||||||
environment: utils.whichEnvironment(),
|
challengeType: challenge.challengeType,
|
||||||
challengeType: challenge.challengeType
|
// video challenges
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
1: function() {
|
|
||||||
res.render('coursewares/showJS', {
|
|
||||||
title: challenge.name,
|
|
||||||
dashedName: dashedName,
|
|
||||||
name: challenge.name,
|
|
||||||
brief: challenge.description[0],
|
|
||||||
details: challenge.description.slice(1),
|
|
||||||
tests: challenge.tests,
|
|
||||||
challengeSeed: challenge.challengeSeed,
|
|
||||||
verb: utils.randomVerb(),
|
|
||||||
phrase: utils.randomPhrase(),
|
|
||||||
compliment: utils.randomCompliment(),
|
|
||||||
challengeId: challenge.id,
|
|
||||||
challengeType: challenge.challengeType
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
2: function() {
|
|
||||||
res.render('coursewares/showVideo', {
|
|
||||||
title: challenge.name,
|
|
||||||
dashedName: dashedName,
|
|
||||||
name: challenge.name,
|
|
||||||
details: challenge.description,
|
|
||||||
tests: challenge.tests,
|
|
||||||
video: challenge.challengeSeed[0],
|
video: challenge.challengeSeed[0],
|
||||||
verb: utils.randomVerb(),
|
// bonfires specific
|
||||||
phrase: utils.randomPhrase(),
|
|
||||||
compliment: utils.randomCompliment(),
|
|
||||||
challengeId: challenge.id,
|
|
||||||
challengeType: challenge.challengeType
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
3: function() {
|
|
||||||
res.render('coursewares/showZiplineOrBasejump', {
|
|
||||||
title: challenge.name,
|
|
||||||
dashedName: dashedName,
|
|
||||||
name: challenge.name,
|
|
||||||
details: challenge.description,
|
|
||||||
video: challenge.challengeSeed[0],
|
|
||||||
verb: utils.randomVerb(),
|
|
||||||
phrase: utils.randomPhrase(),
|
|
||||||
compliment: utils.randomCompliment(),
|
|
||||||
challengeId: challenge.id,
|
|
||||||
challengeType: challenge.challengeType
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
4: function() {
|
|
||||||
res.render('coursewares/showZiplineOrBasejump', {
|
|
||||||
title: challenge.name,
|
|
||||||
dashedName: dashedName,
|
|
||||||
name: challenge.name,
|
|
||||||
details: challenge.description,
|
|
||||||
video: challenge.challengeSeed[0],
|
|
||||||
verb: utils.randomVerb(),
|
|
||||||
phrase: utils.randomPhrase(),
|
|
||||||
compliment: utils.randomCompliment(),
|
|
||||||
challengeId: challenge.id,
|
|
||||||
challengeType: challenge.challengeType
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
5: function() {
|
|
||||||
res.render('coursewares/showBonfire', {
|
|
||||||
completedWith: null,
|
|
||||||
title: challenge.name,
|
|
||||||
dashedName: dashedName,
|
|
||||||
name: challenge.name,
|
|
||||||
difficulty: Math.floor(+challenge.difficulty),
|
difficulty: Math.floor(+challenge.difficulty),
|
||||||
brief: challenge.description.shift(),
|
brief: challenge.description.shift(),
|
||||||
details: challenge.description,
|
|
||||||
tests: challenge.tests,
|
|
||||||
challengeSeed: challenge.challengeSeed,
|
|
||||||
verb: utils.randomVerb(),
|
|
||||||
phrase: utils.randomPhrase(),
|
|
||||||
compliment: utils.randomCompliment(),
|
|
||||||
bonfires: challenge,
|
bonfires: challenge,
|
||||||
challengeId: challenge.id,
|
|
||||||
MDNkeys: challenge.MDNlinks,
|
MDNkeys: challenge.MDNlinks,
|
||||||
MDNlinks: getMDNLinks(challenge.MDNlinks),
|
MDNlinks: getMDNLinks(challenge.MDNlinks),
|
||||||
challengeType: challenge.challengeType
|
// htmls specific
|
||||||
});
|
environment: utils.whichEnvironment()
|
||||||
}
|
|
||||||
};
|
};
|
||||||
if (req.user) {
|
|
||||||
req.user.save(function (err) {
|
var challengeView = {
|
||||||
if (err) {
|
0: 'coursewares/showHTML',
|
||||||
return next(err);
|
1: 'coursewares/showJS',
|
||||||
}
|
2: 'coursewares/showVideo',
|
||||||
return challengeType[challenge.challengeType]();
|
3: 'coursewares/showZiplineOrBasejump',
|
||||||
});
|
4: 'coursewares/showZiplineOrBasejump',
|
||||||
} else {
|
5: 'coursewares/showBonfire'
|
||||||
return challengeType[challenge.challengeType]();
|
};
|
||||||
|
|
||||||
|
saveUser(req.user)
|
||||||
|
.subscribe(
|
||||||
|
function() {},
|
||||||
|
next,
|
||||||
|
function() {
|
||||||
|
var view = challengeView[challenge.challengeType];
|
||||||
|
res.render(view, commonLocals);
|
||||||
}
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ module.exports = function(app) {
|
|||||||
|
|
||||||
function nonprofitsDirectory(req, res, next) {
|
function nonprofitsDirectory(req, res, next) {
|
||||||
Nonprofit.find(
|
Nonprofit.find(
|
||||||
{ where: { estimatedHours: { $gt: 0 } } },
|
{ where: { estimatedHours: { gt: 0 } } },
|
||||||
function(err, nonprofits) {
|
function(err, nonprofits) {
|
||||||
if (err) { return next(err); }
|
if (err) { return next(err); }
|
||||||
|
|
||||||
|
@ -33,3 +33,13 @@ exports.userMigration = function userMigration(req, res, next) {
|
|||||||
);
|
);
|
||||||
return next();
|
return next();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.ifNoUserRedirectTo = function ifNoUserRedirectTo(url) {
|
||||||
|
return function(req, res, next) {
|
||||||
|
if (req.user) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
return res.redirect(url);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user