From c17ff59aef7d3155ea733b0735df3c0c95c3e862 Mon Sep 17 00:00:00 2001 From: jameskopacz Date: Wed, 25 Mar 2015 20:43:11 -0500 Subject: [PATCH 01/24] Handle callback errors for user, bonfire, challenges, courseware, and resources controllers --- controllers/bonfire.js | 53 +++++++++++++++++++++------------------ controllers/challenges.js | 4 +-- controllers/courseware.js | 16 ++++++------ controllers/resources.js | 4 ++- controllers/user.js | 18 +++++++------ 5 files changed, 53 insertions(+), 42 deletions(-) diff --git a/controllers/bonfire.js b/controllers/bonfire.js index 83431a390d4..2fe914df9d8 100644 --- a/controllers/bonfire.js +++ b/controllers/bonfire.js @@ -35,7 +35,7 @@ exports.index = function(req, res) { }); }; -exports.returnNextBonfire = function(req, res) { +exports.returnNextBonfire = function(req, res, next) { if (!req.user) { return res.redirect('../bonfires/meet-bonfire'); } @@ -48,24 +48,24 @@ exports.returnNextBonfire = function(req, res) { return elem; } }); - req.user.save(); - - var uncompletedBonfires = req.user.uncompletedBonfires; - - var displayedBonfires = Bonfire.find({'_id': uncompletedBonfires[0]}); - displayedBonfires.exec(function(err, bonfire) { - if (err) { - next(err); - } - bonfire = bonfire.pop(); - if (bonfire === undefined) { - req.flash('errors', { - msg: "It looks like you've completed all the bonfires we have available. Good job!" - }); - return res.redirect('../bonfires/meet-bonfire'); - } - nameString = bonfire.name.toLowerCase().replace(/\s/g, '-'); - return res.redirect('../bonfires/' + nameString); + req.user.save(function(err) { + if (err) return next(err); + var uncompletedBonfires = req.user.uncompletedBonfires; + var displayedBonfires = Bonfire.find({'_id': uncompletedBonfires[0]}); + displayedBonfires.exec(function(err, bonfire) { + if (err) { + return next(err); + } + bonfire = bonfire.pop(); + if (bonfire === undefined) { + req.flash('errors', { + msg: "It looks like you've completed all the bonfires we have available. Good job!" + }); + return res.redirect('../bonfires/meet-bonfire'); + } + nameString = bonfire.name.toLowerCase().replace(/\s/g, '-'); + return res.redirect('../bonfires/' + nameString); + }); }); }; @@ -76,7 +76,7 @@ exports.returnIndividualBonfire = function(req, res, next) { Bonfire.find({"name" : new RegExp(bonfireName, 'i')}, function(err, bonfire) { if (err) { - next(err); + return next(err); } @@ -215,7 +215,7 @@ exports.generateChallenge = function(req, res) { res.send(response); }; -exports.completedBonfire = function (req, res) { +exports.completedBonfire = function (req, res, next) { var isCompletedWith = req.body.bonfireInfo.completedWith || undefined; var isCompletedDate = Math.round(+new Date() / 1000); var bonfireHash = req.body.bonfireInfo.bonfireHash; @@ -225,7 +225,7 @@ exports.completedBonfire = function (req, res) { var paired = User.find({"profile.username": isCompletedWith.toLowerCase()}).limit(1); paired.exec(function (err, pairedWith) { if (err) { - return err; + return next(err); } else { var index = req.user.uncompletedBonfires.indexOf(bonfireHash); if (index > -1) { @@ -256,9 +256,12 @@ exports.completedBonfire = function (req, res) { }) req.user.save(function (err, user) { + if (err) { + return next(err); + } pairedWith.save(function (err, paired) { if (err) { - throw err; + return next(err); } if (user && paired) { res.send(true); @@ -284,7 +287,7 @@ exports.completedBonfire = function (req, res) { req.user.save(function (err, user) { if (err) { - throw err; + return next(err); } if (user) { debug('Saving user'); @@ -292,4 +295,4 @@ exports.completedBonfire = function (req, res) { } }); } -}; \ No newline at end of file +}; diff --git a/controllers/challenges.js b/controllers/challenges.js index 6658e18e136..85dcae71308 100644 --- a/controllers/challenges.js +++ b/controllers/challenges.js @@ -27,7 +27,7 @@ exports.returnNextChallenge = function(req, res) { } }; -exports.returnChallenge = function(req, res) { +exports.returnChallenge = function(req, res, next) { var challengeNumber = parseInt(req.params.challengeNumber) || 0; if (challengeNumber === 2) { return res.redirect('../challenges/3'); @@ -41,7 +41,7 @@ exports.returnChallenge = function(req, res) { Challenge.find({}, null, { sort: { challengeNumber: 1 } }, function(err, c) { if (err) { debug('Challenge err: ', err); - next(err); + return next(err); } res.render('challenges/show', { title: 'Challenge: ' + c[challengeNumber].name, diff --git a/controllers/courseware.js b/controllers/courseware.js index 58e57cef7da..069ede984fa 100644 --- a/controllers/courseware.js +++ b/controllers/courseware.js @@ -14,7 +14,7 @@ exports.coursewareNames = function(req, res) { }); }; -exports.returnNextCourseware = function(req, res) { +exports.returnNextCourseware = function(req, res, next) { if (!req.user) { return res.redirect('../coursewares/start-our-challenges'); } @@ -27,14 +27,16 @@ exports.returnNextCourseware = function(req, res) { return elem; } }); - req.user.save(); + req.user.save(function(err) { + if (err) return next(err); + }); var uncompletedCoursewares = req.user.uncompletedCoursewares; var displayedCoursewares = Courseware.find({'_id': uncompletedCoursewares[0]}); displayedCoursewares.exec(function(err, courseware) { if (err) { - next(err); + return next(err); } courseware = courseware.pop(); if (courseware === undefined) { @@ -55,7 +57,7 @@ exports.returnIndividualCourseware = function(req, res, next) { Courseware.find({"name" : new RegExp(coursewareName, 'i')}, function(err, courseware) { if (err) { - next(err); + return next(err); } // Handle not found if (courseware.length < 1) { @@ -203,7 +205,7 @@ exports.generateChallenge = function(req, res) { res.send(response); }; -exports.completedCourseware = function (req, res) { +exports.completedCourseware = function (req, res, next) { var isCompletedDate = Math.round(+new Date() / 1000); var coursewareHash = req.body.coursewareInfo.coursewareHash; @@ -221,10 +223,10 @@ exports.completedCourseware = function (req, res) { req.user.save(function (err, user) { if (err) { - throw err; + return next(err); } if (user) { res.send(true) } }); -}; \ No newline at end of file +}; diff --git a/controllers/resources.js b/controllers/resources.js index fe3d09c0aac..cf8fe48bde5 100644 --- a/controllers/resources.js +++ b/controllers/resources.js @@ -182,7 +182,9 @@ module.exports = { if (req.user) { if (!req.user.profile.picture || req.user.profile.picture === "https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon-180x180.png") { req.user.profile.picture = "https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png"; - req.user.save(); + req.user.save(function(err) { + if (err) return next(err); + }); } } var date1 = new Date("10/15/2014"); diff --git a/controllers/user.js b/controllers/user.js index 20fda23b1a1..5b0d2a9bb44 100644 --- a/controllers/user.js +++ b/controllers/user.js @@ -179,7 +179,7 @@ exports.postEmailSignup = function(req, res, next) { ].join('') }; transporter.sendMail(mailOptions, function(err) { - if (err) { return err; } + if (err) { return next(err); } }); }); }); @@ -210,8 +210,9 @@ exports.getAccountAngular = function(req, res) { * Unique username check API Call */ -exports.checkUniqueUsername = function(req, res) { +exports.checkUniqueUsername = function(req, res, next) { User.count({'profile.username': req.params.username.toLowerCase()}, function (err, data) { + if (err) { return next(err); } if (data == 1) { return res.send(true); } else { @@ -223,8 +224,9 @@ exports.checkUniqueUsername = function(req, res) { /** * Existing username check */ -exports.checkExistingUsername = function(req, res) { +exports.checkExistingUsername = function(req, res, next) { User.count({'profile.username': req.params.username.toLowerCase()}, function (err, data) { + if (err) { return next(err); } if (data === 1) { return res.send(true); } else { @@ -237,8 +239,9 @@ exports.checkExistingUsername = function(req, res) { * Unique email check API Call */ -exports.checkUniqueEmail = function(req, res) { +exports.checkUniqueEmail = function(req, res, next) { User.count({'email': decodeURIComponent(req.params.email).toLowerCase()}, function (err, data) { + if (err) { return next(err); } if (data == 1) { return res.send(true); } else { @@ -255,10 +258,11 @@ exports.checkUniqueEmail = function(req, res) { exports.returnUser = function(req, res, next) { User.find({'profile.username': req.params.username.toLowerCase()}, function(err, user) { - if (err) { debug('Username err: ', err); next(err); } + if (err) { debug('Username err: ', err); return next(err); } if (user[0]) { var user = user[0]; Challenge.find({}, null, {sort: {challengeNumber: 1}}, function (err, c) { + if (err) { return next(err); } res.render('account/show', { title: 'Camper ' + user.profile.username + '\'s portfolio', username: user.profile.username, @@ -300,7 +304,7 @@ exports.returnUser = function(req, res, next) { * Update profile information. */ -exports.updateProgress = function(req, res) { +exports.updateProgress = function(req, res, next) { User.findById(req.user.id, function(err, user) { if (err) return next(err); user.email = req.body.email || ''; @@ -471,7 +475,7 @@ exports.getOauthUnlink = function(req, res, next) { * Reset Password page. */ -exports.getReset = function(req, res) { +exports.getReset = function(req, res, next) { if (req.isAuthenticated()) { return res.redirect('/'); } From 5bb084120e8601e430874951f83954636dec377d Mon Sep 17 00:00:00 2001 From: Michael Q Larson Date: Sun, 29 Mar 2015 17:28:25 -0700 Subject: [PATCH 02/24] create a styleguide from @brndbr's sample style guide --- app.js | 1 + controllers/resources.js | 6 ++++++ views/resources/styleguide.jade | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 views/resources/styleguide.jade diff --git a/app.js b/app.js index ecbdc18fd5b..3c1ef9e70b9 100644 --- a/app.js +++ b/app.js @@ -235,6 +235,7 @@ app.get('/install-screenhero', resourcesController.installScreenHero); app.get('/javascript-in-your-inbox', resourcesController.javaScriptInYourInbox); app.get('/guide-to-our-nonprofit-projects', resourcesController.guideToOurNonprofitProjects); app.get('/chromebook', resourcesController.chromebook); +app.get('/styleguide', resourcesController.styleguide); app.get('/deploy-a-website', resourcesController.deployAWebsite); app.get('/gmail-shortcuts', resourcesController.gmailShortcuts); app.get('/control-shortcuts', resourcesController.controlShortcuts); diff --git a/controllers/resources.js b/controllers/resources.js index b6897857b0f..0d8c0e5d552 100644 --- a/controllers/resources.js +++ b/controllers/resources.js @@ -109,6 +109,12 @@ module.exports = { }); }, + styleguide: function styleguide(req, res) { + res.render('resources/styleguide', { + title: 'A Styleguide for Contributing to our Bonfires' + }); + }, + jqueryExercises: function jqueryExercises(req, res) { res.render('resources/jquery-exercises', { title: 'jQuery Exercises' diff --git a/views/resources/styleguide.jade b/views/resources/styleguide.jade new file mode 100644 index 00000000000..71303aa4b1c --- /dev/null +++ b/views/resources/styleguide.jade @@ -0,0 +1,26 @@ +extends ../layout +block content + .jumbotron.text-left + h1.hug-top.text-center Bonfire Style Guide + h3 Writing Bonfire challenges is a great way to exercise your own problem solving and testing abilities. It is a simple three step process. + h4 + ol + li Fill out the generator form and test your challenge:  + a(href="http://www.freecodecamp.com/bonfire-challenge-generator") http://www.freecodecamp.com/bonfire-challenge-generator + li Once you have confirmed a working bonfire challenge in the generator, copy and paste the the fields into the JSON generator: http://www.freecodecamp.com/bonfire-json-generator + li Copy the JSON, fork the freecodecamp repository, and submit a pull request with your addition to the bonfires.json:  + a(href="https://github.com/FreeCodeCamp/freecodecamp/blob/master/seed_data/bonfires.json") https://github.com/FreeCodeCamp/freecodecamp/blob/master/seed_data/bonfires.json + h3 Name + p Name your challenge + h3 Difficulty + p Attempt to rate difficulty compared against existing bonfire challenges. + h3 Description + p Separate paragraphs with a line break. Only the first paragraph is visible prior to a user clicking the "More information" button. + p All necessary information must be included in the first paragraph. Write this first paragraph as succinct as possible. Subsequent paragraphs should offer hints or details if needed. + p If your subject matter warrants deeper understanding, you may link to Wikipedia. + h3 Challenge Seed + p This is where you set up what will be in the editor when the camper starts the bonfire. + h3 Tests + p These tests are what bring your challenge to life. Without them, we cannot confirm the accuracy of a user's submitted answer. Choose your tests wisely. + p Bonfire tests are written using the Chai.js assertion library. Please use the should and expect syntax for end user readability. As an example of what not do to, many of the original Bonfire challenges are written with assert syntax and many of the test cases are difficult to read. + p If your bonfire question has a lot of edge cases, you will need to write many tests for full coverage. If you find yourself writing more tests than you desire, you may consider simplifying the requirements of your bonfire challenge. For difficulty level 1 through 3, you will generally only need 2 to 4 tests. \ No newline at end of file From f5d6abdfefdf91f3578cd1d26ed40dbe7100d7db Mon Sep 17 00:00:00 2001 From: jameskopacz Date: Mon, 30 Mar 2015 23:14:39 -0500 Subject: [PATCH 03/24] On story submission create unique story URL if slug already exists --- controllers/story.js | 75 +++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/controllers/story.js b/controllers/story.js index 82032ba7524..1ec16fc9d2a 100644 --- a/controllers/story.js +++ b/controllers/story.js @@ -119,13 +119,13 @@ exports.returnIndividualStory = function(req, res, next) { var storyName = dashedName.replace(/\-/g, ' '); - Story.find({'storyLink' : new RegExp(storyName, 'i')}, function(err, story) { + Story.findOne({'storyLink' : new RegExp(storyName, 'i')}, function(err, story) { if (err) { next(err); } - if (story.length < 1) { + if (story == null) { req.flash('errors', { msg: "404: We couldn't find a story with that name. Please double check the name." }); @@ -133,13 +133,12 @@ exports.returnIndividualStory = function(req, res, next) { return res.redirect('/stories/'); } - story = story.pop(); var dashedNameFull = story.storyLink.toLowerCase().replace(/\s/g, '-'); if (dashedNameFull !== dashedName) { return res.redirect('../stories/' + dashedNameFull); } - var userVoted = false; + var userVoted = false; try { var votedObj = story.upVotes.filter(function(a){ return a['upVotedByUsername'] === req.user['profile']['username']; @@ -150,7 +149,7 @@ exports.returnIndividualStory = function(req, res, next) { } catch(err){ userVoted = false; } - res.render('stories/index', { + res.render('stories/index', { title: story.headline, link: story.link, author: story.author, @@ -163,7 +162,7 @@ exports.returnIndividualStory = function(req, res, next) { image: story.image, page: 'show', storyMetaDescription: story.metaDescription, - hasUserVoted: userVoted + hasUserVoted: userVoted }); }); }; @@ -308,37 +307,47 @@ exports.storySubmission = function(req, res) { .replace(/[^a-z0-9]/gi, ' ') .replace(/\s+/g, ' ') .toLowerCase(); - var link = data.link; - if (link.search(/^https?:\/\//g) === -1) { - link = 'http://' + link; - } - var story = new Story({ - headline: sanitizeHtml(data.headline, { - allowedTags: [], - allowedAttributes: [] - }).replace(/"/g, '"'), - timePosted: Date.now(), - link: link, - description: sanitizeHtml(data.description, { - allowedTags: [], - allowedAttributes: [] - }).replace(/"/g, '"'), - rank: 1, - upVotes: data.upVotes, - author: data.author, - comments: [], - image: data.image, - storyLink: storyLink, - metaDescription: data.storyMetaDescription - }); - story.save(function(err) { + Story.count({'storyLink': storyLink}, function(err, storyCount) { if (err) { return res.status(500); } - res.send(JSON.stringify({ - storyLink: story.storyLink.replace(/\s/g, '-').toLowerCase() - })); + + // if duplicate storyLink add unique number + storyLink = (storyCount == 0) ? storyLink : storyLink + ' ' + storyCount; + + var link = data.link; + if (link.search(/^https?:\/\//g) === -1) { + link = 'http://' + link; + } + var story = new Story({ + headline: sanitizeHtml(data.headline, { + allowedTags: [], + allowedAttributes: [] + }).replace(/"/g, '"'), + timePosted: Date.now(), + link: link, + description: sanitizeHtml(data.description, { + allowedTags: [], + allowedAttributes: [] + }).replace(/"/g, '"'), + rank: 1, + upVotes: data.upVotes, + author: data.author, + comments: [], + image: data.image, + storyLink: storyLink, + metaDescription: data.storyMetaDescription + }); + + story.save(function(err) { + if (err) { + return res.status(500); + } + res.send(JSON.stringify({ + storyLink: story.storyLink.replace(/\s/g, '-').toLowerCase() + })); + }); }); }; From a24ad9b993efaed77ed4b63db90cf9a21b61b1cb Mon Sep 17 00:00:00 2001 From: Michael Q Larson Date: Tue, 31 Mar 2015 10:00:30 -0700 Subject: [PATCH 04/24] update the welcome mailer and change fontsize on bonfire helpful links --- config/passport.js | 2 +- views/bonfire/show.jade | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/passport.js b/config/passport.js index 970753ce211..1f2ebe8037f 100644 --- a/config/passport.js +++ b/config/passport.js @@ -114,7 +114,7 @@ passport.use(new FacebookStrategy(secrets.facebook, function(req, accessToken, r 'Feel free to email us at this address if you have any questions about Free Code Camp.\n', "And if you have a moment, check out our blog: blog.freecodecamp.com.\n", 'Good luck with the challenges!\n\n', - '- the Volunteer Camp Counselor Team' + '- Our All-Volunteer Team' ].join('') }; transporter.sendMail(mailOptions, function(err) { diff --git a/views/bonfire/show.jade b/views/bonfire/show.jade index aed449bdb53..6c9997d4b43 100644 --- a/views/bonfire/show.jade +++ b/views/bonfire/show.jade @@ -74,7 +74,7 @@ block content for sentence in details p!= sentence #MDN-links - h4 Here are some helpful links. + p Here are some helpful links: for link, index in MDNlinks ul: li: a(href=""+link, target="_blank") !{MDNkeys[index]} #less-info.btn.btn-primary.btn-block.btn-primary-ghost From a60c5eb92c9a57ea8b99e8580b785527b600b712 Mon Sep 17 00:00:00 2001 From: Michael Q Larson Date: Tue, 31 Mar 2015 15:07:34 -0700 Subject: [PATCH 05/24] refactor passport so that emails aren't fired if there are errors in save actions --- config/passport.js | 47 ++++++++++++++++++++++---------------------- controllers/story.js | 4 ++-- controllers/user.js | 46 +++++++++++++++++++++---------------------- 3 files changed, 49 insertions(+), 48 deletions(-) diff --git a/config/passport.js b/config/passport.js index 1f2ebe8037f..799ee1f83b1 100644 --- a/config/passport.js +++ b/config/passport.js @@ -82,6 +82,7 @@ passport.use(new FacebookStrategy(secrets.facebook, function(req, accessToken, r User.findOne({ facebook: profile.id }, function(err, existingUser) { if (existingUser) return done(null, existingUser); User.findOne({ email: profile._json.email }, function(err, existingEmailUser) { + if (err) { return done(err); } if (existingEmailUser) { req.flash('errors', { msg: 'There is already an account using this email address. Sign in to that account and link it with Facebook manually from Account Settings.' }); done(); @@ -96,29 +97,29 @@ passport.use(new FacebookStrategy(secrets.facebook, function(req, accessToken, r user.profile.location = (profile._json.location) ? profile._json.location.name : ''; user.save(function(err) { done(err, user); - }); - var transporter = nodemailer.createTransport({ - service: 'Mandrill', - auth: { - user: secrets.mandrill.user, - pass: secrets.mandrill.password - } - }); - var mailOptions = { - to: user.email, - from: 'Team@freecodecamp.com', - subject: 'Welcome to Free Code Camp!', - text: [ - 'Greetings from San Francisco!\n\n', - 'Thank you for joining our community.\n', - 'Feel free to email us at this address if you have any questions about Free Code Camp.\n', - "And if you have a moment, check out our blog: blog.freecodecamp.com.\n", - 'Good luck with the challenges!\n\n', - '- Our All-Volunteer Team' - ].join('') - }; - transporter.sendMail(mailOptions, function(err) { - if (err) { return err; } + var transporter = nodemailer.createTransport({ + service: 'Mandrill', + auth: { + user: secrets.mandrill.user, + pass: secrets.mandrill.password + } + }); + var mailOptions = { + to: user.email, + from: 'Team@freecodecamp.com', + subject: 'Welcome to Free Code Camp!', + text: [ + 'Greetings from San Francisco!\n\n', + 'Thank you for joining our community.\n', + 'Feel free to email us at this address if you have any questions about Free Code Camp.\n', + "And if you have a moment, check out our blog: blog.freecodecamp.com.\n", + 'Good luck with the challenges!\n\n', + '- Our All-Volunteer Team' + ].join('') + }; + transporter.sendMail(mailOptions, function(err) { + if (err) { return err; } + }); }); } }); diff --git a/controllers/story.js b/controllers/story.js index 1ec16fc9d2a..be62c54b4c3 100644 --- a/controllers/story.js +++ b/controllers/story.js @@ -142,7 +142,7 @@ exports.returnIndividualStory = function(req, res, next) { try { var votedObj = story.upVotes.filter(function(a){ return a['upVotedByUsername'] === req.user['profile']['username']; - }) + }); if (votedObj.length > 0){ userVoted = true; } @@ -314,7 +314,7 @@ exports.storySubmission = function(req, res) { } // if duplicate storyLink add unique number - storyLink = (storyCount == 0) ? storyLink : storyLink + ' ' + storyCount; + storyLink = (storyCount === 0) ? storyLink : storyLink + ' ' + storyCount; var link = data.link; if (link.search(/^https?:\/\//g) === -1) { diff --git a/controllers/user.js b/controllers/user.js index 20fda23b1a1..bd0a0cb326a 100644 --- a/controllers/user.js +++ b/controllers/user.js @@ -153,34 +153,34 @@ exports.postEmailSignup = function(req, res, next) { user.save(function(err) { if (err) { return next(err); } + var transporter = nodemailer.createTransport({ + service: 'Mandrill', + auth: { + user: secrets.mandrill.user, + pass: secrets.mandrill.password + } + }); + var mailOptions = { + to: user.email, + from: 'Team@freecodecamp.com', + subject: 'Welcome to Free Code Camp!', + text: [ + 'Greetings from San Francisco!\n\n', + 'Thank you for joining our community.\n', + 'Feel free to email us at this address if you have any questions about Free Code Camp.\n', + "And if you have a moment, check out our blog: blog.freecodecamp.com.\n", + 'Good luck with the challenges!\n\n', + '- Our All-Volunteer Team' + ].join('') + }; + transporter.sendMail(mailOptions, function(err) { + if (err) { return err; } + }); req.logIn(user, function(err) { if (err) { return next(err); } res.redirect('/email-signup'); }); }); - var transporter = nodemailer.createTransport({ - service: 'Mandrill', - auth: { - user: secrets.mandrill.user, - pass: secrets.mandrill.password - } - }); - var mailOptions = { - to: user.email, - from: 'Team@freecodecamp.com', - subject: 'Welcome to Free Code Camp!', - text: [ - 'Greetings from San Francisco!\n\n', - 'Thank you for joining our community.\n', - 'Feel free to email us at this address if you have any questions about Free Code Camp.\n', - "And if you have a moment, check out our blog: blog.freecodecamp.com.\n", - 'Good luck with the challenges!\n\n', - '- the Volunteer Camp Counselor Team' - ].join('') - }; - transporter.sendMail(mailOptions, function(err) { - if (err) { return err; } - }); }); }); }; From 29568d45b8d87fff8cc7533cb2304251872231bb Mon Sep 17 00:00:00 2001 From: Michael Q Larson Date: Fri, 3 Apr 2015 23:54:31 -0700 Subject: [PATCH 06/24] fix a typo related to challenge tweets --- views/challenges/show.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/challenges/show.jade b/views/challenges/show.jade index a0c81d2a7b6..a03b095640a 100644 --- a/views/challenges/show.jade +++ b/views/challenges/show.jade @@ -50,7 +50,7 @@ block content .success( function (data) { console.log(data); - url = "https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20Bonfire:%20#{name}&url=" + data + "&hashtags=LearnToCode, JavaScript"; + url = "https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20Challenge:%20#{name}&url=" + data + "&hashtags=LearnToCode, JavaScript"; $('.btn-twitter').attr('href', url); } ); \ No newline at end of file From 407bc99061a93ac9248a711655bb40ef5b42e779 Mon Sep 17 00:00:00 2001 From: Ashley Drake Date: Mon, 6 Apr 2015 09:54:49 -0400 Subject: [PATCH 07/24] Fixed chai-jquery tests for coursewares that were not catching correct entries for color attrs. --- seed_data/coursewares.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/seed_data/coursewares.json b/seed_data/coursewares.json index baf5986e280..72bf8f1b5d3 100644 --- a/seed_data/coursewares.json +++ b/seed_data/coursewares.json @@ -162,7 +162,7 @@ "Here's how you would set the h2 element's text color to blue: <h2 style=\"color: blue\">cat photo app<h2>" ], "tests": [ - "expect($('h2')).to.have.css('color', '#ff0000');" + "expect($('h2')).to.have.css('color', 'rgb(255, 0, 0)');" ], "challengeSeed": [ "

hello world

", @@ -186,7 +186,7 @@ "Note that it's important to have an opening and closing curly braces ({ and }) around each element's style. You also need to make sure your element's style is between the opening and closing style tags. Finally, be sure to add the semicolon to the end of each of the element's styles." ], "tests": [ - "expect($('h2')).to.have.css('color', '#0000ff');" + "expect($('h2')).to.have.css('color', 'rgb(0, 0, 255)');" ], "challengeSeed": [ "

hello world

", @@ -207,7 +207,7 @@ "You can follow that pattern to make a red-text class, which you can attach to HTML elements by using the class=\"class\" within the relevant element's opening tag." ], "tests": [ - "expect($('h2')).to.have.css('color', '#ff0000');", + "expect($('h2')).to.have.css('color', 'rgb(255, 0, 0)');", "expect($('h2')).to.have.class('red-text');" ], "challengeSeed": [ @@ -235,9 +235,9 @@ "expect($('h1')).to.have.class('red-text');", "expect($('h2')).to.have.class('red-text');", "expect($('p')).to.have.class('red-text');", - "expect($('h1')).to.have.css('color', '#ff0000');", - "expect($('h2')).to.have.css('color', '#ff0000');", - "expect($('p')).to.have.css('color', '#ff0000');" + "expect($('h1')).to.have.css('color', 'rgb(255, 0, 0)');", + "expect($('h2')).to.have.css('color', 'rgb(255, 0, 0)');", + "expect($('p')).to.have.css('color', 'rgb(255, 0, 0)');" ], "challengeSeed": [ "