fix(api): remove redirects from api
They should be handled either by nginx or by the client. Turned out a lot of code, including the path migration, existed to support them. Hence the large number of removals
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
4a45b5ac1c
commit
1ad5f756e0
2
api-server/.gitignore
vendored
2
api-server/.gitignore
vendored
@ -44,8 +44,6 @@ seed/unpacked
|
|||||||
server/rev-manifest.json
|
server/rev-manifest.json
|
||||||
server/manifests/*
|
server/manifests/*
|
||||||
!server/manifests/README.md
|
!server/manifests/README.md
|
||||||
server/resources/pathMigration.json
|
|
||||||
|
|
||||||
|
|
||||||
webpack-bundle-stats.html
|
webpack-bundle-stats.html
|
||||||
server/rev-manifest.json
|
server/rev-manifest.json
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
const { createPathMigrationMap } = require('../seed/createPathMigrationMap');
|
|
||||||
|
|
||||||
createPathMigrationMap().then(() => console.info('path migration map created'));
|
|
@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
import { Observable } from 'rx';
|
import { Observable } from 'rx';
|
||||||
import { isEmpty, pick, omit, find, uniqBy, last } from 'lodash';
|
import { isEmpty, pick, omit, find, uniqBy } from 'lodash';
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
import dedent from 'dedent';
|
import dedent from 'dedent';
|
||||||
import { ObjectID } from 'mongodb';
|
import { ObjectID } from 'mongodb';
|
||||||
@ -16,7 +16,6 @@ import { homeLocation } from '../../../config/env';
|
|||||||
|
|
||||||
import { ifNoUserSend } from '../utils/middleware';
|
import { ifNoUserSend } from '../utils/middleware';
|
||||||
import { dasherize } from '../../../utils/slugs';
|
import { dasherize } from '../../../utils/slugs';
|
||||||
import _pathMigrations from '../resources/pathMigration.json';
|
|
||||||
import { fixCompletedChallengeItem } from '../../common/utils';
|
import { fixCompletedChallengeItem } from '../../common/utils';
|
||||||
import { getChallenges } from '../utils/get-curriculum';
|
import { getChallenges } from '../utils/get-curriculum';
|
||||||
|
|
||||||
@ -26,7 +25,6 @@ export default async function bootChallenge(app, done) {
|
|||||||
const send200toNonUser = ifNoUserSend(true);
|
const send200toNonUser = ifNoUserSend(true);
|
||||||
const api = app.loopback.Router();
|
const api = app.loopback.Router();
|
||||||
const router = app.loopback.Router();
|
const router = app.loopback.Router();
|
||||||
const redirectToLearn = createRedirectToLearn(_pathMigrations);
|
|
||||||
const challengeUrlResolver = await createChallengeUrlResolver(
|
const challengeUrlResolver = await createChallengeUrlResolver(
|
||||||
await getChallenges()
|
await getChallenges()
|
||||||
);
|
);
|
||||||
@ -57,12 +55,6 @@ export default async function bootChallenge(app, done) {
|
|||||||
|
|
||||||
router.get('/challenges/current-challenge', redirectToCurrentChallenge);
|
router.get('/challenges/current-challenge', redirectToCurrentChallenge);
|
||||||
|
|
||||||
router.get('/challenges', redirectToLearn);
|
|
||||||
|
|
||||||
router.get('/challenges/*', redirectToLearn);
|
|
||||||
|
|
||||||
router.get('/map', redirectToLearn);
|
|
||||||
|
|
||||||
app.use(api);
|
app.use(api);
|
||||||
app.use(router);
|
app.use(router);
|
||||||
done();
|
done();
|
||||||
@ -357,18 +349,3 @@ export function createRedirectToCurrentChallenge(
|
|||||||
return res.redirect(`${_homeLocation}${challengeUrl}`);
|
return res.redirect(`${_homeLocation}${challengeUrl}`);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createRedirectToLearn(
|
|
||||||
pathMigrations,
|
|
||||||
base = homeLocation,
|
|
||||||
learn = learnURL
|
|
||||||
) {
|
|
||||||
return function redirectToLearn(req, res) {
|
|
||||||
const maybeChallenge = last(req.path.split('/'));
|
|
||||||
if (maybeChallenge in pathMigrations) {
|
|
||||||
const redirectPath = pathMigrations[maybeChallenge];
|
|
||||||
return res.status(302).redirect(`${base}${redirectPath}`);
|
|
||||||
}
|
|
||||||
return res.status(302).redirect(learn);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@ -9,8 +9,7 @@ import {
|
|||||||
createChallengeUrlResolver,
|
createChallengeUrlResolver,
|
||||||
createRedirectToCurrentChallenge,
|
createRedirectToCurrentChallenge,
|
||||||
getFirstChallenge,
|
getFirstChallenge,
|
||||||
isValidChallengeCompletion,
|
isValidChallengeCompletion
|
||||||
createRedirectToLearn
|
|
||||||
} from '../boot/challenge';
|
} from '../boot/challenge';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -21,8 +20,7 @@ import {
|
|||||||
mockUser,
|
mockUser,
|
||||||
mockGetFirstChallenge,
|
mockGetFirstChallenge,
|
||||||
mockCompletedChallenge,
|
mockCompletedChallenge,
|
||||||
mockCompletedChallenges,
|
mockCompletedChallenges
|
||||||
mockPathMigrationMap
|
|
||||||
} from './fixtures';
|
} from './fixtures';
|
||||||
|
|
||||||
describe('boot/challenge', () => {
|
describe('boot/challenge', () => {
|
||||||
@ -394,33 +392,4 @@ describe('boot/challenge', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('redirectToLearn', () => {
|
|
||||||
const mockHome = 'https://example.com';
|
|
||||||
const mockLearn = 'https://example.com/learn';
|
|
||||||
const redirectToLearn = createRedirectToLearn(
|
|
||||||
mockPathMigrationMap,
|
|
||||||
mockHome,
|
|
||||||
mockLearn
|
|
||||||
);
|
|
||||||
|
|
||||||
it('redirects to learn by default', () => {
|
|
||||||
const req = mockReq({ path: '/challenges' });
|
|
||||||
const res = mockRes();
|
|
||||||
|
|
||||||
redirectToLearn(req, res);
|
|
||||||
|
|
||||||
expect(res.redirect.calledWith(mockLearn)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('maps to the correct redirect if the path matches a challenge', () => {
|
|
||||||
const req = mockReq({ path: '/challenges/challenge-two' });
|
|
||||||
const res = mockRes();
|
|
||||||
const expectedRedirect =
|
|
||||||
'https://example.com/learn/superblock/block/challenge-two';
|
|
||||||
redirectToLearn(req, res);
|
|
||||||
|
|
||||||
expect(res.redirect.calledWith(expectedRedirect)).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -169,11 +169,6 @@ export const firstChallengeQuery = {
|
|||||||
where: { challengeOrder: 0, superOrder: 1, order: 0 }
|
where: { challengeOrder: 0, superOrder: 1, order: 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mockPathMigrationMap = {
|
|
||||||
'challenge-one': '/learn/superblock/block/challenge-one',
|
|
||||||
'challenge-two': '/learn/superblock/block/challenge-two'
|
|
||||||
};
|
|
||||||
|
|
||||||
export const fullStackChallenges = [
|
export const fullStackChallenges = [
|
||||||
{
|
{
|
||||||
completedDate: 1585210952511,
|
completedDate: 1585210952511,
|
||||||
|
@ -1 +0,0 @@
|
|||||||
# this file is here to add an empty dir to git
|
|
@ -2,41 +2,10 @@ const fs = require('fs');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const debug = require('debug');
|
const debug = require('debug');
|
||||||
|
|
||||||
const log = debug('fcc:tools:ensure-env');
|
|
||||||
|
|
||||||
const env = require('../../../config/env');
|
const env = require('../../../config/env');
|
||||||
const { getChallengesForLang } = require('../../../curriculum/getChallenges');
|
|
||||||
const { createPathMigrationMap } = require('../seed/createPathMigrationMap');
|
|
||||||
|
|
||||||
const apiPath = path.resolve(__dirname, '../../../api-server');
|
|
||||||
const clientPath = path.resolve(__dirname, '../../../client');
|
const clientPath = path.resolve(__dirname, '../../../client');
|
||||||
const globalConfigPath = path.resolve(__dirname, '../../../config');
|
const globalConfigPath = path.resolve(__dirname, '../../../config');
|
||||||
|
|
||||||
const { FREECODECAMP_NODE_ENV } = process.env;
|
|
||||||
const { locale } = env;
|
|
||||||
|
|
||||||
const migrationMapPath = `${apiPath}/server/resources/pathMigration.json`;
|
|
||||||
fs.access(migrationMapPath, err => {
|
|
||||||
if (err && FREECODECAMP_NODE_ENV !== 'production') {
|
|
||||||
log('creating pathMigration');
|
|
||||||
return fs.writeFileSync(migrationMapPath, '{}');
|
|
||||||
}
|
|
||||||
if (FREECODECAMP_NODE_ENV === 'production') {
|
|
||||||
return getChallengesForLang(locale)
|
|
||||||
.then(createPathMigrationMap)
|
|
||||||
.then(map => {
|
|
||||||
fs.writeFileSync(migrationMapPath, JSON.stringify(map));
|
|
||||||
log('pathMigration has been written');
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.error(err);
|
|
||||||
// eslint-disable-next-line
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
log('pathMigration present');
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.writeFileSync(`${clientPath}/config/env.json`, JSON.stringify(env));
|
fs.writeFileSync(`${clientPath}/config/env.json`, JSON.stringify(env));
|
||||||
fs.writeFileSync(`${globalConfigPath}/env.json`, JSON.stringify(env));
|
fs.writeFileSync(`${globalConfigPath}/env.json`, JSON.stringify(env));
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const debug = require('debug');
|
|
||||||
|
|
||||||
const { getChallengesForLang } = require('../../../curriculum/getChallenges');
|
|
||||||
const { createPathMigrationMap } = require('../seed/createPathMigrationMap');
|
|
||||||
|
|
||||||
const log = debug('fcc:tools:ensure-env');
|
|
||||||
|
|
||||||
log.enabled = true;
|
|
||||||
|
|
||||||
const apiPath = path.resolve(__dirname, '../../api-server');
|
|
||||||
|
|
||||||
const migrationMapPath = `${apiPath}/server/resources/pathMigration.json`;
|
|
||||||
|
|
||||||
// The migrationMap is to try and resolve pre-learn challenge urls to
|
|
||||||
// current challenge urls
|
|
||||||
// defaulting to english as there were no other languages available
|
|
||||||
// that would require this mapping
|
|
||||||
getChallengesForLang('english')
|
|
||||||
.then(createPathMigrationMap)
|
|
||||||
.then(map => {
|
|
||||||
fs.writeFileSync(migrationMapPath, JSON.stringify(map));
|
|
||||||
log('pathMigration has been written');
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.error(err);
|
|
||||||
// eslint-disable-next-line
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
@ -1,17 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`createPathMigrationMap output snapshot 1`] = `
|
|
||||||
Object {
|
|
||||||
"challenge-eight": "/learn/super-block-a/block-two/challenge-eight",
|
|
||||||
"challenge-eleven": "/learn/super-block-b/block-one/challenge-eleven",
|
|
||||||
"challenge-five": "/learn/super-block-a/block-two/challenge-five",
|
|
||||||
"challenge-four": "/learn/super-block-a/block-one/challenge-four",
|
|
||||||
"challenge-one": "/learn/super-block-a/block-one/challenge-one",
|
|
||||||
"challenge-seven": "/learn/super-block-a/block-two/challenge-seven",
|
|
||||||
"challenge-six": "/learn/super-block-a/block-two/challenge-six",
|
|
||||||
"challenge-ten": "/learn/super-block-b/block-one/challenge-ten",
|
|
||||||
"challenge-three": "/learn/super-block-a/block-one/challenge-three",
|
|
||||||
"challenge-twelve": "/learn/super-block-b/block-one/challenge-twelve",
|
|
||||||
"challenge-two": "/learn/super-block-a/block-one/challenge-two",
|
|
||||||
}
|
|
||||||
`;
|
|
@ -1,27 +0,0 @@
|
|||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
require('dotenv').config({ path: path.resolve(__dirname, '../../../.env') });
|
|
||||||
const debug = require('debug');
|
|
||||||
|
|
||||||
const { getChallengesForLang } = require('../../../curriculum/getChallenges');
|
|
||||||
const { createPathMigrationMap } = require('./createPathMigrationMap');
|
|
||||||
|
|
||||||
const log = debug('fcc:tools:seedChallenges');
|
|
||||||
const { LOCALE: lang = 'english' } = process.env;
|
|
||||||
|
|
||||||
getChallengesForLang(lang).then(curriculum => {
|
|
||||||
log('generating path migration map');
|
|
||||||
const pathMap = createPathMigrationMap(curriculum);
|
|
||||||
const outputDir = path.resolve(
|
|
||||||
__dirname,
|
|
||||||
'../../../api-server/server/resources/pathMigration.json'
|
|
||||||
);
|
|
||||||
fs.writeFile(outputDir, JSON.stringify(pathMap), err => {
|
|
||||||
if (err) {
|
|
||||||
console.error('failed to save pathMigration');
|
|
||||||
console.error(err);
|
|
||||||
} else {
|
|
||||||
log('path migration map generated');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
const { flatten } = require('lodash');
|
|
||||||
|
|
||||||
const { dasherize } = require('../../../utils/slugs');
|
|
||||||
|
|
||||||
function createPathMigrationMap(curriculum) {
|
|
||||||
return Object.keys(curriculum)
|
|
||||||
.map(key => curriculum[key].blocks)
|
|
||||||
.reduce((challenges, current) => {
|
|
||||||
const superChallenges = Object.keys(current).map(
|
|
||||||
key => current[key].challenges
|
|
||||||
);
|
|
||||||
return challenges.concat(flatten(superChallenges));
|
|
||||||
}, [])
|
|
||||||
.filter(({ isPrivate }) => !isPrivate)
|
|
||||||
.reduce((map, challenge) => {
|
|
||||||
const { title, block, superBlock } = challenge;
|
|
||||||
const dashedTitle = dasherize(title);
|
|
||||||
map[dashedTitle] = `/learn/${dasherize(superBlock)}/${dasherize(
|
|
||||||
block
|
|
||||||
)}/${dashedTitle}`;
|
|
||||||
return map;
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.createPathMigrationMap = createPathMigrationMap;
|
|
@ -1,36 +0,0 @@
|
|||||||
/* global describe expect */
|
|
||||||
const { isPlainObject } = require('lodash');
|
|
||||||
|
|
||||||
const { createPathMigrationMap } = require('./createPathMigrationMap');
|
|
||||||
const mockCurriculum = require('./__mocks__/curriculum.json');
|
|
||||||
|
|
||||||
describe('createPathMigrationMap', () => {
|
|
||||||
const pathMap = createPathMigrationMap(mockCurriculum);
|
|
||||||
|
|
||||||
it('is a function', () => {
|
|
||||||
expect(typeof createPathMigrationMap).toEqual('function');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns an object', () => {
|
|
||||||
expect(isPlainObject(pathMap)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('maps a challenge title to the correct uri slug', () => {
|
|
||||||
expect.assertions(3);
|
|
||||||
const slugOne = '/learn/super-block-b/block-one/challenge-ten';
|
|
||||||
const slugTwo = '/learn/super-block-a/block-two/challenge-five';
|
|
||||||
const slugThree = '/learn/super-block-a/block-one/challenge-three';
|
|
||||||
|
|
||||||
expect(pathMap['challenge-ten']).toEqual(slugOne);
|
|
||||||
expect(pathMap['challenge-five']).toEqual(slugTwo);
|
|
||||||
expect(pathMap['challenge-three']).toEqual(slugThree);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not add uri migrations for private challenges', () => {
|
|
||||||
expect(pathMap['challenge-nine']).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('output snapshot', () => {
|
|
||||||
expect(createPathMigrationMap(mockCurriculum)).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
});
|
|
Reference in New Issue
Block a user