diff --git a/.eslintrc b/.eslintrc index b563c6c..2c0c550 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,16 @@ -extends: openstack/es2015 - +parser: babel-eslint +plugins: + - standard rules: - space-before-function-paren: - - 2 - - never + no-var: error + no-console: off + semi: [error, never] + quotes: [error, single] + lines-between-class-members: error +extends: + - eslint:recommended +env: + browser: true + es6: true + jasmine: true + node: true diff --git a/configure-devstack.js b/configure-devstack.js index d385ea3..2e52adc 100644 --- a/configure-devstack.js +++ b/configure-devstack.js @@ -1,27 +1,26 @@ -/*eslint no-process-env: "off" */ -import fs from 'fs'; -import karma from 'karma/lib/config'; -import path from 'path'; +/* eslint no-process-env: "off" */ +import fs from 'fs' +import karma from 'karma/lib/config' +import path from 'path' -function getDevstackConfig() { - const karmaConfig = karma.parseConfig(path.resolve('./karma.conf.js')); +function getDevstackConfig () { + const karmaConfig = karma.parseConfig(path.resolve('./karma.conf.js')) return getCorsConfig('$KEYSTONE_CONF', karmaConfig) + getCorsConfig('$GLANCE_API_CONF', karmaConfig) + getCorsConfig('$NEUTRON_CONF', karmaConfig) + - getCorsConfig('$NOVA_CONF', karmaConfig); - + getCorsConfig('$NOVA_CONF', karmaConfig) } -function getCorsConfig(service, karmaConfig) { +function getCorsConfig (service, karmaConfig) { return `[[post-config|${service}]] [cors] allowed_origin=http://localhost:${karmaConfig.port} -`; +` } fs.appendFile(process.env.BASE + '/new/devstack/local.conf', getDevstackConfig(), (err) => { if (err) { - throw err; + throw err } -}); +}) diff --git a/karma.conf.babel.js b/karma.conf.babel.js index ebd6c35..838f8e5 100644 --- a/karma.conf.babel.js +++ b/karma.conf.babel.js @@ -1,9 +1,9 @@ -import webpackConfig from './webpack.config.babel'; -import path from 'path'; +import webpackConfig from './webpack.config.babel' +import path from 'path' export default (config) => { // test mode based on basePath parameter (eg. test/unit, test/functional) - const testDir = config.basePath ? path.basename(config.basePath) : 'unit'; + const testDir = config.basePath ? path.basename(config.basePath) : 'unit' config.set({ @@ -69,9 +69,9 @@ export default (config) => { // Generate a coverage report in /cover/karma coverageReporter: { - type: 'html', //produces a html document after code is run - dir: '../../cover/' + testDir + '/browser/' //path to created html doc - }, + type: 'html', // produces a html document after code is run + dir: '../../cover/' + testDir + '/browser/' // path to created html doc + } - }); -}; + }) +} diff --git a/karma.conf.js b/karma.conf.js index a4530e0..b7cb70b 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,2 +1,2 @@ -require('@babel/register'); -module.exports = require('./karma.conf.babel').default; +require('@babel/register') +module.exports = require('./karma.conf.babel').default diff --git a/package.json b/package.json index 03e541c..2d7bc2e 100644 --- a/package.json +++ b/package.json @@ -41,11 +41,12 @@ "@babel/preset-env": "^7.0.0", "@babel/register": "^7.0.0", "babel-core": "^7.0.0-bridge.0", + "babel-eslint": "^10.1.0", "babel-loader": "^8.1.0", "babel-plugin-istanbul": "^6.0.0", "babel-plugin-transform-inline-environment-variables": "^6.8.0", - "eslint": "^3.0.0", - "eslint-config-openstack": "4.0.1", + "eslint": "^7.1.0", + "eslint-plugin-standard": "^4.0.1", "fetch-mock": "^5.0.5", "jasmine": "^3.5.0", "js-yaml": "^3.14.0", diff --git a/src/glance.js b/src/glance.js index 3dfc80f..dbf5548 100644 --- a/src/glance.js +++ b/src/glance.js @@ -13,7 +13,7 @@ * the License for the specific language governing permissions and limitations * under the License. */ -import AbstractService from './util/abstractService'; +import AbstractService from './util/abstractService' /** * A list of all supported versions. Please keep this array sorted by most recent. @@ -23,10 +23,9 @@ import AbstractService from './util/abstractService'; */ const supportedGlanceVersions = [ 'v2.3' -]; +] export default class Glance extends AbstractService { - /** * This class provides direct, idempotent, low-level access to the Glance API of a specific * cloud. The constructor requires that you provide a specific glance interface endpoint @@ -42,17 +41,17 @@ export default class Glance extends AbstractService { * } * @param {{}} endpointConfig The configuration element for a specific glance endpoint. */ - constructor(endpointConfig) { + constructor (endpointConfig) { // Sanity checks. if (!endpointConfig || !endpointConfig.url) { - throw new Error('An endpoint configuration is required.'); + throw new Error('An endpoint configuration is required.') } // Clone the config, so that this instance is immutable // at runtime (no modifying the config after the fact). - endpointConfig = Object.assign({}, endpointConfig); + endpointConfig = Object.assign({}, endpointConfig) - super(endpointConfig.url, supportedGlanceVersions); - this._config = endpointConfig; + super(endpointConfig.url, supportedGlanceVersions) + this._config = endpointConfig } /** @@ -62,11 +61,11 @@ export default class Glance extends AbstractService { * into one. * @returns {Promise.} A promise which will resolve with the list of images. */ - imageList(token = null) { + imageList (token = null) { return this ._requestComponents(token) .then(([url, headers]) => this.http.httpRequest('GET', `${url}images`, headers)) .then((response) => response.json()) - .then((body) => body.images); + .then((body) => body.images) } } diff --git a/src/index.js b/src/index.js index 8890a82..605b66b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -export {default as Keystone} from './keystone'; -export {default as Glance} from './glance'; -export {default as Neutron} from './neutron'; -export {default as OpenStack} from './openstack'; +export { default as Keystone } from './keystone' +export { default as Glance } from './glance' +export { default as Neutron } from './neutron' +export { default as OpenStack } from './openstack' diff --git a/src/keystone.js b/src/keystone.js index 583c0b7..ce45961 100644 --- a/src/keystone.js +++ b/src/keystone.js @@ -1,4 +1,4 @@ -import AbstractService from './util/abstractService'; +import AbstractService from './util/abstractService' /** * A list of all supported versions. Please keep this array sorted by most recent. @@ -8,10 +8,9 @@ import AbstractService from './util/abstractService'; */ const supportedKeystoneVersions = [ 'v3.1' -]; +] export default class Keystone extends AbstractService { - /** * This class provides direct, idempotent, low-level access to the Keystone API of a specific * cloud. The constructor requires that you provide a configuration object for a specific @@ -22,17 +21,17 @@ export default class Keystone extends AbstractService { * @param {{}} cloudConfig The configuration object for a specific cloud. * @see http://docs.openstack.org/developer/os-client-config/#site-specific-file-locations */ - constructor(cloudConfig) { + constructor (cloudConfig) { // Sanity checks. if (!cloudConfig) { - throw new Error('A configuration is required.'); + throw new Error('A configuration is required.') } // Clone the config, so that this instance is immutable // at runtime (no modifying the config after the fact). - cloudConfig = Object.assign({}, cloudConfig); + cloudConfig = Object.assign({}, cloudConfig) - super(cloudConfig.auth.auth_url, supportedKeystoneVersions); - this.cloudConfig = cloudConfig; + super(cloudConfig.auth.auth_url, supportedKeystoneVersions) + this.cloudConfig = cloudConfig } /** @@ -44,18 +43,18 @@ export default class Keystone extends AbstractService { * @returns {String} The value found in the config, or null. * @ignore */ - _safeConfigGet(path) { - let segments = path.split('.'); - let pointer = this.cloudConfig; + _safeConfigGet (path) { + const segments = path.split('.') + let pointer = this.cloudConfig while (segments.length > 0) { - let prop = segments.shift(); - if (pointer.hasOwnProperty(prop)) { - pointer = pointer[prop]; + const prop = segments.shift() + if (Object.prototype.hasOwnProperty.call(pointer, prop)) { + pointer = pointer[prop] } else { - return null; + return null } } - return pointer; + return pointer } /** @@ -64,9 +63,9 @@ export default class Keystone extends AbstractService { * @returns {Promise.} A promise that will resolve with the list of raw versions. * @protected */ - _rawVersions() { + _rawVersions () { return super._rawVersions() - .then((versions) => versions.values); + .then((versions) => versions.values) } /** @@ -92,7 +91,7 @@ export default class Keystone extends AbstractService { * Not required if a project ID is given. * @returns {Promise.} A promise which will resolve with a valid token. */ - tokenIssue({ + tokenIssue ({ user_id: userId = this._safeConfigGet('auth.user_id'), username = this._safeConfigGet('auth.username'), password = this._safeConfigGet('auth.password'), @@ -103,32 +102,32 @@ export default class Keystone extends AbstractService { project_domain_id: projectDomainId = this._safeConfigGet('auth.project_domain_id'), project_domain_name: projectDomainName = this._safeConfigGet('auth.project_domain_name') } = {}) { - let project; - let user = {password}; + let project + const user = { password } if (userId) { - user.id = userId; + user.id = userId } else if (username) { - user.name = username; + user.name = username if (userDomainId) { - user.domain = {id: userDomainId}; + user.domain = { id: userDomainId } } else if (userDomainName) { - user.domain = {name: userDomainName}; + user.domain = { name: userDomainName } } else { - user.domain = {id: 'default'}; + user.domain = { id: 'default' } } } if (projectId) { - project = {id: projectId}; + project = { id: projectId } } else if (projectName) { - project = {name: projectName}; + project = { name: projectName } if (projectDomainId) { - project.domain = {id: projectDomainId}; + project.domain = { id: projectDomainId } } else if (projectDomainName) { - project.domain = {name: projectDomainName}; + project.domain = { name: projectDomainName } } else { - project.domain = {id: 'default'}; + project.domain = { id: 'default' } } } @@ -136,18 +135,18 @@ export default class Keystone extends AbstractService { auth: { identity: { methods: ['password'], - password: {user} + password: { user } }, - scope: project ? {project} : 'unscoped' + scope: project ? { project } : 'unscoped' } - }; + } return this .serviceEndpoint() .then((url) => this.http.httpPost(`${url}auth/tokens`, body)) .then((response) => { - return response.headers.get('X-Subject-Token'); - }); + return response.headers.get('X-Subject-Token') + }) } /** @@ -157,16 +156,16 @@ export default class Keystone extends AbstractService { * @param {String} adminToken An optional admin token. * @returns {Promise.} A promise which will resolve if the token has been successfully revoked. */ - tokenRevoke(token, adminToken = null) { + tokenRevoke (token, adminToken = null) { return Promise .all([this.serviceEndpoint(), token, adminToken]) .then(([url, token, adminToken]) => { return [url, { 'X-Subject-Token': token, 'X-Auth-Token': adminToken || token - }]; + }] }) - .then(([url, headers]) => this.http.httpRequest('DELETE', `${url}auth/tokens`, headers)); + .then(([url, headers]) => this.http.httpRequest('DELETE', `${url}auth/tokens`, headers)) } /** @@ -175,17 +174,17 @@ export default class Keystone extends AbstractService { * @param {String} token The authorization token. * @returns {Promise.} A promise which will resolve with information about the token. */ - tokenInfo(token) { + tokenInfo (token) { return Promise .all([this.serviceEndpoint(), token]) .then(([url, token]) => { return [url, { 'X-Subject-Token': token, 'X-Auth-Token': token - }]; + }] }) .then(([url, headers]) => this.http.httpRequest('GET', `${url}auth/tokens`, headers)) - .then((response) => response.json()); + .then((response) => response.json()) } /** @@ -194,11 +193,11 @@ export default class Keystone extends AbstractService { * @param {String} token The authorization token. * @returns {Promise.} A promise which will resolve with the service catalog. */ - catalogList(token = null) { + catalogList (token = null) { return this ._requestComponents(token) .then(([url, headers]) => this.http.httpRequest('GET', `${url}auth/catalog`, headers)) .then((response) => response.json()) - .then((body) => body.catalog); + .then((body) => body.catalog) } } diff --git a/src/neutron.js b/src/neutron.js index 91610be..716bb67 100644 --- a/src/neutron.js +++ b/src/neutron.js @@ -13,7 +13,7 @@ * the License for the specific language governing permissions and limitations * under the License. */ -import AbstractService from './util/abstractService'; +import AbstractService from './util/abstractService' /** * A list of all supported versions. Please keep this array sorted by most recent. @@ -23,10 +23,9 @@ import AbstractService from './util/abstractService'; */ const supportedNeutronVersions = [ 'v2.0' -]; +] export default class Neutron extends AbstractService { - /** * This class provides direct, idempotent, low-level access to the Neutron API of a specific * cloud. The constructor requires that you provide a specific neutron interface endpoint @@ -42,16 +41,16 @@ export default class Neutron extends AbstractService { * } * @param {{}} endpointConfig The configuration element for a specific glance endpoint. */ - constructor(endpointConfig) { + constructor (endpointConfig) { // Sanity checks. if (!endpointConfig || !endpointConfig.url) { - throw new Error('An endpoint configuration is required.'); + throw new Error('An endpoint configuration is required.') } // Clone the config, so that this instance is immutable // at runtime (no modifying the config after the fact). - endpointConfig = Object.assign({}, endpointConfig); + endpointConfig = Object.assign({}, endpointConfig) - super(endpointConfig.url, supportedNeutronVersions); + super(endpointConfig.url, supportedNeutronVersions) } /** @@ -60,11 +59,11 @@ export default class Neutron extends AbstractService { * @param {String} token An authorization token, or a promise which will resolve into one. * @returns {Promise.} A promise which will resolve with the list of networks. */ - networkList(token = null) { + networkList (token = null) { return this ._requestComponents(token) .then(([url, headers]) => this.http.httpRequest('GET', `${url}/networks`, headers)) .then((response) => response.json()) - .then((body) => body.networks); + .then((body) => body.networks) } } diff --git a/src/nova.js b/src/nova.js index f2aae20..b6e0f86 100644 --- a/src/nova.js +++ b/src/nova.js @@ -14,7 +14,7 @@ * limitations under the License. */ -import AbstractService from "./util/abstractService"; +import AbstractService from './util/abstractService' /** * A list of all supported versions. Please keep this array sorted by most recent. @@ -24,10 +24,9 @@ import AbstractService from "./util/abstractService"; */ const supportedNovaVersions = [ 'v2.1' -]; +] export default class Nova extends AbstractService { - /** * This class provides direct, idempotent, low-level access to the Nova API of a specific * cloud. The constructor requires that you provide a specific nova interface endpoint @@ -43,17 +42,17 @@ export default class Nova extends AbstractService { * } * @param {{}} endpointConfig The configuration element for a specific nova endpoint. */ - constructor(endpointConfig) { + constructor (endpointConfig) { // Sanity checks. if (!endpointConfig || !endpointConfig.url) { - throw new Error('An endpoint configuration is required.'); + throw new Error('An endpoint configuration is required.') } // Clone the config, so that this instance is immutable // at runtime (no modifying the config after the fact). - endpointConfig = Object.assign({}, endpointConfig); + endpointConfig = Object.assign({}, endpointConfig) - super(endpointConfig.url, supportedNovaVersions); - this._config = endpointConfig; + super(endpointConfig.url, supportedNovaVersions) + this._config = endpointConfig } /** @@ -62,11 +61,11 @@ export default class Nova extends AbstractService { * @param {String} token An authorization token, or a promise which will resolve into one. * @returns {Promise.} A promise which will resolve with the list of flavors. */ - flavorList(token = null) { + flavorList (token = null) { return this ._requestComponents(token) .then(([url, headers]) => this.http.httpRequest('GET', `${url}flavors`, headers)) .then((response) => response.json()) - .then((body) => body.flavors); + .then((body) => body.flavors) } } diff --git a/src/openstack.js b/src/openstack.js index 796af47..7718e7e 100644 --- a/src/openstack.js +++ b/src/openstack.js @@ -1,7 +1,7 @@ -import Keystone from "./keystone"; -import Neutron from "./neutron"; -import Glance from "./glance"; -import Nova from "./nova"; +import Keystone from './keystone' +import Neutron from './neutron' +import Glance from './glance' +import Nova from './nova' export default class OpenStack { /** @@ -9,21 +9,21 @@ export default class OpenStack { * * @param {{}} cloudConfig The configuration object for a specific cloud. */ - constructor(cloudConfig) { + constructor (cloudConfig) { // Sanity checks. if (!cloudConfig) { - throw new Error('A configuration is required.'); + throw new Error('A configuration is required.') } // Clone the config, so that this instance is immutable // at runtime (no modifying the config after the fact). - cloudConfig = Object.assign({}, cloudConfig); + cloudConfig = Object.assign({}, cloudConfig) - this.cloudConfig = cloudConfig; + this.cloudConfig = cloudConfig } - getConfig() { + getConfig () { // Returns the config instance - return this.cloudConfig; + return this.cloudConfig } /** @@ -31,9 +31,9 @@ export default class OpenStack { * * @returns {Promise.} A promise which will resolve with the list of networks. */ - networkList() { + networkList () { return this._neutron - .then((neutron) => neutron.networkList(this._token)); + .then((neutron) => neutron.networkList(this._token)) } /** @@ -41,9 +41,9 @@ export default class OpenStack { * * @returns {Promise.} A promise which will resolve with the list of images. */ - imageList() { + imageList () { return this._glance - .then((glance) => glance.imageList(this._token)); + .then((glance) => glance.imageList(this._token)) } /** @@ -51,9 +51,9 @@ export default class OpenStack { * * @returns {Promise.} A promise which will resolve with the list of flavors. */ - flavorList() { + flavorList () { return this._nova - .then((nova) => nova.flavorList(this._token)); + .then((nova) => nova.flavorList(this._token)) } /** @@ -62,12 +62,12 @@ export default class OpenStack { * @returns {Promise.} A promise which will resolve with Keystone instance. * @private */ - get _keystone() { + get _keystone () { if (!this._keystonePromise) { - this._keystonePromise = Promise.resolve(new Keystone(this.getConfig())); + this._keystonePromise = Promise.resolve(new Keystone(this.getConfig())) } - return this._keystonePromise; + return this._keystonePromise } /** @@ -76,12 +76,12 @@ export default class OpenStack { * @returns {Promise.} A promise which will resolve with Neutron instance. * @private */ - get _neutron() { + get _neutron () { if (!this._neutronPromise) { this._neutronPromise = this._getComponentConfigFor('neutron') - .then((componentConfig) => new Neutron(componentConfig)); + .then((componentConfig) => new Neutron(componentConfig)) } - return this._neutronPromise; + return this._neutronPromise } /** @@ -90,12 +90,12 @@ export default class OpenStack { * @returns {Promise.} A promise which will resolve with Glance instance. * @private */ - get _glance() { + get _glance () { if (!this._glancePromise) { this._glancePromise = this._getComponentConfigFor('glance') - .then((componentConfig) => new Glance(componentConfig)); + .then((componentConfig) => new Glance(componentConfig)) } - return this._glancePromise; + return this._glancePromise } /** @@ -104,12 +104,12 @@ export default class OpenStack { * @returns {Promise.} A promise which will resolve with Nova instance. * @private */ - get _nova() { + get _nova () { if (!this._novaPromise) { this._novaPromise = this._getComponentConfigFor('nova') - .then((componentConfig) => new Nova(componentConfig)); + .then((componentConfig) => new Nova(componentConfig)) } - return this._novaPromise; + return this._novaPromise } /** @@ -118,11 +118,11 @@ export default class OpenStack { * @returns {Promise.} A promise which will resolve with the token. * @private */ - get _token() { + get _token () { if (!this._tokenPromise) { - this._tokenPromise = this._keystone.then((k) => k.tokenIssue()); + this._tokenPromise = this._keystone.then((k) => k.tokenIssue()) } - return this._tokenPromise; + return this._tokenPromise } /** @@ -132,14 +132,13 @@ export default class OpenStack { * @returns {Promise.<{}>} A promise which will resolve with the component config. * @private */ - _getComponentConfigFor(name) { - const config = this.getConfig(); + _getComponentConfigFor (name) { + const config = this.getConfig() return this._token .then((token) => this._keystone.then((keystone) => keystone.catalogList(token))) .then((catalog) => catalog.find((entry) => entry.name === name)) .then((entry) => entry.endpoints.find((endpoint) => { - return endpoint.region === config.region_name && endpoint.interface === 'public'; - })); + return endpoint.region === config.region_name && endpoint.interface === 'public' + })) } - } diff --git a/src/util/abstractService.js b/src/util/abstractService.js index 9f12136..358698e 100644 --- a/src/util/abstractService.js +++ b/src/util/abstractService.js @@ -14,12 +14,11 @@ * under the License. */ -import Http from './http'; -import Version from './version'; -import URL from 'url-parse'; +import Http from './http' +import Version from './version' +import URL from 'url-parse' export default class AbstractService { - /** * This class provides an abstract implementation of our services, which includes logic common to * all of our services. @@ -27,9 +26,9 @@ export default class AbstractService { * @param {string} endpointUrl The endpoint URL. * @param {Array} supportedVersions The list of all supported versions. */ - constructor(endpointUrl, supportedVersions) { - this._endpointUrl = endpointUrl; - this._supportedVersions = supportedVersions; + constructor (endpointUrl, supportedVersions) { + this._endpointUrl = endpointUrl + this._supportedVersions = supportedVersions } /** @@ -37,11 +36,11 @@ export default class AbstractService { * * @returns {Http} Our HTTP service instance. */ - get http() { + get http () { if (!this._http) { - this._http = new Http(); + this._http = new Http() } - return this._http; + return this._http } /** @@ -49,8 +48,8 @@ export default class AbstractService { * * @returns {Array} The list of all supported versions, or empty array. */ - get supportedVersions() { - return this._supportedVersions || []; + get supportedVersions () { + return this._supportedVersions || [] } /** @@ -58,8 +57,8 @@ export default class AbstractService { * * @returns {string} The URL of our service. */ - get endpointUrl() { - return this._endpointUrl; + get endpointUrl () { + return this._endpointUrl } /** @@ -67,14 +66,14 @@ export default class AbstractService { * * @returns {Promise.} A promise that will resolve with the list of API versions. */ - versions() { + versions () { return this._rawVersions().then((versions) => { return versions.map((rawVersion) => { - const version = new Version(rawVersion.id); - version.links = rawVersion.links; - return version; - }); - }); + const version = new Version(rawVersion.id) + version.links = rawVersion.links + return version + }) + }) } /** @@ -83,26 +82,26 @@ export default class AbstractService { * @returns {Promise.} A promise that will resolve with the list of raw versions. * @protected */ - _rawVersions() { + _rawVersions () { return new Promise((resolve, reject) => { this.http .httpGet(this._endpointUrl) .catch((response) => { if (response.status === 401) { - let rootUrl = new URL(this._endpointUrl); - rootUrl.set('pathname', '/'); - rootUrl.set('query', ''); - rootUrl.set('hash', ''); + const rootUrl = new URL(this._endpointUrl) + rootUrl.set('pathname', '/') + rootUrl.set('query', '') + rootUrl.set('hash', '') - return this.http.httpGet(rootUrl.href); + return this.http.httpGet(rootUrl.href) } else { - throw response; + throw response } }) .then((response) => response.json()) .then((body) => resolve(body.versions)) - .catch(reject); - }); + .catch(reject) + }) } /** @@ -110,17 +109,17 @@ export default class AbstractService { * * @returns {Promise.} A promise that will resolve with the specific API version. */ - version() { + version () { return this .versions() .then((versions) => { - for (let version of versions) { + for (const version of versions) { if (this.supportedVersions.find(version.supports)) { - return version; + return version } } - throw new Error("No supported API version available."); - }); + throw new Error('No supported API version available.') + }) } /** @@ -128,22 +127,22 @@ export default class AbstractService { * * @returns {Promise.|*} A promise which will resolve with the endpoint URL string. */ - serviceEndpoint() { + serviceEndpoint () { if (!this._endpointPromise) { this._endpointPromise = this.version() .then((version) => { if (version.links) { for (let i = 0; i < version.links.length; i++) { - let link = version.links[i]; + const link = version.links[i] if (link.rel === 'self' && link.href) { - return link.href; + return link.href } } } - throw new Error("No service endpoint discovered."); - }); + throw new Error('No service endpoint discovered.') + }) } - return this._endpointPromise; + return this._endpointPromise } /** @@ -155,18 +154,18 @@ export default class AbstractService { * @returns {Promise} A promise which resolves with [url, token]. * @private */ - _requestComponents(token = null) { + _requestComponents (token = null) { // Make sure the token is a promise. - let headerPromise = Promise + const headerPromise = Promise .resolve(token) .then((token) => { if (token) { return { 'X-Auth-Token': token - }; + } } - return {}; - }); - return Promise.all([this.serviceEndpoint(), headerPromise]); + return {} + }) + return Promise.all([this.serviceEndpoint(), headerPromise]) } } diff --git a/src/util/http.js b/src/util/http.js index 8369198..d2e4c54 100644 --- a/src/util/http.js +++ b/src/util/http.js @@ -14,8 +14,8 @@ * under the License. */ -import 'isomorphic-fetch'; -import log from 'loglevel'; +import 'isomorphic-fetch' +import log from 'loglevel' /** * This utility class provides an abstraction layer for HTTP calls via fetch(). Its purpose is @@ -33,7 +33,6 @@ import log from 'loglevel'; * - Other features. */ export default class Http { - /** * The default headers which will be sent with every request. A copy of these headers will be * added to the Request instance passed through the interceptor chain, and may be @@ -41,18 +40,18 @@ export default class Http { * * @returns {{string: string}} A mapping of 'headerName': 'headerValue' */ - get defaultHeaders() { - return this._defaultHeaders; + get defaultHeaders () { + return this._defaultHeaders } /** * Create a new HTTP handler. */ - constructor() { + constructor () { // Add default response interceptors. this._defaultHeaders = { 'Content-Type': 'application/json' - }; + } } /** @@ -64,40 +63,39 @@ export default class Http { * @param {{}} body The body. It will be JSON-Encoded by the handler. * @returns {Promise} A promise which will resolve with the processed request response. */ - httpRequest(method, url, headers = {}, body) { - + httpRequest (method, url, headers = {}, body) { // Sanitize the headers... - headers = Object.assign({}, headers, this.defaultHeaders); + headers = Object.assign({}, headers, this.defaultHeaders) // Build the request - const init = {method, headers}; + const init = { method, headers } // The Request() constructor will throw an error if the method is GET/HEAD, and there's a body. if (['GET', 'HEAD'].indexOf(method) === -1 && body) { - init.body = JSON.stringify(body); + init.body = JSON.stringify(body) } - const request = new Request(url, init); + const request = new Request(url, init) // Build the wrapper promise. return new Promise((resolve, reject) => { - log.debug('-->', `HTTP ${method}`, url, JSON.stringify(headers), JSON.stringify(body)); - let promise = fetch(request.url, init); + log.debug('-->', `HTTP ${method}`, url, JSON.stringify(headers), JSON.stringify(body)) + const promise = fetch(request.url, init) // Fetch will treat all http responses (2xx, 3xx, 4xx, 5xx, etc) as successful responses. // This will catch all 4xx and 5xx responses and return them to the catch() handler. Note // that it's up to the downstream developer to determine whether what they received is an // error or a failed response. promise.then((response) => { - log.debug('<--', `HTTP ${response.status}`); + log.debug('<--', `HTTP ${response.status}`) if (response.status >= 400) { - return reject(response); + return reject(response) } else { - return response; + return response } - }); + }) - promise.then((response) => resolve(response), (error) => reject(error)); - }); + promise.then((response) => resolve(response), (error) => reject(error)) + }) } /** @@ -106,8 +104,8 @@ export default class Http { * @param {String} url The request URL. * @returns {Promise} A promise which will resolve with the processed request response. */ - httpGet(url) { - return this.httpRequest('GET', url, {}, null); + httpGet (url) { + return this.httpRequest('GET', url, {}, null) } /** @@ -117,8 +115,8 @@ export default class Http { * @param {{}} body The body. It will be JSON-Encoded by the handler. * @returns {Promise} A promise which will resolve with the processed request response. */ - httpPut(url, body) { - return this.httpRequest('PUT', url, {}, body); + httpPut (url, body) { + return this.httpRequest('PUT', url, {}, body) } /** @@ -128,8 +126,8 @@ export default class Http { * @param {{}} body The body. It will be JSON-Encoded by the handler. * @returns {Promise} A promise which will resolve with the processed request response. */ - httpPost(url, body) { - return this.httpRequest('POST', url, {}, body); + httpPost (url, body) { + return this.httpRequest('POST', url, {}, body) } /** @@ -138,7 +136,7 @@ export default class Http { * @param {String} url The request URL. * @returns {Promise} A promise which will resolve with the processed request response. */ - httpDelete(url) { - return this.httpRequest('DELETE', url, {}, null); + httpDelete (url) { + return this.httpRequest('DELETE', url, {}, null) } } diff --git a/src/util/version.js b/src/util/version.js index 2dc1ad4..1e13e16 100644 --- a/src/util/version.js +++ b/src/util/version.js @@ -19,14 +19,13 @@ * comparable instance. */ export default class Version { - /** * The name of the service. * * @returns {String|*|null} The name of the service, or null. */ - get service() { - return this._service || null; + get service () { + return this._service || null } /** @@ -34,8 +33,8 @@ export default class Version { * * @returns {Number} The major version number */ - get major() { - return this._major || 0; + get major () { + return this._major || 0 } /** @@ -43,8 +42,8 @@ export default class Version { * * @returns {Number} The minor version number */ - get minor() { - return this._minor || 0; + get minor () { + return this._minor || 0 } /** @@ -52,8 +51,8 @@ export default class Version { * * @returns {Number} The patch version number. */ - get patch() { - return this._patch || 0; + get patch () { + return this._patch || 0 } /** @@ -61,8 +60,8 @@ export default class Version { * * @returns {Object[]} The list of links. */ - get links() { - return this._links || null; + get links () { + return this._links || null } /** @@ -70,9 +69,9 @@ export default class Version { * * @param {Object[]} links The links to be set */ - set links(links) { + set links (links) { if (Array.isArray(links)) { - this._links = links; + this._links = links } } @@ -82,37 +81,37 @@ export default class Version { * @param {String} [service] The name of the service. * @param {String} versionString The version string for this service. */ - constructor(service, versionString) { + constructor (service, versionString) { // Sanitize input if (typeof service !== 'string') { - service = undefined; + service = undefined } if (typeof versionString !== 'string') { - versionString = undefined; + versionString = undefined } if (versionString === undefined) { - versionString = service; + versionString = service } else { - this._service = service; + this._service = service } // Sanity check before running regex. if (!versionString || !versionString.match) { - return; + return } - const results = versionString.match(/^(([^ ]+) )?v?(([0-9]+)(\.([0-9]+)(.([0-9]+))?)?)$/); + const results = versionString.match(/^(([^ ]+) )?v?(([0-9]+)(\.([0-9]+)(.([0-9]+))?)?)$/) if (results) { - this._service = results[2] || this._service; // regex takes precedence - this._major = parseInt(results[4], 10); - this._minor = parseInt(results[6], 10); - this._patch = parseInt(results[8], 10); + this._service = results[2] || this._service // regex takes precedence + this._major = parseInt(results[4], 10) + this._minor = parseInt(results[6], 10) + this._patch = parseInt(results[8], 10) } - this._links = null; + this._links = null - this.equals = this.equals.bind(this); - this.supports = this.supports.bind(this); + this.equals = this.equals.bind(this) + this.supports = this.supports.bind(this) } /** @@ -121,20 +120,20 @@ export default class Version { * @param {String|Version} version The version to compare to. * @returns {boolean} True if they are exactly the same, otherwise false. */ - equals(version) { + equals (version) { if (!(version instanceof Version)) { // is it a parseable string? if (typeof version === 'string') { - version = new Version(version); + version = new Version(version) } else { - return false; + return false } } return version.major === this.major && version.minor === this.minor && version.patch === this.patch && - version.service === this.service; + version.service === this.service } /** @@ -144,30 +143,30 @@ export default class Version { * @param {String|Version} version the version to support. * @returns {boolean} True if the version is compatible, otherwise false */ - supports(version) { + supports (version) { if (!(version instanceof Version)) { if (typeof version === 'string') { - version = new Version(version); + version = new Version(version) } else { - return false; + return false } } const compatibleVersion = version.service === this.service && version.major === this.major && - version.minor <= this.minor; + version.minor <= this.minor if (compatibleVersion && version.minor === this.minor) { - return version.patch <= this.patch; + return version.patch <= this.patch } - return compatibleVersion; + return compatibleVersion } - toString() { - let version = `${this.major}.${this.minor}`; + toString () { + let version = `${this.major}.${this.minor}` if (this.patch) { - version = `${version}.${this.patch}`; + version = `${version}.${this.patch}` } - return version; + return version } } diff --git a/test/functional/glanceTest.js b/test/functional/glanceTest.js index d2ef6bf..b20b78f 100644 --- a/test/functional/glanceTest.js +++ b/test/functional/glanceTest.js @@ -14,71 +14,69 @@ * under the License. */ -import config from "./helpers/cloudsConfig"; -import Version from '../../src/util/version'; -import Glance from "../../src/glance"; -import Keystone from "../../src/keystone"; -import log from 'loglevel'; +import config from './helpers/cloudsConfig' +import Version from '../../src/util/version' +import Glance from '../../src/glance' +import Keystone from '../../src/keystone' +import log from 'loglevel' -log.setLevel("DEBUG"); +log.setLevel('DEBUG') -describe("Glance", () => { +describe('Glance', () => { // Create a keystone instance and extract the glance API endpoint. - let devstackConfig = config.clouds.devstack; - let keystone = new Keystone(devstackConfig); - let tokenPromise = keystone.tokenIssue(); + const devstackConfig = config.clouds.devstack + const keystone = new Keystone(devstackConfig) + const tokenPromise = keystone.tokenIssue() - let configPromise = tokenPromise + const configPromise = tokenPromise .then((token) => keystone.catalogList(token)) .then((catalog) => catalog.find((entry) => entry.name === 'glance')) - .then((entry) => entry.endpoints.find((endpoint) => endpoint.interface === 'public')); + .then((entry) => entry.endpoints.find((endpoint) => endpoint.interface === 'public')) - describe("versions()", () => { - it("should return a list of all versions available on this clouds' glance", (done) => { + describe('versions()', () => { + it('should return a list of all versions available on this clouds\' glance', (done) => { configPromise .then((config) => new Glance(config)) .then((glance) => glance.versions()) .then((versions) => { // Quick sanity check. - expect(versions.length > 0).toBeTruthy(); - done(); + expect(versions.length > 0).toBeTruthy() + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("version()", () => { + describe('version()', () => { /** * This test acts as a canary, to inform the SDK developers that the Glance API * has changed in a significant way. */ - it("should return a supported version.", (done) => { + it('should return a supported version.', (done) => { configPromise .then((config) => new Glance(config)) .then((glance) => glance.version()) .then((apiVersion) => { - expect(apiVersion instanceof Version).not.toBeFalsy(); - done(); + expect(apiVersion instanceof Version).not.toBeFalsy() + done() }) - .catch((error) => done.fail(error)); - }); - }); - - describe("imageList()", () => { + .catch((error) => done.fail(error)) + }) + }) + describe('imageList()', () => { /** * Assert that we can get a list of images. */ - it("should return a supported version.", (done) => { + it('should return a supported version.', (done) => { configPromise .then((config) => new Glance(config)) .then((glance) => glance.imageList(tokenPromise)) .then((images) => { - expect(images.length > 0).toBeTruthy(); - done(); + expect(images.length > 0).toBeTruthy() + done() }) - .catch((error) => done.fail(error)); - }); - }); - -}); + .catch((error) => done.fail(error)) + }) + }) +}) diff --git a/test/functional/helpers/cloudsConfig.js b/test/functional/helpers/cloudsConfig.js index 8e4274c..7714235 100644 --- a/test/functional/helpers/cloudsConfig.js +++ b/test/functional/helpers/cloudsConfig.js @@ -1,8 +1,8 @@ -/*eslint no-sync: "off"*/ -import yaml from 'js-yaml'; -import fs from 'fs'; -import cloudsYamlPath from './cloudsYamlPath'; +/* eslint no-sync: "off" */ +import yaml from 'js-yaml' +import fs from 'fs' +import cloudsYamlPath from './cloudsYamlPath' -const clouds = yaml.safeLoad(fs.readFileSync(cloudsYamlPath, 'utf8')); +const clouds = yaml.safeLoad(fs.readFileSync(cloudsYamlPath, 'utf8')) -export default clouds; +export default clouds diff --git a/test/functional/helpers/cloudsYamlPath.js b/test/functional/helpers/cloudsYamlPath.js index a07a6a4..80b9ad0 100644 --- a/test/functional/helpers/cloudsYamlPath.js +++ b/test/functional/helpers/cloudsYamlPath.js @@ -1,23 +1,22 @@ -/*eslint no-process-env: "off", no-sync: "off"*/ -import fs from 'fs'; -import path from 'path'; +/* eslint no-process-env: "off", no-sync: "off" */ +import fs from 'fs' +import path from 'path' const resolvePaths = [ './clouds.yaml', process.env.HOME + '/.config/openstack/clouds.yaml', '/etc/openstack/clouds.yaml' -]; +] -function fileExists(path) { +function fileExists (path) { try { - fs.statSync(path); - return true; + fs.statSync(path) + return true } catch (err) { - return false; + return false } } -const cloudFiles = resolvePaths.filter(fileExists); - -export default cloudFiles.length > 0 ? path.resolve(cloudFiles[0]) : 'clouds.yaml'; +const cloudFiles = resolvePaths.filter(fileExists) +export default cloudFiles.length > 0 ? path.resolve(cloudFiles[0]) : 'clouds.yaml' diff --git a/test/functional/keystoneTest.js b/test/functional/keystoneTest.js index d939c34..cd683b5 100644 --- a/test/functional/keystoneTest.js +++ b/test/functional/keystoneTest.js @@ -14,81 +14,81 @@ * under the License. */ -import Version from '../../src/util/version'; -import Keystone from "../../src/keystone"; -import config from "./helpers/cloudsConfig"; -import log from 'loglevel'; +import Version from '../../src/util/version' +import Keystone from '../../src/keystone' +import config from './helpers/cloudsConfig' +import log from 'loglevel' -log.setLevel("DEBUG"); +log.setLevel('DEBUG') -describe("Keystone", () => { - let devstackConfig = config.clouds.devstack; - let adminConfig = config.clouds['devstack-admin']; - let keystone = new Keystone(devstackConfig); +describe('Keystone', () => { + const devstackConfig = config.clouds.devstack + const adminConfig = config.clouds['devstack-admin'] + const keystone = new Keystone(devstackConfig) - describe("versions()", () => { - it("should return a list of all versions available on this clouds' keystone", (done) => { + describe('versions()', () => { + it('should return a list of all versions available on this clouds\' keystone', (done) => { keystone.versions() .then((versions) => { // Quick sanity check. - expect(versions.length > 0).toBeTruthy(); - done(); + expect(versions.length > 0).toBeTruthy() + done() }) .catch((response) => response.json() .then((body) => done.fail(JSON.stringify(body))) - ); - }); - }); + ) + }) + }) - describe("version()", () => { + describe('version()', () => { /** * This test acts as a canary, to inform the SDK developers that the Keystone API * has changed in a significant way. */ - it("should return a supported version.", (done) => { + it('should return a supported version.', (done) => { keystone.version() .then((apiVersion) => { - expect(apiVersion instanceof Version).not.toBeFalsy(); - done(); + expect(apiVersion instanceof Version).not.toBeFalsy() + done() }) .catch((response) => response.json() .then((body) => done.fail(JSON.stringify(body))) - ); - }); - }); + ) + }) + }) - describe("tokenIssue()", () => { - let keystone = null; + describe('tokenIssue()', () => { + let keystone = null beforeEach(() => { - keystone = new Keystone(config.clouds.devstack); - }); + keystone = new Keystone(config.clouds.devstack) + }) - it("should 'just work' by using provided credentials from the config.", (done) => { + it('should "just work" by using provided credentials from the config.', (done) => { keystone .tokenIssue() .then((token) => { - expect(token).not.toBeNull(); - done(); + expect(token).not.toBeNull() + done() }) .catch((response) => response.json() .then((body) => done.fail(JSON.stringify(body))) - ); - }); + ) + }) - it("should permit passing your own user, password, and project.", (done) => { + it('should permit passing your own user, password, and project.', (done) => { keystone .tokenIssue(adminConfig.auth) .then((token) => { - expect(token).not.toBeNull(); - done(); + expect(token).not.toBeNull() + done() }) .catch((response) => response.json() .then((body) => done.fail(JSON.stringify(body))) - ); - }); + ) + }) - it("should throw an exception if invalid username and password are provided.", (done) => { + it('should throw an exception if invalid username and password are provided.', (done) => { keystone .tokenIssue({ username: 'foo', @@ -96,12 +96,12 @@ describe("Keystone", () => { }) .then((token) => done.fail(token)) .catch((error) => { - expect(error).not.toBeNull(); - done(); - }); - }); + expect(error).not.toBeNull() + done() + }) + }) - it("should throw an exception if invalid project is provided.", (done) => { + it('should throw an exception if invalid project is provided.', (done) => { keystone .tokenIssue({ project_id: 'foo', @@ -109,12 +109,12 @@ describe("Keystone", () => { }) .then((token) => done.fail(token)) .catch((error) => { - expect(error).not.toBeNull(); - done(); - }); - }); + expect(error).not.toBeNull() + done() + }) + }) - it("should throw an exception if invalid user domain is provided.", (done) => { + it('should throw an exception if invalid user domain is provided.', (done) => { keystone .tokenIssue({ user_domain_id: 'foo', @@ -122,127 +122,127 @@ describe("Keystone", () => { }) .then((token) => done.fail(token)) .catch((error) => { - expect(error).not.toBeNull(); - done(); - }); - }); - }); + expect(error).not.toBeNull() + done() + }) + }) + }) - describe("tokenRevoke()", () => { - let keystone = null; + describe('tokenRevoke()', () => { + let keystone = null beforeEach(() => { - keystone = new Keystone(config.clouds.devstack); - }); + keystone = new Keystone(config.clouds.devstack) + }) - it("should permit self-revocation.", (done) => { + it('should permit self-revocation.', (done) => { keystone .tokenIssue() .then((token) => { - return keystone.tokenRevoke(token); + return keystone.tokenRevoke(token) }) .then((response) => { - expect(response.status).toBe(204); // No content - done(); + expect(response.status).toBe(204) // No content + done() }) .catch((response) => response.json() .then((body) => done.fail(JSON.stringify(body))) - ); - }); + ) + }) - it("should allow an admin to revoke another token.", (done) => { - let adminToken; - let adminKeystone = new Keystone(adminConfig); + it('should allow an admin to revoke another token.', (done) => { + let adminToken + const adminKeystone = new Keystone(adminConfig) adminKeystone.tokenIssue() // Get an admin token. .then((token) => { - adminToken = token; - return keystone.tokenIssue(); // Regular token. + adminToken = token + return keystone.tokenIssue() // Regular token. }) .then((token) => keystone.tokenRevoke(token, adminToken)) .then((response) => { - expect(response.status).toBe(204); // No content - done(); + expect(response.status).toBe(204) // No content + done() }) .catch((response) => response.json() .then((body) => done.fail(JSON.stringify(body))) - ); - }); + ) + }) - it("should throw an exception if invalid token is provided.", (done) => { + it('should throw an exception if invalid token is provided.', (done) => { keystone .tokenRevoke('not_a_valid_token') .then((response) => done.fail(response)) .catch((error) => { - expect(error).not.toBeNull(); - done(); - }); - }); - }); + expect(error).not.toBeNull() + done() + }) + }) + }) - describe("tokenInfo()", () => { - let keystone = null; + describe('tokenInfo()', () => { + let keystone = null beforeEach(() => { - keystone = new Keystone(config.clouds.devstack); - }); + keystone = new Keystone(config.clouds.devstack) + }) - it("should retrieve info about a token.", (done) => { + it('should retrieve info about a token.', (done) => { keystone .tokenIssue() .then((token) => { - return keystone.tokenInfo(token); + return keystone.tokenInfo(token) }) .then((info) => { - expect('token' in info).toBe(true); - done(); + expect('token' in info).toBe(true) + done() }) .catch((response) => response.json() .then((body) => done.fail(JSON.stringify(body))) - ); - }); + ) + }) - it("should throw an exception if invalid token is provided.", (done) => { + it('should throw an exception if invalid token is provided.', (done) => { keystone .tokenRevoke('not_a_valid_token') .then((response) => done.fail(response)) .catch((error) => { - expect(error).not.toBeNull(); - done(); - }); - }); - }); + expect(error).not.toBeNull() + done() + }) + }) + }) - describe("catalogList()", () => { - let keystone = null; + describe('catalogList()', () => { + let keystone = null beforeEach(() => { - keystone = new Keystone(config.clouds.devstack); - }); + keystone = new Keystone(config.clouds.devstack) + }) - it("should list a catalog.", (done) => { + it('should list a catalog.', (done) => { keystone .tokenIssue() .then((token) => { - return keystone.catalogList(token); + return keystone.catalogList(token) }) .then((catalog) => { - expect(catalog.length).not.toBe(0); - done(); + expect(catalog.length).not.toBe(0) + done() }) .catch((response) => response.json() .then((body) => done.fail(JSON.stringify(body))) - ); - }); + ) + }) - it("should error if not authenticated.", (done) => { + it('should error if not authenticated.', (done) => { keystone .catalogList() .then((response) => done.fail(response)) .catch((error) => { - expect(error).not.toBeNull(); - done(); - }); - }); - }); -}); + expect(error).not.toBeNull() + done() + }) + }) + }) +}) diff --git a/test/functional/neutronTest.js b/test/functional/neutronTest.js index 9740353..b35e4a5 100644 --- a/test/functional/neutronTest.js +++ b/test/functional/neutronTest.js @@ -14,67 +14,66 @@ * under the License. */ -import config from "./helpers/cloudsConfig"; -import Version from '../../src/util/version'; -import Neutron from "../../src/neutron"; -import Keystone from "../../src/keystone"; -import log from 'loglevel'; +import config from './helpers/cloudsConfig' +import Version from '../../src/util/version' +import Neutron from '../../src/neutron' +import Keystone from '../../src/keystone' +import log from 'loglevel' -log.setLevel("DEBUG"); +log.setLevel('DEBUG') -describe("neutron", () => { +describe('neutron', () => { // Create a keystone instance and extract the neutron API endpoint. - let devstackConfig = config.clouds.devstack; - let keystone = new Keystone(devstackConfig); - let tokenPromise = keystone.tokenIssue(); + const devstackConfig = config.clouds.devstack + const keystone = new Keystone(devstackConfig) + const tokenPromise = keystone.tokenIssue() - let configPromise = tokenPromise + const configPromise = tokenPromise .then((token) => keystone.catalogList(token)) .then((catalog) => catalog.find((entry) => entry.name === 'neutron')) - .then((entry) => entry.endpoints.find((endpoint) => endpoint.interface === 'public')); + .then((entry) => entry.endpoints.find((endpoint) => endpoint.interface === 'public')) - describe("versions()", () => { - it("should return a list of all versions available on this clouds' neutron", (done) => { + describe('versions()', () => { + it('should return a list of all versions available on this clouds\' neutron', (done) => { configPromise .then((config) => new Neutron(config)) .then((neutron) => neutron.versions()) .then((versions) => { // Quick sanity check. - expect(versions.length > 0).toBeTruthy(); - done(); + expect(versions.length > 0).toBeTruthy() + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("version()", () => { + describe('version()', () => { /** * This test acts as a canary, to inform the SDK developers that the Neutron API * has changed in a significant way. */ - it("should return a supported version.", (done) => { + it('should return a supported version.', (done) => { configPromise .then((config) => new Neutron(config)) .then((neutron) => neutron.version()) .then((apiVersion) => { - expect(apiVersion instanceof Version).not.toBeFalsy(); - done(); + expect(apiVersion instanceof Version).not.toBeFalsy() + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("networkList()", () => { - it("should return the networks as an array.", (done) => { + describe('networkList()', () => { + it('should return the networks as an array.', (done) => { configPromise .then((config) => new Neutron(config)) .then((neutron) => neutron.networkList(tokenPromise)) .then((networks) => { - expect(networks.length > 0).toBeTruthy(); - done(); + expect(networks.length > 0).toBeTruthy() + done() }) - .catch((error) => done.fail(error)); - }); - }); - -}); + .catch((error) => done.fail(error)) + }) + }) +}) diff --git a/test/functional/novaTest.js b/test/functional/novaTest.js index 2d5cb0a..cde7f59 100644 --- a/test/functional/novaTest.js +++ b/test/functional/novaTest.js @@ -14,56 +14,55 @@ * limitations under the License. */ -import config from "./helpers/cloudsConfig"; -import Version from '../../src/util/version'; -import Nova from "../../src/nova"; -import Keystone from "../../src/keystone"; -import log from 'loglevel'; +import config from './helpers/cloudsConfig' +import Version from '../../src/util/version' +import Nova from '../../src/nova' +import Keystone from '../../src/keystone' +import log from 'loglevel' -log.setLevel("DEBUG"); +log.setLevel('DEBUG') -describe("Nova", () => { +describe('Nova', () => { // Create a keystone instance and extract the nova API endpoint. - let devstackConfig = config.clouds.devstack; - let keystone = new Keystone(devstackConfig); - let tokenPromise = keystone.tokenIssue(); + const devstackConfig = config.clouds.devstack + const keystone = new Keystone(devstackConfig) + const tokenPromise = keystone.tokenIssue() - let configPromise = tokenPromise + const configPromise = tokenPromise .then((token) => keystone.catalogList(token)) .then((catalog) => catalog.find((entry) => entry.name === 'nova')) - .then((entry) => entry.endpoints.find((endpoint) => endpoint.interface === 'public')); + .then((entry) => entry.endpoints.find((endpoint) => endpoint.interface === 'public')) - describe("version()", () => { + describe('version()', () => { /** * This test acts as a canary, to inform the SDK developers that the Nova API * has changed in a significant way. */ - it("should return a supported version.", (done) => { + it('should return a supported version.', (done) => { configPromise .then((config) => new Nova(config)) .then((nova) => nova.version()) .then((apiVersion) => { - expect(apiVersion instanceof Version).not.toBeFalsy(); - done(); + expect(apiVersion instanceof Version).not.toBeFalsy() + done() }) - .catch((error) => done.fail(error)); - }); - }); - - describe("flavorList()", () => { + .catch((error) => done.fail(error)) + }) + }) + describe('flavorList()', () => { /** * Assert that we can get a list of flavors. */ - it("should return a list of flavors.", (done) => { + it('should return a list of flavors.', (done) => { configPromise .then((config) => new Nova(config)) .then((nova) => nova.flavorList(tokenPromise)) .then((flavors) => { - expect(flavors.length > 0).toBeTruthy(); - done(); + expect(flavors.length > 0).toBeTruthy() + done() }) - .catch((error) => done.fail(error)); - }); - }); -}); + .catch((error) => done.fail(error)) + }) + }) +}) diff --git a/test/functional/openstackTest.js b/test/functional/openstackTest.js index 76ff5be..6e8110e 100644 --- a/test/functional/openstackTest.js +++ b/test/functional/openstackTest.js @@ -1,49 +1,48 @@ -import config from "./helpers/cloudsConfig"; -import OpenStack from "../../src/openstack"; -import log from 'loglevel'; +import config from './helpers/cloudsConfig' +import OpenStack from '../../src/openstack' +import log from 'loglevel' -log.setLevel("DEBUG"); +log.setLevel('DEBUG') -describe("OpenStack", () => { - let devstackConfig = config.clouds.devstack; +describe('OpenStack', () => { + const devstackConfig = config.clouds.devstack - describe("networkList()", () => { - it("should return the networks as an array.", (done) => { - const openstack = new OpenStack(devstackConfig); + describe('networkList()', () => { + it('should return the networks as an array.', (done) => { + const openstack = new OpenStack(devstackConfig) openstack.networkList() .then((networks) => { - expect(networks.length > 0).toBeTruthy(); - done(); + expect(networks.length > 0).toBeTruthy() + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("imageList()", () => { - it("should return the images as an array.", (done) => { - const openstack = new OpenStack(devstackConfig); + describe('imageList()', () => { + it('should return the images as an array.', (done) => { + const openstack = new OpenStack(devstackConfig) openstack.imageList() .then((images) => { - expect(images.length > 0).toBeTruthy(); - done(); + expect(images.length > 0).toBeTruthy() + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("flavorList()", () => { - it("should return the flavors as an array.", (done) => { - const openstack = new OpenStack(devstackConfig); + describe('flavorList()', () => { + it('should return the flavors as an array.', (done) => { + const openstack = new OpenStack(devstackConfig) openstack.flavorList() .then((flavors) => { - expect(flavors.length > 0).toBeTruthy(); - done(); + expect(flavors.length > 0).toBeTruthy() + done() }) - .catch((error) => done.fail(error)); - }); - }); - -}); + .catch((error) => done.fail(error)) + }) + }) +}) diff --git a/test/functional/run.js b/test/functional/run.js index a222670..3ed1cbc 100644 --- a/test/functional/run.js +++ b/test/functional/run.js @@ -1,5 +1,5 @@ -import Jasmine from 'jasmine'; +import Jasmine from 'jasmine' -const jasmine = new Jasmine(); -jasmine.loadConfigFile('test/functional/jasmine.json'); -jasmine.execute(); +const jasmine = new Jasmine() +jasmine.loadConfigFile('test/functional/jasmine.json') +jasmine.execute() diff --git a/test/unit/glanceTest.js b/test/unit/glanceTest.js index 898b623..0eeb883 100644 --- a/test/unit/glanceTest.js +++ b/test/unit/glanceTest.js @@ -14,76 +14,75 @@ * under the License. */ -import Glance from "../../src/glance.js"; -import * as mockData from "./helpers/data/glance"; -import fetchMock from "fetch-mock"; +import Glance from '../../src/glance.js' +import * as mockData from './helpers/data/glance' +import fetchMock from 'fetch-mock' describe('Glance', () => { - - afterEach(fetchMock.restore); + afterEach(fetchMock.restore) it('should export a class', () => { - const glance = new Glance(mockData.config); - expect(glance).toBeDefined(); - }); + const glance = new Glance(mockData.config) + expect(glance).toBeDefined() + }) it('should throw an error for an empty config', () => { - expect(() => new Glance()).toThrow(); - }); + expect(() => new Glance()).toThrow() + }) - describe("serviceEndpoint()", () => { - it("Should return a valid endpoint to the glance API.", (done) => { - const glance = new Glance(mockData.config); + describe('serviceEndpoint()', () => { + it('Should return a valid endpoint to the glance API.', (done) => { + const glance = new Glance(mockData.config) - fetchMock.mock(mockData.root()); + fetchMock.mock(mockData.root()) glance.serviceEndpoint() .then((endpoint) => { - expect(endpoint).toEqual('http://192.168.99.99:9292/v2/'); - done(); + expect(endpoint).toEqual('http://192.168.99.99:9292/v2/') + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("imageList()", () => { - let glance = null; + describe('imageList()', () => { + let glance = null beforeEach(() => { - fetchMock.mock(mockData.root()); - glance = new Glance(mockData.config); - }); + fetchMock.mock(mockData.root()) + glance = new Glance(mockData.config) + }) - it("should return the images as an array.", (done) => { - const token = 'test_token'; + it('should return the images as an array.', (done) => { + const token = 'test_token' - fetchMock.mock(mockData.imageList(token)); + fetchMock.mock(mockData.imageList(token)) glance .imageList(token) .then((images) => { - expect(images.length).not.toBe(0); - done(); + expect(images.length).not.toBe(0) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("Should not cache its results", (done) => { - const token = 'test_token'; + it('Should not cache its results', (done) => { + const token = 'test_token' - let mockOptions = mockData.imageList(token); - fetchMock.mock(mockOptions); + const mockOptions = mockData.imageList(token) + fetchMock.mock(mockOptions) glance .imageList(token) .then(() => { - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1); - return glance.imageList(token); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1) + return glance.imageList(token) }) .then(() => { - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2); - done(); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2) + done() }) - .catch((error) => done.fail(error)); - }); - }); -}); + .catch((error) => done.fail(error)) + }) + }) +}) diff --git a/test/unit/helpers/data/glance.js b/test/unit/helpers/data/glance.js index fa8e255..071c6a1 100644 --- a/test/unit/helpers/data/glance.js +++ b/test/unit/helpers/data/glance.js @@ -25,100 +25,100 @@ * format, rather just the subsection pointing to a particular cloud. */ const glanceConfig = { - region_id: "RegionOne", - url: "http://192.168.99.99:9292/", - region: "RegionOne", - interface: "public", - id: "0b8b5f0f14904136ab5a4f83f27ec49a" -}; + region_id: 'RegionOne', + url: 'http://192.168.99.99:9292/', + region: 'RegionOne', + interface: 'public', + id: '0b8b5f0f14904136ab5a4f83f27ec49a' +} /** * Build a new FetchMock configuration for the root endpoint. * * @returns {{}} A full FetchMock configuration for Glance's Root Resource. */ -function rootResponse() { +function rootResponse () { return { method: 'GET', matcher: 'http://192.168.99.99:9292/', response: { versions: [ { - status: "CURRENT", - id: "v2.5", + status: 'CURRENT', + id: 'v2.5', links: [ { - href: "http://192.168.99.99:9292/v2/", - rel: "self" + href: 'http://192.168.99.99:9292/v2/', + rel: 'self' } ] }, { - status: "SUPPORTED", - id: "v2.3", + status: 'SUPPORTED', + id: 'v2.3', links: [ { - href: "http://192.168.99.99:9292/v2/", - rel: "self" + href: 'http://192.168.99.99:9292/v2/', + rel: 'self' } ] }, { - status: "SUPPORTED", - id: "v2.2", + status: 'SUPPORTED', + id: 'v2.2', links: [ { - href: "http://192.168.99.99:9292/v2/", - rel: "self" + href: 'http://192.168.99.99:9292/v2/', + rel: 'self' } ] }, { - status: "SUPPORTED", - id: "v2.1", + status: 'SUPPORTED', + id: 'v2.1', links: [ { - href: "http://192.168.99.99:9292/v2/", - rel: "self" + href: 'http://192.168.99.99:9292/v2/', + rel: 'self' } ] }, { - status: "SUPPORTED", - id: "v2.0", + status: 'SUPPORTED', + id: 'v2.0', links: [ { - href: "http://192.168.99.99:9292/v2/", - rel: "self" + href: 'http://192.168.99.99:9292/v2/', + rel: 'self' } ] }, { - status: "SUPPORTED", - id: "v1.1", + status: 'SUPPORTED', + id: 'v1.1', links: [ { - href: "http://192.168.99.99:9292/v1/", - rel: "self" + href: 'http://192.168.99.99:9292/v1/', + rel: 'self' } ] }, { - status: "SUPPORTED", - id: "v1.0", + status: 'SUPPORTED', + id: 'v1.0', links: [ { - href: "http://192.168.99.99:9292/v1/", - rel: "self" + href: 'http://192.168.99.99:9292/v1/', + rel: 'self' } ] } ] } - }; + } } -function imageList(token) { +function imageList (token) { return { method: 'GET', matcher: 'http://192.168.99.99:9292/v2/images', @@ -195,10 +195,10 @@ function imageList(token) { schema: '/v2/schemas/images', first: '/v2/images' } - }; + } } export { glanceConfig as config, rootResponse as root, imageList -}; +} diff --git a/test/unit/helpers/data/keystone.js b/test/unit/helpers/data/keystone.js index f3752ca..8a4510c 100644 --- a/test/unit/helpers/data/keystone.js +++ b/test/unit/helpers/data/keystone.js @@ -32,302 +32,302 @@ const cloudConfig = { project_name: 'js-openstack-lib', auth_url: 'http://192.168.99.99/' } -}; +} const catalogListData = [ { endpoints: [ { - region_id: "RegionOne", - url: "http://192.168.99.99/identity_v2_admin", - region: "RegionOne", - interface: "admin", - id: "940664e070864b638dfafc53cfcbe887" + region_id: 'RegionOne', + url: 'http://192.168.99.99/identity_v2_admin', + region: 'RegionOne', + interface: 'admin', + id: '940664e070864b638dfafc53cfcbe887' }, { - region_id: "RegionOne", - url: "http://192.168.99.99/identity", - region: "RegionOne", - interface: "internal", - id: "c3707565bccb407c888040fa9b7e77b0" + region_id: 'RegionOne', + url: 'http://192.168.99.99/identity', + region: 'RegionOne', + interface: 'internal', + id: 'c3707565bccb407c888040fa9b7e77b0' }, { - region_id: "RegionOne", - url: "http://192.168.99.99/identity", - region: "RegionOne", - interface: "public", - id: "fb28f261810449ea98b2df646b847a74" + region_id: 'RegionOne', + url: 'http://192.168.99.99/identity', + region: 'RegionOne', + interface: 'public', + id: 'fb28f261810449ea98b2df646b847a74' } ], - type: "identity", - id: "0599684d07a145659fa858c1deb4e885", - name: "keystone" + type: 'identity', + id: '0599684d07a145659fa858c1deb4e885', + name: 'keystone' }, { endpoints: [ { - region_id: "RegionOne", - url: "http://192.168.99.99:8776/v3/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "internal", - id: "611a5108ef0b4f999ad439b0e1abd9da" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8776/v3/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'internal', + id: '611a5108ef0b4f999ad439b0e1abd9da' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:8776/v3/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "public", - id: "ae08047e33d848c8b1c77f99bc572e22" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8776/v3/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'public', + id: 'ae08047e33d848c8b1c77f99bc572e22' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:8776/v3/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "admin", - id: "e26c6757baa549469772e16e03c051b8" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8776/v3/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'admin', + id: 'e26c6757baa549469772e16e03c051b8' } ], - type: "volumev3", - id: "1092f88a41c64fc7b0331fce96e7df6c", - name: "cinderv3" + type: 'volumev3', + id: '1092f88a41c64fc7b0331fce96e7df6c', + name: 'cinderv3' }, { endpoints: [ { - region_id: "RegionOne", - url: "http://192.168.99.99:8776/v1/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "public", - id: "14ad1642b0874816a7ff08eb0e24be87" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8776/v1/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'public', + id: '14ad1642b0874816a7ff08eb0e24be87' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:8776/v1/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "internal", - id: "8bb7b28802d44e9d80fbb358a3e133af" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8776/v1/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'internal', + id: '8bb7b28802d44e9d80fbb358a3e133af' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:8776/v1/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "admin", - id: "c271745ff29c4c9d829ab3187d41cab7" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8776/v1/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'admin', + id: 'c271745ff29c4c9d829ab3187d41cab7' } ], - type: "volume", - id: "5067360b6f264558945b7d2c312dd126", - name: "cinder" + type: 'volume', + id: '5067360b6f264558945b7d2c312dd126', + name: 'cinder' }, { endpoints: [ { - region_id: "RegionOne", - url: "http://192.168.99.99:9292", - region: "RegionOne", - interface: "admin", - id: "0b8b5f0f14904136ab5a4f83f27ec49a" + region_id: 'RegionOne', + url: 'http://192.168.99.99:9292', + region: 'RegionOne', + interface: 'admin', + id: '0b8b5f0f14904136ab5a4f83f27ec49a' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:9292", - region: "RegionOne", - interface: "internal", - id: "97c90e43e1fe473b85ef47627006dcdd" + region_id: 'RegionOne', + url: 'http://192.168.99.99:9292', + region: 'RegionOne', + interface: 'internal', + id: '97c90e43e1fe473b85ef47627006dcdd' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:9292", - region: "RegionOne", - interface: "public", - id: "ee114418c77a45d2a3cc28240dc4281d" + region_id: 'RegionOne', + url: 'http://192.168.99.99:9292', + region: 'RegionOne', + interface: 'public', + id: 'ee114418c77a45d2a3cc28240dc4281d' } ], - type: "image", - id: "6512ca68fbd543928768201198cd7e42", - name: "glance" + type: 'image', + id: '6512ca68fbd543928768201198cd7e42', + name: 'glance' }, { endpoints: [ { - region_id: "RegionOne", - url: "http://192.168.99.99:8774/v2.1", - region: "RegionOne", - interface: "internal", - id: "14129d81da0e44abae0c082c535b58cc" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8774/v2.1', + region: 'RegionOne', + interface: 'internal', + id: '14129d81da0e44abae0c082c535b58cc' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:8774/v2.1", - region: "RegionOne", - interface: "public", - id: "be681632633d4a62a781148c2fedd6aa" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8774/v2.1', + region: 'RegionOne', + interface: 'public', + id: 'be681632633d4a62a781148c2fedd6aa' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:8774/v2.1", - region: "RegionOne", - interface: "admin", - id: "f8979efb0903442a9068d57fce4eafb2" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8774/v2.1', + region: 'RegionOne', + interface: 'admin', + id: 'f8979efb0903442a9068d57fce4eafb2' } ], - type: "compute", - id: "6d3dd68ae2224fd39503342220b5d2c2", - name: "nova" + type: 'compute', + id: '6d3dd68ae2224fd39503342220b5d2c2', + name: 'nova' }, { endpoints: [ { - region_id: "RegionOne", - url: "http://192.168.99.99:8774/v2/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "admin", - id: "308f5ed663a7417db3f078f7e3b66db8" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8774/v2/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'admin', + id: '308f5ed663a7417db3f078f7e3b66db8' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:8774/v2/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "public", - id: "9f08e41e8156498ba01b5cc83cc9e1da" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8774/v2/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'public', + id: '9f08e41e8156498ba01b5cc83cc9e1da' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:8774/v2/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "internal", - id: "b855d4c048f1468f9df5a9950ae811c6" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8774/v2/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'internal', + id: 'b855d4c048f1468f9df5a9950ae811c6' } ], - type: "compute_legacy", - id: "8ca07a04d03145a094c404b5edf70c18", - name: "nova_legacy" + type: 'compute_legacy', + id: '8ca07a04d03145a094c404b5edf70c18', + name: 'nova_legacy' }, { endpoints: [ { - region_id: "RegionOne", - url: "http://192.168.99.99:8776/v2/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "internal", - id: "2b6e28e0aade41b5b80baa9012e54ca4" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8776/v2/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'internal', + id: '2b6e28e0aade41b5b80baa9012e54ca4' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:8776/v2/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "admin", - id: "79c96252a8ab4c7181ef4fe97237c314" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8776/v2/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'admin', + id: '79c96252a8ab4c7181ef4fe97237c314' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:8776/v2/8b2aa635109f4d0ab355e18a269d341f", - region: "RegionOne", - interface: "public", - id: "8d4cbc86845a4ecb90f19903636205a7" + region_id: 'RegionOne', + url: 'http://192.168.99.99:8776/v2/8b2aa635109f4d0ab355e18a269d341f', + region: 'RegionOne', + interface: 'public', + id: '8d4cbc86845a4ecb90f19903636205a7' } ], - type: "volumev2", - id: "a7967e90d1044b1fa6d80b033f1da510", - name: "cinderv2" + type: 'volumev2', + id: 'a7967e90d1044b1fa6d80b033f1da510', + name: 'cinderv2' }, { endpoints: [ { - region_id: "RegionOne", - url: "http://192.168.99.99:9696/", - region: "RegionOne", - interface: "public", - id: "7033fa4ebed74e3fa51753162150a1f2" + region_id: 'RegionOne', + url: 'http://192.168.99.99:9696/', + region: 'RegionOne', + interface: 'public', + id: '7033fa4ebed74e3fa51753162150a1f2' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:9696/", - region: "RegionOne", - interface: "internal", - id: "7aa942d402a34d4c90454b9d84285855" + region_id: 'RegionOne', + url: 'http://192.168.99.99:9696/', + region: 'RegionOne', + interface: 'internal', + id: '7aa942d402a34d4c90454b9d84285855' }, { - region_id: "RegionOne", - url: "http://192.168.99.99:9696/", - region: "RegionOne", - interface: "admin", - id: "bd8db1bafe41489bbbc45641e525ee7d" + region_id: 'RegionOne', + url: 'http://192.168.99.99:9696/', + region: 'RegionOne', + interface: 'admin', + id: 'bd8db1bafe41489bbbc45641e525ee7d' }, { - region_id: "RegionTwo", - url: "http://192.168.99.100:9696/", - region: "RegionTwo", - interface: "public", - id: "7033fa4ebed74e3fa51753162150a1f2" + region_id: 'RegionTwo', + url: 'http://192.168.99.100:9696/', + region: 'RegionTwo', + interface: 'public', + id: '7033fa4ebed74e3fa51753162150a1f2' }, { - region_id: "RegionTwo", - url: "http://192.168.99.100:9696/", - region: "RegionOne", - interface: "RegionTwo", - id: "7aa942d402a34d4c90454b9d84285855" + region_id: 'RegionTwo', + url: 'http://192.168.99.100:9696/', + region: 'RegionOne', + interface: 'RegionTwo', + id: '7aa942d402a34d4c90454b9d84285855' }, { - region_id: "RegionTwo", - url: "http://192.168.99.100:9696/", - region: "RegionTwo", - interface: "admin", - id: "bd8db1bafe41489bbbc45641e525ee7d" + region_id: 'RegionTwo', + url: 'http://192.168.99.100:9696/', + region: 'RegionTwo', + interface: 'admin', + id: 'bd8db1bafe41489bbbc45641e525ee7d' } ], - type: "network", - id: "f36b9e68ef114769b85024513ee61047", - name: "neutron" + type: 'network', + id: 'f36b9e68ef114769b85024513ee61047', + name: 'neutron' } -]; +] const tokenInfoData = { is_domain: false, methods: [ - "password" + 'password' ], roles: [ { - id: "cfa75a8719f544e2903e5899785b0cf0", - name: "anotherrole" + id: 'cfa75a8719f544e2903e5899785b0cf0', + name: 'anotherrole' }, { - id: "5f8126fad6704a999a3651955c7d8219", - name: "Member" + id: '5f8126fad6704a999a3651955c7d8219', + name: 'Member' } ], is_admin_project: false, project: { domain: { - id: "default", - name: "Default" + id: 'default', + name: 'Default' }, - id: "8b2aa635109f4d0ab355e18a269d341f", - name: "demo" + id: '8b2aa635109f4d0ab355e18a269d341f', + name: 'demo' }, catalog: catalogListData, - expires_at: "2016-08-19T18:04:11.157434Z", + expires_at: '2016-08-19T18:04:11.157434Z', user: { domain: { - id: "default", - name: "Default" + id: 'default', + name: 'Default' }, - id: "d56a64f45da0450a826ede637be64304", - name: "demo" + id: 'd56a64f45da0450a826ede637be64304', + name: 'demo' }, audit_ids: [ - "FtgqCjtuR2-V36loBJ8mxQ" + 'FtgqCjtuR2-V36loBJ8mxQ' ], - issued_at: "2016-08-19T17:04:11.157456Z" -}; + issued_at: '2016-08-19T17:04:11.157456Z' +} /** * Build a new FetchMock configuration for the root endpoint. * * @returns {{}} A full FetchMock configuration for Keystone's Root Resource. */ -function rootResponse() { +function rootResponse () { return { method: 'GET', matcher: 'http://192.168.99.99/', @@ -335,56 +335,56 @@ function rootResponse() { versions: { values: [ { - status: "stable", - updated: "2016-10-06T00:00:00Z", - "media-types": [ + status: 'stable', + updated: '2016-10-06T00:00:00Z', + 'media-types': [ { - base: "application/json", - type: "application/vnd.openstack.identity-v3+json" + base: 'application/json', + type: 'application/vnd.openstack.identity-v3+json' } ], - id: "v3.7", + id: 'v3.7', links: [ { - href: "http://docs.openstack.org/", - type: "text/html", - rel: "describedby" + href: 'http://docs.openstack.org/', + type: 'text/html', + rel: 'describedby' }, { - href: "http://192.168.99.99/identity_v2_admin/v3/", - rel: "self" + href: 'http://192.168.99.99/identity_v2_admin/v3/', + rel: 'self' } ] }, { - status: "deprecated", - updated: "2016-08-04T00:00:00Z", - "media-types": [ + status: 'deprecated', + updated: '2016-08-04T00:00:00Z', + 'media-types': [ { - base: "application/json", - type: "application/vnd.openstack.identity-v2.0+json" + base: 'application/json', + type: 'application/vnd.openstack.identity-v2.0+json' } ], - id: "v2.0", + id: 'v2.0', links: [ { - href: "http://192.168.99.99/identity_v2_admin/v2.0/", - rel: "self" + href: 'http://192.168.99.99/identity_v2_admin/v2.0/', + rel: 'self' }, { - href: "http://docs.openstack.org/", - type: "text/html", - rel: "describedby" + href: 'http://docs.openstack.org/', + type: 'text/html', + rel: 'describedby' } ] } ] } } - }; + } } -function tokenIssue() { +function tokenIssue () { return { method: 'POST', matcher: 'http://192.168.99.99/identity_v2_admin/v3/auth/tokens', @@ -397,10 +397,10 @@ function tokenIssue() { token: tokenInfoData } } - }; + } } -function tokenRevoke(token, adminToken = null) { +function tokenRevoke (token, adminToken = null) { return { method: 'DELETE', matcher: 'http://192.168.99.99/identity_v2_admin/v3/auth/tokens', @@ -411,10 +411,10 @@ function tokenRevoke(token, adminToken = null) { response: { status: 204 } - }; + } } -function tokenInfo(token) { +function tokenInfo (token) { return { method: 'GET', matcher: 'http://192.168.99.99/identity_v2_admin/v3/auth/tokens', @@ -427,10 +427,10 @@ function tokenInfo(token) { token: tokenInfoData } } - }; + } } -function catalogList(token) { +function catalogList (token) { return { method: 'GET', matcher: 'http://192.168.99.99/identity_v2_admin/v3/auth/catalog', @@ -440,7 +440,7 @@ function catalogList(token) { response: { catalog: catalogListData } - }; + } } export { @@ -449,5 +449,5 @@ export { tokenIssue, tokenRevoke, tokenInfo, - catalogList, -}; + catalogList +} diff --git a/test/unit/helpers/data/neutron.js b/test/unit/helpers/data/neutron.js index bce8f36..93ce6eb 100644 --- a/test/unit/helpers/data/neutron.js +++ b/test/unit/helpers/data/neutron.js @@ -25,19 +25,19 @@ * format but a subsection of service endpoint return by keystone's catalog. */ const neutronConfig = { - region_id: "RegionOne", - url: "http://192.168.99.99:9696/", - region: "RegionOne", - interface: "public", - id: "0b8b5f0f14904136ab5a4f83f27ec49a" -}; + region_id: 'RegionOne', + url: 'http://192.168.99.99:9696/', + region: 'RegionOne', + interface: 'public', + id: '0b8b5f0f14904136ab5a4f83f27ec49a' +} /** * Build a new FetchMock configuration for the root endpoint. * * @returns {{}} A full FetchMock configuration for Neutron's Root Resource. */ -function rootResponse() { +function rootResponse () { return { method: 'GET', matcher: 'http://192.168.99.99:9696/', @@ -55,10 +55,10 @@ function rootResponse() { } ] } - }; + } } -function networkList(token) { +function networkList (token) { return { method: 'GET', matcher: 'http://192.168.99.99:9696/v2.0/networks', @@ -103,11 +103,11 @@ function networkList(token) { } ] } - }; + } } export { neutronConfig as config, rootResponse as root, networkList -}; +} diff --git a/test/unit/helpers/data/nova.js b/test/unit/helpers/data/nova.js index aedacb9..2436b69 100644 --- a/test/unit/helpers/data/nova.js +++ b/test/unit/helpers/data/nova.js @@ -24,40 +24,40 @@ * A catalog entry that matches what we expect from the Keystone Catalog for nova compute. */ const novaConfig = { - region_id: "RegionOne", - url: "http://192.168.99.99:8774/v2.1", - region: "RegionOne", - interface: "public", - id: "be681632633d4a62a781148c2fedd6aa" -}; + region_id: 'RegionOne', + url: 'http://192.168.99.99:8774/v2.1', + region: 'RegionOne', + interface: 'public', + id: 'be681632633d4a62a781148c2fedd6aa' +} /** * Build a new FetchMock configuration for the root endpoint. * * @returns {{}} A full FetchMock configuration for Nova's Root Resource. */ -function rootResponse() { +function rootResponse () { return { method: 'GET', matcher: 'http://192.168.99.99:8774/', response: { versions: [{ - status: "CURRENT", - updated: "2013-07-23T11:33:21Z", - links: [{href: "http://192.168.99.99:8774/v2.1/", rel: "self"}], - min_version: "2.1", - version: "2.38", - id: "v2.1" + status: 'CURRENT', + updated: '2013-07-23T11:33:21Z', + links: [{ href: 'http://192.168.99.99:8774/v2.1/', rel: 'self' }], + min_version: '2.1', + version: '2.38', + id: 'v2.1' }, { - status: "SUPPORTED", - updated: "2011-01-21T11:33:21Z", - links: [{href: "http://192.168.99.99:8774/v2/", rel: "self"}], - min_version: "", - version: "", - id: "v2.0" + status: 'SUPPORTED', + updated: '2011-01-21T11:33:21Z', + links: [{ href: 'http://192.168.99.99:8774/v2/', rel: 'self' }], + min_version: '', + version: '', + id: 'v2.0' }] } - }; + } } /** @@ -66,14 +66,14 @@ function rootResponse() { * @param {String} version The version ID. * @return {{}} A FetchMock configuration for this request's response. */ -function versionedRootResponse(version = 'v2.1') { +function versionedRootResponse (version = 'v2.1') { return { method: 'GET', matcher: `http://192.168.99.99:8774/${version}`, response: { status: 401 } - }; + } } /** @@ -82,7 +82,7 @@ function versionedRootResponse(version = 'v2.1') { * @param {String} token An auth token. * @return {{}} A FetchMock configuration for this request's response. */ -function flavorList(token) { +function flavorList (token) { return { method: 'GET', matcher: 'http://192.168.99.99:8774/v2.1/flavors', @@ -91,92 +91,92 @@ function flavorList(token) { }, response: { flavors: [{ - id: "1", + id: '1', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/1", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/1", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/1', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/1', rel: 'bookmark' } ], - name: "m1.tiny" + name: 'm1.tiny' }, { - id: "2", + id: '2', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/2", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/2", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/2', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/2', rel: 'bookmark' } ], - name: "m1.small" + name: 'm1.small' }, { - id: "3", + id: '3', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/3", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/3", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/3', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/3', rel: 'bookmark' } ], - name: "m1.medium" + name: 'm1.medium' }, { - id: "4", + id: '4', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/4", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/4", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/4', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/4', rel: 'bookmark' } ], - name: "m1.large" + name: 'm1.large' }, { - id: "42", + id: '42', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/42", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/42", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/42', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/42', rel: 'bookmark' } ], - name: "m1.nano" + name: 'm1.nano' }, { - id: "5", + id: '5', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/5", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/5", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/5', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/5', rel: 'bookmark' } ], - name: "m1.xlarge" + name: 'm1.xlarge' }, { - id: "84", + id: '84', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/84", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/84", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/84', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/84', rel: 'bookmark' } ], - name: "m1.micro" + name: 'm1.micro' }, { - id: "c1", + id: 'c1', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/c1", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/c1", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/c1', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/c1', rel: 'bookmark' } ], - name: "cirros256" + name: 'cirros256' }, { - id: "d1", + id: 'd1', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/d1", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/d1", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/d1', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/d1', rel: 'bookmark' } ], - name: "ds512M" + name: 'ds512M' }, { - id: "d2", + id: 'd2', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/d2", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/d2", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/d2', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/d2', rel: 'bookmark' } ], - name: "ds1G" + name: 'ds1G' }, { - id: "d3", + id: 'd3', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/d3", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/d3", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/d3', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/d3', rel: 'bookmark' } ], - name: "ds2G" + name: 'ds2G' }, { - id: "d4", + id: 'd4', links: [ - {href: "http://192.168.99.99:8774/v2.1/flavors/d4", rel: "self"}, - {href: "http://192.168.99.99:8774/flavors/d4", rel: "bookmark"} + { href: 'http://192.168.99.99:8774/v2.1/flavors/d4', rel: 'self' }, + { href: 'http://192.168.99.99:8774/flavors/d4', rel: 'bookmark' } ], - name: "ds4G" + name: 'ds4G' }] } - }; + } } export { @@ -184,4 +184,4 @@ export { rootResponse as root, versionedRootResponse as rootVersion, flavorList -}; +} diff --git a/test/unit/helpers/data/openstack.js b/test/unit/helpers/data/openstack.js index 5c14c4c..d084447 100644 --- a/test/unit/helpers/data/openstack.js +++ b/test/unit/helpers/data/openstack.js @@ -25,7 +25,7 @@ * @param {String} regionName A region name to use * @returns {{}} a cloud config object. */ -function cloudConfig(regionName = 'RegionOne') { +function cloudConfig (regionName = 'RegionOne') { return { region_name: regionName, auth: { @@ -34,9 +34,9 @@ function cloudConfig(regionName = 'RegionOne') { project_name: 'js-openstack-lib', auth_url: 'http://192.168.99.99/' } - }; + } } export { - cloudConfig as config, -}; + cloudConfig as config +} diff --git a/test/unit/helpers/data/versions.js b/test/unit/helpers/data/versions.js index e637dd3..56ed147 100644 --- a/test/unit/helpers/data/versions.js +++ b/test/unit/helpers/data/versions.js @@ -22,8 +22,8 @@ /** * URLs to match the test data below. */ -const rootUrl = "http://example.com/"; -const subUrl = `${rootUrl}v1`; +const rootUrl = 'http://example.com/' +const subUrl = `${rootUrl}v1` /** * A mock list of supported versions for the below requests. @@ -32,72 +32,72 @@ const subUrl = `${rootUrl}v1`; */ const versions = [ 'v2.3' -]; +] /** * Build a new FetchMock configuration for the versions (root) endpoint. * * @returns {{}} A full FetchMock configuration for a versions resource. */ -function rootResponse() { +function rootResponse () { return { method: 'GET', matcher: rootUrl, response: { versions: [ { - status: "CURRENT", - id: "v2.3", + status: 'CURRENT', + id: 'v2.3', links: [ { href: `${rootUrl}v2/`, - rel: "self" + rel: 'self' } ] }, { - status: "SUPPORTED", - id: "v2.2", + status: 'SUPPORTED', + id: 'v2.2', links: [ { href: `${rootUrl}v2/`, - rel: "self" + rel: 'self' } ] }, { - status: "SUPPORTED", - id: "v2.1", + status: 'SUPPORTED', + id: 'v2.1', links: [ { href: `${rootUrl}v2/`, - rel: "self" + rel: 'self' } ] }, { - status: "SUPPORTED", - id: "v1.1", + status: 'SUPPORTED', + id: 'v1.1', links: [ { href: `${rootUrl}v1/`, - rel: "self" + rel: 'self' } ] }, { - status: "SUPPORTED", - id: "v1.0", + status: 'SUPPORTED', + id: 'v1.0', links: [ { href: `${rootUrl}v1/`, - rel: "self" + rel: 'self' } ] } ] } - }; + } } /** @@ -106,14 +106,14 @@ function rootResponse() { * @param {int} httpStatus The HTTP status for the response. * @returns {{}} A full FetchMock configuration a failing request.. */ -function subResponse(httpStatus = 401) { +function subResponse (httpStatus = 401) { return { method: 'GET', matcher: subUrl, response: { status: httpStatus } - }; + } } export { @@ -122,4 +122,4 @@ export { versions, rootResponse, subResponse -}; +} diff --git a/test/unit/keystoneTest.js b/test/unit/keystoneTest.js index e21f458..822ef97 100644 --- a/test/unit/keystoneTest.js +++ b/test/unit/keystoneTest.js @@ -1,332 +1,330 @@ -import Keystone from '../../src/keystone.js'; -import * as mockData from './helpers/data/keystone'; -import fetchMock from 'fetch-mock'; +import Keystone from '../../src/keystone.js' +import * as mockData from './helpers/data/keystone' +import fetchMock from 'fetch-mock' describe('Keystone', () => { - - afterEach(fetchMock.restore); + afterEach(fetchMock.restore) it('should export a class', () => { - const keystone = new Keystone(mockData.config); - expect(keystone).toBeDefined(); - }); + const keystone = new Keystone(mockData.config) + expect(keystone).toBeDefined() + }) it('should throw an error for an empty config', () => { - expect(() => new Keystone()).toThrow(); - }); + expect(() => new Keystone()).toThrow() + }) - describe("serviceEndpoint()", () => { - it("Should return a valid endpoint to the keystone API.", (done) => { - const keystone = new Keystone(mockData.config); + describe('serviceEndpoint()', () => { + it('Should return a valid endpoint to the keystone API.', (done) => { + const keystone = new Keystone(mockData.config) - fetchMock.mock(mockData.root()); + fetchMock.mock(mockData.root()) keystone.serviceEndpoint() .then((endpoint) => { - expect(endpoint).toEqual('http://192.168.99.99/identity_v2_admin/v3/'); - done(); + expect(endpoint).toEqual('http://192.168.99.99/identity_v2_admin/v3/') + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("tokenIssue()", () => { + describe('tokenIssue()', () => { + it('should "just work" by using provided credentials from the config.', (done) => { + const mockOptions = mockData.tokenIssue() + fetchMock.mock(mockData.root()) + fetchMock.mock(mockOptions) - it("should 'just work' by using provided credentials from the config.", (done) => { - let mockOptions = mockData.tokenIssue(); - fetchMock.mock(mockData.root()); - fetchMock.mock(mockOptions); - - const keystone = new Keystone(mockData.config); + const keystone = new Keystone(mockData.config) keystone .tokenIssue() .then((token) => { - expect(token).toEqual('test_token'); // From mock data - done(); + expect(token).toEqual('test_token') // From mock data + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should support authentication with a user ID", (done) => { - let mockOptions = mockData.tokenIssue(); - fetchMock.mock(mockData.root()); - fetchMock.mock(mockOptions); + it('should support authentication with a user ID', (done) => { + const mockOptions = mockData.tokenIssue() + fetchMock.mock(mockData.root()) + fetchMock.mock(mockOptions) - const userId = 'userId'; + const userId = 'userId' - const keystone = new Keystone(mockData.config); + const keystone = new Keystone(mockData.config) keystone .tokenIssue({ user_id: userId }) .then(() => { - const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body); - expect(requestBody.auth.identity.password.user.id).toEqual(userId); - done(); + const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body) + expect(requestBody.auth.identity.password.user.id).toEqual(userId) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should support authentication with a username and a user domain ID", (done) => { - let mockOptions = mockData.tokenIssue(); - fetchMock.mock(mockData.root()); - fetchMock.mock(mockOptions); + it('should support authentication with a username and a user domain ID', (done) => { + const mockOptions = mockData.tokenIssue() + fetchMock.mock(mockData.root()) + fetchMock.mock(mockOptions) - const username = 'username'; - const userDomainId = 'userDomainId'; + const username = 'username' + const userDomainId = 'userDomainId' - const keystone = new Keystone(mockData.config); + const keystone = new Keystone(mockData.config) keystone .tokenIssue({ username: username, user_domain_id: userDomainId }) .then(() => { - const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body); - expect(requestBody.auth.identity.password.user.name).toEqual(username); - expect(requestBody.auth.identity.password.user.domain.id).toEqual(userDomainId); - done(); + const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body) + expect(requestBody.auth.identity.password.user.name).toEqual(username) + expect(requestBody.auth.identity.password.user.domain.id).toEqual(userDomainId) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should support authentication with a username and a user domain name", (done) => { - let mockOptions = mockData.tokenIssue(); - fetchMock.mock(mockData.root()); - fetchMock.mock(mockOptions); + it('should support authentication with a username and a user domain name', (done) => { + const mockOptions = mockData.tokenIssue() + fetchMock.mock(mockData.root()) + fetchMock.mock(mockOptions) - const username = 'username'; - const userDomainName = 'userDomainName'; + const username = 'username' + const userDomainName = 'userDomainName' - const keystone = new Keystone(mockData.config); + const keystone = new Keystone(mockData.config) keystone .tokenIssue({ username: username, user_domain_name: userDomainName }) .then(() => { - const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body); - expect(requestBody.auth.identity.password.user.name).toEqual(username); - expect(requestBody.auth.identity.password.user.domain.name).toEqual(userDomainName); - done(); + const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body) + expect(requestBody.auth.identity.password.user.name).toEqual(username) + expect(requestBody.auth.identity.password.user.domain.name).toEqual(userDomainName) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should support authentication with a project ID", (done) => { - let mockOptions = mockData.tokenIssue(); - fetchMock.mock(mockData.root()); - fetchMock.mock(mockOptions); + it('should support authentication with a project ID', (done) => { + const mockOptions = mockData.tokenIssue() + fetchMock.mock(mockData.root()) + fetchMock.mock(mockOptions) - const projectId = 'projectId'; + const projectId = 'projectId' - const keystone = new Keystone(mockData.config); + const keystone = new Keystone(mockData.config) keystone .tokenIssue({ - project_id: projectId, + project_id: projectId }) .then(() => { - const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body); - expect(requestBody.auth.scope.project.id).toEqual(projectId); - done(); + const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body) + expect(requestBody.auth.scope.project.id).toEqual(projectId) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should support authentication with a project name and a project domain ID", (done) => { - let mockOptions = mockData.tokenIssue(); - fetchMock.mock(mockData.root()); - fetchMock.mock(mockOptions); + it('should support authentication with a project name and a project domain ID', (done) => { + const mockOptions = mockData.tokenIssue() + fetchMock.mock(mockData.root()) + fetchMock.mock(mockOptions) - const projectName = 'projectName'; - const projectDomainId = 'projectDomainId'; + const projectName = 'projectName' + const projectDomainId = 'projectDomainId' - const keystone = new Keystone(mockData.config); + const keystone = new Keystone(mockData.config) keystone .tokenIssue({ project_name: projectName, project_domain_id: projectDomainId }) .then(() => { - const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body); - expect(requestBody.auth.scope.project.name).toEqual(projectName); - expect(requestBody.auth.scope.project.domain.id).toEqual(projectDomainId); - done(); + const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body) + expect(requestBody.auth.scope.project.name).toEqual(projectName) + expect(requestBody.auth.scope.project.domain.id).toEqual(projectDomainId) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should support authentication with a project name and a project domain name", (done) => { - let mockOptions = mockData.tokenIssue(); - fetchMock.mock(mockData.root()); - fetchMock.mock(mockOptions); + it('should support authentication with a project name and a project domain name', (done) => { + const mockOptions = mockData.tokenIssue() + fetchMock.mock(mockData.root()) + fetchMock.mock(mockOptions) - const projectName = 'projectName'; - const projectDomainName = 'projectDomainName'; + const projectName = 'projectName' + const projectDomainName = 'projectDomainName' - const keystone = new Keystone(mockData.config); + const keystone = new Keystone(mockData.config) keystone .tokenIssue({ project_name: projectName, project_domain_name: projectDomainName }) .then(() => { - const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body); - expect(requestBody.auth.scope.project.name).toEqual(projectName); - expect(requestBody.auth.scope.project.domain.name).toEqual(projectDomainName); - done(); + const requestBody = JSON.parse(fetchMock.lastCall(mockOptions.matcher)[1].body) + expect(requestBody.auth.scope.project.name).toEqual(projectName) + expect(requestBody.auth.scope.project.domain.name).toEqual(projectDomainName) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("Should not cache its results", (done) => { - let mockOptions = mockData.tokenIssue(); - fetchMock.mock(mockData.root()); - fetchMock.mock(mockOptions); + it('Should not cache its results', (done) => { + const mockOptions = mockData.tokenIssue() + fetchMock.mock(mockData.root()) + fetchMock.mock(mockOptions) - const keystone = new Keystone(mockData.config); + const keystone = new Keystone(mockData.config) keystone .tokenIssue() .then((token) => { - expect(token).toEqual('test_token'); // From mock data - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1); - return keystone.tokenIssue(); + expect(token).toEqual('test_token') // From mock data + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1) + return keystone.tokenIssue() }) .then((token) => { - expect(token).toEqual('test_token'); // From mock data - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2); - done(); + expect(token).toEqual('test_token') // From mock data + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("tokenRevoke()", () => { - let keystone = null; + describe('tokenRevoke()', () => { + let keystone = null beforeEach(() => { - fetchMock.mock(mockData.root()); - keystone = new Keystone(mockData.config); - }); + fetchMock.mock(mockData.root()) + keystone = new Keystone(mockData.config) + }) - it("should return a 204 response on a valid revocation.", (done) => { - const token = 'test_token'; - const adminToken = 'test_admin_token'; + it('should return a 204 response on a valid revocation.', (done) => { + const token = 'test_token' + const adminToken = 'test_admin_token' - fetchMock.mock(mockData.tokenRevoke(token, adminToken)); + fetchMock.mock(mockData.tokenRevoke(token, adminToken)) keystone .tokenRevoke(token, adminToken) .then((response) => { - expect(response.status).toEqual(204); // From mock data - done(); + expect(response.status).toEqual(204) // From mock data + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("Should not cache its results", (done) => { - const token = 'test_token'; + it('Should not cache its results', (done) => { + const token = 'test_token' - let mockOptions = mockData.tokenRevoke(token); - fetchMock.mock(mockOptions); + const mockOptions = mockData.tokenRevoke(token) + fetchMock.mock(mockOptions) keystone .tokenRevoke(token) .then((response) => { - expect(response.status).toEqual(204); - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1); + expect(response.status).toEqual(204) + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1) // Yes, I realize that this should actually return an error since the token is no // longer valid, but we're testing for promise caching here, not valid http flow. - return keystone.tokenRevoke(token); + return keystone.tokenRevoke(token) }) .then((response) => { - expect(response.status).toEqual(204); - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2); - done(); + expect(response.status).toEqual(204) + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("tokenInfo()", () => { - let keystone = null; + describe('tokenInfo()', () => { + let keystone = null beforeEach(() => { - fetchMock.mock(mockData.root()); - keystone = new Keystone(mockData.config); - }); + fetchMock.mock(mockData.root()) + keystone = new Keystone(mockData.config) + }) - const token = 'test_token'; + const token = 'test_token' - it("should return information about a token", (done) => { - fetchMock.mock(mockData.tokenInfo(token)); + it('should return information about a token', (done) => { + fetchMock.mock(mockData.tokenInfo(token)) keystone .tokenInfo(token) .then((info) => { - expect(info.token).toBeDefined(); - done(); + expect(info.token).toBeDefined() + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("Should not cache its results", (done) => { - let mockOptions = mockData.tokenInfo(token); - fetchMock.mock(mockOptions); + it('Should not cache its results', (done) => { + const mockOptions = mockData.tokenInfo(token) + fetchMock.mock(mockOptions) keystone .tokenInfo(token) .then((info) => { - expect(info.token).toBeDefined(); - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1); - return keystone.tokenInfo(token); + expect(info.token).toBeDefined() + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1) + return keystone.tokenInfo(token) }) .then((info) => { - expect(info.token).toBeDefined(); - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2); - done(); + expect(info.token).toBeDefined() + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("catalogList()", () => { - let keystone = null; + describe('catalogList()', () => { + let keystone = null beforeEach(() => { - fetchMock.mock(mockData.root()); - keystone = new Keystone(mockData.config); - }); + fetchMock.mock(mockData.root()) + keystone = new Keystone(mockData.config) + }) - it("should return the catalog as an array.", (done) => { - const token = 'test_token'; + it('should return the catalog as an array.', (done) => { + const token = 'test_token' - fetchMock.mock(mockData.catalogList(token)); + fetchMock.mock(mockData.catalogList(token)) keystone .catalogList(token) .then((catalog) => { - expect(catalog.length).not.toBe(0); - done(); + expect(catalog.length).not.toBe(0) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("Should not cache its results", (done) => { - const token = 'test_token'; + it('Should not cache its results', (done) => { + const token = 'test_token' - let mockOptions = mockData.catalogList(token); - fetchMock.mock(mockOptions); + const mockOptions = mockData.catalogList(token) + fetchMock.mock(mockOptions) keystone .catalogList(token) .then(() => { - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1); - return keystone.catalogList(token); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1) + return keystone.catalogList(token) }) .then(() => { - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2); - done(); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2) + done() }) - .catch((error) => done.fail(error)); - }); - }); -}); + .catch((error) => done.fail(error)) + }) + }) +}) diff --git a/test/unit/neutronTest.js b/test/unit/neutronTest.js index e31f592..8385579 100644 --- a/test/unit/neutronTest.js +++ b/test/unit/neutronTest.js @@ -14,66 +14,65 @@ * under the License. */ -import Neutron from '../../src/neutron.js'; -import * as mockData from './helpers/data/neutron'; -import fetchMock from 'fetch-mock'; +import Neutron from '../../src/neutron.js' +import * as mockData from './helpers/data/neutron' +import fetchMock from 'fetch-mock' describe('neutron', () => { - - afterEach(fetchMock.restore); + afterEach(fetchMock.restore) it('should export a class', () => { - const neutron = new Neutron(mockData.config); - expect(neutron).toBeDefined(); - }); + const neutron = new Neutron(mockData.config) + expect(neutron).toBeDefined() + }) it('should throw an error for an empty config', () => { try { - const neutron = new Neutron(); - neutron.versions(); + const neutron = new Neutron() + neutron.versions() } catch (e) { - expect(e.message).toEqual('An endpoint configuration is required.'); + expect(e.message).toEqual('An endpoint configuration is required.') } - }); + }) - describe("networkList()", () => { - let neutron = null; + describe('networkList()', () => { + let neutron = null beforeEach(() => { - fetchMock.mock(mockData.root()); - neutron = new Neutron(mockData.config); - }); + fetchMock.mock(mockData.root()) + neutron = new Neutron(mockData.config) + }) - it("should return the networks as an array.", (done) => { - const token = 'test_token'; + it('should return the networks as an array.', (done) => { + const token = 'test_token' - fetchMock.mock(mockData.networkList(token)); + fetchMock.mock(mockData.networkList(token)) neutron .networkList(token) .then((networks) => { - expect(networks.length).toBe(2); - done(); + expect(networks.length).toBe(2) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("Should not cache its results", (done) => { - const token = 'test_token'; + it('Should not cache its results', (done) => { + const token = 'test_token' - let mockOptions = mockData.networkList(token); - fetchMock.mock(mockOptions); + const mockOptions = mockData.networkList(token) + fetchMock.mock(mockOptions) neutron .networkList(token) .then(() => { - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1); - return neutron.networkList(token); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1) + return neutron.networkList(token) }) .then(() => { - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2); - done(); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2) + done() }) - .catch((error) => done.fail(error)); - }); - }); -}); + .catch((error) => done.fail(error)) + }) + }) +}) diff --git a/test/unit/novaTest.js b/test/unit/novaTest.js index 57bff95..138e7b5 100644 --- a/test/unit/novaTest.js +++ b/test/unit/novaTest.js @@ -14,62 +14,61 @@ * limitations under the License. */ -import Nova from "../../src/nova.js"; -import * as mockData from "./helpers/data/nova"; -import fetchMock from "fetch-mock"; +import Nova from '../../src/nova.js' +import * as mockData from './helpers/data/nova' +import fetchMock from 'fetch-mock' describe('Nova', () => { - - afterEach(fetchMock.restore); + afterEach(fetchMock.restore) it('should export a class', () => { - const nova = new Nova(mockData.config); - expect(nova).toBeDefined(); - }); + const nova = new Nova(mockData.config) + expect(nova).toBeDefined() + }) it('should throw an error for an empty config', () => { - expect(() => new Nova(null)).toThrow(); - }); + expect(() => new Nova(null)).toThrow() + }) - describe("flavorList()", () => { - let nova = null; + describe('flavorList()', () => { + let nova = null beforeEach(() => { - fetchMock.mock(mockData.rootVersion()); - fetchMock.mock(mockData.root()); - nova = new Nova(mockData.config); - }); + fetchMock.mock(mockData.rootVersion()) + fetchMock.mock(mockData.root()) + nova = new Nova(mockData.config) + }) - it("should return the flavors as an array.", (done) => { - const token = 'test_token'; + it('should return the flavors as an array.', (done) => { + const token = 'test_token' - fetchMock.mock(mockData.flavorList(token)); + fetchMock.mock(mockData.flavorList(token)) nova .flavorList(token) .then((images) => { - expect(images.length).not.toBe(0); - done(); + expect(images.length).not.toBe(0) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("Should not cache its results", (done) => { - const token = 'test_token'; + it('Should not cache its results', (done) => { + const token = 'test_token' - let mockOptions = mockData.flavorList(token); - fetchMock.mock(mockOptions); + const mockOptions = mockData.flavorList(token) + fetchMock.mock(mockOptions) nova .flavorList(token) .then(() => { - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1); - return nova.flavorList(token); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1) + return nova.flavorList(token) }) .then(() => { - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2); - done(); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2) + done() }) - .catch((error) => done.fail(error)); - }); - }); -}); + .catch((error) => done.fail(error)) + }) + }) +}) diff --git a/test/unit/openstackTest.js b/test/unit/openstackTest.js index de8ccb1..5e0b86f 100644 --- a/test/unit/openstackTest.js +++ b/test/unit/openstackTest.js @@ -1,290 +1,288 @@ -import OpenStack from "../../src/openstack"; -import * as openStackMockData from './helpers/data/openstack'; -import * as neutronMockData from './helpers/data/neutron'; -import * as keystoneMockData from './helpers/data/keystone'; -import * as glanceMockData from './helpers/data/glance'; -import * as novaMockData from './helpers/data/nova'; -import fetchMock from 'fetch-mock'; -import Neutron from "../../src/neutron"; -import Keystone from "../../src/keystone"; -import Glance from "../../src/glance"; -import Nova from "../../src/nova"; +import OpenStack from '../../src/openstack' +import * as openStackMockData from './helpers/data/openstack' +import * as neutronMockData from './helpers/data/neutron' +import * as keystoneMockData from './helpers/data/keystone' +import * as glanceMockData from './helpers/data/glance' +import * as novaMockData from './helpers/data/nova' +import fetchMock from 'fetch-mock' +import Neutron from '../../src/neutron' +import Keystone from '../../src/keystone' +import Glance from '../../src/glance' +import Nova from '../../src/nova' -describe("Simple test", () => { +describe('Simple test', () => { + afterEach(fetchMock.restore) - afterEach(fetchMock.restore); + it('should export a class', () => { + const t = new OpenStack(openStackMockData.config()) + expect(t).toBeDefined() + }) - it("should export a class", () => { - let t = new OpenStack(openStackMockData.config()); - expect(t).toBeDefined(); - }); - - it("should throw an error for an empty config", () => { + it('should throw an error for an empty config', () => { try { - let t = new OpenStack(); - t.getConfig(); + const t = new OpenStack() + t.getConfig() } catch (e) { - expect(e.message).toEqual('A configuration is required.'); + expect(e.message).toEqual('A configuration is required.') } - }); + }) - it("getConfig should returns the config", () => { - let openstack = new OpenStack(openStackMockData.config()); - let config = openstack.getConfig(); - expect(config.region_name).toEqual('RegionOne'); - }); + it('getConfig should returns the config', () => { + const openstack = new OpenStack(openStackMockData.config()) + const config = openstack.getConfig() + expect(config.region_name).toEqual('RegionOne') + }) describe('networkList', () => { it('should fetch networkList from neutron', (done) => { - const openstack = new OpenStack(openStackMockData.config()); - const neutron = mockNeutron(openstack); - const networksData = neutronMockData.networkList('token').response.networks; + const openstack = new OpenStack(openStackMockData.config()) + const neutron = mockNeutron(openstack) + const networksData = neutronMockData.networkList('token').response.networks - spyOn(neutron, 'networkList').and.returnValue(Promise.resolve(networksData)); + spyOn(neutron, 'networkList').and.returnValue(Promise.resolve(networksData)) openstack.networkList() .then((networks) => { - expect(networks.length).toBe(2); - done(); + expect(networks.length).toBe(2) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) describe('imageList', () => { it('should fetch imageList from glance', (done) => { - const openstack = new OpenStack(openStackMockData.config()); - const glance = mockGlance(openstack); - const imagesData = glanceMockData.imageList('token').response.images; + const openstack = new OpenStack(openStackMockData.config()) + const glance = mockGlance(openstack) + const imagesData = glanceMockData.imageList('token').response.images - spyOn(glance, 'imageList').and.returnValue(Promise.resolve(imagesData)); + spyOn(glance, 'imageList').and.returnValue(Promise.resolve(imagesData)) openstack.imageList() .then((images) => { - expect(images.length).toBe(3); - done(); + expect(images.length).toBe(3) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) describe('flavorList', () => { it('should fetch flavorList from nova', (done) => { - const openstack = new OpenStack(openStackMockData.config()); - const nova = mockNova(openstack); - const flavorsData = novaMockData.flavorList('token').response.flavors; + const openstack = new OpenStack(openStackMockData.config()) + const nova = mockNova(openstack) + const flavorsData = novaMockData.flavorList('token').response.flavors - spyOn(nova, 'flavorList').and.returnValue(Promise.resolve(flavorsData)); + spyOn(nova, 'flavorList').and.returnValue(Promise.resolve(flavorsData)) openstack.flavorList() .then((flavors) => { - expect(flavors.length).toBe(12); - done(); + expect(flavors.length).toBe(12) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) describe('_neutron', () => { it('creates Neutron instance with the correct endpoint', (done) => { - const token = 'test_token'; - const openstack = new OpenStack(openStackMockData.config()); - const keystone = mockKeystone(openstack); - const catalogData = keystoneMockData.catalogList(token).response.catalog; + const token = 'test_token' + const openstack = new OpenStack(openStackMockData.config()) + const keystone = mockKeystone(openstack) + const catalogData = keystoneMockData.catalogList(token).response.catalog - spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve(token)); - spyOn(keystone, 'catalogList').and.returnValue(Promise.resolve(catalogData)); + spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve(token)) + spyOn(keystone, 'catalogList').and.returnValue(Promise.resolve(catalogData)) openstack._neutron .then((neutron) => { - expect(keystone.catalogList).toHaveBeenCalledWith(token); - expect(neutron).toEqual(jasmine.any(Neutron)); - expect(neutron.endpointUrl).toEqual('http://192.168.99.99:9696/'); - done(); + expect(keystone.catalogList).toHaveBeenCalledWith(token) + expect(neutron).toEqual(jasmine.any(Neutron)) + expect(neutron.endpointUrl).toEqual('http://192.168.99.99:9696/') + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) it('creates Neutron instance for the correct endpoint', (done) => { - const token = 'test_token'; - const openstack = new OpenStack(openStackMockData.config('RegionTwo')); - const keystone = mockKeystone(openstack); - const catalogData = keystoneMockData.catalogList(token).response.catalog; + const token = 'test_token' + const openstack = new OpenStack(openStackMockData.config('RegionTwo')) + const keystone = mockKeystone(openstack) + const catalogData = keystoneMockData.catalogList(token).response.catalog - spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve(token)); - spyOn(keystone, 'catalogList').and.returnValue(Promise.resolve(catalogData)); + spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve(token)) + spyOn(keystone, 'catalogList').and.returnValue(Promise.resolve(catalogData)) openstack._neutron .then((neutron) => { - expect(neutron).toEqual(jasmine.any(Neutron)); - expect(neutron.endpointUrl).toEqual('http://192.168.99.100:9696/'); - done(); + expect(neutron).toEqual(jasmine.any(Neutron)) + expect(neutron.endpointUrl).toEqual('http://192.168.99.100:9696/') + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) it('should cache Neutron instance and Keystone token', (done) => { - const openstack = new OpenStack(openStackMockData.config()); - const tokenIssueMock = keystoneMockData.tokenIssue(); - const catalogListMock = keystoneMockData.catalogList('test_token'); + const openstack = new OpenStack(openStackMockData.config()) + const tokenIssueMock = keystoneMockData.tokenIssue() + const catalogListMock = keystoneMockData.catalogList('test_token') - fetchMock.mock(keystoneMockData.root()); - fetchMock.mock(tokenIssueMock); - fetchMock.mock(catalogListMock); + fetchMock.mock(keystoneMockData.root()) + fetchMock.mock(tokenIssueMock) + fetchMock.mock(catalogListMock) openstack._neutron .then((neutron) => { - expect(neutron).toEqual(jasmine.any(Neutron)); - expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1); - expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1); - return openstack._neutron; + expect(neutron).toEqual(jasmine.any(Neutron)) + expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1) + expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1) + return openstack._neutron }) .then((neutron) => { - expect(neutron).toEqual(jasmine.any(Neutron)); - expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1); - expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1); - done(); + expect(neutron).toEqual(jasmine.any(Neutron)) + expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1) + expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) describe('_glance', () => { it('creates Glance instance with the correct endpoint', (done) => { - const token = 'test_token'; - const openstack = new OpenStack(openStackMockData.config()); - const keystone = mockKeystone(openstack); - const catalogData = keystoneMockData.catalogList(token).response.catalog; + const token = 'test_token' + const openstack = new OpenStack(openStackMockData.config()) + const keystone = mockKeystone(openstack) + const catalogData = keystoneMockData.catalogList(token).response.catalog - spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve(token)); - spyOn(keystone, 'catalogList').and.returnValue(Promise.resolve(catalogData)); + spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve(token)) + spyOn(keystone, 'catalogList').and.returnValue(Promise.resolve(catalogData)) openstack._glance .then((glance) => { - expect(keystone.catalogList).toHaveBeenCalledWith(token); - expect(glance).toEqual(jasmine.any(Glance)); - expect(glance.endpointUrl).toEqual('http://192.168.99.99:9292'); - done(); + expect(keystone.catalogList).toHaveBeenCalledWith(token) + expect(glance).toEqual(jasmine.any(Glance)) + expect(glance.endpointUrl).toEqual('http://192.168.99.99:9292') + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) it('should cache Glance instance and Keystone token', (done) => { - const openstack = new OpenStack(openStackMockData.config()); - const tokenIssueMock = keystoneMockData.tokenIssue(); - const catalogListMock = keystoneMockData.catalogList('test_token'); + const openstack = new OpenStack(openStackMockData.config()) + const tokenIssueMock = keystoneMockData.tokenIssue() + const catalogListMock = keystoneMockData.catalogList('test_token') - fetchMock.mock(keystoneMockData.root()); - fetchMock.mock(tokenIssueMock); - fetchMock.mock(catalogListMock); + fetchMock.mock(keystoneMockData.root()) + fetchMock.mock(tokenIssueMock) + fetchMock.mock(catalogListMock) openstack._glance .then((glance) => { - expect(glance).toEqual(jasmine.any(Glance)); - expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1); - expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1); - return openstack._glance; + expect(glance).toEqual(jasmine.any(Glance)) + expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1) + expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1) + return openstack._glance }) .then((glance) => { - expect(glance).toEqual(jasmine.any(Glance)); - expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1); - expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1); - done(); + expect(glance).toEqual(jasmine.any(Glance)) + expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1) + expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) describe('_nova', () => { it('creates Nova instance with the correct endpoint', (done) => { - const token = 'test_token'; - const openstack = new OpenStack(openStackMockData.config()); - const keystone = mockKeystone(openstack); - const catalogData = keystoneMockData.catalogList(token).response.catalog; + const token = 'test_token' + const openstack = new OpenStack(openStackMockData.config()) + const keystone = mockKeystone(openstack) + const catalogData = keystoneMockData.catalogList(token).response.catalog - spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve(token)); - spyOn(keystone, 'catalogList').and.returnValue(Promise.resolve(catalogData)); + spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve(token)) + spyOn(keystone, 'catalogList').and.returnValue(Promise.resolve(catalogData)) openstack._nova .then((nova) => { - expect(keystone.catalogList).toHaveBeenCalledWith(token); - expect(nova).toEqual(jasmine.any(Nova)); - expect(nova.endpointUrl).toEqual('http://192.168.99.99:8774/v2.1'); - done(); + expect(keystone.catalogList).toHaveBeenCalledWith(token) + expect(nova).toEqual(jasmine.any(Nova)) + expect(nova.endpointUrl).toEqual('http://192.168.99.99:8774/v2.1') + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) it('should cache Nova instance and Keystone token', (done) => { - const openstack = new OpenStack(openStackMockData.config()); - const tokenIssueMock = keystoneMockData.tokenIssue(); - const catalogListMock = keystoneMockData.catalogList('test_token'); + const openstack = new OpenStack(openStackMockData.config()) + const tokenIssueMock = keystoneMockData.tokenIssue() + const catalogListMock = keystoneMockData.catalogList('test_token') - fetchMock.mock(keystoneMockData.root()); - fetchMock.mock(tokenIssueMock); - fetchMock.mock(catalogListMock); + fetchMock.mock(keystoneMockData.root()) + fetchMock.mock(tokenIssueMock) + fetchMock.mock(catalogListMock) openstack._nova .then((nova) => { - expect(nova).toEqual(jasmine.any(Nova)); - expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1); - expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1); - return openstack._nova; + expect(nova).toEqual(jasmine.any(Nova)) + expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1) + expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1) + return openstack._nova }) .then((nova) => { - expect(nova).toEqual(jasmine.any(Nova)); - expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1); - expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1); - done(); + expect(nova).toEqual(jasmine.any(Nova)) + expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1) + expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) describe('_token', () => { it('should fetch the token and cache it', (done) => { - const openstack = new OpenStack(openStackMockData.config()); - const keystone = mockKeystone(openstack); + const openstack = new OpenStack(openStackMockData.config()) + const keystone = mockKeystone(openstack) - spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve('test_token')); + spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve('test_token')) openstack._token .then((token) => { - expect(token).toEqual('test_token'); - expect(keystone.tokenIssue.calls.count()).toEqual(1); - return openstack._token; + expect(token).toEqual('test_token') + expect(keystone.tokenIssue.calls.count()).toEqual(1) + return openstack._token }) .then((token) => { - expect(token).toEqual('test_token'); - expect(keystone.tokenIssue.calls.count()).toEqual(1); - done(); + expect(token).toEqual('test_token') + expect(keystone.tokenIssue.calls.count()).toEqual(1) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - function mockKeystone(openstack) { - const keystone = new Keystone(keystoneMockData.config); - openstack._keystonePromise = Promise.resolve(keystone); - return keystone; + function mockKeystone (openstack) { + const keystone = new Keystone(keystoneMockData.config) + openstack._keystonePromise = Promise.resolve(keystone) + return keystone } - function mockNeutron(openstack) { - const neutron = new Neutron(neutronMockData.config); - openstack._neutronPromise = Promise.resolve(neutron); - return neutron; + function mockNeutron (openstack) { + const neutron = new Neutron(neutronMockData.config) + openstack._neutronPromise = Promise.resolve(neutron) + return neutron } - function mockGlance(openstack) { - const glance = new Glance(glanceMockData.config); - openstack._glancePromise = Promise.resolve(glance); - return glance; + function mockGlance (openstack) { + const glance = new Glance(glanceMockData.config) + openstack._glancePromise = Promise.resolve(glance) + return glance } - function mockNova(openstack) { - const nova = new Nova(novaMockData.config); - openstack._novaPromise = Promise.resolve(nova); - return nova; + function mockNova (openstack) { + const nova = new Nova(novaMockData.config) + openstack._novaPromise = Promise.resolve(nova) + return nova } - -}); +}) diff --git a/test/unit/run.js b/test/unit/run.js index 48b0621..b3f1538 100644 --- a/test/unit/run.js +++ b/test/unit/run.js @@ -1,5 +1,5 @@ -import Jasmine from 'jasmine'; +import Jasmine from 'jasmine' -const jasmine = new Jasmine(); -jasmine.loadConfigFile('test/unit/jasmine.json'); -jasmine.execute(); +const jasmine = new Jasmine() +jasmine.loadConfigFile('test/unit/jasmine.json') +jasmine.execute() diff --git a/test/unit/util/abstractServiceTest.js b/test/unit/util/abstractServiceTest.js index 99f74bb..a25d550 100644 --- a/test/unit/util/abstractServiceTest.js +++ b/test/unit/util/abstractServiceTest.js @@ -14,235 +14,231 @@ * limitations under the License. */ -import AbstractService from "../../../src/util/abstractService"; -import * as mockData from "../helpers/data/versions"; -import fetchMock from "fetch-mock"; // Might as well use service +import AbstractService from '../../../src/util/abstractService' +import * as mockData from '../helpers/data/versions' +import fetchMock from 'fetch-mock' // Might as well use service describe('AbstractService', () => { - - afterEach(fetchMock.restore); + afterEach(fetchMock.restore) it('should provide a singleton HTTP instance', () => { - let service = new AbstractService(mockData.rootUrl, mockData.versions); + const service = new AbstractService(mockData.rootUrl, mockData.versions) - expect(service._http).toBeUndefined(); - let http1 = service.http; - expect(service._http).toBeDefined(); - expect(http1).not.toBeNull(); - let http2 = service.http; - expect(http1).toBe(http2); - }); + expect(service._http).toBeUndefined() + const http1 = service.http + expect(service._http).toBeDefined() + expect(http1).not.toBeNull() + const http2 = service.http + expect(http1).toBe(http2) + }) it('should return supported versions', () => { - let service = new AbstractService(mockData.rootUrl, mockData.versions); - expect(service.supportedVersions).toEqual(mockData.versions); - }); + const service = new AbstractService(mockData.rootUrl, mockData.versions) + expect(service.supportedVersions).toEqual(mockData.versions) + }) it('should return an empty array if no versions are configured', () => { - let service = new AbstractService(mockData.rootUrl, null); - expect(service.supportedVersions).toEqual([]); - }); + const service = new AbstractService(mockData.rootUrl, null) + expect(service.supportedVersions).toEqual([]) + }) - describe("versions()", () => { + describe('versions()', () => { + it('Should return a list of all versions available from this resource', (done) => { + const service = new AbstractService(mockData.rootUrl, mockData.versions) - it("Should return a list of all versions available from this resource", (done) => { - const service = new AbstractService(mockData.rootUrl, mockData.versions); - - fetchMock.mock(mockData.rootResponse()); + fetchMock.mock(mockData.rootResponse()) service.versions() .then((versions) => { // Quick sanity check. - expect(versions.length).toBe(5); - expect(versions[0].major).toEqual(2); - expect(versions[0].minor).toEqual(3); - expect(versions[0].patch).toEqual(0); - expect(versions[0].links).not.toBe(null); - expect(versions[0].links[0].href).toEqual('http://example.com/v2/'); - done(); + expect(versions.length).toBe(5) + expect(versions[0].major).toEqual(2) + expect(versions[0].minor).toEqual(3) + expect(versions[0].patch).toEqual(0) + expect(versions[0].links).not.toBe(null) + expect(versions[0].links[0].href).toEqual('http://example.com/v2/') + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) // This test catches the case when the service catalog already points // at an API version. - it("Should retry at the root URL if a 401 is encountered", (done) => { - const service = new AbstractService(mockData.subUrl, mockData.versions); + it('Should retry at the root URL if a 401 is encountered', (done) => { + const service = new AbstractService(mockData.subUrl, mockData.versions) - fetchMock.mock(mockData.subResponse()); - fetchMock.mock(mockData.rootResponse()); + fetchMock.mock(mockData.subResponse()) + fetchMock.mock(mockData.rootResponse()) service.versions() .then((versions) => { // Quick sanity check. - expect(versions.length).toBe(5); - done(); + expect(versions.length).toBe(5) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("Should not retry at the root URL if a different status is encountered", (done) => { - const service = new AbstractService(mockData.subUrl, mockData.versions); + it('Should not retry at the root URL if a different status is encountered', (done) => { + const service = new AbstractService(mockData.subUrl, mockData.versions) - fetchMock.mock(mockData.subResponse(500)); + fetchMock.mock(mockData.subResponse(500)) service.versions() .then((response) => done.fail(response)) .catch((error) => { - expect(error).not.toBeNull(); - done(); - }); - }); + expect(error).not.toBeNull() + done() + }) + }) - it("Should NOT cache its results", (done) => { - const service = new AbstractService(mockData.rootUrl, mockData.versions); - const mockOptions = mockData.rootResponse(); + it('Should NOT cache its results', (done) => { + const service = new AbstractService(mockData.rootUrl, mockData.versions) + const mockOptions = mockData.rootResponse() - fetchMock.mock(mockOptions); + fetchMock.mock(mockOptions) service.versions() .then(() => { // Validate that the mock has only been invoked once - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1); - return service.versions(); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1) + return service.versions() }) .then(() => { - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2); - done(); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("version()", () => { + describe('version()', () => { + it('Should return a supported version of the service API.', (done) => { + const service = new AbstractService(mockData.rootUrl, mockData.versions) - it("Should return a supported version of the service API.", (done) => { - const service = new AbstractService(mockData.rootUrl, mockData.versions); - - fetchMock.mock(mockData.rootResponse()); + fetchMock.mock(mockData.rootResponse()) service.version() .then((version) => { - expect(version.equals('v2.3')).toBe(true); - done(); + expect(version.equals('v2.3')).toBe(true) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("Should return the latest compatible version of the service API.", (done) => { + it('Should return the latest compatible version of the service API.', (done) => { const service = new AbstractService(mockData.rootUrl, [ 'v2.0' - ]); + ]) - fetchMock.mock(mockData.rootResponse()); + fetchMock.mock(mockData.rootResponse()) service.version() .then((version) => { - expect(version.equals('v2.3')).toBe(true); - done(); + expect(version.equals('v2.3')).toBe(true) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("Should throw an exception if no supported version is found.", (done) => { - const service = new AbstractService(mockData.rootUrl, mockData.versions); + it('Should throw an exception if no supported version is found.', (done) => { + const service = new AbstractService(mockData.rootUrl, mockData.versions) // Build an invalid mock object. - const mockOptions = mockData.rootResponse(); - mockOptions.response.versions.shift(); + const mockOptions = mockData.rootResponse() + mockOptions.response.versions.shift() - fetchMock.mock(mockOptions); + fetchMock.mock(mockOptions) service.version() .then((response) => done.fail(response)) .catch((error) => { - expect(error).not.toBeNull(); - done(); - }); - }); + expect(error).not.toBeNull() + done() + }) + }) - it("Should NOT cache its results", (done) => { - const service = new AbstractService(mockData.rootUrl, mockData.versions); - const mockOptions = mockData.rootResponse(); - fetchMock.mock(mockOptions); + it('Should NOT cache its results', (done) => { + const service = new AbstractService(mockData.rootUrl, mockData.versions) + const mockOptions = mockData.rootResponse() + fetchMock.mock(mockOptions) service.version() .then(() => { // Validate that the mock has only been invoked once - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1); - return service.version(); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1) + return service.version() }) .then(() => { - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2); - done(); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(2) + done() }) - .catch((error) => done.fail(error)); - }); - }); + .catch((error) => done.fail(error)) + }) + }) - describe("serviceEndpoint()", () => { + describe('serviceEndpoint()', () => { + it('Should return a valid endpoint to the API.', (done) => { + const service = new AbstractService(mockData.rootUrl, mockData.versions) - it("Should return a valid endpoint to the API.", (done) => { - const service = new AbstractService(mockData.rootUrl, mockData.versions); - - fetchMock.mock(mockData.rootResponse()); + fetchMock.mock(mockData.rootResponse()) service.serviceEndpoint() .then((endpoint) => { - expect(endpoint).toEqual('http://example.com/v2/'); - done(); + expect(endpoint).toEqual('http://example.com/v2/') + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("Should throw an exception if no endpoint is provided.", (done) => { - const service = new AbstractService(mockData.rootUrl, mockData.versions); + it('Should throw an exception if no endpoint is provided.', (done) => { + const service = new AbstractService(mockData.rootUrl, mockData.versions) // Build an exception payload. - const mockOptions = mockData.rootResponse(); - mockOptions.response.versions[0].links = []; - fetchMock.mock(mockOptions); + const mockOptions = mockData.rootResponse() + mockOptions.response.versions[0].links = [] + fetchMock.mock(mockOptions) service.serviceEndpoint() .then((response) => done.fail(response)) .catch((error) => { - expect(error).not.toBeNull(); - done(); - }); - }); + expect(error).not.toBeNull() + done() + }) + }) - it("Should throw an exception if no links array exists.", (done) => { - const service = new AbstractService(mockData.rootUrl, mockData.versions); + it('Should throw an exception if no links array exists.', (done) => { + const service = new AbstractService(mockData.rootUrl, mockData.versions) // Build an exception payload. - const mockOptions = mockData.rootResponse(); - delete mockOptions.response.versions[0].links; - fetchMock.mock(mockOptions); + const mockOptions = mockData.rootResponse() + delete mockOptions.response.versions[0].links + fetchMock.mock(mockOptions) service.serviceEndpoint() .then((response) => done.fail(response)) .catch((error) => { - expect(error).not.toBeNull(); - done(); - }); - }); + expect(error).not.toBeNull() + done() + }) + }) - it("Should cache its results", (done) => { - const service = new AbstractService(mockData.rootUrl, mockData.versions); - const mockOptions = mockData.rootResponse(); - fetchMock.mock(mockOptions); + it('Should cache its results', (done) => { + const service = new AbstractService(mockData.rootUrl, mockData.versions) + const mockOptions = mockData.rootResponse() + fetchMock.mock(mockOptions) service.serviceEndpoint() .then(() => { // Validate that the mock has only been invoked once - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1); - return service.serviceEndpoint(); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1) + return service.serviceEndpoint() }) .then(() => { - expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1); - done(); + expect(fetchMock.calls(mockOptions.matcher).length).toEqual(1) + done() }) - .catch((error) => done.fail(error)); - }); - }); -}); + .catch((error) => done.fail(error)) + }) + }) +}) diff --git a/test/unit/util/httpTest.js b/test/unit/util/httpTest.js index 8c7ff6b..03e67cd 100644 --- a/test/unit/util/httpTest.js +++ b/test/unit/util/httpTest.js @@ -14,122 +14,122 @@ * under the License. */ -import Http from '../../../src/util/http.js'; -import fetchMock from 'fetch-mock'; +import Http from '../../../src/util/http.js' +import fetchMock from 'fetch-mock' describe('Http', () => { - let http; - const testUrl = 'https://example.com/'; - const testRequest = {lol: 'cat'}; - const testResponse = {foo: 'bar'}; + let http + const testUrl = 'https://example.com/' + const testRequest = { lol: 'cat' } + const testResponse = { foo: 'bar' } beforeEach(() => { - http = new Http(); - }); + http = new Http() + }) - afterEach(fetchMock.restore); + afterEach(fetchMock.restore) - it("should permit manually constructing requests", (done) => { - fetchMock.get(testUrl, testResponse); + it('should permit manually constructing requests', (done) => { + fetchMock.get(testUrl, testResponse) http.httpRequest('GET', testUrl) .then((response) => response.json()) .then((body) => { - expect(fetchMock.called(testUrl)).toBe(true); - expect(body).toEqual(testResponse); - done(); + expect(fetchMock.called(testUrl)).toBe(true) + expect(body).toEqual(testResponse) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should make GET requests", (done) => { - fetchMock.get(testUrl, testResponse); + it('should make GET requests', (done) => { + fetchMock.get(testUrl, testResponse) http.httpGet(testUrl) .then((response) => response.json()) .then((body) => { - expect(fetchMock.called(testUrl)).toBe(true); - expect(body).toEqual(testResponse); - done(); + expect(fetchMock.called(testUrl)).toBe(true) + expect(body).toEqual(testResponse) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should make PUT requests", (done) => { - fetchMock.put(testUrl, testResponse, testRequest); + it('should make PUT requests', (done) => { + fetchMock.put(testUrl, testResponse, testRequest) http.httpPut(testUrl, testRequest) .then((response) => response.json()) .then((body) => { - expect(fetchMock.called(testUrl)).toEqual(true); - expect(body).toEqual(testResponse); - done(); + expect(fetchMock.called(testUrl)).toEqual(true) + expect(body).toEqual(testResponse) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should make POST requests", (done) => { - fetchMock.post(testUrl, testResponse, testRequest); + it('should make POST requests', (done) => { + fetchMock.post(testUrl, testResponse, testRequest) http.httpPost(testUrl, testRequest) .then((response) => response.json()) .then((body) => { - expect(fetchMock.called(testUrl)).toEqual(true); - expect(body).toEqual(testResponse); - done(); + expect(fetchMock.called(testUrl)).toEqual(true) + expect(body).toEqual(testResponse) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should make DELETE requests", (done) => { - fetchMock.delete(testUrl, testRequest); + it('should make DELETE requests', (done) => { + fetchMock.delete(testUrl, testRequest) http.httpDelete(testUrl, testRequest) .then(() => { - expect(fetchMock.called(testUrl)).toEqual(true); - done(); + expect(fetchMock.called(testUrl)).toEqual(true) + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should permit setting default headers", (done) => { - http.defaultHeaders['Custom-Header'] = 'Custom-Value'; - fetchMock.get(testUrl, testResponse); + it('should permit setting default headers', (done) => { + http.defaultHeaders['Custom-Header'] = 'Custom-Value' + fetchMock.get(testUrl, testResponse) http.httpGet(testUrl) .then(() => { - let headers = fetchMock.lastOptions().headers; - expect(headers['Custom-Header']).toEqual('Custom-Value'); - done(); + const headers = fetchMock.lastOptions().headers + expect(headers['Custom-Header']).toEqual('Custom-Value') + done() }) - .catch((error) => done.fail(error)); - }); + .catch((error) => done.fail(error)) + }) - it("should pass exceptions back to the invoker", (done) => { + it('should pass exceptions back to the invoker', (done) => { fetchMock.get(testUrl, () => { - throw new TypeError(); // Example- net::ERR_NAME_NOT_RESOLVED - }); + throw new TypeError() // Example- net::ERR_NAME_NOT_RESOLVED + }) http.httpGet(testUrl) .then((response) => done.fail(response)) .catch((error) => { - expect(error.stack).toBeDefined(); - done(); - }); - }); + expect(error.stack).toBeDefined() + done() + }) + }) - it("should pass failed requests to the catch block.", (done) => { - fetchMock.get(testUrl, {status: 500, body: testResponse}); + it('should pass failed requests to the catch block.', (done) => { + fetchMock.get(testUrl, { status: 500, body: testResponse }) http.httpGet(testUrl) .then((response) => done.fail(response)) .catch((response) => { - expect(response.status).toBe(500); - done(); - }); - }); + expect(response.status).toBe(500) + done() + }) + }) - it("should not interfere with mocks that have matching headers.", (done) => { + it('should not interfere with mocks that have matching headers.', (done) => { fetchMock.mock({ method: 'GET', matcher: testUrl, @@ -137,11 +137,11 @@ describe('Http', () => { 'Content-Type': 'application/json' }, response: testResponse - }); + }) http - .httpRequest('GET', testUrl, {'Content-Type': 'application/json'}) + .httpRequest('GET', testUrl, { 'Content-Type': 'application/json' }) .then(() => done()) - .catch((error) => done.fail(error)); - }); -}); + .catch((error) => done.fail(error)) + }) +}) diff --git a/test/unit/util/versionTest.js b/test/unit/util/versionTest.js index 7f73b88..05f443e 100644 --- a/test/unit/util/versionTest.js +++ b/test/unit/util/versionTest.js @@ -14,145 +14,143 @@ * under the License. */ -import Version from '../../../src/util/version.js'; +import Version from '../../../src/util/version.js' describe('Version', () => { + it('should parse various header versions', () => { + const testVersion = function (args, results) { + const v = new Version(...args) + expect(v.service).toBe(results[0]) + expect(v.major).toBe(results[1]) + expect(v.minor).toBe(results[2]) + expect(v.patch).toBe(results[3]) + } - it("should parse various header versions", () => { - - const testVersion = function(args, results) { - const v = new Version(...args); - expect(v.service).toBe(results[0]); - expect(v.major).toBe(results[1]); - expect(v.minor).toBe(results[2]); - expect(v.patch).toBe(results[3]); - }; - - testVersion(['identity 1.2'], ['identity', 1, 2, 0]); - testVersion(['identity 0.2'], ['identity', 0, 2, 0]); - testVersion(['compute 2222222.09'], ['compute', 2222222, 9, 0]); - testVersion(['compute 03.09'], ['compute', 3, 9, 0]); - testVersion(['compute 03.0'], ['compute', 3, 0, 0]); - testVersion(['compute 1'], ['compute', 1, 0, 0]); - testVersion(['compute 0'], ['compute', 0, 0, 0]); - testVersion(['v2.1.1'], [null, 2, 1, 1]); - testVersion(['v2.1'], [null, 2, 1, 0]); - testVersion(['v2'], [null, 2, 0, 0]); - testVersion(['v'], [null, 0, 0, 0]); - testVersion(['v0.2'], [null, 0, 2, 0]); - testVersion(['2.1.1'], [null, 2, 1, 1]); - testVersion(['2.1'], [null, 2, 1, 0]); - testVersion(['2'], [null, 2, 0, 0]); - testVersion([''], [null, 0, 0, 0]); - testVersion(['0.2'], [null, 0, 2, 0]); - testVersion(['compute', 'v2.1.1'], ['compute', 2, 1, 1]); - testVersion(['compute', 'v2.1'], ['compute', 2, 1, 0]); - testVersion(['compute', 'v2'], ['compute', 2, 0, 0]); - testVersion(['compute', 'v'], ['compute', 0, 0, 0]); - testVersion(['compute', 'v0.2'], ['compute', 0, 2, 0]); - testVersion(['compute', '2.1.1'], ['compute', 2, 1, 1]); - testVersion(['compute', '2.1'], ['compute', 2, 1, 0]); - testVersion(['compute', '2'], ['compute', 2, 0, 0]); - testVersion(['compute', ''], ['compute', 0, 0, 0]); - testVersion(['compute', '0.2'], ['compute', 0, 2, 0]); + testVersion(['identity 1.2'], ['identity', 1, 2, 0]) + testVersion(['identity 0.2'], ['identity', 0, 2, 0]) + testVersion(['compute 2222222.09'], ['compute', 2222222, 9, 0]) + testVersion(['compute 03.09'], ['compute', 3, 9, 0]) + testVersion(['compute 03.0'], ['compute', 3, 0, 0]) + testVersion(['compute 1'], ['compute', 1, 0, 0]) + testVersion(['compute 0'], ['compute', 0, 0, 0]) + testVersion(['v2.1.1'], [null, 2, 1, 1]) + testVersion(['v2.1'], [null, 2, 1, 0]) + testVersion(['v2'], [null, 2, 0, 0]) + testVersion(['v'], [null, 0, 0, 0]) + testVersion(['v0.2'], [null, 0, 2, 0]) + testVersion(['2.1.1'], [null, 2, 1, 1]) + testVersion(['2.1'], [null, 2, 1, 0]) + testVersion(['2'], [null, 2, 0, 0]) + testVersion([''], [null, 0, 0, 0]) + testVersion(['0.2'], [null, 0, 2, 0]) + testVersion(['compute', 'v2.1.1'], ['compute', 2, 1, 1]) + testVersion(['compute', 'v2.1'], ['compute', 2, 1, 0]) + testVersion(['compute', 'v2'], ['compute', 2, 0, 0]) + testVersion(['compute', 'v'], ['compute', 0, 0, 0]) + testVersion(['compute', 'v0.2'], ['compute', 0, 2, 0]) + testVersion(['compute', '2.1.1'], ['compute', 2, 1, 1]) + testVersion(['compute', '2.1'], ['compute', 2, 1, 0]) + testVersion(['compute', '2'], ['compute', 2, 0, 0]) + testVersion(['compute', ''], ['compute', 0, 0, 0]) + testVersion(['compute', '0.2'], ['compute', 0, 2, 0]) // Invalid inputs... - testVersion([null, null], [null, 0, 0, 0]); - testVersion([{}, {}], [null, 0, 0, 0]); - testVersion([null, {}], [null, 0, 0, 0]); - testVersion([{}, null], [null, 0, 0, 0]); - }); + testVersion([null, null], [null, 0, 0, 0]) + testVersion([{}, {}], [null, 0, 0, 0]) + testVersion([null, {}], [null, 0, 0, 0]) + testVersion([{}, null], [null, 0, 0, 0]) + }) - it("should test for correct equality", () => { - const v1 = new Version("compute", "1.0.0"); + it('should test for correct equality', () => { + const v1 = new Version('compute', '1.0.0') // String tests... - expect(v1.equals("compute 1.0.0")).toBe(true); - expect(v1.equals("compute 1.0.1")).toBe(false); - expect(v1.equals("identity 1.0.0")).toBe(false); + expect(v1.equals('compute 1.0.0')).toBe(true) + expect(v1.equals('compute 1.0.1')).toBe(false) + expect(v1.equals('identity 1.0.0')).toBe(false) // Version tests - expect(v1.equals(new Version("compute 1.0.0"))).toBe(true); - expect(v1.equals(new Version("compute 1.0.1"))).toBe(false); - expect(v1.equals(new Version("identity 1.0.0"))).toBe(false); - expect(v1.equals(new Version("1.0.0"))).toBe(false); + expect(v1.equals(new Version('compute 1.0.0'))).toBe(true) + expect(v1.equals(new Version('compute 1.0.1'))).toBe(false) + expect(v1.equals(new Version('identity 1.0.0'))).toBe(false) + expect(v1.equals(new Version('1.0.0'))).toBe(false) // Other tests... - expect(v1.equals({})).toBe(false); + expect(v1.equals({})).toBe(false) - const v2 = new Version("1.0.0"); + const v2 = new Version('1.0.0') // String tests... - expect(v2.equals("compute 1.0.0")).toBe(false); - expect(v2.equals("compute 1.0.1")).toBe(false); - expect(v2.equals("1.0.0")).toBe(true); + expect(v2.equals('compute 1.0.0')).toBe(false) + expect(v2.equals('compute 1.0.1')).toBe(false) + expect(v2.equals('1.0.0')).toBe(true) // Version tests - expect(v2.equals(new Version("compute 1.0.0"))).toBe(false); - expect(v2.equals(new Version("compute 1.0.1"))).toBe(false); - expect(v2.equals(new Version("identity 1.0.0"))).toBe(false); - expect(v2.equals(new Version("1.0.0"))).toBe(true); + expect(v2.equals(new Version('compute 1.0.0'))).toBe(false) + expect(v2.equals(new Version('compute 1.0.1'))).toBe(false) + expect(v2.equals(new Version('identity 1.0.0'))).toBe(false) + expect(v2.equals(new Version('1.0.0'))).toBe(true) // Other tests... - expect(v2.equals({})).toBe(false); - }); + expect(v2.equals({})).toBe(false) + }) - it("should test for correct compatibility", () => { - const v1 = new Version("compute", "1.3.2"); + it('should test for correct compatibility', () => { + const v1 = new Version('compute', '1.3.2') // String tests - expect(v1.supports("compute 1.0.0")).toBe(true); - expect(v1.supports("compute 1.0.1")).toBe(true); - expect(v1.supports("compute 1.3.0")).toBe(true); - expect(v1.supports("compute 1.3.3")).toBe(false); - expect(v1.supports("compute 1.4.0")).toBe(false); - expect(v1.supports("compute 2.3.0")).toBe(false); + expect(v1.supports('compute 1.0.0')).toBe(true) + expect(v1.supports('compute 1.0.1')).toBe(true) + expect(v1.supports('compute 1.3.0')).toBe(true) + expect(v1.supports('compute 1.3.3')).toBe(false) + expect(v1.supports('compute 1.4.0')).toBe(false) + expect(v1.supports('compute 2.3.0')).toBe(false) // Version tests - expect(v1.supports(new Version("compute", "1.0.0"))).toBe(true); - expect(v1.supports(new Version("compute", "1.0.1"))).toBe(true); - expect(v1.supports(new Version("compute", "1.3.0"))).toBe(true); - expect(v1.supports(new Version("compute", "1.3.3"))).toBe(false); - expect(v1.supports(new Version("compute", "1.4.0"))).toBe(false); - expect(v1.supports(new Version("compute", "2.3.0"))).toBe(false); + expect(v1.supports(new Version('compute', '1.0.0'))).toBe(true) + expect(v1.supports(new Version('compute', '1.0.1'))).toBe(true) + expect(v1.supports(new Version('compute', '1.3.0'))).toBe(true) + expect(v1.supports(new Version('compute', '1.3.3'))).toBe(false) + expect(v1.supports(new Version('compute', '1.4.0'))).toBe(false) + expect(v1.supports(new Version('compute', '2.3.0'))).toBe(false) - const v2 = new Version("1.3.2"); + const v2 = new Version('1.3.2') // String tests - expect(v2.supports("1.0.0")).toBe(true); - expect(v2.supports("1.0.1")).toBe(true); - expect(v2.supports("1.3.0")).toBe(true); - expect(v2.supports("1.3.3")).toBe(false); - expect(v2.supports("1.4.0")).toBe(false); - expect(v2.supports("2.3.0")).toBe(false); + expect(v2.supports('1.0.0')).toBe(true) + expect(v2.supports('1.0.1')).toBe(true) + expect(v2.supports('1.3.0')).toBe(true) + expect(v2.supports('1.3.3')).toBe(false) + expect(v2.supports('1.4.0')).toBe(false) + expect(v2.supports('2.3.0')).toBe(false) // Version tests - expect(v2.supports(new Version("1.0.0"))).toBe(true); - expect(v2.supports(new Version("1.0.1"))).toBe(true); - expect(v2.supports(new Version("1.3.0"))).toBe(true); - expect(v2.supports(new Version("1.3.3"))).toBe(false); - expect(v2.supports(new Version("1.4.0"))).toBe(false); - expect(v2.supports(new Version("2.3.0"))).toBe(false); - }); + expect(v2.supports(new Version('1.0.0'))).toBe(true) + expect(v2.supports(new Version('1.0.1'))).toBe(true) + expect(v2.supports(new Version('1.3.0'))).toBe(true) + expect(v2.supports(new Version('1.3.3'))).toBe(false) + expect(v2.supports(new Version('1.4.0'))).toBe(false) + expect(v2.supports(new Version('2.3.0'))).toBe(false) + }) - it("should store links", () => { - const v1 = new Version("compute", "1.3.2"); + it('should store links', () => { + const v1 = new Version('compute', '1.3.2') - expect(v1.links).toBe(null); + expect(v1.links).toBe(null) - v1.links = 'wrong data'; - expect(v1.links).toBe(null); + v1.links = 'wrong data' + expect(v1.links).toBe(null) v1.links = [ { - href: `http://example.org/v2/`, - rel: "self" + href: 'http://example.org/v2/', + rel: 'self' } - ]; - expect(v1.links).not.toBe(null); - expect(v1.links.length).toBe(1); + ] + expect(v1.links).not.toBe(null) + expect(v1.links.length).toBe(1) expect(v1.links[0]).toEqual({ - href: "http://example.org/v2/", - rel: "self" - }); - }); -}); + href: 'http://example.org/v2/', + rel: 'self' + }) + }) +}) diff --git a/webpack.config.babel.js b/webpack.config.babel.js index 7b6a4c6..9cc3675 100644 --- a/webpack.config.babel.js +++ b/webpack.config.babel.js @@ -1,6 +1,6 @@ -import path from 'path'; -import webpack from 'webpack'; -import cloudsYamlPath from './test/functional/helpers/cloudsYamlPath'; +import path from 'path' +import webpack from 'webpack' +import cloudsYamlPath from './test/functional/helpers/cloudsYamlPath' export default { entry: ['./src/index.js'], @@ -23,13 +23,13 @@ export default { } } } - ], + ] }, plugins: [ new webpack.NormalModuleReplacementPlugin(/helpers\/cloudsConfig/, 'json!yaml!' + cloudsYamlPath) ], node: { - fs: "empty" + fs: 'empty' } -}; +} diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index 8427ba1..7c03627 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -2,13 +2,16 @@ - project: templates: - nodejs8-docs - - nodejs8-jobs - nodejs8-publish-to-npm check: jobs: + - nodejs-run-lint + - nodejs-run-test-browser - js-openstack-lib-unit-tests-nodejs12 gate: jobs: + - nodejs-run-lint + - nodejs-run-test-browser - js-openstack-lib-unit-tests-nodejs12 experimental: jobs: