Skip to content

Commit 759fa1a

Browse files
committed
Adds basic tests
1 parent 543224e commit 759fa1a

File tree

3 files changed

+213
-100
lines changed

3 files changed

+213
-100
lines changed
+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
const ParseServerRESTController = require('../src/ParseServerRESTController').ParseServerRESTController;
2+
const ParseServer = require('../src/ParseServer').default;
3+
let RESTController;
4+
5+
describe('ParseServerRESTController', () => {
6+
7+
beforeEach(() => {
8+
RESTController = ParseServerRESTController(Parse.applicationId, ParseServer.promiseRouter({appId: Parse.applicationId}));
9+
})
10+
11+
it('should handle a get request', (done) => {
12+
RESTController.request("GET", "/classes/MyObject").then((res) => {
13+
expect(res.results.length).toBe(0);
14+
done();
15+
}, (err) => {
16+
console.log(err);
17+
jfail(err);
18+
done();
19+
});
20+
});
21+
22+
it('should handle a get request with full serverURL mount path', (done) => {
23+
RESTController.request("GET", "/1/classes/MyObject").then((res) => {
24+
expect(res.results.length).toBe(0);
25+
done();
26+
}, (err) => {
27+
jfail(err);
28+
done();
29+
});
30+
});
31+
32+
it('should handle a POST batch', (done) => {
33+
RESTController.request("POST", "batch", {
34+
requests: [
35+
{
36+
method: 'GET',
37+
path: '/classes/MyObject'
38+
},
39+
{
40+
method: 'POST',
41+
path: '/classes/MyObject',
42+
body: {"key": "value"}
43+
},
44+
{
45+
method: 'GET',
46+
path: '/classes/MyObject'
47+
}
48+
]
49+
}).then((res) => {
50+
expect(res.length).toBe(3);
51+
done();
52+
}, (err) => {
53+
jfail(err);
54+
done();
55+
});
56+
});
57+
58+
it('should handle a POST request', (done) => {
59+
RESTController.request("POST", "/classes/MyObject", {"key": "value"}).then((res) => {
60+
return RESTController.request("GET", "/classes/MyObject");
61+
}).then((res) => {
62+
expect(res.results.length).toBe(1);
63+
expect(res.results[0].key).toEqual("value");
64+
done();
65+
}).fail((err) => {
66+
console.log(err);
67+
jfail(err);
68+
done();
69+
});
70+
});
71+
72+
it('ensures sessionTokens are properly handled', (done) => {
73+
let userId;
74+
Parse.User.signUp('user', 'pass').then((user) => {
75+
userId = user.id;
76+
let sessionToken = user.getSessionToken();
77+
return RESTController.request("GET", "/users/me", undefined, {sessionToken});
78+
}).then((res) => {
79+
// Result is in JSON format
80+
expect(res.objectId).toEqual(userId);
81+
done();
82+
}).fail((err) => {
83+
console.log(err);
84+
jfail(err);
85+
done();
86+
});
87+
});
88+
89+
it('ensures masterKey is properly handled', (done) => {
90+
let userId;
91+
Parse.User.signUp('user', 'pass').then((user) => {
92+
userId = user.id;
93+
let sessionToken = user.getSessionToken();
94+
return Parse.User.logOut().then(() => {
95+
console.log('Sending request');
96+
return RESTController.request("GET", "/classes/_User", undefined, {useMasterKey: true});
97+
});
98+
}).then((res) => {
99+
expect(res.results.length).toBe(1);
100+
expect(res.results[0].objectId).toEqual(userId);
101+
done();
102+
}, (err) => {
103+
jfail(err);
104+
done();
105+
});
106+
});
107+
});

src/ParseServer.js

