Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow servers and channels to be fetched from components #430

Merged
46 changes: 46 additions & 0 deletions lib/models/components.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const { createMapOfType, getMapValueOfType, mix } = require('./utils');

const Base = require('./base');
const Channel = require('./channel');
const Message = require('./message');
const Schema = require('./schema');
const SecurityScheme = require('./security-scheme');
const Server = require('./server');
const ChannelParameter = require('./channel-parameter');
const CorrelationId = require('./correlation-id');
const OperationTrait = require('./operation-trait');
Expand All @@ -20,6 +22,28 @@ const MixinSpecificationExtensions = require('../mixins/specification-extensions
* @returns {Components}
*/
class Components extends Base {
/**
* @returns {Object<string, Channel>}
*/
channels() {
return createMapOfType(this._json.channels, Channel);
}

/**
* @returns {boolean}
*/
hasChannels() {
return !!this._json.channels;
}

/**
* @param {string} name - Name of the channel.
* @returns {Channel}
*/
channel(name) {
return getMapValueOfType(this._json.channels, name, Channel);
}

/**
* @returns {Object<string, Message>}
*/
Expand Down Expand Up @@ -85,6 +109,28 @@ class Components extends Base {
securityScheme(name) {
return getMapValueOfType(this._json.securitySchemes, name, SecurityScheme);
}

/**
* @returns {Object<string, Server>}
*/
servers() {
return createMapOfType(this._json.servers, Server);
}

/**
* @returns {boolean}
*/
hasServers() {
return !!this._json.servers;
}

/**
* @param {string} name - Name of the server.
* @returns {Server}
*/
server(name) {
return getMapValueOfType(this._json.servers, name, Server);
}

/**
* @returns {Object<string, ChannelParameter>}
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
},
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^9.0.6",
"@asyncapi/specs": "2.13.0-2022-01-release.1",
"@asyncapi/specs": "2022-01-release",
"@fmvilas/pseudo-yaml-ast": "^0.3.1",
"ajv": "^6.10.1",
"js-yaml": "^3.13.1",
Expand Down
102 changes: 102 additions & 0 deletions test/models/components_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,57 @@ const Components = require('../../lib/models/components');
const { assertMixinSpecificationExtensionsInheritance } = require('../mixins/specification-extensions_test');

describe('Components', function() {
describe('#channels()', function() {
it('should return a map of Channel objects', function() {
const doc = { channels: { test1: { description: 'test1' }, test2: { description: 'test2' } } };
const d = new Components(doc);
expect(typeof d.channels()).to.be.equal('object');
expect(d.channels().test1.constructor.name).to.equal('Channel');
expect(d.channels().test1.json()).to.equal(doc.channels.test1);
expect(d.channels().test2.constructor.name).to.equal('Channel');
expect(d.channels().test2.json()).to.equal(doc.channels.test2);
});

it('should return an empty object if the components field has no defined channels', function() {
const doc = {};
const d = new Components(doc);
expect(typeof d.channels()).to.be.equal('object');
expect(d.channels()).to.deep.equal({});
});
});

describe('#hasChannels()', function() {
it('should return a boolean indicating if the components field has channels', function() {
const doc = { channels: { test1: { description: 'test1' }, test2: { description: 'test2' } } };
const docNoChannels = { schemas: {} };
const d = new Components(doc);
const d2 = new Components(docNoChannels);
expect(d.hasChannels()).to.equal(true);
expect(d2.hasChannels()).to.equal(false);
});
});

describe('#channel()', function() {
it('should return a specific Channel object', function() {
const doc = { channels: { test1: { description: 'test1' }, test2: { description: 'test2' } } };
const d = new Components(doc);
expect(d.channel('test1').constructor.name).to.equal('Channel');
expect(d.channel('test1').json()).to.equal(doc.channels.test1);
});

it('should return null if a channel name is not provided', function() {
const doc = { channels: { test1: { description: 'test1' }, test2: { description: 'test2' } } };
const d = new Components(doc);
expect(d.channel()).to.equal(null);
});

it('should return null if a channel name is not found', function() {
const doc = { channels: { test1: { description: 'test1' }, test2: { description: 'test2' } } };
const d = new Components(doc);
expect(d.channel('not found')).to.equal(null);
});
});

describe('#messages()', function() {
it('should return a map of Message objects', function() {
const doc = { messages: { test1: { test: 'test1' }, test2: { test: 'test2' } } };
Expand Down Expand Up @@ -157,6 +208,57 @@ describe('Components', function() {
expect(d.securityScheme('not found')).to.equal(null);
});
});

describe('#servers()', function() {
it('should return a map of Server objects', function() {
const doc = { servers: { test1: { url: 'test1' }, test2: { url: 'test2' } } };
const d = new Components(doc);
expect(typeof d.servers()).to.be.equal('object');
expect(d.servers().test1.constructor.name).to.equal('Server');
expect(d.servers().test1.json()).to.equal(doc.servers.test1);
expect(d.servers().test2.constructor.name).to.equal('Server');
expect(d.servers().test2.json()).to.equal(doc.servers.test2);
});

it('should return an empty object if the components field has no defined servers', function() {
const doc = {};
const d = new Components(doc);
expect(typeof d.servers()).to.be.equal('object');
expect(d.servers()).to.deep.equal({});
});
});

describe('#hasServers()', function() {
it('should return a boolean indicating if the components field has servers', function() {
const doc = { servers: { test1: { url: 'test1' }, test2: { url: 'test2' } } };
const docNoServers = { schemas: {} };
const d = new Components(doc);
const d2 = new Components(docNoServers);
expect(d.hasServers()).to.equal(true);
expect(d2.hasServers()).to.equal(false);
});
});

describe('#server()', function() {
it('should return a specific Server object', function() {
const doc = { servers: { test1: { url: 'test1' }, test2: { url: 'test2' } } };
const d = new Components(doc);
expect(d.server('test1').constructor.name).to.equal('Server');
expect(d.server('test1').json()).to.equal(doc.servers.test1);
});

it('should return null if a message name is not provided', function() {
const doc = { servers: { test1: { url: 'test1' }, test2: { url: 'test2' } } };
const d = new Components(doc);
expect(d.server()).to.equal(null);
});

it('should return null if a message name is not found', function() {
const doc = { servers: { test1: { url: 'test1' }, test2: { url: 'test2' } } };
const d = new Components(doc);
expect(d.server('not found')).to.equal(null);
});
});

describe('#parameters()', function() {
it('should return a map of ChannelParameter objects', function() {
Expand Down