Skip to content

Commit b477a8e

Browse files
authored
Merge pull request #391 from gets0ul/filter_org_configs
Filter orgConfigs
2 parents 39bdf46 + 038b0a0 commit b477a8e

File tree

2 files changed

+164
-26
lines changed

2 files changed

+164
-26
lines changed

src/routes/orgConfig/list.js

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44
import validate from 'express-validation';
55
import Joi from 'joi';
6+
import _ from 'lodash';
67
import { middleware as tcMiddleware } from 'tc-core-library-js';
78
import models from '../../models';
89
import util from '../../util';
@@ -20,24 +21,51 @@ module.exports = [
2021
validate(schema),
2122
permissions('orgConfig.view'),
2223
(req, res, next) => {
23-
util.fetchFromES('orgConfigs')
24-
.then((data) => {
25-
// handle filters
26-
const filters = req.query;
27-
// Throw error if orgId is not present in filter
28-
if (!filters.orgId) {
29-
next(util.buildApiError('Missing filter orgId', 400));
30-
}
31-
if (!util.isValidFilter(filters, ['orgId', 'configName'])) {
32-
util.handleError('Invalid filters', null, req, next);
33-
}
34-
req.log.debug(filters);
24+
// handle filters
25+
const filters = req.query;
26+
// Throw error if orgId is not present in filter
27+
if (!filters.orgId) {
28+
next(util.buildApiError('Missing filter orgId', 400));
29+
}
30+
if (!util.isValidFilter(filters, ['orgId', 'configName'])) {
31+
util.handleError('Invalid filters', null, req, next);
32+
}
33+
req.log.debug(filters);
34+
const orgIds = filters.orgId.split(',');
3535

36+
// build filter query for ES
37+
const must = [{
38+
terms: {
39+
'orgConfigs.orgId': orgIds,
40+
},
41+
}];
42+
if (filters.configName) {
43+
must.push({
44+
term: {
45+
'orgConfigs.configName': filters.configName,
46+
},
47+
});
48+
}
49+
50+
util.fetchFromES('orgConfigs', {
51+
query: {
52+
nested: {
53+
path: 'orgConfigs',
54+
query: {
55+
bool: {
56+
must,
57+
},
58+
},
59+
inner_hits: {},
60+
},
61+
},
62+
}, 'metadata')
63+
.then((data) => {
3664
if (data.orgConfigs.length === 0) {
3765
req.log.debug('No orgConfig found in ES');
3866

3967
// Get all organization config
40-
const where = filters || {};
68+
const where = filters ? _.assign({}, filters, { orgId: { $in: orgIds } }) : {};
4169
models.OrgConfig.findAll({
4270
where,
4371
attributes: { exclude: ['deletedAt', 'deletedBy'] },
@@ -49,7 +77,7 @@ module.exports = [
4977
.catch(next);
5078
} else {
5179
req.log.debug('orgConfigs found in ES');
52-
res.json(data.orgConfigs);
80+
res.json(data.orgConfigs.hits.hits.map(hit => hit._source)); // eslint-disable-line no-underscore-dangle
5381
}
5482
});
5583
},

src/routes/orgConfig/list.spec.js

Lines changed: 122 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,30 @@
33
*/
44
import chai from 'chai';
55
import request from 'supertest';
6+
import config from 'config';
7+
import _ from 'lodash';
68

79
import models from '../../models';
810
import server from '../../app';
911
import testUtil from '../../tests/util';
1012

1113
const should = chai.should();
1214

15+
const ES_ORGCONFIG_INDEX = config.get('elasticsearchConfig.metadataIndexName');
16+
const ES_ORGCONFIG_TYPE = config.get('elasticsearchConfig.metadataDocType');
17+
18+
const validateOrgConfig = (resJson, orgConfig) => {
19+
resJson.id.should.be.eql(orgConfig.id);
20+
resJson.orgId.should.be.eql(orgConfig.orgId);
21+
resJson.configName.should.be.eql(orgConfig.configName);
22+
resJson.configValue.should.be.eql(orgConfig.configValue);
23+
should.exist(resJson.createdAt);
24+
resJson.updatedBy.should.be.eql(orgConfig.updatedBy);
25+
should.exist(resJson.updatedAt);
26+
should.not.exist(resJson.deletedBy);
27+
should.not.exist(resJson.deletedAt);
28+
};
29+
1330
describe('LIST organization config', () => {
1431
const orgConfigPath = '/v5/projects/metadata/orgConfig';
1532
const configs = [
@@ -23,17 +40,50 @@ describe('LIST organization config', () => {
2340
},
2441
{
2542
id: 2,
26-
orgId: 'ORG1',
43+
orgId: 'ORG2',
2744
configName: 'project_catalog_url',
2845
configValue: '/projects/2',
2946
createdBy: 1,
3047
updatedBy: 1,
3148
},
49+
{
50+
id: 3,
51+
orgId: 'ORG3',
52+
configName: 'project_catalog_url',
53+
configValue: '/projects/3',
54+
createdBy: 1,
55+
updatedBy: 1,
56+
},
57+
{
58+
id: 4,
59+
orgId: 'ORG4',
60+
configName: 'project_catalog_url',
61+
configValue: '/projects/4',
62+
createdBy: 1,
63+
updatedBy: 1,
64+
},
3265
];
3366

3467
beforeEach((done) => {
3568
testUtil.clearDb()
36-
.then(() => models.OrgConfig.bulkCreate(configs).then(() => done()));
69+
.then(() => models.OrgConfig.bulkCreate(configs, { returning: true }),
70+
).then(async (createdConfigs) => {
71+
// Index to ES only orgConfigs with id: 3 and 4
72+
const indexedConfigs = _(createdConfigs).filter(createdConfig => createdConfig.toJSON().id > 2)
73+
.map((filteredConfig) => {
74+
const orgConfigJson = _.omit(filteredConfig.toJSON(), 'deletedAt', 'deletedBy');
75+
return orgConfigJson;
76+
}).value();
77+
78+
await server.services.es.index({
79+
index: ES_ORGCONFIG_INDEX,
80+
type: ES_ORGCONFIG_TYPE,
81+
body: {
82+
orgConfigs: indexedConfigs,
83+
},
84+
});
85+
done();
86+
});
3787
});
3888
after((done) => {
3989
testUtil.clearDb(done);
@@ -48,19 +98,79 @@ describe('LIST organization config', () => {
4898
})
4999
.expect(200)
50100
.end((err, res) => {
51-
const config = configs[0];
101+
const config1 = configs[0];
102+
103+
const resJson = res.body;
104+
resJson.should.have.length(1);
105+
validateOrgConfig(resJson[0], config1);
106+
107+
done();
108+
});
109+
});
110+
111+
it('should return 200 for admin with filter (ES)', (done) => {
112+
request(server)
113+
.get(`${orgConfigPath}?orgId=${configs[2].orgId}&configName=${configs[2].configName}`)
114+
.set({
115+
Authorization: `Bearer ${testUtil.jwts.admin}`,
116+
})
117+
.expect(200)
118+
.end((err, res) => {
119+
const config3 = configs[2];
52120

53121
const resJson = res.body;
54122
resJson.should.have.length(1);
55-
resJson[0].id.should.be.eql(config.id);
56-
resJson[0].orgId.should.be.eql(config.orgId);
57-
resJson[0].configName.should.be.eql(config.configName);
58-
resJson[0].configValue.should.be.eql(config.configValue);
59-
should.exist(resJson[0].createdAt);
60-
resJson[0].updatedBy.should.be.eql(config.updatedBy);
61-
should.exist(resJson[0].updatedAt);
62-
should.not.exist(resJson[0].deletedBy);
63-
should.not.exist(resJson[0].deletedAt);
123+
validateOrgConfig(resJson[0], config3);
124+
125+
done();
126+
});
127+
});
128+
129+
it('should return 200 for admin and filter by multiple orgId (DB)', (done) => {
130+
request(server)
131+
.get(`${orgConfigPath}?orgId=${configs[0].orgId},${configs[1].orgId}`)
132+
.set({
133+
Authorization: `Bearer ${testUtil.jwts.admin}`,
134+
})
135+
.expect(200)
136+
.end((err, res) => {
137+
const config1 = configs[0];
138+
const config2 = configs[1];
139+
140+
const resJson = res.body;
141+
resJson.should.have.length(2);
142+
resJson.forEach((result) => {
143+
if (result.id === 1) {
144+
validateOrgConfig(result, config1);
145+
} else {
146+
validateOrgConfig(result, config2);
147+
}
148+
});
149+
150+
done();
151+
});
152+
});
153+
154+
it('should return 200 for admin and filter by multiple orgId (ES)', (done) => {
155+
request(server)
156+
.get(`${orgConfigPath}?orgId=${configs[2].orgId},${configs[3].orgId}`)
157+
.set({
158+
Authorization: `Bearer ${testUtil.jwts.admin}`,
159+
})
160+
.expect(200)
161+
.end((err, res) => {
162+
const config3 = configs[2];
163+
const config4 = configs[3];
164+
165+
const resJson = res.body;
166+
resJson.should.have.length(2);
167+
resJson.forEach((result) => {
168+
if (result.id === 3) {
169+
validateOrgConfig(result, config3);
170+
} else {
171+
validateOrgConfig(result, config4);
172+
}
173+
});
64174

65175
done();
66176
});

0 commit comments

Comments
 (0)