diff --git a/server/controllers/project.controller/__test__/getProjectsForUser.test.js b/server/controllers/project.controller/__test__/getProjectsForUser.test.js index 121a2184fd..0160cb1477 100644 --- a/server/controllers/project.controller/__test__/getProjectsForUser.test.js +++ b/server/controllers/project.controller/__test__/getProjectsForUser.test.js @@ -23,7 +23,7 @@ describe('project.controller', () => { }); describe('getProjectsForUser()', () => { - it('returns empty array user not supplied as parameter', (done) => { + it('returns validation error if username not provided', (done) => { const request = new Request(); request.setParams({}); const response = new Response(); @@ -31,8 +31,10 @@ describe('project.controller', () => { const promise = getProjectsForUser(request, response); function expectations() { - expect(response.status).toHaveBeenCalledWith(200); - expect(response.json).toHaveBeenCalledWith([]); + expect(response.status).toHaveBeenCalledWith(422); + expect(response.json).toHaveBeenCalledWith({ + message: 'Username not provided' + }); done(); } @@ -47,7 +49,7 @@ describe('project.controller', () => { UserMock.expects('findOne') .withArgs({ username: 'abc123' }) - .yields(null, null); + .resolves(null); const promise = getProjectsForUser(request, response); @@ -70,15 +72,15 @@ describe('project.controller', () => { UserMock.expects('findOne') .withArgs({ username: 'abc123' }) - .yields(new Error(), null); + .rejects(new Error()); const promise = getProjectsForUser(request, response); function expectations() { - expect(response.status).toHaveBeenCalledWith(500); expect(response.json).toHaveBeenCalledWith({ message: 'Error fetching projects' }); + expect(response.status).toHaveBeenCalledWith(500); done(); } @@ -88,7 +90,7 @@ describe('project.controller', () => { }); describe('apiGetProjectsForUser()', () => { - it('returns validation error if user id not provided', (done) => { + it('returns validation error if username not provided', (done) => { const request = new Request(); request.setParams({}); const response = new Response(); @@ -114,7 +116,7 @@ describe('project.controller', () => { UserMock.expects('findOne') .withArgs({ username: 'abc123' }) - .yields(null, null); + .resolves(null); const promise = apiGetProjectsForUser(request, response); @@ -137,7 +139,7 @@ describe('project.controller', () => { UserMock.expects('findOne') .withArgs({ username: 'abc123' }) - .yields(new Error(), null); + .rejects(new Error()); const promise = apiGetProjectsForUser(request, response); diff --git a/server/controllers/project.controller/getProjectsForUser.js b/server/controllers/project.controller/getProjectsForUser.js index 5579559915..a811ecd55c 100644 --- a/server/controllers/project.controller/getProjectsForUser.js +++ b/server/controllers/project.controller/getProjectsForUser.js @@ -1,76 +1,47 @@ import Project from '../../models/project'; import User from '../../models/user'; import { toApi as toApiProjectObject } from '../../domain-objects/Project'; -import createApplicationErrorClass from '../../utils/createApplicationErrorClass'; -const UserNotFoundError = createApplicationErrorClass('UserNotFoundError'); - -function getProjectsForUserName(username) { - return new Promise((resolve, reject) => { - User.findByUsername(username, (err, user) => { - if (err) { - reject(err); - return; - } - - if (!user) { - reject(new UserNotFoundError()); - return; - } - - Project.find({ user: user._id }) - .sort('-createdAt') - .select('name files id createdAt updatedAt') - .exec((innerErr, projects) => { - if (innerErr) { - reject(innerErr); - return; - } - - resolve(projects); - }); - }); - }); -} - -export default function getProjectsForUser(req, res) { - if (req.params.username) { - return getProjectsForUserName(req.params.username) - .then((projects) => res.json(projects)) - .catch((err) => { - if (err instanceof UserNotFoundError) { - res - .status(404) - .json({ message: 'User with that username does not exist.' }); - } else { - res.status(500).json({ message: 'Error fetching projects' }); - } - }); +/** + * Fetches projects for the username in the request. + * Handles errors. + * Returns a success response based on the provided `mapProjectsToResponse` function. + */ +const createCoreHandler = (mapProjectsToResponse) => async (req, res) => { + try { + const { username } = req.params; + if (!username) { + res.status(422).json({ message: 'Username not provided' }); + return; + } + const user = await User.findByUsername(username); + if (!user) { + res + .status(404) + .json({ message: 'User with that username does not exist.' }); + return; + } + const projects = await Project.find({ user: user._id }) + .sort('-createdAt') + .select('name files id createdAt updatedAt') + .exec(); + const response = mapProjectsToResponse(projects); + res.json(response); + } catch (e) { + res.status(500).json({ message: 'Error fetching projects' }); } - - // could just move this to client side - res.status(200).json([]); - return Promise.resolve(); -} - -export function apiGetProjectsForUser(req, res) { - if (req.params.username) { - return getProjectsForUserName(req.params.username) - .then((projects) => { - const asApiObjects = projects.map((p) => toApiProjectObject(p)); - res.json({ sketches: asApiObjects }); - }) - .catch((err) => { - if (err instanceof UserNotFoundError) { - res - .status(404) - .json({ message: 'User with that username does not exist.' }); - } else { - res.status(500).json({ message: 'Error fetching projects' }); - } - }); - } - - res.status(422).json({ message: 'Username not provided' }); - return Promise.resolve(); -} +}; + +/** + * Main handler returns an array of project objects. + */ +const getProjectsForUser = createCoreHandler((projects) => projects); +export default getProjectsForUser; + +/** + * Handler for the public API returns an object with property `sketches`. + * The array of sketches contains the `id` and `name` only. + */ +export const apiGetProjectsForUser = createCoreHandler((projects) => ({ + sketches: projects.map((p) => toApiProjectObject(p)) +}));