feat(portal-data): support sub-queries

This commit is contained in:
geek 2017-06-07 16:35:45 -05:00 committed by Sérgio Ramos
parent b6f6f1b2a8
commit 7e01748e8a
4 changed files with 217 additions and 48 deletions

View File

@ -3,12 +3,15 @@
const Code = require('code');
const Hapi = require('hapi');
const Lab = require('lab');
const PortalData = require('portal-data');
const PortalApi = require('../');
// Test shortcuts
const lab = exports.lab = Lab.script();
const afterEach = lab.afterEach;
const beforeEach = lab.beforeEach;
const describe = lab.describe;
const it = lab.it;
const expect = Code.expect;
@ -48,4 +51,118 @@ describe('graphql', () => {
});
});
});
it('can query for a deployment group inside a portal', (done) => {
const server = new Hapi.Server();
server.connection();
server.register(internals.register, (err) => {
expect(err).to.not.exist();
// internals.bootstrap(server.plugins['portal-api'].data, (err) => {
const payload = {
query: '{ portal { datacenter { region }, deploymentGroups(name: "test1") { name, slug } } }'
};
server.inject({ method: 'POST', url: '/graphql', payload }, (res) => {
expect(res.statusCode).to.equal(200);
const result = JSON.parse(res.result);
expect(result.data).to.exist();
expect(result.data.portal.deploymentGroups[0].name).to.equal('test1');
done();
});
});
});
it('defaults to all deployment groups inside a portal', (done) => {
const server = new Hapi.Server();
server.connection();
server.register(internals.register, (err) => {
expect(err).to.not.exist();
// internals.bootstrap(server.plugins['portal-api'].data, (err) => {
const payload = {
query: '{ portal { datacenter { region }, deploymentGroups { name, slug } } }'
};
server.inject({ method: 'POST', url: '/graphql', payload }, (res) => {
expect(res.statusCode).to.equal(200);
const result = JSON.parse(res.result);
expect(result.data).to.exist();
expect(result.data.portal.deploymentGroups.length).to.equal(2);
done();
});
});
});
it('can sub-filter services for a deployment group', (done) => {
const server = new Hapi.Server();
server.connection();
server.register(internals.register, (err) => {
expect(err).to.not.exist();
// internals.bootstrap(server.plugins['portal-api'].data, (err) => {
const payload = {
query: '{ portal { datacenter { region }, deploymentGroups(name: "test2") { name, services(name: "service") { name } } } }'
};
server.inject({ method: 'POST', url: '/graphql', payload }, (res) => {
expect(res.statusCode).to.equal(200);
const result = JSON.parse(res.result);
const deploymentGroup = result.data.portal.deploymentGroups[0];
expect(deploymentGroup.name).to.equal('test2');
expect(deploymentGroup.services[0].name).to.equal('service');
done();
});
});
});
beforeEach((done) => {
const data = new PortalData({ name: 'test', db: { test: true } });
data.connect(() => {
data.createDatacenter({ region: 'us-sw', name: 'us-sw' }, (err, datacenter) => {
if (err) {
return done(err);
}
data.createUser({ firstName: 'Nikola', lastName: 'Tesla', email: 'nikola@tesla.com', login: 'nikola' }, (err, user) => {
if (err) {
return done(err);
}
data.createPortal({
user,
datacenter
}, (err, portal) => {
if (err) {
return done(err);
}
data.createDeploymentGroup({ name: 'test1' }, () => {
data.createDeploymentGroup({ name: 'test2' }, (err, deploymentGroup) => {
if (err) {
return done(err);
}
data.createService({
name: 'service',
slug: 'service_slug',
deploymentGroupId: deploymentGroup.id
}, () => { done(); });
});
});
});
});
});
});
});
afterEach((done) => {
const data = new PortalData({ name: 'test', db: { test: true } });
data.connect(() => {
data._db.r.dbDrop('test').run(data._db._connection, () => {
done();
});
});
});
});

View File