+24-20
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,29 @@ class ParseServer {
275275
api.use(bodyParser.json({ 'type': '*/*' , limit: maxUploadSize }));
276276
api.use(middlewares.allowMethodOverride);
277277

278+
let appRouter = ParseServer.promiseRouter({ appId });
279+
api.use(appRouter.expressRouter());
280+
281+
api.use(middlewares.handleParseErrors);
282+
283+
//This causes tests to spew some useless warnings, so disable in test
284+
if (!process.env.TESTING) {
285+
process.on('uncaughtException', (err) => {
286+
if ( err.code === "EADDRINUSE" ) { // user-friendly message for this common error
287+
console.error(`Unable to listen on port ${err.port}. The port is already in use.`);
288+
process.exit(0);
289+
} else {
290+
throw err;
291+
}
292+
});
293+
}
294+
if (process.env.PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS === '1') {
295+
Parse.CoreManager.setRESTController(ParseServerRESTController(appId, appRouter));
296+
}
297+
return api;
298+
}
299+
300+
static promiseRouter({appId}) {
278301
let routers = [
279302
new ClassesRouter(),
280303
new UsersRouter(),
@@ -303,26 +326,7 @@ class ParseServer {
303326
appRouter.use(middlewares.handleParseHeaders);
304327

305328
batch.mountOnto(appRouter);
306-
307-
api.use(appRouter.expressRouter());
308-
309-
api.use(middlewares.handleParseErrors);
310-
311-
//This causes tests to spew some useless warnings, so disable in test
312-
if (!process.env.TESTING) {
313-
process.on('uncaughtException', (err) => {
314-
if ( err.code === "EADDRINUSE" ) { // user-friendly message for this common error
315-
console.error(`Unable to listen on port ${err.port}. The port is already in use.`);
316-
process.exit(0);
317-
} else {
318-
throw err;
319-
}
320-
});
321-
}
322-
if (process.env.PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS === '1') {
323-
Parse.CoreManager.setRESTController(ParseServerRESTController(appId, appRouter));
324-
}
325-
return api;
329+
return appRouter;
326330
}
327331

328332
static createLiveQueryServer(httpServer, config) {

src/ParseServerRESTController.js

+82-80
Original file line numberDiff line numberDiff line change
@@ -2,95 +2,97 @@ const Config = require('./Config');
22
const Auth = require('./Auth');
33
const RESTController = require('parse/lib/node/RESTController');
44
const URL = require('url');
5-
import { logger } from './logger';
5+
const Parse = require('parse/node');
66

7-
export function ParseServerRESTController(applicationId, router) {
7+
function getSessionToken(options) {
8+
if (options && typeof options.sessionToken === 'string') {
9+
return Parse.Promise.as(options.sessionToken);
10+
}
11+
return Parse.Promise.as(null);
12+
}
13+
14+
function getAuth(options, config) {
15+
if (options.useMasterKey) {
16+
return Parse.Promise.as(new Auth.Auth({config, isMaster: true }));
17+
}
18+
return getSessionToken(options).then((sessionToken) => {
19+
if (sessionToken) {
20+
options.sessionToken = sessionToken;
21+
return Auth.getAuthForSessionToken({
22+
config,
23+
sessionToken: sessionToken
24+
});
25+
} else {
26+
return Parse.Promise.as(new Auth.Auth({ config }));
27+
}
28+
})
29+
}
30+
31+
function ParseServerRESTController(applicationId, router) {
832
function handleRequest(method, path, data = {}, options = {}) {
9-
let args = arguments;
10-
if (path == 'batch') {
11-
let promises = data.requests.map((request) => {
12-
return handleRequest(request.method, request.path, request.body, options).then((response) => {
13-
return Parse.Promise.as({success: response});
14-
}, (error) => {
15-
return Parse.Promise.as({error: {code: error.code, error: error.message}});
16-
});
17-
});
18-
return Parse.Promise.all(promises);
19-
}
33+
// Store the arguments, for later use if internal fails
34+
let args = arguments;
35+
36+
let config = new Config(applicationId);
37+
let serverURL = URL.parse(config.serverURL);
38+
if (path.indexOf(serverURL.path) === 0) {
39+
path = path.slice(serverURL.path.length, path.length);
40+
}
2041

21-
let config = new Config(applicationId);
22-
let serverURL = URL.parse(config.serverURL);
23-
if (path.indexOf(serverURL.path) === 0) {
24-
path = path.slice(serverURL.path.length, path.length);
25-
}
42+
if (path[0] !== "/") {
43+
path = "/" + path;
44+
}
2645

27-
if (path[0] !== "/") {
28-
path = "/" + path;
29-
}
46+
if (path === '/batch') {
47+
let promises = data.requests.map((request) => {
48+
return handleRequest(request.method, request.path, request.body, options).then((response) => {
49+
return Parse.Promise.as({success: response});
50+
}, (error) => {
51+
return Parse.Promise.as({error: {code: error.code, error: error.message}});
52+
});
53+
});
54+
return Parse.Promise.all(promises);
55+
}
3056

31-
function getSessionToken(options) {
32-
if (options && typeof options.sessionToken === 'string') {
33-
return Parse.Promise.as(options.sessionToken);
34-
}
35-
return Parse.Promise.as(null);
36-
}
57+
let query;
58+
if (method === 'GET') {
59+
query = data;
60+
}
3761

38-
function getAuth(options, config) {
39-
if (options.useMasterKey) {
40-
return Parse.Promise.as(new Auth.Auth({config, isMaster: true }));
41-
}
42-
return getSessionToken(options).then((sessionToken) => {
43-
if (sessionToken) {
44-
options.sessionToken = sessionToken;
45-
return Auth.getAuthForSessionToken({
46-
config,
47-
sessionToken: sessionToken
48-
});
62+
return new Parse.Promise((resolve, reject) => {
63+
getAuth(options, config).then((auth) => {
64+
let request = {
65+
body: data,
66+
config,
67+
auth,
68+
info: {
69+
applicationId: applicationId,
70+
sessionToken: options.sessionToken
71+
},
72+
query
73+
};
74+
return Promise.resolve().then(() => {
75+
return router.tryRouteRequest(method, path, request);
76+
}).then((response) => {
77+
resolve(response.response, response.status, response);
78+
}, (err) => {
79+
if (err instanceof Parse.Error &&
80+
err.code == Parse.Error.INVALID_JSON &&
81+
err.message == `cannot route ${method} ${path}`) {
82+
RESTController.request.apply(null, args).then(resolve, reject);
4983
} else {
50-
return Parse.Promise.as(new Auth.Auth({ config }));
84+
reject(err);
5185
}
52-
})
53-
}
54-
55-
let query;
56-
if (method === 'GET') {
57-
query = data;
58-
}
59-
60-
return new Parse.Promise((resolve, reject) => {
61-
getAuth(options, config).then((auth) => {
62-
let request = {
63-
body: data,
64-
config,
65-
auth,
66-
info: {
67-
applicationId: applicationId,
68-
sessionToken: options.sessionToken
69-
},
70-
query
71-
};
72-
return Promise.resolve().then(() => {
73-
return router.tryRouteRequest(method, path, request);
74-
}).then((response) => {
75-
resolve(response.response, response.status, response);
76-
}, (err) => {
77-
if (err instanceof Parse.Error &&
78-
err.code == Parse.Error.INVALID_JSON &&
79-
err.message == `cannot route ${method} ${path}`) {
80-
RESTController.request.apply(null, args).then(resolve, reject);
81-
} else {
82-
reject(err);
83-
}
84-
});
85-
}, reject);
86-
});
87-
88-
};
86+
});
87+
}, reject);
88+
});
89+
};
8990

9091
return {
9192
request: handleRequest,
92-
ajax: function() {
93-
return RESTController.ajax.apply(null, arguments);
94-
}
93+
ajax: RESTController.ajax
9594
};
96-
};
95+
};
96+
97+
export default ParseServerRESTController;
98+
export { ParseServerRESTController };

0 commit comments

Comments
 (0)