Skip to content

Commit fbb5e44

Browse files
committed
refactors LoggerController with LogsRouter
1 parent 305879a commit fbb5e44

File tree

6 files changed

+234
-73
lines changed

6 files changed

+234
-73
lines changed

spec/LoggerController.spec.js

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,85 @@ var LoggerController = require('../src/Controllers/LoggerController').LoggerCont
22
var FileLoggerAdapter = require('../src/Adapters/Logger/FileLoggerAdapter').FileLoggerAdapter;
33

44
describe('LoggerController', () => {
5-
it('can check valid master key of request', (done) => {
5+
it('can check process a query witout throwing', (done) => {
66
// Make mock request
7-
var request = {
8-
auth: {
9-
isMaster: true
10-
},
11-
query: {}
12-
};
7+
var query = {};
138

149
var loggerController = new LoggerController(new FileLoggerAdapter());
1510

1611
expect(() => {
17-
loggerController.handleGET(request);
12+
loggerController.getLogs(query).then(function(res) {
13+
expect(res.length).toBe(0);
14+
done();
15+
})
1816
}).not.toThrow();
17+
});
18+
19+
it('properly validates dateTimes', (done) => {
20+
expect(LoggerController.validDateTime()).toBe(null);
21+
expect(LoggerController.validDateTime("String")).toBe(null);
22+
expect(LoggerController.validDateTime(123456).getTime()).toBe(123456);
23+
expect(LoggerController.validDateTime("2016-01-01Z00:00:00").getTime()).toBe(1451606400000);
1924
done();
2025
});
21-
22-
it('can check invalid construction of controller', (done) => {
26+
27+
it('can set the proper default values', (done) => {
28+
// Make mock request
29+
var result = LoggerController.parseOptions();
30+
expect(result.size).toEqual(10);
31+
expect(result.order).toEqual('desc');
32+
expect(result.level).toEqual('info');
33+
34+
done();
35+
});
36+
37+
it('can process a query witout throwing', (done) => {
2338
// Make mock request
24-
var request = {
25-
auth: {
26-
isMaster: true
27-
},
28-
query: {}
39+
var query = {
40+
from: "2016-01-01Z00:00:00",
41+
until: "2016-01-01Z00:00:00",
42+
size: 5,
43+
order: 'asc',
44+
level: 'error'
2945
};
3046

31-
var loggerController = new LoggerController();
47+
var result = LoggerController.parseOptions(query);
3248

33-
expect(() => {
34-
loggerController.handleGET(request);
35-
}).toThrow();
49+
expect(result.from.getTime()).toEqual(1451606400000);
50+
expect(result.until.getTime()).toEqual(1451606400000);
51+
expect(result.size).toEqual(5);
52+
expect(result.order).toEqual('asc');
53+
expect(result.level).toEqual('error');
54+
3655
done();
3756
});
38-
39-
it('can check invalid master key of request', (done) => {
57+
58+
it('can check process a query witout throwing', (done) => {
4059
// Make mock request
41-
var request = {
42-
auth: {
43-
isMaster: false
44-
},
45-
query: {}
60+
var query = {
61+
from: "2015-01-01",
62+
until: "2016-01-01",
63+
size: 5,
64+
order: 'desc',
65+
level: 'error'
4666
};
4767

4868
var loggerController = new LoggerController(new FileLoggerAdapter());
4969

5070
expect(() => {
51-
loggerController.handleGET(request);
71+
loggerController.getLogs(query).then(function(res) {
72+
expect(res.length).toBe(0);
73+
done();
74+
})
75+
}).not.toThrow();
76+
});
77+
78+
it('should throw without an adapter', (done) => {
79+
80+
var loggerController = new LoggerController();
81+
82+
expect(() => {
83+
loggerController.getLogs();
5284
}).toThrow();
5385
done();
5486
});

spec/LogsRouter.spec.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
var LogsRouter = require('../src/Routers/LogsRouter').LogsRouter;
2+
var LoggerController = require('../src/Controllers/LoggerController').LoggerController;
3+
var FileLoggerAdapter = require('../src/Adapters/Logger/FileLoggerAdapter').FileLoggerAdapter;
4+
5+
const loggerController = new LoggerController(new FileLoggerAdapter());
6+
7+
describe('LogsRouter', () => {
8+
it('can check valid master key of request', (done) => {
9+
// Make mock request
10+
var request = {
11+
auth: {
12+
isMaster: true
13+
},
14+
query: {},
15+
config: {
16+
loggerController: loggerController
17+
}
18+
};
19+
20+
var router = new LogsRouter();
21+
22+
expect(() => {
23+
router.handleGET(request);
24+
}).not.toThrow();
25+
done();
26+
});
27+
28+
it('can check invalid construction of controller', (done) => {
29+
// Make mock request
30+
var request = {
31+
auth: {
32+
isMaster: true
33+
},
34+
query: {},
35+
config: {
36+
loggerController: undefined // missing controller
37+
}
38+
};
39+
40+
var router = new LogsRouter();
41+
42+
expect(() => {
43+
router.handleGET(request);
44+
}).toThrow();
45+
done();
46+
});
47+
48+
it('can check invalid master key of request', (done) => {
49+
// Make mock request
50+
var request = {
51+
auth: {
52+
isMaster: false
53+
},
54+
query: {},
55+
config: {
56+
loggerController: loggerController
57+
}
58+
};
59+
60+
var router = new LogsRouter();
61+
62+
expect(() => {
63+
router.handleGET(request);
64+
}).toThrow();
65+
done();
66+
});
67+
});

src/Config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export class Config {
2727
this.database = DatabaseAdapter.getDatabaseConnection(applicationId);
2828
this.filesController = cacheInfo.filesController;
2929
this.pushController = cacheInfo.pushController;
30+
this.loggerController = cacheInfo.loggerController;
3031
this.oauth = cacheInfo.oauth;
3132

3233
this.mount = mount;

src/Controllers/LoggerController.js

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,55 @@
11
import { Parse } from 'parse/node';
22
import PromiseRouter from '../PromiseRouter';
3-
import rest from '../rest';
43

54
const Promise = Parse.Promise;
6-
const INFO = 'info';
7-
const ERROR = 'error';
85
const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000;
96

10-
// only allow request with master key
11-
let enforceSecurity = (auth) => {
12-
if (!auth || !auth.isMaster) {
13-
throw new Parse.Error(
14-
Parse.Error.OPERATION_FORBIDDEN,
15-
'Clients aren\'t allowed to perform the ' +
16-
'get' + ' operation on logs.'
17-
);
18-
}
7+
export const LogLevel = {
8+
INFO: 'info',
9+
ERROR: 'error'
1910
}
2011

21-
// check that date input is valid
22-
let isValidDateTime = (date) => {
23-
if (!date || isNaN(Number(date))) {
24-
return false;
25-
}
12+
export const LogOrder = {
13+
DESCENDING: 'desc',
14+
ASCENDING: 'asc'
2615
}
2716

2817
export class LoggerController {
29-
30-
constructor(loggerAdapter) {
18+
19+
constructor(loggerAdapter, loggerOptions) {
3120
this._loggerAdapter = loggerAdapter;
3221
}
22+
23+
// check that date input is valid
24+
static validDateTime(date) {
25+
if (!date) {
26+
return null;
27+
}
28+
date = new Date(date);
29+
30+
if (!isNaN(date.getTime())) {
31+
return date;
32+
}
33+
34+
return null;
35+
}
36+
37+
static parseOptions(options = {}) {
38+
let from = LoggerController.validDateTime(options.from) ||
39+
new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY);
40+
let until = LoggerController.validDateTime(options.until) || new Date();
41+
let size = Number(options.size) || 10;
42+
let order = options.order || LogOrder.DESCENDING;
43+
let level = options.level || LogLevel.INFO;
44+
45+
return {
46+
from,
47+
until,
48+
size,
49+
order,
50+
level,
51+
};
52+
}
3353

3454
// Returns a promise for a {response} object.
3555
// query params:
@@ -38,41 +58,21 @@ export class LoggerController {
3858
// until (optional) End time for the search. Defaults to current time.
3959
// order (optional) Direction of results returned, either “asc” or “desc”. Defaults to “desc”.
4060
// size (optional) Number of rows returned by search. Defaults to 10
41-
handleGET(req) {
61+
getLogs(options= {}) {
4262
if (!this._loggerAdapter) {
4363
throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED,
4464
'Logger adapter is not availabe');
4565
}
4666

4767
let promise = new Parse.Promise();
48-
let from = (isValidDateTime(req.query.from) && new Date(req.query.from)) ||
49-
new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY);
50-
let until = (isValidDateTime(req.query.until) && new Date(req.query.until)) || new Date();
51-
let size = Number(req.query.size) || 10;
52-
let order = req.query.order || 'desc';
53-
let level = req.query.level || INFO;
54-
enforceSecurity(req.auth);
55-
this._loggerAdapter.query({
56-
from,
57-
until,
58-
size,
59-
order,
60-
level,
61-
}, (result) => {
62-
promise.resolve({
63-
response: result
64-
});
68+
69+
options = LoggerController.parseOptions(options);
70+
71+
this._loggerAdapter.query(options, (result) => {
72+
promise.resolve(result);
6573
});
6674
return promise;
6775
}
68-
69-
getExpressRouter() {
70-
let router = new PromiseRouter();
71-
router.route('GET','/logs', (req) => {
72-
return this.handleGET(req);
73-
});
74-
return router;
75-
}
7676
}
7777

7878
export default LoggerController;

src/Routers/LogsRouter.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { Parse } from 'parse/node';
2+
import PromiseRouter from '../PromiseRouter';
3+
4+
// only allow request with master key
5+
let enforceSecurity = (auth) => {
6+
if (!auth || !auth.isMaster) {
7+
throw new Parse.Error(
8+
Parse.Error.OPERATION_FORBIDDEN,
9+
'Clients aren\'t allowed to perform the ' +
10+
'get' + ' operation on logs.'
11+
);
12+
}
13+
}
14+
15+
export class LogsRouter extends PromiseRouter {
16+
17+
mountRoutes() {
18+
this.route('GET','/logs', (req) => {
19+
return this.handleGET(req);
20+
});
21+
}
22+
23+
// Returns a promise for a {response} object.
24+
// query params:
25+
// level (optional) Level of logging you want to query for (info || error)
26+
// from (optional) Start time for the search. Defaults to 1 week ago.
27+
// until (optional) End time for the search. Defaults to current time.
28+
// order (optional) Direction of results returned, either “asc” or “desc”. Defaults to “desc”.
29+
// size (optional) Number of rows returned by search. Defaults to 10
30+
handleGET(req) {
31+
if (!req.config || !req.config.loggerController) {
32+
throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED,
33+
'Logger adapter is not availabe');
34+
}
35+
36+
let promise = new Parse.Promise();
37+
let from = req.query.from;
38+
let until = req.query.until;
39+
let size = req.query.size;
40+
let order = req.query.order
41+
let level = req.query.level;
42+
enforceSecurity(req.auth);
43+
44+
const options = {
45+
from,
46+
until,
47+
size,
48+
order,
49+
level,
50+
}
51+
52+
return req.config.loggerController.getLogs(options).then((result) => {
53+
return Promise.resolve({
54+
response: result
55+
});
56+
})
57+
}
58+
}
59+
60+
export default LogsRouter;

src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { SchemasRouter } from './Routers/SchemasRouter';
3030
import { IAPValidationRouter } from './Routers/IAPValidationRouter';
3131
import { PushRouter } from './Routers/PushRouter';
3232
import { FilesRouter } from './Routers/FilesRouter';
33+
import { LogsRouter } from './Routers/LogsRouter';
3334

3435
import { FileLoggerAdapter } from './Adapters/Logger/FileLoggerAdapter';
3536
import { LoggerController } from './Controllers/LoggerController';
@@ -168,7 +169,7 @@ function ParseServer({
168169
new FunctionsRouter(),
169170
new SchemasRouter(),
170171
new PushRouter(),
171-
new LoggerController(loggerAdapter).getExpressRouter(),
172+
new LogsRouter(),
172173
new IAPValidationRouter()
173174
];
174175

0 commit comments

Comments
 (0)