@ -78,9 +78,6 @@ module.exports = class Data extends EventEmitter {
(next) => {
this.getDatacenter({ id: portal.datacenter_id }, next);
},
(next) => {
this._db.deployment_groups.all(next);
},
(next) => {
this.getUser({}, next);
}
@ -90,11 +87,24 @@ module.exports = class Data extends EventEmitter {
return cb(err);
}
// Sub query/filter for deploymentGroups
const deploymentGroups = (args) => {
return new Promise((resolve, reject) => {
this.getDeploymentGroups(args, (err, groups) => {
if (err) {
return reject(err);
}
resolve(groups);
});
});
};
cb(null, Transform.fromPortal({
portal,
datacenter: results.successes[0],
deploymentGroups: results.successes[1],
user: results.successes[2]
deploymentGroups,
datacenter: results.operations[0].result,
user: results.operations[1].result
}));
});
});
@ -201,7 +211,27 @@ module.exports = class Data extends EventEmitter {
return cb(err);
}
cb(null, deploymentGroups ? deploymentGroups.map(Transform.fromDeploymentGroup) : null);
const getServices = (service_ids) => {
return (args) => {
args = args || {};
args.ids = service_ids;
return new Promise((resolve, reject) => {
this.getServices(args, (err, services) => {
if (err) {
return reject(err);
}
resolve(services);
});
});
};
};
const convertedGroups = deploymentGroups ? deploymentGroups.map((deploymentGroup) => {
return Transform.fromDeploymentGroup(deploymentGroup, getServices(deploymentGroup.service_ids));
}) : [];
cb(null, convertedGroups);
};
if (ids) {
@ -216,28 +246,38 @@ module.exports = class Data extends EventEmitter {
return this._db.deployment_groups.query({ slug }, finish);
}
finish();
return this._db.deployment_groups.all(finish);
}
getDeploymentGroup (query, cb) {
this._db.deployment_groups.sync(() => {
this._db.deployment_groups.single(query, (err, deploymentGroup) => {
if (err) {
return cb(err);
}
this._db.deployment_groups.single(query, (err, deploymentGroup) => {
if (err) {
return cb(err);
}
if (!deploymentGroup) {
return cb(null, {});
}
if (!deploymentGroup) {
return cb(null, {});
}
if (!deploymentGroup.service_ids || !deploymentGroup.service_ids.length) {
return cb(null, Transform.fromDeploymentGroup(deploymentGroup));
}
if (!deploymentGroup.service_ids || !deploymentGroup.service_ids.length) {
return cb(null, Transform.fromDeploymentGroup(deploymentGroup));
}
this._db.services.get(deploymentGroup.service_ids, (err, services) => {
cb(err, Transform.fromDeploymentGroup(deploymentGroup, services));
const getServices = (args) => {
args = args || {};
args.ids = deploymentGroup.service_ids;
return new Promise((resolve, reject) => {
this.getServices(args, (err, services) => {
if (err) {
return reject(err);
}
resolve(services);
});
});
});
};
cb(err, Transform.fromDeploymentGroup(deploymentGroup, getServices));
});
}
@ -673,7 +713,42 @@ module.exports = class Data extends EventEmitter {
});
}
// TODO: get services with join/merge
getServices (options, cb) {
const query = {};
if (options.ids && options.ids.length) {
query.id = this._db.or(options.ids);
}
if (options.name) {
query.name = options.name;
}
if (options.slug) {
query.slug = options.slug;
}
if (options.parentId) {
query.parent_id = options.parentId;
}
if (options.deploymentGroupId) {
query.deployment_group_id = options.deploymentGroupId;
}
this._db.services.query(query, (err, services) => {
if (err) {
return cb(err);
}
if (!services || !services.length) {
return cb();
}
return cb(null, services.map((service) => {
return Transform.fromService({ service });
}));
});
}
// instances

View File

@ -4,13 +4,11 @@ const Yamljs = require('yamljs');
exports.fromPortal = function ({ portal, datacenter, deploymentGroups, user }) {
deploymentGroups = Array.isArray(deploymentGroups) ? deploymentGroups : [];
return {
id: portal.id,
user,
datacenter,
deploymentGroups: deploymentGroups.map(exports.fromDeploymentGroup)
deploymentGroups
};
};
@ -26,15 +24,11 @@ exports.toPortal = function (clientPortal) {
exports.fromDeploymentGroup = function (deploymentGroup, services) {
if (!Array.isArray(services)) {
services = [];
}
return {
id: deploymentGroup.id,
name: deploymentGroup.name,
slug: deploymentGroup.slug,
services: services ? services.map((service) => { return exports.fromService({ service }); }) : [],
services,
version: deploymentGroup.version_id,
history: deploymentGroup.history_version_ids || []
};

View File

@ -24,23 +24,6 @@ describe('connect()', () => {
});
describe('portals', () => {
describe('createPortal()', () => {
it('creates a new portal', (done) => {
const data = new PortalData(internals.options);
data.connect((err) => {
expect(err).to.not.exist();
const portal = {};
data.createPortal(portal, (err, result) => {
expect(err).to.not.exist();
expect(result.id).to.exist();
done();
});
});
});
});
describe('getPortal()', () => {
it('retrieves a single portal record', (done) => {
const data = new PortalData(internals.options);