Skip to content

Commit 1e218f4

Browse files
authored
Merge pull request #2320 from lindapaiste/refactor/getProjectsForUser
Cleanup `getProjectsForUser` function
2 parents b6b457c + 3008089 commit 1e218f4

File tree

2 files changed

+53
-80
lines changed

2 files changed

+53
-80
lines changed

server/controllers/project.controller/__test__/getProjectsForUser.test.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,18 @@ describe('project.controller', () => {
2323
});
2424

2525
describe('getProjectsForUser()', () => {
26-
it('returns empty array user not supplied as parameter', (done) => {
26+
it('returns validation error if username not provided', (done) => {
2727
const request = new Request();
2828
request.setParams({});
2929
const response = new Response();
3030

3131
const promise = getProjectsForUser(request, response);
3232

3333
function expectations() {
34-
expect(response.status).toHaveBeenCalledWith(200);
35-
expect(response.json).toHaveBeenCalledWith([]);
34+
expect(response.status).toHaveBeenCalledWith(422);
35+
expect(response.json).toHaveBeenCalledWith({
36+
message: 'Username not provided'
37+
});
3638

3739
done();
3840
}
@@ -47,7 +49,7 @@ describe('project.controller', () => {
4749

4850
UserMock.expects('findOne')
4951
.withArgs({ username: 'abc123' })
50-
.yields(null, null);
52+
.resolves(null);
5153

5254
const promise = getProjectsForUser(request, response);
5355

@@ -70,15 +72,15 @@ describe('project.controller', () => {
7072

7173
UserMock.expects('findOne')
7274
.withArgs({ username: 'abc123' })
73-
.yields(new Error(), null);
75+
.rejects(new Error());
7476

7577
const promise = getProjectsForUser(request, response);
7678

7779
function expectations() {
78-
expect(response.status).toHaveBeenCalledWith(500);
7980
expect(response.json).toHaveBeenCalledWith({
8081
message: 'Error fetching projects'
8182
});
83+
expect(response.status).toHaveBeenCalledWith(500);
8284

8385
done();
8486
}
@@ -88,7 +90,7 @@ describe('project.controller', () => {
8890
});
8991

9092
describe('apiGetProjectsForUser()', () => {
91-
it('returns validation error if user id not provided', (done) => {
93+
it('returns validation error if username not provided', (done) => {
9294
const request = new Request();
9395
request.setParams({});
9496
const response = new Response();
@@ -114,7 +116,7 @@ describe('project.controller', () => {
114116

115117
UserMock.expects('findOne')
116118
.withArgs({ username: 'abc123' })
117-
.yields(null, null);
119+
.resolves(null);
118120

119121
const promise = apiGetProjectsForUser(request, response);
120122

@@ -137,7 +139,7 @@ describe('project.controller', () => {
137139

138140
UserMock.expects('findOne')
139141
.withArgs({ username: 'abc123' })
140-
.yields(new Error(), null);
142+
.rejects(new Error());
141143

142144
const promise = apiGetProjectsForUser(request, response);
143145

Lines changed: 42 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,47 @@
11
import Project from '../../models/project';
22
import User from '../../models/user';
33
import { toApi as toApiProjectObject } from '../../domain-objects/Project';
4-
import createApplicationErrorClass from '../../utils/createApplicationErrorClass';
54

6-
const UserNotFoundError = createApplicationErrorClass('UserNotFoundError');
7-
8-
function getProjectsForUserName(username) {
9-
return new Promise((resolve, reject) => {
10-
User.findByUsername(username, (err, user) => {
11-
if (err) {
12-
reject(err);
13-
return;
14-
}
15-
16-
if (!user) {
17-
reject(new UserNotFoundError());
18-
return;
19-
}
20-
21-
Project.find({ user: user._id })
22-
.sort('-createdAt')
23-
.select('name files id createdAt updatedAt')
24-
.exec((innerErr, projects) => {
25-
if (innerErr) {
26-
reject(innerErr);
27-
return;
28-
}
29-
30-
resolve(projects);
31-
});
32-
});
33-
});
34-
}
35-
36-
export default function getProjectsForUser(req, res) {
37-
if (req.params.username) {
38-
return getProjectsForUserName(req.params.username)
39-
.then((projects) => res.json(projects))
40-
.catch((err) => {
41-
if (err instanceof UserNotFoundError) {
42-
res
43-
.status(404)
44-
.json({ message: 'User with that username does not exist.' });
45-
} else {
46-
res.status(500).json({ message: 'Error fetching projects' });
47-
}
48-
});
5+
/**
6+
* Fetches projects for the username in the request.
7+
* Handles errors.
8+
* Returns a success response based on the provided `mapProjectsToResponse` function.
9+
*/
10+
const createCoreHandler = (mapProjectsToResponse) => async (req, res) => {
11+
try {
12+
const { username } = req.params;
13+
if (!username) {
14+
res.status(422).json({ message: 'Username not provided' });
15+
return;
16+
}
17+
const user = await User.findByUsername(username);
18+
if (!user) {
19+
res
20+
.status(404)
21+
.json({ message: 'User with that username does not exist.' });
22+
return;
23+
}
24+
const projects = await Project.find({ user: user._id })
25+
.sort('-createdAt')
26+
.select('name files id createdAt updatedAt')
27+
.exec();
28+
const response = mapProjectsToResponse(projects);
29+
res.json(response);
30+
} catch (e) {
31+
res.status(500).json({ message: 'Error fetching projects' });
4932
}
50-
51-
// could just move this to client side
52-
res.status(200).json([]);
53-
return Promise.resolve();
54-
}
55-
56-
export function apiGetProjectsForUser(req, res) {
57-
if (req.params.username) {
58-
return getProjectsForUserName(req.params.username)
59-
.then((projects) => {
60-
const asApiObjects = projects.map((p) => toApiProjectObject(p));
61-
res.json({ sketches: asApiObjects });
62-
})
63-
.catch((err) => {
64-
if (err instanceof UserNotFoundError) {
65-
res
66-
.status(404)
67-
.json({ message: 'User with that username does not exist.' });
68-
} else {
69-
res.status(500).json({ message: 'Error fetching projects' });
70-
}
71-
});
72-
}
73-
74-
res.status(422).json({ message: 'Username not provided' });
75-
return Promise.resolve();
76-
}
33+
};
34+
35+
/**
36+
* Main handler returns an array of project objects.
37+
*/
38+
const getProjectsForUser = createCoreHandler((projects) => projects);
39+
export default getProjectsForUser;
40+
41+
/**
42+
* Handler for the public API returns an object with property `sketches`.
43+
* The array of sketches contains the `id` and `name` only.
44+
*/
45+
export const apiGetProjectsForUser = createCoreHandler((projects) => ({
46+
sketches: projects.map((p) => toApiProjectObject(p))
47+
}));

0 commit comments

Comments
 (0)