Merge branch 'staging' of github.com:FreeCodeCamp/freecodecamp into staging

This commit is contained in:
Quincy Larson
2015-08-03 21:17:55 -07:00
11 changed files with 82 additions and 66 deletions

View File

@ -7,9 +7,6 @@
Welcome to Free Code Camp's open source codebase!
=======================
#Note
We're currently very close to moving from Express to Loopback. As such, please keep in mind that the instructions here for setting up and running the project do not directly translate to the staging branch. Additionally, the file structure is quite a bit different. As always, the staging branch is the appropriate place to branch off of to fix/add something!
Free Code Camp is an open-source community of busy people who learn to code, then build projects for nonprofits.
Our campers (students) start by working through our free, self-paced, browser-based curriculum. Next, they build several practice projects. Finally, we pair two campers together with a stakeholder from a nonprofit organization, and help them build the solution the nonprofit has requested.
@ -20,7 +17,14 @@ Our campers (students) start by working through our free, self-paced, browser-ba
This code is running live at [FreeCodeCamp.com](http://www.FreeCodeCamp.com). We also have [Gitter](https://gitter.im/FreeCodeCamp/FreeCodeCamp), a [blog](http://blog.freecodecamp.com), and even a [Twitch.tv channel](http://twitch.tv/freecodecamp).
[Join our community](http://www.freecodecamp.com/signin)!
[Join our community here](http://www.freecodecamp.com/signin).
*Note: We're currently very close to moving from Express to Loopback. As such, please keep in mind that the instructions here for setting up and running the project do not directly translate to the staging branch. Additionally, the file structure is quite a bit different. As always, the staging branch is the appropriate place to branch off of to fix/add something.*
Wiki
------------
We would love your help expanding our [wiki](https://github.com/freecodecamp/freecodecamp/wiki) with more information about learning to code and getting a coding job.
Contributing
------------

View File

@ -210,7 +210,17 @@ var runTests = function(err, data) {
err: "No user tests were run."
}];
createTestDisplay();
} else if (userTests) {
}
//Add blocks to test exploits here!
else if(editorValue.match(/if\s\(null\)\sconsole\.log\(1\);/gi)){
allTestsPassed = false;
userTests = [{
text: "Program Execution Failure",
err: "Invalid if (null) console.log(1); detected"
}];
createTestDisplay();
}
else if (userTests) {
userTests.push(false);
pushed = true;
userTests.forEach(function(chaiTestFromJSON, indexOfTestArray,

View File

@ -104,7 +104,8 @@
"weeks": "12",
"cities": [
"provo",
"salt-lake-city"
"salt-lake-city",
"dallas"
]
}, {
"name": "Epicodus",

View File

@ -277,9 +277,9 @@
],
"tests": [
"assert.deepEqual(friendly(['2015-07-01', '2015-07-04']), ['July 1st','4th'], 'ending month should be omitted since it is already mentioned');",
"assert.deepEqual(friendly(['2015-12-01', '2016-02-03']), ['December 1st','February 3rd'], 'one month apart can be inferred it is the next year');",
"assert.deepEqual(friendly(['2015-12-01', '2016-02-03']), ['December 1st','February 3rd'], 'two months apart can be inferred if it is the next year');",
"assert.deepEqual(friendly(['2015-12-01', '2017-02-03']), ['December 1st, 2015','February 3rd, 2017']);",
"assert.deepEqual(friendly(['2016-03-01', '2016-05-05']), ['March 1st','May 5th, 2016']);",
"assert.deepEqual(friendly(['2016-03-01', '2016-05-05']), ['March 1st','May 5th'], 'one month apart can be inferred it is the same year');",
"assert.deepEqual(friendly(['2017-01-01', '2017-01-01']), ['January 1st, 2017'], 'since we do not duplicate only return once');",
"assert.deepEqual(friendly(['2022-09-05', '2023-09-04']), ['September 5th, 2022','September 4th, 2023']);"
],

View File

@ -121,23 +121,26 @@
"For example, if we created a variable <code>var firstName = \"Julie\"</code>, we could find out how long the string \"Julie\" is by using the <code>firstName.length</code> property."
],
"tests": [
"assert((function(){if(typeof(lastNameLength) != 'undefined' && typeof(lastNameLength) == 'number' && lastNameLength == 4){return(true);}else{return(false);}})(), 'lastNameLength should be equal to four')"
"assert((function(){if(typeof(lastNameLength) != 'undefined' && typeof(lastNameLength) == 'number' && lastNameLength == 4){return(true);}else{return(false);}})(), 'lastNameLength should be equal to four')",
"assert((function(){if(editor.getValue().match(/\\.length/gi).length >= 2 && editor.getValue().match(/var lastNameLength \\= 0;/gi).length >= 1){return(true);}else{return(false);}})(), 'You should be getting the length of <code>lastName</code> by using .length like this <code>lastName.length</code>');"
],
"challengeSeed": [
"var firstNameLength = 0;",
"var lastNameLength = 0;",
"var firstName = \"Madeline\";",
"",
"var firstNameLength = firstName.length;",
"firstNameLength = firstName.length;",
"",
"var lastName = \"Chen\";",
"",
"var lastNameLength = lastName;",
"lastNameLength = lastName;",
"",
"",
"",
"// You can ignore this.",
"// We use this to show you the value of your variable in your output box.",
"// We'll learn about functions soon.",
"if(typeof(lastNameLength) != 'undefined')(function(v){return(v);})(lastNameLength);}"
"if(typeof(lastNameLength) != 'undefined'){(function(v){return(v);})(lastNameLength);}"
],
"challengeType": 1
},
@ -154,16 +157,19 @@
"Try looking at the <code>firstLetterOfFirstName</code> variable declaration if you get stuck."
],
"tests": [
"assert((function(){if(typeof(firstLetterOfLastName) != 'undefined' && typeof(firstLetterOfLastName) == 'string' && firstLetterOfLastName == 'C'){return(true);}else{return(false);}})(), 'The first letter of firstLetterOfLastName should be a C');"
"assert((function(){if(typeof(firstLetterOfLastName) != 'undefined' && editor.getValue().match(/\\[0\\]/gi) && typeof(firstLetterOfLastName) == 'string' && firstLetterOfLastName == 'C'){return(true);}else{return(false);}})(), 'The first letter of firstLetterOfLastName should be a C');"
],
"challengeSeed": [
"var firstLetterOfLastName = \"\"",
"var firstLetterOfLastName = \"\"",
"",
"var firstName = \"Madeline\";",
"",
"var firstLetterOfFirstName = firstName[0];",
"firstLetterOfFirstName = firstName[0];",
"",
"var lastName = \"Chen\";",
"",
"var firstLetterOfLastName = lastName;",
"firstLetterOfLastName = lastName;",
"",
"",
"// You can ignore this.",
@ -562,7 +568,7 @@
"difficulty": "9.9818",
"description": [
"",
"Now that we've learn how to <code> pop </code> things from the end of the array, we need to learn how to <code> push </code> stuff back to the end",
"Now that we've learned how to <code> pop </code> things from the end of the array, we need to learn how to <code> push </code> stuff back to the end",
"Let's take the code we had last time and <code> push </code> this value to the end: <code> ['dog', 3] </code>"
],
"tests": [
@ -644,7 +650,7 @@
"Let's try creating and calling a function now called <code>myFunction</code>"
],
"tests":[
"assert((function(){if(typeof(f) !== 'undefined' && typeof(f) === 'number' && f === a + b && editor.getValue().match(RegExp('return\\\\(a\\\\+b\\\\)', 'g')).length >= 1){return(true);}else{return(false);}})(), 'Your function should return the value of a + b');"
"assert((function(){if(typeof(f) !== 'undefined' && typeof(f) === 'number' && f === a + b && editor.getValue().match(/return/gi).length >= 1 && editor.getValue().match(/a/gi).length >= 1 && editor.getValue().match(/b/gi).length >= 1 && editor.getValue().match(/\\+/gi).length >= 1){return(true);}else{return(false);}})(), 'Your function should return the value of a + b');"
],
"challengeSeed":[
"var a = 4;",
@ -794,7 +800,7 @@
"description":[
"",
"Loops are a critical part of any program! The next few challenges",
"first we will be taking a look at the for loop",
"first we will be taking a look at the while loop",
"<code>",
"var ourArray = [];",
"var i = 0;",

View File

@ -797,8 +797,8 @@
"Delete the \".red-text\", \"p\", and \".smaller-image\" CSS declarations from your <code>style</code> element so that the only declarations left in your <code>style</code> element are \"h2\" and \"thick-green-border\". Then Delete the <code>p</code> element that contains a dead link. Then remove the \"red-text\" class from your <code>h2</code> element and replace it with the \"text-primary\" Bootstrap class. Finally, remove the \"smaller-image\" class from your first <code>img</code> element and replace it with the <code>img-responsive</code> class."
],
"tests": [
"assert(!$('h2').hasClass('red-text'), 'You h2 element should no longer have the class \"red-text\".')",
"assert($('h2').hasClass('text-primary'), 'You h2 element should now have the class \"text-primary\".')",
"assert(!$('h2').hasClass('red-text'), 'Your h2 element should no longer have the class \"red-text\".')",
"assert($('h2').hasClass('text-primary'), 'Your h2 element should now have the class \"text-primary\".')",
"assert(!$('p').css('font-family').match(/monospace/i), 'Your paragraph elements should no longer use the font \"Monospace\".')",
"assert(!$('img').hasClass('smaller-image'), 'Remove the \"smaller-image\" class from your top image.')",
"assert($('.img-responsive').length > 1, 'Add the \"img-responsive\" class to your top image.')"
@ -1874,7 +1874,7 @@
},
{
"id": "bad87fee1348bd9aec908854",
"name": "Waypoint: Label Boostrap Wells",
"name": "Waypoint: Label Bootstrap Wells",
"dashedName": "waypoint-label-bootstrap-wells",
"difficulty": 2.26,
"description": [
@ -1883,9 +1883,9 @@
"Above your right-well, inside its \"col-xs-6\" <code>div</code> element, add a <code>h4</code> element with the text \"#right-well\"."
],
"tests": [
"assert($('.col-xs-12').children('h4') && $('.col-xs-12').children('h4').length > 1, 'Add an <code>h4</code> element to each of your <code>&#60;div class='col-xs-6'&#62;</code> elements.')",
"assert(new RegExp('#left-well','gi').test($('h4').text()), 'One <code>h4</code> element should have the text \"#left-well\".')",
"assert(new RegExp('#right-well','gi').test($('h4').text()), 'One <code>h4</code> element should have the text \"#right-well\".')"
"assert($('.col-xs-12').children('h4') && $('.col-xs-12').children('h4').length > 1, 'Add an <code>h4</code> element to each of your <code>&#60;div class=\\'col-xs-6\\'&#62;</code> elements.');",
"assert(new RegExp('#left-well','gi').test($('h4').text()), 'One <code>h4</code> element should have the text \"#left-well\".');",
"assert(new RegExp('#right-well','gi').test($('h4').text()), 'One <code>h4</code> element should have the text \"#right-well\".');"
],
"challengeSeed": [
"<div class='container-fluid'>",
@ -1930,12 +1930,12 @@
"Give each of your buttons a unique id like, starting with \"target1\" and ending with \"target6\"."
],
"tests": [
"assert($('#target1') && $('#target1').length > 0, 'One <code>button</code> element should have the id \"#target1\".')",
"assert($('#target2') && $('#target2').length > 0, 'One <code>button</code> element should have the id \"#target2\".')",
"assert($('#target3') && $('#target3').length > 0, 'One <code>button</code> element should have the id \"#target3\".')",
"assert($('#target4') && $('#target4').length > 0, 'One <code>button</code> element should have the id \"#target4\".')",
"assert($('#target5') && $('#target5').length > 0, 'One <code>button</code> element should have the id \"#target5\".')",
"assert($('#target6') && $('#target6').length > 0, 'One <code>button</code> element should have the id \"#target6\".')"
"assert($('#target1') && $('#target1').length > 0, 'One <code>button</code> element should have the id \"target1\".')",
"assert($('#target2') && $('#target2').length > 0, 'One <code>button</code> element should have the id \"target2\".')",
"assert($('#target3') && $('#target3').length > 0, 'One <code>button</code> element should have the id \"target3\".')",
"assert($('#target4') && $('#target4').length > 0, 'One <code>button</code> element should have the id \"target4\".')",
"assert($('#target5') && $('#target5').length > 0, 'One <code>button</code> element should have the id \"target5\".')",
"assert($('#target6') && $('#target6').length > 0, 'One <code>button</code> element should have the id \"target6\".')"
],
"challengeSeed": [
"<div class='container-fluid'>",

View File

@ -160,8 +160,8 @@
"Make all the <code>button</code> element with the id \"target3\" fadeOut. <code>$('#target3').addClass('animated fadeOut')</code>."
],
"tests": [
"$('#target3').hasClass('animated') && $('#target3').hasClass('fadeOut'), 'Select the <code>button</code>element with the <code>id</code> of \"target3\" and use the jQuery <code>addClass()</code> function to give it the classes of \"animated\" and \"fadeOut\".')",
"assert(!editor.match(/class.*animated/g), 'Only use jQuery to add these classes to the element.')"
"assert($('#target3').hasClass('animated') && $('#target3').hasClass('fadeOut'), 'Select the <code>button</code>element with the <code>id</code> of \"target3\" and use the jQuery <code>addClass()</code> function to give it the classes of \"animated\" and \"fadeOut\".');",
"assert(!editor.match(/class.*animated/g), 'Only use jQuery to add these classes to the element.');"
],
"challengeSeed": [
"fccss",

View File

@ -372,7 +372,7 @@ module.exports = function(app) {
function completedZiplineOrBasejump(req, res, next) {
var completedWith = req.body.challengeInfo.completedWith || false;
var completedWith = req.body.challengeInfo.completedWith || '';
var completedDate = Math.round(+new Date());
var challengeId = req.body.challengeInfo.challengeId;
var solutionLink = req.body.challengeInfo.publicURL;
@ -423,17 +423,17 @@ module.exports = function(app) {
pairedWith: pairedWith
};
})
.doOnNext(function(dats) {
.doOnNext(function({ user, pairedWith }) {
updateUserProgress(
dats.user,
user,
challengeId,
dats.pairedWith ?
assign({ completedWith: dats.pairedWith.id }, challengeData) :
pairedWith ?
assign({ completedWith: pairedWith.id }, challengeData) :
challengeData
);
})
.flatMap(function(dats) {
return Rx.Observable.from([dats.user, dats.pairedWith]);
.flatMap(function({ user, pairedWith }) {
return Rx.Observable.from([user, pairedWith]);
})
// save users
.flatMap(function(user) {

View File

@ -186,11 +186,6 @@ passportConfigurator.init();
app.use(rxMiddleware());
app.use(function(req, res, next) {
// add beta warning
req.flash('info', {
msg: `warning: you are on experimental branch of Free Code Camp:
Your progress here may or may not be saved to the main site`
});
// Make user object available in templates.
res.locals.user = req.user;

View File

@ -261,31 +261,31 @@ block content
.panel-heading.text-center Manage your account here:
.panel-body
if (!user.google || !user.facebook || !user.linkedin || !user.twitter)
if (!user.google)
if (!user.github)
.col-xs-12
a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/auth/google')
i.fa.fa-google-plus
| Link Google with my account
if (!user.facebook)
.col-xs-12
a.btn.btn-lg.btn-block.btn-facebook.btn-link-social(href='/auth/facebook')
i.fa.fa-facebook
| Link Facebook with my account
//if (!user.github)
// .col-xs-12
// a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/auth/github')
// i.fa.fa-github
// | Link GitHub with my account
if (!user.linkedin)
.col-xs-12
a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social(href='/auth/linkedin')
i.fa.fa-linkedin
| Link LinkedIn with my account
a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/auth/github')
i.fa.fa-github
| Link GitHub with my account
if (!user.twitter)
.col-xs-12
a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/auth/twitter')
i.fa.fa-twitter
| Link Twitter with my account
if (!user.google)
.col-xs-12
a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social.disabled(href='#')
i.fa.fa-google-plus
| Link Google with my account
if (!user.facebook)
.col-xs-12
a.btn.btn-lg.btn-block.btn-facebook.btn-link-social.disabled(href='#')
i.fa.fa-facebook
| Link Facebook with my account
if (!user.linkedin)
.col-xs-12
a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social.disabled(href='#')
i.fa.fa-linkedin
| Link LinkedIn with my account
.col-xs-12
a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout')
span.ion-android-exit

View File

@ -8,13 +8,13 @@ block content
a.btn.btn-lg.btn-block.btn-twitter.btn-social(href='/auth/twitter')
i.fa.fa-twitter
| Sign in with Twitter
a.btn.btn-lg.btn-block.btn-facebook.btn-social(href='/auth/facebook')
a.btn.btn-lg.btn-block.btn-facebook.btn-social.disabled(href='#')
i.fa.fa-facebook
| Sign in with Facebook
a.btn.btn-lg.btn-block.btn-google-plus.btn-social(href='/auth/google')
a.btn.btn-lg.btn-block.btn-google-plus.btn-social.disabled(href='#')
i.fa.fa-google-plus
| Sign in with Google
a.btn.btn-lg.btn-block.btn-linkedin.btn-social(href='/auth/linkedin')
a.btn.btn-lg.btn-block.btn-linkedin.btn-social.disabled(href='#')
i.fa.fa-linkedin
| Sign in with LinkedIn
br