Fix zipline/basejump completed endpoint
This PR refactors and normalizes the endpoint and the ajax request. Some weird bug keeps popping up on the server, but keymetrics has decided to take a crap and not actually report back with the error I don't know what exactly is causing it. Normally I don't like fixing something I can't see, but I'm getting a constant flood of emails because of some obscure bug here. We removed the `completedWith` functionality a while back so that was removed from this endpoint and the ajax call. To test, verify that you can complete both a zipline/basejump. Also show last updated date since it is possible a user might want to update links
This commit is contained in:
@ -74,14 +74,14 @@ window.common = (function(global) {
|
|||||||
$('#next-courseware-button').unbind('click');
|
$('#next-courseware-button').unbind('click');
|
||||||
if ($('.signup-btn-nav').length < 1) {
|
if ($('.signup-btn-nav').length < 1) {
|
||||||
var data;
|
var data;
|
||||||
var completedWith = $('#completed-with').val() || null;
|
var solution = $('#public-url').val() || null;
|
||||||
var publicURL = $('#public-url').val() || null;
|
var githubLink = $('#github-url').val() || null;
|
||||||
var githubURL = $('#github-url').val() || null;
|
|
||||||
switch (common.challengeType) {
|
switch (common.challengeType) {
|
||||||
case common.challengeTypes.VIDEO:
|
case common.challengeTypes.VIDEO:
|
||||||
data = {
|
data = {
|
||||||
id: common.challengeId,
|
id: common.challengeId,
|
||||||
name: common.challengeName
|
name: common.challengeName,
|
||||||
|
challengeType: common.challengeType
|
||||||
};
|
};
|
||||||
$.post('/completed-challenge/', data)
|
$.post('/completed-challenge/', data)
|
||||||
.success(function(res) {
|
.success(function(res) {
|
||||||
@ -99,15 +99,11 @@ window.common = (function(global) {
|
|||||||
case common.challengeTypes.BASEJUMP:
|
case common.challengeTypes.BASEJUMP:
|
||||||
case common.challengeTypes.ZIPLINE:
|
case common.challengeTypes.ZIPLINE:
|
||||||
data = {
|
data = {
|
||||||
challengeInfo: {
|
id: common.challengeId,
|
||||||
challengeId: common.challengeId,
|
name: common.challengeName,
|
||||||
challengeName: common.challengeName,
|
challengeType: +common.challengeType,
|
||||||
completedWith: completedWith,
|
solution,
|
||||||
publicURL: publicURL,
|
githubLink
|
||||||
githubURL: githubURL,
|
|
||||||
challengeType: common.challengeType,
|
|
||||||
verified: false
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$.post('/completed-zipline-or-basejump/', data)
|
$.post('/completed-zipline-or-basejump/', data)
|
||||||
|
@ -2,7 +2,6 @@ import _ from 'lodash';
|
|||||||
import dedent from 'dedent';
|
import dedent from 'dedent';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { Observable, Scheduler } from 'rx';
|
import { Observable, Scheduler } from 'rx';
|
||||||
import assign from 'object.assign';
|
|
||||||
import debugFactory from 'debug';
|
import debugFactory from 'debug';
|
||||||
import accepts from 'accepts';
|
import accepts from 'accepts';
|
||||||
|
|
||||||
@ -15,11 +14,7 @@ import {
|
|||||||
randomCompliment
|
randomCompliment
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
|
|
||||||
import {
|
import { saveUser, observeMethod } from '../utils/rx';
|
||||||
saveUser,
|
|
||||||
observeMethod,
|
|
||||||
observeQuery
|
|
||||||
} from '../utils/rx';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ifNoUserSend
|
ifNoUserSend
|
||||||
@ -384,7 +379,6 @@ module.exports = function(app) {
|
|||||||
.map(challenge => challenge.toJSON())
|
.map(challenge => challenge.toJSON())
|
||||||
.shareReplay();
|
.shareReplay();
|
||||||
|
|
||||||
const User = app.models.User;
|
|
||||||
const send200toNonUser = ifNoUserSend(true);
|
const send200toNonUser = ifNoUserSend(true);
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
@ -506,7 +500,7 @@ module.exports = function(app) {
|
|||||||
function completedChallenge(req, res, next) {
|
function completedChallenge(req, res, next) {
|
||||||
const type = accepts(req).type('html', 'json', 'text');
|
const type = accepts(req).type('html', 'json', 'text');
|
||||||
|
|
||||||
const completedDate = Math.round(+new Date());
|
const completedDate = Date.now();
|
||||||
const {
|
const {
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
@ -547,21 +541,46 @@ module.exports = function(app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function completedZiplineOrBasejump(req, res, next) {
|
function completedZiplineOrBasejump(req, res, next) {
|
||||||
|
const { body = {} } = req;
|
||||||
|
|
||||||
var completedWith = req.body.challengeInfo.completedWith || '';
|
let completedChallenge;
|
||||||
var completedDate = Math.round(+new Date());
|
// backwards compatibility
|
||||||
var challengeId = req.body.challengeInfo.challengeId;
|
// please remove once in production
|
||||||
var solutionLink = req.body.challengeInfo.publicURL;
|
// to allow users to transition to new client code
|
||||||
|
if (body.challengeInfo) {
|
||||||
|
|
||||||
var githubLink = req.body.challengeInfo.challengeType === '4' ?
|
if (!body.challengeInfo.challengeId) {
|
||||||
req.body.challengeInfo.githubURL :
|
req.flash('error', { msg: 'No id returned during save' });
|
||||||
true;
|
return res.sendStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
var challengeType = req.body.challengeInfo.challengeType === '4' ?
|
completedChallenge = {
|
||||||
4 :
|
id: body.challengeInfo.challengeId,
|
||||||
3;
|
name: body.challengeInfo.challengeName || '',
|
||||||
|
completedDate: Date.now(),
|
||||||
|
|
||||||
if (!solutionLink || !githubLink) {
|
challengeType: +body.challengeInfo.challengeType === 4 ? 4 : 3,
|
||||||
|
|
||||||
|
solution: body.challengeInfo.publicURL,
|
||||||
|
githubLink: body.challengeInfo.githubURL
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
completedChallenge = _.pick(
|
||||||
|
body,
|
||||||
|
[ 'id', 'name', 'solution', 'githubLink', 'challengeType' ]
|
||||||
|
);
|
||||||
|
completedChallenge.challengeType = +completedChallenge.challengeType;
|
||||||
|
completedChallenge.completedDate = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!completedChallenge.solution ||
|
||||||
|
// only basejumps require github links
|
||||||
|
(
|
||||||
|
completedChallenge.challengeType === 4 &&
|
||||||
|
!completedChallenge.githubLink
|
||||||
|
)
|
||||||
|
) {
|
||||||
req.flash('errors', {
|
req.flash('errors', {
|
||||||
msg: 'You haven\'t supplied the necessary URLs for us to inspect ' +
|
msg: 'You haven\'t supplied the necessary URLs for us to inspect ' +
|
||||||
'your work.'
|
'your work.'
|
||||||
@ -569,64 +588,12 @@ module.exports = function(app) {
|
|||||||
return res.sendStatus(403);
|
return res.sendStatus(403);
|
||||||
}
|
}
|
||||||
|
|
||||||
var challengeData = {
|
|
||||||
id: challengeId,
|
|
||||||
name: req.body.challengeInfo.challengeName || '',
|
|
||||||
completedDate: completedDate,
|
|
||||||
solution: solutionLink,
|
|
||||||
githubLink: githubLink,
|
|
||||||
challengeType: challengeType,
|
|
||||||
verified: false
|
|
||||||
};
|
|
||||||
|
|
||||||
observeQuery(
|
updateUserProgress(req.user, completedChallenge.id, completedChallenge);
|
||||||
User,
|
|
||||||
'findOne',
|
return saveUser(req.user)
|
||||||
{ where: { username: completedWith.toLowerCase() } }
|
.doOnNext(() => res.status(200).send(true))
|
||||||
)
|
.subscribe(() => {}, next);
|
||||||
.doOnNext(function(pairedWith) {
|
|
||||||
if (pairedWith) {
|
|
||||||
updateUserProgress(
|
|
||||||
pairedWith,
|
|
||||||
challengeId,
|
|
||||||
assign({ completedWith: req.user.id }, challengeData)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.withLatestFrom(Observable.just(req.user), function(pairedWith, user) {
|
|
||||||
return {
|
|
||||||
user: user,
|
|
||||||
pairedWith: pairedWith
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.doOnNext(function({ user, pairedWith }) {
|
|
||||||
updateUserProgress(
|
|
||||||
user,
|
|
||||||
challengeId,
|
|
||||||
pairedWith ?
|
|
||||||
assign({ completedWith: pairedWith.id }, challengeData) :
|
|
||||||
challengeData
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.flatMap(function({ user, pairedWith }) {
|
|
||||||
return Observable.from([user, pairedWith]);
|
|
||||||
})
|
|
||||||
// save users
|
|
||||||
.flatMap(function(user) {
|
|
||||||
// save user will do nothing if user is falsey
|
|
||||||
return saveUser(user);
|
|
||||||
})
|
|
||||||
.subscribe(
|
|
||||||
function(user) {
|
|
||||||
if (user) {
|
|
||||||
debug('user %s saved', user.username);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
next,
|
|
||||||
function() {
|
|
||||||
return res.status(200).send(true);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showMap(showAside, { user }, res, next) {
|
function showMap(showAside, { user }, res, next) {
|
||||||
|
@ -126,15 +126,17 @@ block content
|
|||||||
table.table.table-striped
|
table.table.table-striped
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th.col-xs-6 Projects
|
th.col-xs-5 Projects
|
||||||
th.col-xs-3.hidden-xs Completed
|
th.col-xs-2.hidden-xs Completed
|
||||||
th.col-xs-3.hidden-xs Link
|
th.col-xs-2.hidden-xs Last Updated
|
||||||
|
th.col-xs-2.hidden-xs Link
|
||||||
for challenge in projects
|
for challenge in projects
|
||||||
tr
|
tr
|
||||||
td.col-xs-4.hidden-xs
|
td.col-xs-5.hidden-xs
|
||||||
a(href='/challenges/' + removeOldTerms(challenge.name), target='_blank')= removeOldTerms(challenge.name)
|
a(href='/challenges/' + removeOldTerms(challenge.name), target='_blank')= removeOldTerms(challenge.name)
|
||||||
td.col-xs-2.hidden-xs= challenge.completedDate ? moment(challenge.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available'
|
td.col-xs-2.hidden-xs= challenge.completedDate ? moment(challenge.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available'
|
||||||
td.col-xs-6.hidden-xs
|
td.col-xs-2.hidden-xs= challenge.lastUpdated ? moment(challenge.lastUpdated, 'x').format("MMM DD, YYYY") : ''
|
||||||
|
td.col-xs-2.hidden-xs
|
||||||
a(href=challenge.solution, target='_blank') View my project
|
a(href=challenge.solution, target='_blank') View my project
|
||||||
td.col-xs-12.visible-xs
|
td.col-xs-12.visible-xs
|
||||||
a(href=challenge.solution, target='_blank')= removeOldTerms(challenge.name)
|
a(href=challenge.solution, target='_blank')= removeOldTerms(challenge.name)
|
||||||
|
Reference in New Issue
Block a user