diff --git a/Gruntfile.js b/Gruntfile.js index 46ebf98b..38c05a29 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -3,8 +3,8 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -/* global module:false */ 'use strict'; + module.exports = function(grunt) { // Do not report warnings from unit-tests exercising deprecated paths process.env.NO_DEPRECATION = 'loopback'; @@ -218,8 +218,8 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-karma'); grunt.registerTask('e2e-server', function() { - var done = this.async(); - var app = require('./test/fixtures/e2e/app'); + const done = this.async(); + const app = require('./test/fixtures/e2e/app'); app.listen(0, function() { process.env.PORT = this.address().port; done(); diff --git a/common/models/access-token.js b/common/models/access-token.js index 7d4c380b..8829f5a5 100644 --- a/common/models/access-token.js +++ b/common/models/access-token.js @@ -8,11 +8,11 @@ */ 'use strict'; -var g = require('../../lib/globalize'); -var loopback = require('../../lib/loopback'); -var assert = require('assert'); -var uid = require('uid2'); -var DEFAULT_TOKEN_LEN = 64; +const g = require('../../lib/globalize'); +const loopback = require('../../lib/loopback'); +const assert = require('assert'); +const uid = require('uid2'); +const DEFAULT_TOKEN_LEN = 64; /** * Token based authentication and access control. @@ -93,11 +93,11 @@ module.exports = function(AccessToken) { */ AccessToken.getIdForRequest = function(req, options) { options = options || {}; - var params = options.params || []; - var headers = options.headers || []; - var cookies = options.cookies || []; - var i = 0; - var length, id; + let params = options.params || []; + let headers = options.headers || []; + let cookies = options.cookies || []; + let i = 0; + let length, id; // https://github.com/strongloop/loopback/issues/1326 if (options.searchDefaultTokenKeys !== false) { @@ -107,7 +107,7 @@ module.exports = function(AccessToken) { } for (length = params.length; i < length; i++) { - var param = params[i]; + const param = params[i]; // replacement for deprecated req.param() id = req.params && req.params[param] !== undefined ? req.params[param] : req.body && req.body[param] !== undefined ? req.body[param] : @@ -134,7 +134,7 @@ module.exports = function(AccessToken) { id = id.substring(7); if (options.bearerTokenBase64Encoded) { // Decode from base64 - var buf = new Buffer(id, 'base64'); + const buf = new Buffer(id, 'base64'); id = buf.toString('utf8'); } } else if (/^Basic /i.test(id)) { @@ -147,7 +147,7 @@ module.exports = function(AccessToken) { // "a2b2c3:" (curl http://a2b2c3@localhost:3000/) // "token:a2b2c3" (curl http://token:a2b2c3@localhost:3000/) // ":a2b2c3" - var parts = /^([^:]*):(.*)$/.exec(id); + const parts = /^([^:]*):(.*)$/.exec(id); if (parts) { id = parts[2].length > parts[1].length ? parts[2] : parts[1]; } @@ -186,7 +186,7 @@ module.exports = function(AccessToken) { } else if (isValid) { cb(null, token); } else { - var e = new Error(g.f('Invalid Access Token')); + const e = new Error(g.f('Invalid Access Token')); e.status = e.statusCode = 401; e.code = 'INVALID_TOKEN'; cb(e); @@ -213,7 +213,7 @@ module.exports = function(AccessToken) { options = {}; } - var id = this.getIdForRequest(req, options); + const id = this.getIdForRequest(req, options); if (id) { this.resolve(id, cb); @@ -239,9 +239,9 @@ module.exports = function(AccessToken) { assert(this.ttl, 'token.ttl must exist'); assert(this.ttl >= -1, 'token.ttl must be >= -1'); - var AccessToken = this.constructor; - var userRelation = AccessToken.relations.user; // may not be set up - var User = userRelation && userRelation.modelTo; + const AccessToken = this.constructor; + const userRelation = AccessToken.relations.user; // may not be set up + let User = userRelation && userRelation.modelTo; // redefine user model if accessToken's principalType is available if (this.principalType) { @@ -253,13 +253,13 @@ module.exports = function(AccessToken) { } } - var now = Date.now(); - var created = this.created.getTime(); - var elapsedSeconds = (now - created) / 1000; - var secondsToLive = this.ttl; - var eternalTokensAllowed = !!(User && User.settings.allowEternalTokens); - var isEternalToken = secondsToLive === -1; - var isValid = isEternalToken ? + const now = Date.now(); + const created = this.created.getTime(); + const elapsedSeconds = (now - created) / 1000; + const secondsToLive = this.ttl; + const eternalTokensAllowed = !!(User && User.settings.allowEternalTokens); + const isEternalToken = secondsToLive === -1; + const isValid = isEternalToken ? eternalTokensAllowed : elapsedSeconds < secondsToLive; diff --git a/common/models/acl.js b/common/models/acl.js index d3302af3..922678df 100644 --- a/common/models/acl.js +++ b/common/models/acl.js @@ -30,20 +30,20 @@ Map to oAuth 2.0 scopes */ -var g = require('../../lib/globalize'); -var loopback = require('../../lib/loopback'); -var utils = require('../../lib/utils'); -var async = require('async'); -var extend = require('util')._extend; -var assert = require('assert'); -var debug = require('debug')('loopback:security:acl'); +const g = require('../../lib/globalize'); +const loopback = require('../../lib/loopback'); +const utils = require('../../lib/utils'); +const async = require('async'); +const extend = require('util')._extend; +const assert = require('assert'); +const debug = require('debug')('loopback:security:acl'); -var ctx = require('../../lib/access-context'); -var AccessContext = ctx.AccessContext; -var Principal = ctx.Principal; -var AccessRequest = ctx.AccessRequest; +const ctx = require('../../lib/access-context'); +const AccessContext = ctx.AccessContext; +const Principal = ctx.Principal; +const AccessRequest = ctx.AccessRequest; -var Role = loopback.Role; +const Role = loopback.Role; assert(Role, 'Role model must be defined before ACL model'); /** @@ -107,18 +107,18 @@ module.exports = function(ACL) { * @returns {Number} */ ACL.getMatchingScore = function getMatchingScore(rule, req) { - var props = ['model', 'property', 'accessType']; - var score = 0; + const props = ['model', 'property', 'accessType']; + let score = 0; - for (var i = 0; i < props.length; i++) { + for (let i = 0; i < props.length; i++) { // Shift the score by 4 for each of the properties as the weight score = score * 4; - var ruleValue = rule[props[i]] || ACL.ALL; - var requestedValue = req[props[i]] || ACL.ALL; - var isMatchingMethodName = props[i] === 'property' && + const ruleValue = rule[props[i]] || ACL.ALL; + const requestedValue = req[props[i]] || ACL.ALL; + const isMatchingMethodName = props[i] === 'property' && req.methodNames.indexOf(ruleValue) !== -1; - var isMatchingAccessType = ruleValue === requestedValue; + let isMatchingAccessType = ruleValue === requestedValue; if (props[i] === 'accessType' && !isMatchingAccessType) { switch (ruleValue) { case ACL.EXECUTE: @@ -219,11 +219,11 @@ module.exports = function(ACL) { acls = acls.sort(function(rule1, rule2) { return ACL.getMatchingScore(rule2, req) - ACL.getMatchingScore(rule1, req); }); - var permission = ACL.DEFAULT; - var score = 0; + let permission = ACL.DEFAULT; + let score = 0; - for (var i = 0; i < acls.length; i++) { - var candidate = acls[i]; + for (let i = 0; i < acls.length; i++) { + const candidate = acls[i]; score = ACL.getMatchingScore(candidate, req); if (score < 0) { // the highest scored ACL did not match @@ -239,8 +239,8 @@ module.exports = function(ACL) { break; } // For wildcard match, find the strongest permission - var candidateOrder = AccessContext.permissionOrder[candidate.permission]; - var permissionOrder = AccessContext.permissionOrder[permission]; + const candidateOrder = AccessContext.permissionOrder[candidate.permission]; + const permissionOrder = AccessContext.permissionOrder[permission]; if (candidateOrder > permissionOrder) { permission = candidate.permission; break; @@ -255,7 +255,7 @@ module.exports = function(ACL) { debug('with score:', acl.score(req)); }); } - var res = new AccessRequest({ + const res = new AccessRequest({ model: req.model, property: req.property, accessType: req.accessType, @@ -276,11 +276,11 @@ module.exports = function(ACL) { * @return {Object[]} An array of ACLs */ ACL.getStaticACLs = function getStaticACLs(model, property) { - var modelClass = this.registry.findModel(model); - var staticACLs = []; + const modelClass = this.registry.findModel(model); + const staticACLs = []; if (modelClass && modelClass.settings.acls) { modelClass.settings.acls.forEach(function(acl) { - var prop = acl.property; + let prop = acl.property; // We support static ACL property with array of string values. if (Array.isArray(prop) && prop.indexOf(property) >= 0) prop = property; @@ -296,7 +296,7 @@ module.exports = function(ACL) { } }); } - var prop = modelClass && ( + const prop = modelClass && ( // regular property modelClass.definition.properties[property] || // relation/scope @@ -339,17 +339,17 @@ module.exports = function(ACL) { principalId = principalId.toString(); } property = property || ACL.ALL; - var propertyQuery = (property === ACL.ALL) ? undefined : {inq: [property, ACL.ALL]}; + const propertyQuery = (property === ACL.ALL) ? undefined : {inq: [property, ACL.ALL]}; accessType = accessType || ACL.ALL; - var accessTypeQuery = (accessType === ACL.ALL) ? undefined : + const accessTypeQuery = (accessType === ACL.ALL) ? undefined : {inq: [accessType, ACL.ALL, ACL.EXECUTE]}; - var req = new AccessRequest({model, property, accessType, registry: this.registry}); + const req = new AccessRequest({model, property, accessType, registry: this.registry}); - var acls = this.getStaticACLs(model, property); + let acls = this.getStaticACLs(model, property); // resolved is an instance of AccessRequest - var resolved = this.resolvePermission(acls, req); + let resolved = this.resolvePermission(acls, req); if (resolved && resolved.permission === ACL.DENY) { debug('Permission denied by statically resolved permission'); @@ -360,7 +360,7 @@ module.exports = function(ACL) { return callback.promise; } - var self = this; + const self = this; this.find({where: {principalType: principalType, principalId: principalId, model: model, property: propertyQuery, accessType: accessTypeQuery}}, function(err, dynACLs) { @@ -431,33 +431,33 @@ module.exports = function(ACL) { */ ACL.checkAccessForContext = function(context, callback) { if (!callback) callback = utils.createPromiseCallback(); - var self = this; + const self = this; self.resolveRelatedModels(); - var roleModel = self.roleModel; + const roleModel = self.roleModel; if (!(context instanceof AccessContext)) { context.registry = this.registry; context = new AccessContext(context); } - var authorizedRoles = {}; - var remotingContext = context.remotingContext; - var model = context.model; - var modelDefaultPermission = model && model.settings.defaultPermission; - var property = context.property; - var accessType = context.accessType; - var modelName = context.modelName; + let authorizedRoles = {}; + const remotingContext = context.remotingContext; + const model = context.model; + const modelDefaultPermission = model && model.settings.defaultPermission; + const property = context.property; + const accessType = context.accessType; + const modelName = context.modelName; - var methodNames = context.methodNames; - var propertyQuery = (property === ACL.ALL) ? undefined : {inq: methodNames.concat([ACL.ALL])}; + const methodNames = context.methodNames; + const propertyQuery = (property === ACL.ALL) ? undefined : {inq: methodNames.concat([ACL.ALL])}; - var accessTypeQuery = (accessType === ACL.ALL) ? + const accessTypeQuery = (accessType === ACL.ALL) ? undefined : (accessType === ACL.REPLICATE) ? {inq: [ACL.REPLICATE, ACL.WRITE, ACL.ALL]} : {inq: [accessType, ACL.ALL]}; - var req = new AccessRequest({ + const req = new AccessRequest({ model: modelName, property, accessType, @@ -475,8 +475,8 @@ module.exports = function(ACL) { return callback.promise; } - var effectiveACLs = []; - var staticACLs = self.getStaticACLs(model.modelName, property); + const effectiveACLs = []; + const staticACLs = self.getStaticACLs(model.modelName, property); const query = { where: { @@ -488,16 +488,16 @@ module.exports = function(ACL) { this.find(query, function(err, acls) { if (err) return callback(err); - var inRoleTasks = []; + const inRoleTasks = []; acls = acls.concat(staticACLs); acls.forEach(function(acl) { // Check exact matches - for (var i = 0; i < context.principals.length; i++) { - var p = context.principals[i]; - var typeMatch = p.type === acl.principalType; - var idMatch = String(p.id) === String(acl.principalId); + for (let i = 0; i < context.principals.length; i++) { + const p = context.principals[i]; + const typeMatch = p.type === acl.principalType; + const idMatch = String(p.id) === String(acl.principalId); if (typeMatch && idMatch) { effectiveACLs.push(acl); return; @@ -525,7 +525,7 @@ module.exports = function(ACL) { if (err) return callback(err, null); // resolved is an instance of AccessRequest - var resolved = self.resolvePermission(effectiveACLs, req); + const resolved = self.resolvePermission(effectiveACLs, req); debug('---Resolved---'); resolved.debug(); @@ -562,7 +562,7 @@ module.exports = function(ACL) { ACL.checkAccessForToken = function(token, model, modelId, method, callback) { assert(token, 'Access token is required'); if (!callback) callback = utils.createPromiseCallback(); - var context = new AccessContext({ + const context = new AccessContext({ registry: this.registry, accessToken: token, model: model, @@ -580,7 +580,7 @@ module.exports = function(ACL) { ACL.resolveRelatedModels = function() { if (!this.roleModel) { - var reg = this.registry; + const reg = this.registry; this.roleModel = reg.getModelByType('Role'); this.roleMappingModel = reg.getModelByType('RoleMapping'); this.userModel = reg.getModelByType('User'); @@ -617,7 +617,7 @@ module.exports = function(ACL) { break; default: // try resolving a user model with a name matching the principalType - var userModel = this.registry.findModel(type); + const userModel = this.registry.findModel(type); if (userModel) { userModel.findOne( {where: {or: [{username: id}, {email: id}, {id: id}]}}, @@ -625,7 +625,7 @@ module.exports = function(ACL) { ); } else { process.nextTick(function() { - var err = new Error(g.f('Invalid principal type: %s', type)); + const err = new Error(g.f('Invalid principal type: %s', type)); err.statusCode = 400; err.code = 'INVALID_PRINCIPAL_TYPE'; cb(err); @@ -646,7 +646,7 @@ module.exports = function(ACL) { */ ACL.isMappedToRole = function(principalType, principalId, role, cb) { cb = cb || utils.createPromiseCallback(); - var self = this; + const self = this; this.resolvePrincipal(principalType, principalId, function(err, principal) { if (err) return cb(err); diff --git a/common/models/application.js b/common/models/application.js index 59a4820b..d296ca88 100644 --- a/common/models/application.js +++ b/common/models/application.js @@ -4,23 +4,23 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var utils = require('../../lib/utils'); +const assert = require('assert'); +const utils = require('../../lib/utils'); /*! * Application management functions */ -var crypto = require('crypto'); +const crypto = require('crypto'); function generateKey(hmacKey, algorithm, encoding) { hmacKey = hmacKey || 'loopback'; algorithm = algorithm || 'sha1'; encoding = encoding || 'hex'; - var hmac = crypto.createHmac(algorithm, hmacKey); - var buf = crypto.randomBytes(32); + const hmac = crypto.createHmac(algorithm, hmacKey); + const buf = crypto.randomBytes(32); hmac.update(buf); - var key = hmac.digest(encoding); + const key = hmac.digest(encoding); return key; } @@ -83,7 +83,7 @@ module.exports = function(Application) { return next(); } - var app = ctx.instance; + const app = ctx.instance; app.created = app.modified = new Date(); if (!app.id) { app.id = generateKey('id', 'md5'); @@ -115,8 +115,8 @@ module.exports = function(Application) { } cb = cb || utils.createPromiseCallback(); - var props = {owner: owner, name: name}; - for (var p in options) { + const props = {owner: owner, name: name}; + for (const p in options) { if (!(p in props)) { props[p] = options[p]; } @@ -182,9 +182,9 @@ module.exports = function(Application) { cb(err, null); return cb.promise; } - var result = null; - var keyNames = ['clientKey', 'javaScriptKey', 'restApiKey', 'windowsKey', 'masterKey']; - for (var i = 0; i < keyNames.length; i++) { + let result = null; + const keyNames = ['clientKey', 'javaScriptKey', 'restApiKey', 'windowsKey', 'masterKey']; + for (let i = 0; i < keyNames.length; i++) { if (app[keyNames[i]] === key) { result = { application: app, diff --git a/common/models/change.js b/common/models/change.js index ff926200..ba4542d7 100644 --- a/common/models/change.js +++ b/common/models/change.js @@ -8,15 +8,15 @@ */ 'use strict'; -var g = require('../../lib/globalize'); -var PersistedModel = require('../../lib/loopback').PersistedModel; -var loopback = require('../../lib/loopback'); -var utils = require('../../lib/utils'); -var crypto = require('crypto'); -var CJSON = {stringify: require('canonical-json')}; -var async = require('async'); -var assert = require('assert'); -var debug = require('debug')('loopback:change'); +const g = require('../../lib/globalize'); +const PersistedModel = require('../../lib/loopback').PersistedModel; +const loopback = require('../../lib/loopback'); +const utils = require('../../lib/utils'); +const crypto = require('crypto'); +const CJSON = {stringify: require('canonical-json')}; +const async = require('async'); +const assert = require('assert'); +const debug = require('debug')('loopback:change'); /** * Change list entry. @@ -58,10 +58,10 @@ module.exports = function(Change) { Change.setup = function() { PersistedModel.setup.call(this); - var Change = this; + const Change = this; Change.getter.id = function() { - var hasModel = this.modelName && this.modelId; + const hasModel = this.modelName && this.modelId; if (!hasModel) return null; return Change.idForModel(this.modelName, this.modelId); @@ -80,12 +80,12 @@ module.exports = function(Change) { */ Change.rectifyModelChanges = function(modelName, modelIds, callback) { - var Change = this; - var errors = []; + const Change = this; + const errors = []; callback = callback || utils.createPromiseCallback(); - var tasks = modelIds.map(function(id) { + const tasks = modelIds.map(function(id) { return function(cb) { Change.findOrCreateChange(modelName, id, function(err, change) { if (err) return next(err); @@ -106,13 +106,13 @@ module.exports = function(Change) { async.parallel(tasks, function(err) { if (err) return callback(err); if (errors.length) { - var desc = errors + const desc = errors .map(function(e) { return '#' + e.modelId + ' - ' + e.toString(); }) .join('\n'); - var msg = g.f('Cannot rectify %s changes:\n%s', modelName, desc); + const msg = g.f('Cannot rectify %s changes:\n%s', modelName, desc); err = new Error(msg); err.details = {errors: errors}; return callback(err); @@ -148,15 +148,15 @@ module.exports = function(Change) { Change.findOrCreateChange = function(modelName, modelId, callback) { assert(this.registry.findModel(modelName), modelName + ' does not exist'); callback = callback || utils.createPromiseCallback(); - var id = this.idForModel(modelName, modelId); - var Change = this; + const id = this.idForModel(modelName, modelId); + const Change = this; this.findById(id, function(err, change) { if (err) return callback(err); if (change) { callback(null, change); } else { - var ch = new Change({ + const ch = new Change({ id: id, modelName: modelName, modelId: modelId, @@ -177,8 +177,8 @@ module.exports = function(Change) { */ Change.prototype.rectify = function(cb) { - var change = this; - var currentRev = this.rev; + const change = this; + const currentRev = this.rev; change.debug('rectify change'); @@ -274,8 +274,8 @@ module.exports = function(Change) { Change.prototype.currentRevision = function(cb) { cb = cb || utils.createPromiseCallback(); - var model = this.getModelCtor(); - var id = this.getModelId(); + const model = this.getModelCtor(); + const id = this.getModelId(); model.findById(id, function(err, inst) { if (err) return cb(err); if (inst) { @@ -345,8 +345,8 @@ module.exports = function(Change) { Change.prototype.equals = function(change) { if (!change) return false; - var thisRev = this.rev || null; - var thatRev = change.rev || null; + const thisRev = this.rev || null; + const thatRev = change.rev || null; return thisRev === thatRev; }; @@ -423,8 +423,8 @@ module.exports = function(Change) { callback(null, {deltas: [], conflicts: []}); return callback.promise; } - var remoteChangeIndex = {}; - var modelIds = []; + const remoteChangeIndex = {}; + const modelIds = []; remoteChanges.forEach(function(ch) { modelIds.push(ch.modelId); remoteChangeIndex[ch.modelId] = new Change(ch); @@ -439,18 +439,18 @@ module.exports = function(Change) { }, }, function(err, allLocalChanges) { if (err) return callback(err); - var deltas = []; - var conflicts = []; - var localModelIds = []; + const deltas = []; + const conflicts = []; + const localModelIds = []; - var localChanges = allLocalChanges.filter(function(c) { + const localChanges = allLocalChanges.filter(function(c) { return c.checkpoint >= since; }); localChanges.forEach(function(localChange) { localChange = new Change(localChange); localModelIds.push(localChange.modelId); - var remoteChange = remoteChangeIndex[localChange.modelId]; + const remoteChange = remoteChangeIndex[localChange.modelId]; if (remoteChange && !localChange.equals(remoteChange)) { if (remoteChange.conflictsWith(localChange)) { remoteChange.debug('remote conflict'); @@ -466,8 +466,8 @@ module.exports = function(Change) { modelIds.forEach(function(id) { if (localModelIds.indexOf(id) !== -1) return; - var d = remoteChangeIndex[id]; - var oldChange = allLocalChanges.filter(function(c) { + const d = remoteChangeIndex[id]; + const oldChange = allLocalChanges.filter(function(c) { return c.modelId === id; })[0]; @@ -495,7 +495,7 @@ module.exports = function(Change) { Change.rectifyAll = function(cb) { debug('rectify all'); - var Change = this; + const Change = this; // this should be optimized this.find(function(err, changes) { if (err) return cb(err); @@ -513,7 +513,7 @@ module.exports = function(Change) { */ Change.getCheckpointModel = function() { - var checkpointModel = this.Checkpoint; + let checkpointModel = this.Checkpoint; if (checkpointModel) return checkpointModel; // FIXME(bajtos) This code creates multiple different models with the same // model name, which is not a valid supported usage of juggler's API. @@ -526,7 +526,7 @@ module.exports = function(Change) { Change.prototype.debug = function() { if (debug.enabled) { - var args = Array.prototype.slice.call(arguments); + const args = Array.prototype.slice.call(arguments); args[0] = args[0] + ' %s'; args.push(this.modelName); debug.apply(this, args); @@ -551,16 +551,16 @@ module.exports = function(Change) { Change.prototype.getModelId = function() { // TODO(ritch) get rid of the need to create an instance - var Model = this.getModelCtor(); - var id = this.modelId; - var m = new Model(); + const Model = this.getModelCtor(); + const id = this.modelId; + const m = new Model(); m.setId(id); return m.getId(); }; Change.prototype.getModel = function(callback) { - var Model = this.constructor.settings.trackModel; - var id = this.getModelId(); + const Model = this.constructor.settings.trackModel; + const id = this.getModelId(); Model.findById(id, callback); }; @@ -595,10 +595,10 @@ module.exports = function(Change) { */ Conflict.prototype.models = function(cb) { - var conflict = this; - var SourceModel = this.SourceModel; - var TargetModel = this.TargetModel; - var source, target; + const conflict = this; + const SourceModel = this.SourceModel; + const TargetModel = this.TargetModel; + let source, target; async.parallel([ getSourceModel, @@ -637,8 +637,8 @@ module.exports = function(Change) { */ Conflict.prototype.changes = function(cb) { - var conflict = this; - var sourceChange, targetChange; + const conflict = this; + let sourceChange, targetChange; async.parallel([ getSourceChange, @@ -646,7 +646,7 @@ module.exports = function(Change) { ], done); function getSourceChange(cb) { - var SourceModel = conflict.SourceModel; + const SourceModel = conflict.SourceModel; SourceModel.findLastChange(conflict.modelId, function(err, change) { if (err) return cb(err); sourceChange = change; @@ -655,7 +655,7 @@ module.exports = function(Change) { } function getTargetChange(cb) { - var TargetModel = conflict.TargetModel; + const TargetModel = conflict.TargetModel; TargetModel.findLastChange(conflict.modelId, function(err, change) { if (err) return cb(err); targetChange = change; @@ -684,7 +684,7 @@ module.exports = function(Change) { */ Conflict.prototype.resolve = function(cb) { - var conflict = this; + const conflict = this; conflict.TargetModel.findLastChange( this.modelId, function(err, targetChange) { @@ -718,14 +718,14 @@ module.exports = function(Change) { * @param {Error} err */ Conflict.prototype.resolveUsingTarget = function(cb) { - var conflict = this; + const conflict = this; conflict.models(function(err, source, target) { if (err) return done(err); if (target === null) { return conflict.SourceModel.deleteById(conflict.modelId, done); } - var inst = new conflict.SourceModel( + const inst = new conflict.SourceModel( target.toObject(), {persisted: true} ); @@ -751,7 +751,7 @@ module.exports = function(Change) { * @returns {Conflict} A new Conflict instance. */ Conflict.prototype.swapParties = function() { - var Ctor = this.constructor; + const Ctor = this.constructor; return new Ctor(this.modelId, this.TargetModel, this.SourceModel); }; @@ -765,14 +765,14 @@ module.exports = function(Change) { */ Conflict.prototype.resolveManually = function(data, cb) { - var conflict = this; + const conflict = this; if (!data) { return conflict.SourceModel.deleteById(conflict.modelId, done); } conflict.models(function(err, source, target) { if (err) return done(err); - var inst = source || new conflict.SourceModel(target); + const inst = source || new conflict.SourceModel(target); inst.setAttributes(data); inst.save(function(err) { if (err) return done(err); @@ -801,11 +801,11 @@ module.exports = function(Change) { */ Conflict.prototype.type = function(cb) { - var conflict = this; + const conflict = this; this.changes(function(err, sourceChange, targetChange) { if (err) return cb(err); - var sourceChangeType = sourceChange.type(); - var targetChangeType = targetChange.type(); + const sourceChangeType = sourceChange.type(); + const targetChangeType = targetChange.type(); if (sourceChangeType === Change.UPDATE && targetChangeType === Change.UPDATE) { return cb(null, Change.UPDATE); } diff --git a/common/models/checkpoint.js b/common/models/checkpoint.js index ea33ca83..e1439145 100644 --- a/common/models/checkpoint.js +++ b/common/models/checkpoint.js @@ -8,7 +8,7 @@ */ 'use strict'; -var assert = require('assert'); +const assert = require('assert'); /** * Checkpoint list entry. @@ -35,15 +35,15 @@ module.exports = function(Checkpoint) { * @param {Number} checkpoint The current checkpoint seq */ Checkpoint.current = function(cb) { - var Checkpoint = this; + const Checkpoint = this; Checkpoint._getSingleton(function(err, cp) { cb(err, cp.seq); }); }; Checkpoint._getSingleton = function(cb) { - var query = {limit: 1}; // match all instances, return only one - var initialData = {seq: 1}; + const query = {limit: 1}; // match all instances, return only one + const initialData = {seq: 1}; this.findOrCreate(query, initialData, cb); }; @@ -54,10 +54,10 @@ module.exports = function(Checkpoint) { * @param {Object} checkpoint The current checkpoint */ Checkpoint.bumpLastSeq = function(cb) { - var Checkpoint = this; + const Checkpoint = this; Checkpoint._getSingleton(function(err, cp) { if (err) return cb(err); - var originalSeq = cp.seq; + const originalSeq = cp.seq; cp.seq++; // Update the checkpoint but only if it was not changed under our hands Checkpoint.updateAll({id: cp.id, seq: originalSeq}, {seq: cp.seq}, function(err, info) { diff --git a/common/models/email.js b/common/models/email.js index 29fd61f5..10294e0d 100644 --- a/common/models/email.js +++ b/common/models/email.js @@ -4,7 +4,7 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var g = require('../../lib/globalize'); +const g = require('../../lib/globalize'); /** * Email model. Extends LoopBack base [Model](#model-new-model). diff --git a/common/models/key-value-model.js b/common/models/key-value-model.js index dd48777c..196032d4 100644 --- a/common/models/key-value-model.js +++ b/common/models/key-value-model.js @@ -4,7 +4,7 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var g = require('../../lib/globalize'); +const g = require('../../lib/globalize'); /** * Data model for key-value databases. @@ -233,10 +233,10 @@ function throwNotAttached(modelName, methodName) { function convertNullToNotFoundError(ctx, cb) { if (ctx.result !== null) return cb(); - var modelName = ctx.method.sharedClass.name; - var id = ctx.getArgByName('id'); - var msg = g.f('Unknown "%s" {{key}} "%s".', modelName, id); - var error = new Error(msg); + const modelName = ctx.method.sharedClass.name; + const id = ctx.getArgByName('id'); + const msg = g.f('Unknown "%s" {{key}} "%s".', modelName, id); + const error = new Error(msg); error.statusCode = error.status = 404; error.code = 'KEY_NOT_FOUND'; cb(error); diff --git a/common/models/role-mapping.js b/common/models/role-mapping.js index 61dd5e3b..d6d5f384 100644 --- a/common/models/role-mapping.js +++ b/common/models/role-mapping.js @@ -4,8 +4,8 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../lib/loopback'); -var utils = require('../../lib/utils'); +const loopback = require('../../lib/loopback'); +const utils = require('../../lib/utils'); /** * The `RoleMapping` model extends from the built in `loopback.Model` type. @@ -26,7 +26,7 @@ module.exports = function(RoleMapping) { RoleMapping.resolveRelatedModels = function() { if (!this.userModel) { - var reg = this.registry; + const reg = this.registry; this.roleModel = reg.getModelByType('Role'); this.userModel = reg.getModelByType('User'); this.applicationModel = reg.getModelByType('Application'); @@ -44,7 +44,7 @@ module.exports = function(RoleMapping) { this.constructor.resolveRelatedModels(); if (this.principalType === RoleMapping.APPLICATION) { - var applicationModel = this.constructor.applicationModel; + const applicationModel = this.constructor.applicationModel; applicationModel.findById(this.principalId, callback); } else { process.nextTick(function() { @@ -63,7 +63,7 @@ module.exports = function(RoleMapping) { RoleMapping.prototype.user = function(callback) { callback = callback || utils.createPromiseCallback(); this.constructor.resolveRelatedModels(); - var userModel; + let userModel; if (this.principalType === RoleMapping.USER) { userModel = this.constructor.userModel; @@ -94,7 +94,7 @@ module.exports = function(RoleMapping) { this.constructor.resolveRelatedModels(); if (this.principalType === RoleMapping.ROLE) { - var roleModel = this.constructor.roleModel; + const roleModel = this.constructor.roleModel; roleModel.findById(this.principalId, callback); } else { process.nextTick(function() { diff --git a/common/models/role.js b/common/models/role.js index b9515cbd..606dacea 100644 --- a/common/models/role.js +++ b/common/models/role.js @@ -4,15 +4,15 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../lib/loopback'); -var debug = require('debug')('loopback:security:role'); -var assert = require('assert'); -var async = require('async'); -var utils = require('../../lib/utils'); -var ctx = require('../../lib/access-context'); -var AccessContext = ctx.AccessContext; -var Principal = ctx.Principal; -var RoleMapping = loopback.RoleMapping; +const loopback = require('../../lib/loopback'); +const debug = require('debug')('loopback:security:role'); +const assert = require('assert'); +const async = require('async'); +const utils = require('../../lib/utils'); +const ctx = require('../../lib/access-context'); +const AccessContext = ctx.AccessContext; +const Principal = ctx.Principal; +const RoleMapping = loopback.RoleMapping; assert(RoleMapping, 'RoleMapping model must be defined before Role model'); @@ -24,7 +24,7 @@ assert(RoleMapping, 'RoleMapping model must be defined before Role model'); module.exports = function(Role) { Role.resolveRelatedModels = function() { if (!this.userModel) { - var reg = this.registry; + const reg = this.registry; this.roleMappingModel = reg.getModelByType('RoleMapping'); this.userModel = reg.getModelByType('User'); this.applicationModel = reg.getModelByType('Application'); @@ -74,29 +74,29 @@ module.exports = function(Role) { query.where = query.where || {}; roleModel.resolveRelatedModels(); - var relsToModels = { + const relsToModels = { users: roleModel.userModel, applications: roleModel.applicationModel, roles: roleModel, }; - var ACL = loopback.ACL; - var relsToTypes = { + const ACL = loopback.ACL; + const relsToTypes = { users: ACL.USER, applications: ACL.APP, roles: ACL.ROLE, }; - var principalModel = relsToModels[rel]; - var principalType = relsToTypes[rel]; + let principalModel = relsToModels[rel]; + let principalType = relsToTypes[rel]; // redefine user model and user type if user principalType is custom (available and not "USER") - var isCustomUserPrincipalType = rel === 'users' && + const isCustomUserPrincipalType = rel === 'users' && query.where.principalType && query.where.principalType !== RoleMapping.USER; if (isCustomUserPrincipalType) { - var registry = this.constructor.registry; + const registry = this.constructor.registry; principalModel = registry.findModel(query.where.principalType); principalType = query.where.principalType; } @@ -133,11 +133,10 @@ module.exports = function(Role) { roleModel.roleMappingModel.find({ where: {roleId: context.id, principalType: principalType}, }, function(err, mappings) { - var ids; if (err) { return callback(err); } - ids = mappings.map(function(m) { + const ids = mappings.map(function(m) { return m.principalId; }); query.where = query.where || {}; @@ -177,18 +176,18 @@ module.exports = function(Role) { }); return; } - var modelClass = context.model; - var modelId = context.modelId; - var user = context.getUser(); - var userId = user && user.id; - var principalType = user && user.principalType; - var opts = {accessToken: context.accessToken}; + const modelClass = context.model; + const modelId = context.modelId; + const user = context.getUser(); + const userId = user && user.id; + const principalType = user && user.principalType; + const opts = {accessToken: context.accessToken}; Role.isOwner(modelClass, modelId, userId, principalType, opts, callback); }); function isUserClass(modelClass) { if (!modelClass) return false; - var User = modelClass.modelBuilder.models.User; + const User = modelClass.modelBuilder.models.User; if (!User) return false; return modelClass == User || modelClass.prototype instanceof User; } @@ -222,7 +221,7 @@ module.exports = function(Role) { * @promise */ Role.isOwner = function isOwner(modelClass, modelId, userId, principalType, options, callback) { - var _this = this; + const _this = this; if (!callback && typeof options === 'function') { callback = options; @@ -253,8 +252,8 @@ module.exports = function(Role) { // 1. the app has a single user model and principalType is 'USER' // 2. the app has multiple user models and principalType is not 'USER' // multiple user models - var isMultipleUsers = _isMultipleUsers(); - var isPrincipalTypeValid = + const isMultipleUsers = _isMultipleUsers(); + const isPrincipalTypeValid = (!isMultipleUsers && principalType === Principal.USER) || (isMultipleUsers && principalType !== Principal.USER); @@ -271,7 +270,7 @@ module.exports = function(Role) { // Is the modelClass User or a subclass of User? if (isUserClass(modelClass)) { - var userModelName = modelClass.modelName; + const userModelName = modelClass.modelName; // matching ids is enough if principalType is USER or matches given user model name if (principalType === Principal.USER || principalType === userModelName) { process.nextTick(function() { @@ -289,7 +288,7 @@ module.exports = function(Role) { } debug('Model found: %j', inst); - var ownerRelations = modelClass.settings.ownerRelations; + const ownerRelations = modelClass.settings.ownerRelations; if (!ownerRelations) { return legacyOwnershipCheck(inst); } else { @@ -308,24 +307,24 @@ module.exports = function(Role) { // ownership check induced the whole isOwner() to resolve as false. // This behaviour will be pruned at next LoopBack major release. function legacyOwnershipCheck(inst) { - var ownerId = inst.userId || inst.owner; + const ownerId = inst.userId || inst.owner; if (principalType === Principal.USER && ownerId && 'function' !== typeof ownerId) { return callback(null, matches(ownerId, userId)); } // Try to follow belongsTo - for (var r in modelClass.relations) { - var rel = modelClass.relations[r]; + for (const r in modelClass.relations) { + const rel = modelClass.relations[r]; // relation should be belongsTo and target a User based class - var belongsToUser = rel.type === 'belongsTo' && isUserClass(rel.modelTo); + const belongsToUser = rel.type === 'belongsTo' && isUserClass(rel.modelTo); if (!belongsToUser) { continue; } // checking related user - var relatedUser = rel.modelTo; - var userModelName = relatedUser.modelName; - var isMultipleUsers = _isMultipleUsers(relatedUser); + const relatedUser = rel.modelTo; + const userModelName = relatedUser.modelName; + const isMultipleUsers = _isMultipleUsers(relatedUser); // a relation can be considered for isOwner resolution if: // 1. the app has a single user model and principalType is 'USER' // 2. the app has multiple user models and principalType is the related user model name @@ -349,20 +348,20 @@ module.exports = function(Role) { } function checkOwnership(inst) { - var ownerRelations = inst.constructor.settings.ownerRelations; + const ownerRelations = inst.constructor.settings.ownerRelations; // collecting related users - var relWithUsers = []; - for (var r in modelClass.relations) { - var rel = modelClass.relations[r]; + const relWithUsers = []; + for (const r in modelClass.relations) { + const rel = modelClass.relations[r]; // relation should be belongsTo and target a User based class if (rel.type !== 'belongsTo' || !isUserClass(rel.modelTo)) { continue; } // checking related user - var relatedUser = rel.modelTo; - var userModelName = relatedUser.modelName; - var isMultipleUsers = _isMultipleUsers(relatedUser); + const relatedUser = rel.modelTo; + const userModelName = relatedUser.modelName; + const isMultipleUsers = _isMultipleUsers(relatedUser); // a relation can be considered for isOwner resolution if: // 1. the app has a single user model and principalType is 'USER' // 2. the app has multiple user models and principalType is the related user model name @@ -403,8 +402,8 @@ module.exports = function(Role) { // user model by type. The relation with AccessToken is used to check // if polymorphism is used, and thus if multiple users. function _isMultipleUsers(userModel) { - var oneOfUserModels = userModel || _this.registry.getModelByType('User'); - var accessTokensRel = oneOfUserModels.relations.accessTokens; + const oneOfUserModels = userModel || _this.registry.getModelByType('User'); + const accessTokensRel = oneOfUserModels.relations.accessTokens; return !!(accessTokensRel && accessTokensRel.polymorphic); } }; @@ -480,11 +479,11 @@ module.exports = function(Role) { debug('isInRole(): %s', role); context.debug(); - var resolver = Role.resolvers[role]; + const resolver = Role.resolvers[role]; if (resolver) { debug('Custom resolver found for role %s', role); - var promise = resolver(role, context, callback); + const promise = resolver(role, context, callback); if (promise && typeof promise.then === 'function') { promise.then( function(result) { callback(null, result); }, @@ -502,9 +501,9 @@ module.exports = function(Role) { return callback.promise; } - var inRole = context.principals.some(function(p) { - var principalType = p.type || undefined; - var principalId = p.id || undefined; + const inRole = context.principals.some(function(p) { + const principalType = p.type || undefined; + const principalId = p.id || undefined; // Check if it's the same role return principalType === RoleMapping.ROLE && principalId === role; @@ -518,7 +517,7 @@ module.exports = function(Role) { return callback.promise; } - var roleMappingModel = this.roleMappingModel; + const roleMappingModel = this.roleMappingModel; this.findOne({where: {name: role}}, function(err, result) { if (err) { if (callback) callback(err); @@ -532,10 +531,10 @@ module.exports = function(Role) { // Iterate through the list of principals async.some(context.principals, function(p, done) { - var principalType = p.type || undefined; - var principalId = p.id || undefined; - var roleId = result.id.toString(); - var principalIdIsString = typeof principalId === 'string'; + const principalType = p.type || undefined; + let principalId = p.id || undefined; + const roleId = result.id.toString(); + const principalIdIsString = typeof principalId === 'string'; if (principalId !== null && principalId !== undefined && !principalIdIsString) { principalId = principalId.toString(); @@ -585,18 +584,18 @@ module.exports = function(Role) { if (!(context instanceof AccessContext)) { context = new AccessContext(context); } - var roles = []; + const roles = []; this.resolveRelatedModels(); - var addRole = function(role) { + const addRole = function(role) { if (role && roles.indexOf(role) === -1) { roles.push(role); } }; - var self = this; + const self = this; // Check against the smart roles - var inRoleTasks = []; + const inRoleTasks = []; Object.keys(Role.resolvers).forEach(function(role) { inRoleTasks.push(function(done) { self.isInRole(role, context, function(err, inRole) { @@ -613,11 +612,11 @@ module.exports = function(Role) { }); }); - var roleMappingModel = this.roleMappingModel; + const roleMappingModel = this.roleMappingModel; context.principals.forEach(function(p) { // Check against the role mappings - var principalType = p.type || undefined; - var principalId = p.id == null ? undefined : p.id; + const principalType = p.type || undefined; + let principalId = p.id == null ? undefined : p.id; if (typeof principalId !== 'string' && principalId != null) { principalId = principalId.toString(); @@ -631,7 +630,7 @@ module.exports = function(Role) { if (principalType && principalId) { // Please find() treat undefined matches all values inRoleTasks.push(function(done) { - var filter = {where: {principalType: principalType, principalId: principalId}}; + const filter = {where: {principalType: principalType, principalId: principalId}}; if (options.returnOnlyRoleNames === true) { filter.include = ['role']; } @@ -642,7 +641,7 @@ module.exports = function(Role) { return; } mappings.forEach(function(m) { - var role; + let role; if (options.returnOnlyRoleNames === true) { role = m.toJSON().role.name; } else { diff --git a/common/models/scope.js b/common/models/scope.js index 1c119458..3294da5a 100644 --- a/common/models/scope.js +++ b/common/models/scope.js @@ -4,8 +4,8 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var loopback = require('../../lib/loopback'); +const assert = require('assert'); +const loopback = require('../../lib/loopback'); /** * Resource owner grants/delegates permissions to client applications @@ -21,7 +21,7 @@ var loopback = require('../../lib/loopback'); module.exports = function(Scope) { Scope.resolveRelatedModels = function() { if (!this.aclModel) { - var reg = this.registry; + const reg = this.registry; this.aclModel = reg.getModelByType(loopback.ACL); } }; @@ -38,7 +38,7 @@ module.exports = function(Scope) { */ Scope.checkPermission = function(scope, model, property, accessType, callback) { this.resolveRelatedModels(); - var aclModel = this.aclModel; + const aclModel = this.aclModel; assert(aclModel, 'ACL model must be defined before Scope.checkPermission is called'); diff --git a/common/models/user.js b/common/models/user.js index a8dd29cb..1826c0c4 100644 --- a/common/models/user.js +++ b/common/models/user.js @@ -8,18 +8,18 @@ */ 'use strict'; -var g = require('../../lib/globalize'); -var isEmail = require('isemail'); -var loopback = require('../../lib/loopback'); -var utils = require('../../lib/utils'); -var path = require('path'); -var qs = require('querystring'); -var SALT_WORK_FACTOR = 10; -var crypto = require('crypto'); +const g = require('../../lib/globalize'); +const isEmail = require('isemail'); +const loopback = require('../../lib/loopback'); +const utils = require('../../lib/utils'); +const path = require('path'); +const qs = require('querystring'); +const SALT_WORK_FACTOR = 10; +const crypto = require('crypto'); // bcrypt's max length is 72 bytes; // See https://github.com/kelektiv/node.bcrypt.js/blob/45f498ef6dc6e8234e58e07834ce06a50ff16352/src/node_blf.h#L59 -var MAX_PASSWORD_LENGTH = 72; -var bcrypt; +const MAX_PASSWORD_LENGTH = 72; +let bcrypt; try { // Try the native module first bcrypt = require('bcrypt'); @@ -32,12 +32,12 @@ try { bcrypt = require('bcryptjs'); } -var DEFAULT_TTL = 1209600; // 2 weeks in seconds -var DEFAULT_RESET_PW_TTL = 15 * 60; // 15 mins in seconds -var DEFAULT_MAX_TTL = 31556926; // 1 year in seconds -var assert = require('assert'); +const DEFAULT_TTL = 1209600; // 2 weeks in seconds +const DEFAULT_RESET_PW_TTL = 15 * 60; // 15 mins in seconds +const DEFAULT_MAX_TTL = 31556926; // 1 year in seconds +const assert = require('assert'); -var debug = require('debug')('loopback:user'); +const debug = require('debug')('loopback:user'); /** * Built-in User model. @@ -123,18 +123,18 @@ module.exports = function(User) { tokenData = {}; } - var userSettings = this.constructor.settings; + const userSettings = this.constructor.settings; tokenData.ttl = Math.min(tokenData.ttl || userSettings.ttl, userSettings.maxTTL); this.accessTokens.create(tokenData, options, cb); return cb.promise; }; function splitPrincipal(name, realmDelimiter) { - var parts = [null, name]; + const parts = [null, name]; if (!realmDelimiter) { return parts; } - var index = name.indexOf(realmDelimiter); + const index = name.indexOf(realmDelimiter); if (index !== -1) { parts[0] = name.substring(0, index); parts[1] = name.substring(index + realmDelimiter.length); @@ -150,7 +150,7 @@ module.exports = function(User) { * @returns {Object} The normalized credential object */ User.normalizeCredentials = function(credentials, realmRequired, realmDelimiter) { - var query = {}; + const query = {}; credentials = credentials || {}; if (!realmRequired) { if (credentials.email) { @@ -162,7 +162,7 @@ module.exports = function(User) { if (credentials.realm) { query.realm = credentials.realm; } - var parts; + let parts; if (credentials.email) { parts = splitPrincipal(credentials.email, realmDelimiter); query.email = parts[1]; @@ -205,7 +205,7 @@ module.exports = function(User) { */ User.login = function(credentials, include, fn) { - var self = this; + const self = this; if (typeof include === 'function') { fn = include; include = undefined; @@ -222,25 +222,25 @@ module.exports = function(User) { include = include.toLowerCase(); } - var realmDelimiter; + let realmDelimiter; // Check if realm is required - var realmRequired = !!(self.settings.realmRequired || + const realmRequired = !!(self.settings.realmRequired || self.settings.realmDelimiter); if (realmRequired) { realmDelimiter = self.settings.realmDelimiter; } - var query = self.normalizeCredentials(credentials, realmRequired, + const query = self.normalizeCredentials(credentials, realmRequired, realmDelimiter); if (realmRequired) { if (!query.realm) { - var err1 = new Error(g.f('{{realm}} is required')); + const err1 = new Error(g.f('{{realm}} is required')); err1.statusCode = 400; err1.code = 'REALM_REQUIRED'; fn(err1); return fn.promise; } else if (typeof query.realm !== 'string') { - var err5 = new Error(g.f('Invalid realm')); + const err5 = new Error(g.f('Invalid realm')); err5.statusCode = 400; err5.code = 'INVALID_REALM'; fn(err5); @@ -248,20 +248,20 @@ module.exports = function(User) { } } if (!query.email && !query.username) { - var err2 = new Error(g.f('{{username}} or {{email}} is required')); + const err2 = new Error(g.f('{{username}} or {{email}} is required')); err2.statusCode = 400; err2.code = 'USERNAME_EMAIL_REQUIRED'; fn(err2); return fn.promise; } if (query.username && typeof query.username !== 'string') { - var err3 = new Error(g.f('Invalid username')); + const err3 = new Error(g.f('Invalid username')); err3.statusCode = 400; err3.code = 'INVALID_USERNAME'; fn(err3); return fn.promise; } else if (query.email && typeof query.email !== 'string') { - var err4 = new Error(g.f('Invalid email')); + const err4 = new Error(g.f('Invalid email')); err4.statusCode = 400; err4.code = 'INVALID_EMAIL'; fn(err4); @@ -269,7 +269,7 @@ module.exports = function(User) { } self.findOne({where: query}, function(err, user) { - var defaultError = new Error(g.f('login failed')); + const defaultError = new Error(g.f('login failed')); defaultError.statusCode = 401; defaultError.code = 'LOGIN_FAILED'; @@ -344,7 +344,7 @@ module.exports = function(User) { User.logout = function(tokenId, fn) { fn = fn || utils.createPromiseCallback(); - var err; + let err; if (!tokenId) { err = new Error(g.f('{{accessToken}} is required to logout')); err.statusCode = 401; @@ -370,12 +370,12 @@ module.exports = function(User) { // Do nothing when the access control was disabled for this user model. if (!ctx.Model.relations.accessTokens) return next(); - var AccessToken = ctx.Model.relations.accessTokens.modelTo; - var pkName = ctx.Model.definition.idName() || 'id'; + const AccessToken = ctx.Model.relations.accessTokens.modelTo; + const pkName = ctx.Model.definition.idName() || 'id'; ctx.Model.find({where: ctx.where, fields: [pkName]}, function(err, list) { if (err) return next(err); - var ids = list.map(function(u) { return u[pkName]; }); + const ids = list.map(function(u) { return u[pkName]; }); ctx.where = {}; ctx.where[pkName] = {inq: ids}; @@ -720,9 +720,9 @@ module.exports = function(User) { } cb = cb || utils.createPromiseCallback(); - var user = this; - var userModel = this.constructor; - var registry = userModel.registry; + const user = this; + const userModel = this.constructor; + const registry = userModel.registry; verifyOptions = Object.assign({}, verifyOptions); // final assertion is performed once all options are assigned assert(typeof verifyOptions === 'object', @@ -743,19 +743,19 @@ module.exports = function(User) { verifyOptions.mailer = verifyOptions.mailer || userModel.email || registry.getModelByType(loopback.Email); - var pkName = userModel.definition.idName() || 'id'; + const pkName = userModel.definition.idName() || 'id'; verifyOptions.redirect = verifyOptions.redirect || '/'; - var defaultTemplate = path.join(__dirname, '..', '..', 'templates', 'verify.ejs'); + const defaultTemplate = path.join(__dirname, '..', '..', 'templates', 'verify.ejs'); verifyOptions.template = path.resolve(verifyOptions.template || defaultTemplate); verifyOptions.user = user; verifyOptions.protocol = verifyOptions.protocol || 'http'; - var app = userModel.app; + const app = userModel.app; verifyOptions.host = verifyOptions.host || (app && app.get('host')) || 'localhost'; verifyOptions.port = verifyOptions.port || (app && app.get('port')) || 3000; verifyOptions.restApiRoot = verifyOptions.restApiRoot || (app && app.get('restApiRoot')) || '/api'; - var displayPort = ( + const displayPort = ( (verifyOptions.protocol === 'http' && verifyOptions.port == '80') || (verifyOptions.protocol === 'https' && verifyOptions.port == '443') ) ? '' : ':' + verifyOptions.port; @@ -796,7 +796,7 @@ module.exports = function(User) { assertVerifyOptions(verifyOptions); // argument "options" is passed depending on verifyOptions.generateVerificationToken function requirements - var tokenGenerator = verifyOptions.generateVerificationToken; + const tokenGenerator = verifyOptions.generateVerificationToken; if (tokenGenerator.length == 3) { tokenGenerator(user, options, addTokenToUserAndSave); } else { @@ -824,7 +824,7 @@ module.exports = function(User) { verifyOptions.text = verifyOptions.text.replace(/\{href\}/g, verifyOptions.verifyHref); // argument "options" is passed depending on templateFn function requirements - var templateFn = verifyOptions.templateFn; + const templateFn = verifyOptions.templateFn; if (templateFn.length == 3) { templateFn(verifyOptions, options, setHtmlContentAndSend); } else { @@ -841,7 +841,7 @@ module.exports = function(User) { delete verifyOptions.template; // argument "options" is passed depending on Email.send function requirements - var Email = verifyOptions.mailer; + const Email = verifyOptions.mailer; if (Email.send.length == 3) { Email.send(verifyOptions, options, handleAfterSend); } else { @@ -873,8 +873,8 @@ module.exports = function(User) { } function createVerificationEmailBody(verifyOptions, options, cb) { - var template = loopback.template(verifyOptions.template); - var body = template(verifyOptions); + const template = loopback.template(verifyOptions.template); + const body = template(verifyOptions); cb(null, body); } @@ -952,11 +952,11 @@ module.exports = function(User) { User.resetPassword = function(options, cb) { cb = cb || utils.createPromiseCallback(); - var UserModel = this; - var ttl = UserModel.settings.resetPasswordTokenTTL || DEFAULT_RESET_PW_TTL; + const UserModel = this; + const ttl = UserModel.settings.resetPasswordTokenTTL || DEFAULT_RESET_PW_TTL; options = options || {}; if (typeof options.email !== 'string') { - var err = new Error(g.f('Email is required')); + const err = new Error(g.f('Email is required')); err.statusCode = 400; err.code = 'EMAIL_REQUIRED'; cb(err); @@ -970,7 +970,7 @@ module.exports = function(User) { } catch (err) { return cb(err); } - var where = { + const where = { email: options.email, }; if (options.realm) { @@ -1031,12 +1031,12 @@ module.exports = function(User) { */ User.hashPassword = function(plain) { this.validatePassword(plain); - var salt = bcrypt.genSaltSync(this.settings.saltWorkFactor || SALT_WORK_FACTOR); + const salt = bcrypt.genSaltSync(this.settings.saltWorkFactor || SALT_WORK_FACTOR); return bcrypt.hashSync(plain, salt); }; User.validatePassword = function(plain) { - var err; + let err; if (!plain || typeof plain !== 'string') { err = new Error(g.f('Invalid password.')); err.code = 'INVALID_PASSWORD'; @@ -1045,7 +1045,7 @@ module.exports = function(User) { } // Bcrypt only supports up to 72 bytes; the rest is silently dropped. - var len = Buffer.byteLength(plain, 'utf8'); + const len = Buffer.byteLength(plain, 'utf8'); if (len > MAX_PASSWORD_LENGTH) { err = new Error(g.f('The password entered was too long. Max length is %d (entered %d)', MAX_PASSWORD_LENGTH, len)); @@ -1064,20 +1064,20 @@ module.exports = function(User) { if (!Array.isArray(userIds) || !userIds.length) return process.nextTick(cb); - var accessTokenRelation = this.relations.accessTokens; + const accessTokenRelation = this.relations.accessTokens; if (!accessTokenRelation) return process.nextTick(cb); - var AccessToken = accessTokenRelation.modelTo; - var query = {userId: {inq: userIds}}; - var tokenPK = AccessToken.definition.idName() || 'id'; + const AccessToken = accessTokenRelation.modelTo; + const query = {userId: {inq: userIds}}; + const tokenPK = AccessToken.definition.idName() || 'id'; if (options.accessToken && tokenPK in options.accessToken) { query[tokenPK] = {neq: options.accessToken[tokenPK]}; } // add principalType in AccessToken.query if using polymorphic relations // between AccessToken and User - var relatedUser = AccessToken.relations.user; - var isRelationPolymorphic = relatedUser && relatedUser.polymorphic && + const relatedUser = AccessToken.relations.user; + const isRelationPolymorphic = relatedUser && relatedUser.polymorphic && !relatedUser.modelTo; if (isRelationPolymorphic) { query.principalType = this.modelName; @@ -1092,7 +1092,7 @@ module.exports = function(User) { User.setup = function() { // We need to call the base class's setup method User.base.setup.call(this); - var UserModel = this; + const UserModel = this; // max ttl this.settings.maxTTL = this.settings.maxTTL || DEFAULT_MAX_TTL; @@ -1121,7 +1121,7 @@ module.exports = function(User) { // Make sure emailVerified is not set by creation UserModel.beforeRemote('create', function(ctx, user, next) { - var body = ctx.req.body; + const body = ctx.req.body; if (body && body.emailVerified) { body.emailVerified = false; } @@ -1157,9 +1157,9 @@ module.exports = function(User) { description: 'Logout a user with access token.', accepts: [ {arg: 'access_token', type: 'string', http: function(ctx) { - var req = ctx && ctx.req; - var accessToken = req && req.accessToken; - var tokenID = accessToken ? accessToken.id : undefined; + const req = ctx && ctx.req; + const accessToken = req && req.accessToken; + const tokenID = accessToken ? accessToken.id : undefined; return tokenID; }, description: 'Do not supply this argument, it is automatically extracted ' + @@ -1361,8 +1361,8 @@ module.exports = function(User) { if (ctx.isNewInstance) return next(); if (!ctx.where && !ctx.instance) return next(); - var pkName = ctx.Model.definition.idName() || 'id'; - var where = ctx.where; + const pkName = ctx.Model.definition.idName() || 'id'; + let where = ctx.where; if (!where) { where = {}; where[pkName] = ctx.instance[pkName]; @@ -1371,13 +1371,13 @@ module.exports = function(User) { ctx.Model.find({where: where}, ctx.options, function(err, userInstances) { if (err) return next(err); ctx.hookState.originalUserData = userInstances.map(function(u) { - var user = {}; + const user = {}; user[pkName] = u[pkName]; user.email = u.email; user.password = u.password; return user; }); - var emailChanged; + let emailChanged; if (ctx.instance) { // Check if map does not return an empty array // Fix server crashes when try to PUT a non existent id @@ -1407,15 +1407,15 @@ module.exports = function(User) { if (!ctx.instance && !ctx.data) return next(); if (!ctx.hookState.originalUserData) return next(); - var pkName = ctx.Model.definition.idName() || 'id'; - var newEmail = (ctx.instance || ctx.data).email; - var newPassword = (ctx.instance || ctx.data).password; + const pkName = ctx.Model.definition.idName() || 'id'; + const newEmail = (ctx.instance || ctx.data).email; + const newPassword = (ctx.instance || ctx.data).password; if (!newEmail && !newPassword) return next(); if (ctx.options.preserveAccessTokens) return next(); - var userIdsToExpire = ctx.hookState.originalUserData.filter(function(u) { + const userIdsToExpire = ctx.hookState.originalUserData.filter(function(u) { return (newEmail && u.email !== newEmail) || (newPassword && u.password !== newPassword); }).map(function(u) { @@ -1426,7 +1426,7 @@ module.exports = function(User) { }; function emailValidator(err, done) { - var value = this.email; + const value = this.email; if (value == null) return; if (typeof value !== 'string') @@ -1437,9 +1437,9 @@ function emailValidator(err, done) { } function joinUrlPath(args) { - var result = arguments[0]; - for (var ix = 1; ix < arguments.length; ix++) { - var next = arguments[ix]; + let result = arguments[0]; + for (let ix = 1; ix < arguments.length; ix++) { + const next = arguments[ix]; result += result[result.length - 1] === '/' && next[0] === '/' ? next.slice(1) : next; } diff --git a/example/client-server/client.js b/example/client-server/client.js index f812b4ca..ed5284da 100644 --- a/example/client-server/client.js +++ b/example/client-server/client.js @@ -4,11 +4,11 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var g = require('../../lib/globalize'); -var loopback = require('../../'); -var client = loopback(); -var CartItem = require('./models').CartItem; -var remote = loopback.createDataSource({ +const g = require('../../lib/globalize'); +const loopback = require('../../'); +const client = loopback(); +const CartItem = require('./models').CartItem; +const remote = loopback.createDataSource({ connector: loopback.Remote, url: 'http://localhost:3000', }); diff --git a/example/client-server/models.js b/example/client-server/models.js index 87ba0892..9c76ca2b 100644 --- a/example/client-server/models.js +++ b/example/client-server/models.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../'); +const loopback = require('../../'); -var CartItem = exports.CartItem = loopback.PersistedModel.extend('CartItem', { +const CartItem = exports.CartItem = loopback.PersistedModel.extend('CartItem', { tax: {type: Number, default: 0.1}, price: Number, item: String, @@ -17,7 +17,7 @@ var CartItem = exports.CartItem = loopback.PersistedModel.extend('CartItem', { CartItem.sum = function(cartId, callback) { this.find({where: {cartId: cartId}}, function(err, items) { if (err) return callback(err); - var total = items + const total = items .map(function(item) { return item.total(); }) @@ -33,8 +33,7 @@ CartItem.remoteMethod('sum', { accepts: {arg: 'cartId', type: 'number'}, returns: {arg: 'total', type: 'number'}, - } -); + }); CartItem.prototype.total = function() { return this.price * this.qty * (1 + this.tax); diff --git a/example/client-server/server.js b/example/client-server/server.js index e5eae552..feb4c294 100644 --- a/example/client-server/server.js +++ b/example/client-server/server.js @@ -4,10 +4,10 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../'); -var server = module.exports = loopback(); -var CartItem = require('./models').CartItem; -var memory = loopback.createDataSource({ +const loopback = require('../../'); +const server = module.exports = loopback(); +const CartItem = require('./models').CartItem; +const memory = loopback.createDataSource({ connector: loopback.Memory, }); diff --git a/example/colors/app.js b/example/colors/app.js index b1fe8dc4..4cbccafa 100644 --- a/example/colors/app.js +++ b/example/colors/app.js @@ -4,18 +4,18 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var g = require('../../lib/globalize'); -var loopback = require('../../'); -var app = loopback(); +const g = require('../../lib/globalize'); +const loopback = require('../../'); +const app = loopback(); app.use(loopback.rest()); -var schema = { +const schema = { name: String, }; app.dataSource('db', {connector: 'memory'}); -var Color = app.registry.createModel('color', schema); +const Color = app.registry.createModel('color', schema); app.model(Color, {dataSource: 'db'}); Color.create({name: 'red'}); diff --git a/example/mobile-models/app.js b/example/mobile-models/app.js index d82baf4f..67963f78 100644 --- a/example/mobile-models/app.js +++ b/example/mobile-models/app.js @@ -4,20 +4,20 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var g = require('../../lib/globalize'); -var models = require('../../lib/models'); -var loopback = require('../../'); -var app = loopback(); +const g = require('../../lib/globalize'); +const models = require('../../lib/models'); +const loopback = require('../../'); +const app = loopback(); app.use(loopback.rest()); -var dataSource = loopback.createDataSource('db', {connector: loopback.Memory}); +const dataSource = loopback.createDataSource('db', {connector: loopback.Memory}); -var Application = models.Application(dataSource); +const Application = models.Application(dataSource); app.model(Application); -var data = { +const data = { pushSettings: [{ 'platform': 'apns', 'apns': { diff --git a/example/replication/app.js b/example/replication/app.js index 2acab0a8..ec9a886c 100644 --- a/example/replication/app.js +++ b/example/replication/app.js @@ -4,19 +4,19 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../'); -var app = loopback(); -var db = app.dataSource('db', {connector: 'memory'}); -var Color = app.registry.createModel('color', {}, {trackChanges: true}); +const loopback = require('../../'); +const app = loopback(); +const db = app.dataSource('db', {connector: 'memory'}); +const Color = app.registry.createModel('color', {}, {trackChanges: true}); app.model(Color, {dataSource: 'db'}); -var Color2 = app.registry.createModel('color2', {}, {trackChanges: true}); +const Color2 = app.registry.createModel('color2', {}, {trackChanges: true}); app.model(Color2, {dataSource: 'db'}); -var target = Color2; -var source = Color; -var SPEED = process.env.SPEED || 100; -var conflicts; +const target = Color2; +const source = Color; +const SPEED = process.env.SPEED || 100; +let conflicts; -var steps = [ +const steps = [ createSomeInitialSourceData, @@ -137,7 +137,7 @@ function list(model, msg) { function run(steps) { setInterval(function() { - var step = steps.shift(); + const step = steps.shift(); if (step) { console.log(step.name); step(); diff --git a/example/simple-data-source/app.js b/example/simple-data-source/app.js index 67e29913..e5b5f12b 100644 --- a/example/simple-data-source/app.js +++ b/example/simple-data-source/app.js @@ -4,15 +4,15 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var g = require('../../lib/globalize'); -var loopback = require('../../'); -var app = loopback(); +const g = require('../../lib/globalize'); +const loopback = require('../../'); +const app = loopback(); app.use(loopback.rest()); -var dataSource = app.dataSource('db', {adapter: 'memory'}); +const dataSource = app.dataSource('db', {adapter: 'memory'}); -var Color = dataSource.define('color', { +const Color = dataSource.define('color', { 'name': String, }); diff --git a/lib/access-context.js b/lib/access-context.js index ed37bd4e..5a9a55b5 100644 --- a/lib/access-context.js +++ b/lib/access-context.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var loopback = require('./loopback'); -var debug = require('debug')('loopback:security:access-context'); +const assert = require('assert'); +const loopback = require('./loopback'); +const debug = require('debug')('loopback:security:access-context'); const DEFAULT_SCOPES = ['DEFAULT']; @@ -50,7 +50,7 @@ function AccessContext(context) { 'Application registry is mandatory in AccessContext but missing in provided context'); this.registry = context.registry; this.principals = context.principals || []; - var model = context.model; + let model = context.model; model = ('string' === typeof model) ? this.registry.getModel(model) : model; this.model = model; this.modelName = model && model.modelName; @@ -77,9 +77,9 @@ function AccessContext(context) { 'AccessToken model must be defined before AccessContext model'); this.accessToken = context.accessToken || loopback.AccessToken.ANONYMOUS; - var principalType = context.principalType || Principal.USER; - var principalId = context.principalId || undefined; - var principalName = context.principalName || undefined; + const principalType = context.principalType || Principal.USER; + const principalId = context.principalId || undefined; + const principalName = context.principalName || undefined; if (principalId != null) { this.addPrincipal(principalType, principalId, principalName); } @@ -126,9 +126,9 @@ AccessContext.permissionOrder = { * @returns {boolean} */ AccessContext.prototype.addPrincipal = function(principalType, principalId, principalName) { - var principal = new Principal(principalType, principalId, principalName); - for (var i = 0; i < this.principals.length; i++) { - var p = this.principals[i]; + const principal = new Principal(principalType, principalId, principalName); + for (let i = 0; i < this.principals.length; i++) { + const p = this.principals[i]; if (p.equals(principal)) { return false; } @@ -142,7 +142,7 @@ AccessContext.prototype.addPrincipal = function(principalType, principalId, prin * @returns {*} */ AccessContext.prototype.getUserId = function() { - var user = this.getUser(); + const user = this.getUser(); return user && user.id; }; @@ -151,10 +151,10 @@ AccessContext.prototype.getUserId = function() { * @returns {*} */ AccessContext.prototype.getUser = function() { - var BaseUser = this.registry.getModel('User'); - for (var i = 0; i < this.principals.length; i++) { - var p = this.principals[i]; - var isBuiltinPrincipal = p.type === Principal.APP || + const BaseUser = this.registry.getModel('User'); + for (let i = 0; i < this.principals.length; i++) { + const p = this.principals[i]; + const isBuiltinPrincipal = p.type === Principal.APP || p.type === Principal.ROLE || p.type == Principal.SCOPE; if (isBuiltinPrincipal) continue; @@ -165,7 +165,7 @@ AccessContext.prototype.getUser = function() { } // or permit to resolve a valid user model - var userModel = this.registry.findModel(p.type); + const userModel = this.registry.findModel(p.type); if (!userModel) continue; if (userModel.prototype instanceof BaseUser) { return {id: p.id, principalType: p.type}; @@ -178,8 +178,8 @@ AccessContext.prototype.getUser = function() { * @returns {*} */ AccessContext.prototype.getAppId = function() { - for (var i = 0; i < this.principals.length; i++) { - var p = this.principals[i]; + for (let i = 0; i < this.principals.length; i++) { + const p = this.principals[i]; if (p.type === Principal.APPLICATION) { return p.id; } @@ -325,7 +325,7 @@ function AccessRequest(model, property, accessType, permission, methodNames, reg } if (arguments.length === 1 && typeof model === 'object') { // The argument is an object that contains all required properties - var obj = model || {}; + const obj = model || {}; this.model = obj.model || AccessContext.ALL; this.property = obj.property || AccessContext.ALL; this.accessType = obj.accessType || AccessContext.ALL; @@ -363,10 +363,10 @@ AccessRequest.prototype.isWildcard = function() { */ AccessRequest.prototype.exactlyMatches = function(acl) { - var matchesModel = acl.model === this.model; - var matchesProperty = acl.property === this.property; - var matchesMethodName = this.methodNames.indexOf(acl.property) !== -1; - var matchesAccessType = acl.accessType === this.accessType; + const matchesModel = acl.model === this.model; + const matchesProperty = acl.property === this.property; + const matchesMethodName = this.methodNames.indexOf(acl.property) !== -1; + const matchesAccessType = acl.accessType === this.accessType; if (matchesModel && matchesAccessType) { return matchesProperty || matchesMethodName; @@ -388,9 +388,9 @@ AccessRequest.prototype.settleDefaultPermission = function(defaultPermission) { if (this.permission !== 'DEFAULT') return; - var modelName = this.model; + const modelName = this.model; if (!defaultPermission) { - var modelClass = this.registry.findModel(modelName); + const modelClass = this.registry.findModel(modelName); defaultPermission = modelClass && modelClass.settings.defaultPermission; } diff --git a/lib/application.js b/lib/application.js index bc1ba664..0d7b5a5c 100644 --- a/lib/application.js +++ b/lib/application.js @@ -8,17 +8,17 @@ */ 'use strict'; -var g = require('./globalize'); -var DataSource = require('loopback-datasource-juggler').DataSource; -var Registry = require('./registry'); -var assert = require('assert'); -var fs = require('fs'); -var extend = require('util')._extend; -var RemoteObjects = require('strong-remoting'); -var classify = require('underscore.string/classify'); -var camelize = require('underscore.string/camelize'); -var path = require('path'); -var util = require('util'); +const g = require('./globalize'); +const DataSource = require('loopback-datasource-juggler').DataSource; +const Registry = require('./registry'); +const assert = require('assert'); +const fs = require('fs'); +const extend = require('util')._extend; +const RemoteObjects = require('strong-remoting'); +const classify = require('underscore.string/classify'); +const camelize = require('underscore.string/camelize'); +const path = require('path'); +const util = require('util'); /** * The `App` object represents a Loopback application. @@ -49,7 +49,7 @@ function App() { * Export the app prototype. */ -var app = module.exports = {}; +const app = module.exports = {}; /** * Lazily load a set of [remote objects](http://apidocs.strongloop.com/strong-remoting/#remoteobjectsoptions). @@ -62,7 +62,7 @@ app.remotes = function() { if (this._remotes) { return this._remotes; } else { - var options = {}; + let options = {}; if (this.get) { options = this.get('remoting'); @@ -78,7 +78,7 @@ app.remotes = function() { app.disuse = function(route) { if (this.stack) { - for (var i = 0; i < this.stack.length; i++) { + for (let i = 0; i < this.stack.length; i++) { if (this.stack[i].route === route) { this.stack.splice(i, 1); } @@ -111,11 +111,11 @@ app.disuse = function(route) { */ app.model = function(Model, config) { - var isPublic = true; - var registry = this.registry; + let isPublic = true; + const registry = this.registry; if (typeof Model === 'string') { - var msg = 'app.model(modelName, settings) is no longer supported. ' + + const msg = 'app.model(modelName, settings) is no longer supported. ' + 'Use app.registry.createModel(modelName, definition) and ' + 'app.model(ModelCtor, config) instead.'; throw new Error(msg); @@ -130,7 +130,7 @@ app.model = function(Model, config) { Model.modelName + ' must be a descendant of loopback.Model'); } - var modelName = Model.modelName; + const modelName = Model.modelName; this.models[modelName] = this.models[classify(modelName)] = this.models[camelize(modelName)] = Model; @@ -149,7 +149,7 @@ app.model = function(Model, config) { this.emit('modelRemoted', Model.sharedClass); } - var self = this; + const self = this; Model.on('remoteMethodDisabled', function(model, methodName) { clearHandlerCache(self); self.emit('remoteMethodDisabled', model, methodName); @@ -266,7 +266,7 @@ app.models = function() { */ app.dataSource = function(name, config) { try { - var ds = dataSourcesFromConfig(name, config, this.connectors, this.registry); + const ds = dataSourcesFromConfig(name, config, this.connectors, this.registry); this.dataSources[name] = this.dataSources[classify(name)] = this.dataSources[camelize(name)] = ds; @@ -307,7 +307,7 @@ app.connector = function(name, connector) { */ app.remoteObjects = function() { - var result = {}; + const result = {}; this.remotes().classes().forEach(function(sharedClass) { result[sharedClass.name] = sharedClass.ctor; @@ -322,13 +322,13 @@ app.remoteObjects = function() { */ app.handler = function(type, options) { - var handlers = this._handlers || (this._handlers = {}); + const handlers = this._handlers || (this._handlers = {}); if (handlers[type]) { return handlers[type]; } - var remotes = this.remotes(); - var handler = this._handlers[type] = remotes.handler(type, options); + const remotes = this.remotes(); + const handler = this._handlers[type] = remotes.handler(type, options); remotes.classes().forEach(function(sharedClass) { sharedClass.ctor.emit('mounted', app, sharedClass, remotes); @@ -348,15 +348,15 @@ app.dataSources = app.datasources = {}; */ app.enableAuth = function(options) { - var AUTH_MODELS = ['User', 'AccessToken', 'ACL', 'Role', 'RoleMapping']; + const AUTH_MODELS = ['User', 'AccessToken', 'ACL', 'Role', 'RoleMapping']; - var remotes = this.remotes(); - var app = this; + const remotes = this.remotes(); + const app = this; if (options && options.dataSource) { - var appModels = app.registry.modelBuilder.models; + const appModels = app.registry.modelBuilder.models; AUTH_MODELS.forEach(function(m) { - var Model = app.registry.findModel(m); + const Model = app.registry.findModel(m); if (!Model) { throw new Error( g.f('Authentication requires model %s to be defined.', m) @@ -367,10 +367,10 @@ app.enableAuth = function(options) { // Find descendants of Model that are attached, // for example "Customer" extending "User" model - for (var name in appModels) { - var candidate = appModels[name]; - var isSubclass = candidate.prototype instanceof Model; - var isAttached = !!candidate.dataSource || !!candidate.app; + for (const name in appModels) { + const candidate = appModels[name]; + const isSubclass = candidate.prototype instanceof Model; + const isAttached = !!candidate.dataSource || !!candidate.app; if (isSubclass && isAttached) return; } @@ -382,22 +382,22 @@ app.enableAuth = function(options) { } remotes.authorization = function(ctx, next) { - var method = ctx.method; - var req = ctx.req; - var Model = method.ctor; - var modelInstance = ctx.instance; + const method = ctx.method; + const req = ctx.req; + const Model = method.ctor; + const modelInstance = ctx.instance; - var modelId = modelInstance && modelInstance.id || + const modelId = modelInstance && modelInstance.id || // replacement for deprecated req.param() (req.params && req.params.id !== undefined ? req.params.id : req.body && req.body.id !== undefined ? req.body.id : req.query && req.query.id !== undefined ? req.query.id : undefined); - var modelName = Model.modelName; + const modelName = Model.modelName; - var modelSettings = Model.settings || {}; - var errStatusCode = modelSettings.aclErrorStatus || app.get('aclErrorStatus') || 401; + const modelSettings = Model.settings || {}; + let errStatusCode = modelSettings.aclErrorStatus || app.get('aclErrorStatus') || 401; if (!req.accessToken) { errStatusCode = 401; } @@ -415,7 +415,7 @@ app.enableAuth = function(options) { } else if (allowed) { next(); } else { - var messages = { + const messages = { 403: { message: g.f('Access Denied'), code: 'ACCESS_DENIED', @@ -430,7 +430,7 @@ app.enableAuth = function(options) { }, }; - var e = new Error(messages[errStatusCode].message || messages[403].message); + const e = new Error(messages[errStatusCode].message || messages[403].message); e.statusCode = errStatusCode; e.code = messages[errStatusCode].code || messages[403].code; next(e); @@ -547,7 +547,7 @@ app.boot = function(options) { }; function dataSourcesFromConfig(name, config, connectorRegistry, registry) { - var connectorPath; + let connectorPath; assert(typeof config === 'object', 'can not create data source without config object'); @@ -574,7 +574,7 @@ function configureModel(ModelCtor, config, app) { assert(ModelCtor.prototype instanceof ModelCtor.registry.getModel('Model'), ModelCtor.modelName + ' must be a descendant of loopback.Model'); - var dataSource = config.dataSource; + let dataSource = config.dataSource; if (dataSource) { if (typeof dataSource === 'string') { @@ -627,15 +627,15 @@ function clearHandlerCache(app) { * as the request handler. */ app.listen = function(cb) { - var self = this; + const self = this; - var server = require('http').createServer(this); + const server = require('http').createServer(this); server.on('listening', function() { self.set('port', this.address().port); - var listeningOnAll = false; - var host = self.get('host'); + let listeningOnAll = false; + let host = self.get('host'); if (!host) { listeningOnAll = true; host = this.address().address; @@ -650,17 +650,17 @@ app.listen = function(cb) { // that can be copied and pasted into the browser. host = 'localhost'; } - var url = 'http://' + host + ':' + self.get('port') + '/'; + const url = 'http://' + host + ':' + self.get('port') + '/'; self.set('url', url); } }); - var useAppConfig = + const useAppConfig = arguments.length === 0 || (arguments.length == 1 && typeof arguments[0] == 'function'); if (useAppConfig) { - var port = this.get('port'); + let port = this.get('port'); // NOTE(bajtos) port:undefined no longer works on node@6, // we must pass port:0 explicitly if (port === undefined) port = 0; diff --git a/lib/browser-express.js b/lib/browser-express.js index 26ba4090..992dc6e8 100644 --- a/lib/browser-express.js +++ b/lib/browser-express.js @@ -4,8 +4,8 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var EventEmitter = require('events').EventEmitter; -var util = require('util'); +const EventEmitter = require('events').EventEmitter; +const util = require('util'); module.exports = browserExpress; diff --git a/lib/builtin-models.js b/lib/builtin-models.js index 21b82afe..870bac52 100644 --- a/lib/builtin-models.js +++ b/lib/builtin-models.js @@ -74,7 +74,7 @@ module.exports = function(registry) { // object instance it loaded during the first call. definitionJson = cloneDeepJson(definitionJson); - var Model = registry.createModel(definitionJson); + const Model = registry.createModel(definitionJson); customizeFn(Model); return Model; } diff --git a/lib/configure-shared-methods.js b/lib/configure-shared-methods.js index 45d4382d..5791db2a 100644 --- a/lib/configure-shared-methods.js +++ b/lib/configure-shared-methods.js @@ -5,15 +5,15 @@ 'use strict'; -var util = require('util'); -var extend = require('util')._extend; -var g = require('./globalize'); +const util = require('util'); +const extend = require('util')._extend; +const g = require('./globalize'); module.exports = function(modelCtor, remotingConfig, modelConfig) { - var settings = {}; + const settings = {}; // apply config.json settings - var configHasSharedMethodsSettings = remotingConfig && + const configHasSharedMethodsSettings = remotingConfig && remotingConfig.sharedMethods && typeof remotingConfig.sharedMethods === 'object'; if (configHasSharedMethodsSettings) @@ -21,7 +21,7 @@ module.exports = function(modelCtor, remotingConfig, modelConfig) { // apply model-config.json settings const options = modelConfig.options; - var modelConfigHasSharedMethodsSettings = options && + const modelConfigHasSharedMethodsSettings = options && options.remoting && options.remoting.sharedMethods && typeof options.remoting.sharedMethods === 'object'; @@ -30,30 +30,30 @@ module.exports = function(modelCtor, remotingConfig, modelConfig) { // validate setting values Object.keys(settings).forEach(function(setting) { - var settingValue = settings[setting]; - var settingValueType = typeof settingValue; + const settingValue = settings[setting]; + const settingValueType = typeof settingValue; if (settingValueType !== 'boolean') throw new TypeError(g.f('Expected boolean, got %s', settingValueType)); }); // set sharedMethod.shared using the merged settings - var sharedMethods = modelCtor.sharedClass.methods({includeDisabled: true}); + const sharedMethods = modelCtor.sharedClass.methods({includeDisabled: true}); // re-map glob style values to regular expressions - var tests = Object + const tests = Object .keys(settings) .filter(function(setting) { return settings.hasOwnProperty(setting) && setting.indexOf('*') >= 0; }) .map(function(setting) { // Turn * into an testable regexp string - var glob = escapeRegExp(setting).replace(/\*/g, '(.)*'); + const glob = escapeRegExp(setting).replace(/\*/g, '(.)*'); return {regex: new RegExp(glob), setting: settings[setting]}; }) || []; sharedMethods.forEach(function(sharedMethod) { // use the specific setting if it exists - var methodName = sharedMethod.isStatic ? sharedMethod.name : 'prototype.' + sharedMethod.name; - var hasSpecificSetting = settings.hasOwnProperty(methodName); + const methodName = sharedMethod.isStatic ? sharedMethod.name : 'prototype.' + sharedMethod.name; + const hasSpecificSetting = settings.hasOwnProperty(methodName); if (hasSpecificSetting) { if (settings[methodName] === false) { sharedMethod.sharedClass.disableMethodByName(methodName); diff --git a/lib/connectors/base-connector.js b/lib/connectors/base-connector.js index 5caadd9b..07706d39 100644 --- a/lib/connectors/base-connector.js +++ b/lib/connectors/base-connector.js @@ -14,11 +14,11 @@ module.exports = Connector; * Module dependencies. */ -var EventEmitter = require('events').EventEmitter; -var debug = require('debug')('connector'); -var util = require('util'); -var inherits = util.inherits; -var assert = require('assert'); +const EventEmitter = require('events').EventEmitter; +const debug = require('debug')('connector'); +const util = require('util'); +const inherits = util.inherits; +const assert = require('assert'); /** * Create a new `Connector` with the given `options`. @@ -45,7 +45,7 @@ inherits(Connector, EventEmitter); */ Connector._createJDBAdapter = function(jdbModule) { - var fauxSchema = {}; + const fauxSchema = {}; jdbModule.initialize(fauxSchema, function() { // connected }); diff --git a/lib/connectors/mail.js b/lib/connectors/mail.js index a06a802d..1aa156a5 100644 --- a/lib/connectors/mail.js +++ b/lib/connectors/mail.js @@ -8,11 +8,11 @@ */ 'use strict'; -var g = require('../globalize'); -var mailer = require('nodemailer'); -var assert = require('assert'); -var debug = require('debug')('loopback:connector:mail'); -var loopback = require('../loopback'); +const g = require('../globalize'); +const mailer = require('nodemailer'); +const assert = require('assert'); +const debug = require('debug')('loopback:connector:mail'); +const loopback = require('../loopback'); /** * Export the MailConnector class. @@ -27,7 +27,7 @@ module.exports = MailConnector; function MailConnector(settings) { assert(typeof settings === 'object', 'cannot initialize MailConnector without a settings object'); - var transports = settings.transports; + let transports = settings.transports; // if transports is not in settings object AND settings.transport exists if (!transports && settings.transport) { @@ -74,17 +74,17 @@ MailConnector.prototype.DataAccessObject = Mailer; */ MailConnector.prototype.setupTransport = function(setting) { - var connector = this; + const connector = this; connector.transports = connector.transports || []; connector.transportsIndex = connector.transportsIndex || {}; - var transport; - var transportType = (setting.type || 'STUB').toLowerCase(); + let transport; + const transportType = (setting.type || 'STUB').toLowerCase(); if (transportType === 'smtp') { transport = mailer.createTransport(setting); } else { - var transportModuleName = 'nodemailer-' + transportType + '-transport'; - var transportModule = require(transportModuleName); + const transportModuleName = 'nodemailer-' + transportType + '-transport'; + const transportModule = require(transportModuleName); transport = mailer.createTransport(transportModule(setting)); } @@ -138,12 +138,12 @@ MailConnector.prototype.defaultTransport = function() { */ Mailer.send = function(options, fn) { - var dataSource = this.dataSource; - var settings = dataSource && dataSource.settings; - var connector = dataSource.connector; + const dataSource = this.dataSource; + const settings = dataSource && dataSource.settings; + const connector = dataSource.connector; assert(connector, 'Cannot send mail without a connector!'); - var transport = connector.transportForName(options.transport); + let transport = connector.transportForName(options.transport); if (!transport) { transport = connector.defaultTransport(); diff --git a/lib/connectors/memory.js b/lib/connectors/memory.js index bf2f775f..758b05aa 100644 --- a/lib/connectors/memory.js +++ b/lib/connectors/memory.js @@ -14,12 +14,12 @@ module.exports = Memory; * Module dependencies. */ -var Connector = require('./base-connector'); -var debug = require('debug')('memory'); -var util = require('util'); -var inherits = util.inherits; -var assert = require('assert'); -var JdbMemory = require('loopback-datasource-juggler/lib/connectors/memory'); +const Connector = require('./base-connector'); +const debug = require('debug')('memory'); +const util = require('util'); +const inherits = util.inherits; +const assert = require('assert'); +const JdbMemory = require('loopback-datasource-juggler/lib/connectors/memory'); /** * Create a new `Memory` connector with the given `options`. diff --git a/lib/current-context.js b/lib/current-context.js index 4f6eb735..4bfdf822 100644 --- a/lib/current-context.js +++ b/lib/current-context.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var g = require('./globalize'); -var juggler = require('loopback-datasource-juggler'); -var remoting = require('strong-remoting'); +const g = require('./globalize'); +const juggler = require('loopback-datasource-juggler'); +const remoting = require('strong-remoting'); module.exports = function(loopback) { juggler.getCurrentContext = diff --git a/lib/globalize.js b/lib/globalize.js index 56dbd0d1..778d9283 100644 --- a/lib/globalize.js +++ b/lib/globalize.js @@ -4,8 +4,8 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var path = require('path'); -var SG = require('strong-globalize'); +const path = require('path'); +const SG = require('strong-globalize'); SG.SetRootDir(path.join(__dirname, '..'), {autonomousMsgLoading: 'all'}); module.exports = SG(); diff --git a/lib/loopback.js b/lib/loopback.js index 76e0942a..250a8879 100644 --- a/lib/loopback.js +++ b/lib/loopback.js @@ -8,17 +8,17 @@ */ 'use strict'; -var express = require('express'); -var loopbackExpress = require('./server-app'); -var proto = require('./application'); -var fs = require('fs'); -var ejs = require('ejs'); -var path = require('path'); -var merge = require('util')._extend; -var assert = require('assert'); -var Registry = require('./registry'); -var juggler = require('loopback-datasource-juggler'); -var configureSharedMethods = require('./configure-shared-methods'); +const express = require('express'); +const loopbackExpress = require('./server-app'); +const proto = require('./application'); +const fs = require('fs'); +const ejs = require('ejs'); +const path = require('path'); +const merge = require('util')._extend; +const assert = require('assert'); +const Registry = require('./registry'); +const juggler = require('loopback-datasource-juggler'); +const configureSharedMethods = require('./configure-shared-methods'); /** * LoopBack core module. It provides static properties and @@ -40,7 +40,7 @@ var configureSharedMethods = require('./configure-shared-methods'); * @header loopback */ -var loopback = module.exports = createApplication; +const loopback = module.exports = createApplication; /*! * Framework version. @@ -73,7 +73,7 @@ Object.defineProperties(loopback, { */ function createApplication(options) { - var app = loopbackExpress(); + const app = loopbackExpress(); merge(app, proto); @@ -107,7 +107,7 @@ function createApplication(options) { if (loopback.localRegistry || options && options.localRegistry === true) { // setup the app registry - var registry = app.registry = new Registry(); + const registry = app.registry = new Registry(); if (options && options.loadBuiltinModels === true) { require('./builtin-models')(registry); } @@ -119,8 +119,8 @@ function createApplication(options) { } function mixin(source) { - for (var key in source) { - var desc = Object.getOwnPropertyDescriptor(source, key); + for (const key in source) { + const desc = Object.getOwnPropertyDescriptor(source, key); // Fix for legacy (pre-ES5) browsers like PhantomJS if (!desc) continue; @@ -204,8 +204,8 @@ loopback.remoteMethod = function(fn, options) { */ loopback.template = function(file) { - var templates = this._templates || (this._templates = {}); - var str = templates[file] || (templates[file] = fs.readFileSync(file, 'utf8')); + const templates = this._templates || (this._templates = {}); + const str = templates[file] || (templates[file] = fs.readFileSync(file, 'utf8')); return ejs.compile(str, { filename: file, }); diff --git a/lib/model.js b/lib/model.js index 55f805ee..39e2132d 100644 --- a/lib/model.js +++ b/lib/model.js @@ -7,14 +7,14 @@ * Module Dependencies. */ 'use strict'; -var g = require('./globalize'); -var assert = require('assert'); -var debug = require('debug')('loopback:model'); -var RemoteObjects = require('strong-remoting'); -var SharedClass = require('strong-remoting').SharedClass; -var extend = require('util')._extend; +const g = require('./globalize'); +const assert = require('assert'); +const debug = require('debug')('loopback:model'); +const RemoteObjects = require('strong-remoting'); +const SharedClass = require('strong-remoting').SharedClass; +const extend = require('util')._extend; -var deprecated = require('depd')('loopback'); +const deprecated = require('depd')('loopback'); module.exports = function(registry) { /** @@ -104,7 +104,7 @@ module.exports = function(registry) { * @property {Array.} settings.acls Array of ACLs for the model. * @class */ - var Model = registry.modelBuilder.define('Model'); + const Model = registry.modelBuilder.define('Model'); Model.registry = registry; @@ -115,23 +115,23 @@ module.exports = function(registry) { */ Model.setup = function() { - var ModelCtor = this; - var Parent = this.super_; + const ModelCtor = this; + const Parent = this.super_; if (!ModelCtor.registry && Parent && Parent.registry) { ModelCtor.registry = Parent.registry; } - var options = this.settings; - var typeName = this.modelName; + const options = this.settings; + const typeName = this.modelName; // support remoting prototype methods // it's important to setup this function *before* calling `new SharedClass` // otherwise remoting metadata from our base model is picked up ModelCtor.sharedCtor = function(data, id, options, fn) { - var ModelCtor = this; + const ModelCtor = this; - var isRemoteInvocationWithOptions = typeof data !== 'object' && + const isRemoteInvocationWithOptions = typeof data !== 'object' && typeof id === 'object' && typeof options === 'function'; if (isRemoteInvocationWithOptions) { @@ -161,13 +161,13 @@ module.exports = function(registry) { } if (id != null && data) { - var model = new ModelCtor(data); + const model = new ModelCtor(data); model.id = id; fn(null, model); } else if (data) { fn(null, new ModelCtor(data)); } else if (id != null) { - var filter = {}; + const filter = {}; ModelCtor.findById(id, filter, options, function(err, model) { if (err) { fn(err); @@ -185,7 +185,7 @@ module.exports = function(registry) { } }; - var idDesc = ModelCtor.modelName + ' id'; + const idDesc = ModelCtor.modelName + ' id'; ModelCtor.sharedCtor.accepts = [ {arg: 'id', type: 'any', required: true, http: {source: 'path'}, description: idDesc}, @@ -199,11 +199,11 @@ module.exports = function(registry) { ModelCtor.sharedCtor.returns = {root: true}; - var remotingOptions = {}; + const remotingOptions = {}; extend(remotingOptions, options.remoting || {}); // create a sharedClass - var sharedClass = ModelCtor.sharedClass = new SharedClass( + const sharedClass = ModelCtor.sharedClass = new SharedClass( ModelCtor.modelName, ModelCtor, remotingOptions @@ -211,9 +211,9 @@ module.exports = function(registry) { // before remote hook ModelCtor.beforeRemote = function(name, fn) { - var className = this.modelName; + const className = this.modelName; this._runWhenAttachedToApp(function(app) { - var remotes = app.remotes(); + const remotes = app.remotes(); remotes.before(className + '.' + name, function(ctx, next) { return fn(ctx, ctx.result, next); }); @@ -222,9 +222,9 @@ module.exports = function(registry) { // after remote hook ModelCtor.afterRemote = function(name, fn) { - var className = this.modelName; + const className = this.modelName; this._runWhenAttachedToApp(function(app) { - var remotes = app.remotes(); + const remotes = app.remotes(); remotes.after(className + '.' + name, function(ctx, next) { return fn(ctx, ctx.result, next); }); @@ -232,16 +232,16 @@ module.exports = function(registry) { }; ModelCtor.afterRemoteError = function(name, fn) { - var className = this.modelName; + const className = this.modelName; this._runWhenAttachedToApp(function(app) { - var remotes = app.remotes(); + const remotes = app.remotes(); remotes.afterError(className + '.' + name, fn); }); }; ModelCtor._runWhenAttachedToApp = function(fn) { if (this.app) return fn(this.app); - var self = this; + const self = this; self.once('attached', function() { fn(self.app); }); @@ -261,8 +261,8 @@ module.exports = function(registry) { // resolve relation functions sharedClass.resolve(function resolver(define) { - var relations = ModelCtor.relations || {}; - var defineRaw = define; + const relations = ModelCtor.relations || {}; + const defineRaw = define; define = function(name, options, fn) { if (options.accepts) { options = extend({}, options); @@ -272,8 +272,8 @@ module.exports = function(registry) { }; // get the relations - for (var relationName in relations) { - var relation = relations[relationName]; + for (const relationName in relations) { + const relation = relations[relationName]; if (relation.type === 'belongsTo') { ModelCtor.belongsToRemoting(relationName, relation, define); } else if ( @@ -295,8 +295,8 @@ module.exports = function(registry) { } // handle scopes - var scopes = ModelCtor.scopes || {}; - for (var scopeName in scopes) { + const scopes = ModelCtor.scopes || {}; + for (const scopeName in scopes) { ModelCtor.scopeRemoting(scopeName, scopes[scopeName], define); } }); @@ -307,9 +307,9 @@ module.exports = function(registry) { /*! * Get the reference to ACL in a lazy fashion to avoid race condition in require */ - var _aclModel = null; + let _aclModel = null; Model._ACL = function getACL(ACL) { - var registry = this.registry; + const registry = this.registry; if (ACL !== undefined) { // The function is used as a setter _aclModel = ACL; @@ -317,7 +317,7 @@ module.exports = function(registry) { if (_aclModel) { return _aclModel; } - var aclModel = registry.getModel('ACL'); + const aclModel = registry.getModel('ACL'); _aclModel = registry.getModelByType(aclModel); return _aclModel; }; @@ -335,9 +335,9 @@ module.exports = function(registry) { */ Model.checkAccess = function(token, modelId, sharedMethod, ctx, callback) { - var ANONYMOUS = registry.getModel('AccessToken').ANONYMOUS; + const ANONYMOUS = registry.getModel('AccessToken').ANONYMOUS; token = token || ANONYMOUS; - var aclModel = Model._ACL(); + const aclModel = Model._ACL(); ctx = ctx || {}; if (typeof ctx === 'function' && callback === undefined) { @@ -376,7 +376,7 @@ module.exports = function(registry) { 'method is a required argument and must be a RemoteMethod object' ); - var ACL = Model._ACL(); + const ACL = Model._ACL(); // Check the explicit setting of accessType if (method.accessType) { @@ -390,7 +390,7 @@ module.exports = function(registry) { } // Default GET requests to READ - var verb = method.http && method.http.verb; + let verb = method.http && method.http.verb; if (typeof verb === 'string') { verb = verb.toUpperCase(); } @@ -438,7 +438,7 @@ module.exports = function(registry) { */ Model.getApp = function(callback) { - var self = this; + const self = this; self._runWhenAttachedToApp(function(app) { assert(self.app); assert.equal(app, self.app); @@ -463,7 +463,7 @@ module.exports = function(registry) { Model.remoteMethod = function(name, options) { if (options.isStatic === undefined) { - var m = name.match(/^prototype\.(.*)$/); + const m = name.match(/^prototype\.(.*)$/); options.isStatic = !m; name = options.isStatic ? name : m[1]; } @@ -492,13 +492,13 @@ module.exports = function(registry) { } function createOptionsViaModelMethod(ctx) { - var ModelCtor = (ctx.method && ctx.method.ctor) || this; + const ModelCtor = (ctx.method && ctx.method.ctor) || this; /** * Configure default values for juggler settings to protect user-supplied * input from attacking juggler */ - var DEFAULT_OPTIONS = { + const DEFAULT_OPTIONS = { // Default to `true` so that hidden properties cannot be used in query prohibitHiddenPropertiesInQuery: ModelCtor._getProhibitHiddenPropertiesInQuery({}, true), // Default to `12` for the max depth of a query object @@ -526,7 +526,7 @@ module.exports = function(registry) { Model.disableRemoteMethod = function(name, isStatic) { deprecated('Model.disableRemoteMethod is deprecated. ' + 'Use Model.disableRemoteMethodByName instead.'); - var key = this.sharedClass.getKeyFromMethodNameAndTarget(name, isStatic); + const key = this.sharedClass.getKeyFromMethodNameAndTarget(name, isStatic); this.sharedClass.disableMethodByName(key); this.emit('remoteMethodDisabled', this.sharedClass, key); }; @@ -544,10 +544,10 @@ module.exports = function(registry) { }; Model.belongsToRemoting = function(relationName, relation, define) { - var modelName = relation.modelTo && relation.modelTo.modelName; + let modelName = relation.modelTo && relation.modelTo.modelName; modelName = modelName || 'PersistedModel'; - var fn = this.prototype[relationName]; - var pathName = (relation.options.http && relation.options.http.path) || relationName; + const fn = this.prototype[relationName]; + const pathName = (relation.options.http && relation.options.http.path) || relationName; define('__get__' + relationName, { isStatic: false, http: {verb: 'get', path: '/' + pathName}, @@ -564,17 +564,17 @@ module.exports = function(registry) { function convertNullToNotFoundError(toModelName, ctx, cb) { if (ctx.result !== null) return cb(); - var fk = ctx.getArgByName('fk'); - var msg = g.f('Unknown "%s" id "%s".', toModelName, fk); - var error = new Error(msg); + const fk = ctx.getArgByName('fk'); + const msg = g.f('Unknown "%s" id "%s".', toModelName, fk); + const error = new Error(msg); error.statusCode = error.status = 404; error.code = 'MODEL_NOT_FOUND'; cb(error); } Model.hasOneRemoting = function(relationName, relation, define) { - var pathName = (relation.options.http && relation.options.http.path) || relationName; - var toModelName = relation.modelTo.modelName; + const pathName = (relation.options.http && relation.options.http.path) || relationName; + const toModelName = relation.modelTo.modelName; define('__get__' + relationName, { isStatic: false, @@ -631,10 +631,10 @@ module.exports = function(registry) { }; Model.hasManyRemoting = function(relationName, relation, define) { - var pathName = (relation.options.http && relation.options.http.path) || relationName; - var toModelName = relation.modelTo.modelName; + const pathName = (relation.options.http && relation.options.http.path) || relationName; + const toModelName = relation.modelTo.modelName; - var findByIdFunc = this.prototype['__findById__' + relationName]; + const findByIdFunc = this.prototype['__findById__' + relationName]; define('__findById__' + relationName, { isStatic: false, http: {verb: 'get', path: '/' + pathName + '/:fk'}, @@ -653,7 +653,7 @@ module.exports = function(registry) { rest: {after: convertNullToNotFoundError.bind(null, toModelName)}, }, findByIdFunc); - var destroyByIdFunc = this.prototype['__destroyById__' + relationName]; + const destroyByIdFunc = this.prototype['__destroyById__' + relationName]; define('__destroyById__' + relationName, { isStatic: false, http: {verb: 'delete', path: '/' + pathName + '/:fk'}, @@ -671,7 +671,7 @@ module.exports = function(registry) { returns: [], }, destroyByIdFunc); - var updateByIdFunc = this.prototype['__updateById__' + relationName]; + const updateByIdFunc = this.prototype['__updateById__' + relationName]; define('__updateById__' + relationName, { isStatic: false, http: {verb: 'put', path: '/' + pathName + '/:fk'}, @@ -689,9 +689,9 @@ module.exports = function(registry) { }, updateByIdFunc); if (relation.modelThrough || relation.type === 'referencesMany') { - var modelThrough = relation.modelThrough || relation.modelTo; + const modelThrough = relation.modelThrough || relation.modelTo; - var accepts = []; + const accepts = []; if (relation.type === 'hasMany' && relation.modelThrough) { // Restrict: only hasManyThrough relation can have additional properties accepts.push({ @@ -700,7 +700,7 @@ module.exports = function(registry) { }); } - var addFunc = this.prototype['__link__' + relationName]; + const addFunc = this.prototype['__link__' + relationName]; define('__link__' + relationName, { isStatic: false, http: {verb: 'put', path: '/' + pathName + '/rel/:fk'}, @@ -716,7 +716,7 @@ module.exports = function(registry) { returns: {arg: relationName, type: modelThrough.modelName, root: true}, }, addFunc); - var removeFunc = this.prototype['__unlink__' + relationName]; + const removeFunc = this.prototype['__unlink__' + relationName]; define('__unlink__' + relationName, { isStatic: false, http: {verb: 'delete', path: '/' + pathName + '/rel/:fk'}, @@ -736,7 +736,7 @@ module.exports = function(registry) { // FIXME: [rfeng] How to map a function with callback(err, true|false) to HEAD? // true --> 200 and false --> 404? - var existsFunc = this.prototype['__exists__' + relationName]; + const existsFunc = this.prototype['__exists__' + relationName]; define('__exists__' + relationName, { isStatic: false, http: {verb: 'head', path: '/' + pathName + '/rel/:fk'}, @@ -756,10 +756,10 @@ module.exports = function(registry) { // After hook to map exists to 200/404 for HEAD after: function(ctx, cb) { if (ctx.result === false) { - var modelName = ctx.method.sharedClass.name; - var id = ctx.getArgByName('id'); - var msg = g.f('Unknown "%s" {{id}} "%s".', modelName, id); - var error = new Error(msg); + const modelName = ctx.method.sharedClass.name; + const id = ctx.getArgByName('id'); + const msg = g.f('Unknown "%s" {{id}} "%s".', modelName, id); + const error = new Error(msg); error.statusCode = error.status = 404; error.code = 'MODEL_NOT_FOUND'; cb(error); @@ -773,17 +773,17 @@ module.exports = function(registry) { }; Model.scopeRemoting = function(scopeName, scope, define) { - var pathName = + const pathName = (scope.options && scope.options.http && scope.options.http.path) || scopeName; - var modelTo = scope.modelTo; + let modelTo = scope.modelTo; - var isStatic = scope.isStatic; - var toModelName = scope.modelTo.modelName; + const isStatic = scope.isStatic; + let toModelName = scope.modelTo.modelName; // https://github.com/strongloop/loopback/issues/811 // Check if the scope is for a hasMany relation - var relation = this.relations[scopeName]; + const relation = this.relations[scopeName]; if (relation && relation.modelTo) { // For a relation with through model, the toModelName should be the one // from the target model @@ -884,22 +884,22 @@ module.exports = function(registry) { } options = options || {}; - var regExp = /^__([^_]+)__([^_]+)$/; - var relation = this.relations[relationName]; + const regExp = /^__([^_]+)__([^_]+)$/; + const relation = this.relations[relationName]; if (relation && relation._nestRemotingProcessed) { return; // Prevent unwanted circular traversals! } else if (relation && relation.modelTo && relation.modelTo.sharedClass) { relation._nestRemotingProcessed = true; - var self = this; - var sharedClass = this.sharedClass; - var sharedToClass = relation.modelTo.sharedClass; - var toModelName = relation.modelTo.modelName; + const self = this; + const sharedClass = this.sharedClass; + const sharedToClass = relation.modelTo.sharedClass; + const toModelName = relation.modelTo.modelName; - var pathName = options.pathName || relation.options.path || relationName; - var paramName = options.paramName || 'nk'; + const pathName = options.pathName || relation.options.path || relationName; + const paramName = options.paramName || 'nk'; - var http = [].concat(sharedToClass.http || [])[0]; - var httpPath, acceptArgs; + const http = [].concat(sharedToClass.http || [])[0]; + let httpPath, acceptArgs; if (relation.multiple) { httpPath = pathName + '/:' + paramName; @@ -921,30 +921,30 @@ module.exports = function(registry) { // A method should return the method name to use, if it is to be // included as a nested method - a falsy return value will skip. - var filter = filterCallback || options.filterMethod || function(method, relation) { - var matches = method.name.match(regExp); + const filter = filterCallback || options.filterMethod || function(method, relation) { + const matches = method.name.match(regExp); if (matches) { return '__' + matches[1] + '__' + relation.name + '__' + matches[2]; } }; sharedToClass.methods().forEach(function(method) { - var methodName; + let methodName; if (!method.isStatic && (methodName = filter(method, relation))) { - var prefix = relation.multiple ? '__findById__' : '__get__'; - var getterName = options.getterName || (prefix + relationName); + const prefix = relation.multiple ? '__findById__' : '__get__'; + const getterName = options.getterName || (prefix + relationName); - var getterFn = relation.modelFrom.prototype[getterName]; + const getterFn = relation.modelFrom.prototype[getterName]; if (typeof getterFn !== 'function') { throw new Error(g.f('Invalid remote method: `%s`', getterName)); } - var nestedFn = relation.modelTo.prototype[method.name]; + const nestedFn = relation.modelTo.prototype[method.name]; if (typeof nestedFn !== 'function') { throw new Error(g.f('Invalid remote method: `%s`', method.name)); } - var opts = {}; + const opts = {}; opts.accepts = acceptArgs.concat(method.accepts || []); opts.returns = [].concat(method.returns || []); @@ -954,10 +954,10 @@ module.exports = function(registry) { opts.rest.delegateTo = method; opts.http = []; - var routes = [].concat(method.http || []); + const routes = [].concat(method.http || []); routes.forEach(function(route) { if (route.path) { - var copy = extend({}, route); + const copy = extend({}, route); copy.path = httpPath + route.path; opts.http.push(copy); } @@ -1015,19 +1015,19 @@ module.exports = function(registry) { if (options.hooks === false) return; // don't inherit before/after hooks self.once('mounted', function(app, sc, remotes) { - var listenerTree = extend({}, remotes.listenerTree || {}); + const listenerTree = extend({}, remotes.listenerTree || {}); listenerTree.before = listenerTree.before || {}; listenerTree.after = listenerTree.after || {}; - var beforeListeners = listenerTree.before[toModelName] || {}; - var afterListeners = listenerTree.after[toModelName] || {}; + const beforeListeners = listenerTree.before[toModelName] || {}; + const afterListeners = listenerTree.after[toModelName] || {}; sharedClass.methods().forEach(function(method) { - var delegateTo = method.rest && method.rest.delegateTo; + const delegateTo = method.rest && method.rest.delegateTo; if (delegateTo && delegateTo.ctor == relation.modelTo) { - var before = method.isStatic ? beforeListeners : beforeListeners['prototype']; - var after = method.isStatic ? afterListeners : afterListeners['prototype']; - var m = method.isStatic ? method.name : 'prototype.' + method.name; + const before = method.isStatic ? beforeListeners : beforeListeners['prototype']; + const after = method.isStatic ? afterListeners : afterListeners['prototype']; + const m = method.isStatic ? method.name : 'prototype.' + method.name; if (before && before[delegateTo.name]) { self.beforeRemote(m, function(ctx, result, next) { before[delegateTo.name]._listeners.call(null, ctx, next); @@ -1042,7 +1042,7 @@ module.exports = function(registry) { }); }); } else { - var msg = g.f('Relation `%s` does not exist for model `%s`', relationName, this.modelName); + const msg = g.f('Relation `%s` does not exist for model `%s`', relationName, this.modelName); throw new Error(msg); } }; diff --git a/lib/persisted-model.js b/lib/persisted-model.js index 47cd1b84..462ffe28 100644 --- a/lib/persisted-model.js +++ b/lib/persisted-model.js @@ -7,20 +7,20 @@ * Module Dependencies. */ 'use strict'; -var g = require('./globalize'); -var runtime = require('./runtime'); -var assert = require('assert'); -var async = require('async'); -var deprecated = require('depd')('loopback'); -var debug = require('debug')('loopback:persisted-model'); -var PassThrough = require('stream').PassThrough; -var utils = require('./utils'); -var filterNodes = require('loopback-filters'); +const g = require('./globalize'); +const runtime = require('./runtime'); +const assert = require('assert'); +const async = require('async'); +const deprecated = require('depd')('loopback'); +const debug = require('debug')('loopback:persisted-model'); +const PassThrough = require('stream').PassThrough; +const utils = require('./utils'); +const filterNodes = require('loopback-filters'); -var REPLICATION_CHUNK_SIZE = -1; +const REPLICATION_CHUNK_SIZE = -1; module.exports = function(registry) { - var Model = registry.getModel('Model'); + const Model = registry.getModel('Model'); /** * Extends Model with basic query and CRUD support. @@ -38,7 +38,7 @@ module.exports = function(registry) { * @class PersistedModel */ - var PersistedModel = Model.extend('PersistedModel'); + const PersistedModel = Model.extend('PersistedModel'); /*! * Setup the `PersistedModel` constructor. @@ -48,7 +48,7 @@ module.exports = function(registry) { // call Model.setup first Model.setup.call(this); - var PersistedModel = this; + const PersistedModel = this; // enable change tracking (usually for replication) if (this.settings.trackChanges) { @@ -85,10 +85,10 @@ module.exports = function(registry) { function convertNullToNotFoundError(ctx, cb) { if (ctx.result !== null) return cb(); - var modelName = ctx.method.sharedClass.name; - var id = ctx.getArgByName('id'); - var msg = g.f('Unknown "%s" {{id}} "%s".', modelName, id); - var error = new Error(msg); + const modelName = ctx.method.sharedClass.name; + const id = ctx.getArgByName('id'); + const msg = g.f('Unknown "%s" {{id}} "%s".', modelName, id); + const error = new Error(msg); error.statusCode = error.status = 404; error.code = 'MODEL_NOT_FOUND'; cb(error); @@ -403,7 +403,7 @@ module.exports = function(registry) { */ PersistedModel.prototype.save = function(options, callback) { - var Model = this.constructor; + const Model = this.constructor; if (typeof options == 'function') { callback = options; @@ -421,9 +421,9 @@ module.exports = function(registry) { options.throws = false; } - var inst = this; - var data = inst.toObject(true); - var id = this.getId(); + const inst = this; + const data = inst.toObject(true); + const id = this.getId(); if (!id) { return Model.create(this, callback); @@ -438,7 +438,7 @@ module.exports = function(registry) { if (valid) { save(); } else { - var err = new Model.ValidationError(inst); + const err = new Model.ValidationError(inst); // throws option is dangerous for async usage if (options.throws) { throw err; @@ -581,7 +581,7 @@ module.exports = function(registry) { */ PersistedModel.prototype.setId = function(val) { - var ds = this.getDataSource(); + const ds = this.getDataSource(); this[this.getIdName()] = val; }; @@ -592,7 +592,7 @@ module.exports = function(registry) { */ PersistedModel.prototype.getId = function() { - var data = this.toObject(); + const data = this.toObject(); if (!data) return; return data[this.getIdName()]; }; @@ -614,8 +614,8 @@ module.exports = function(registry) { */ PersistedModel.getIdName = function() { - var Model = this; - var ds = Model.getDataSource(); + const Model = this; + const ds = Model.getDataSource(); if (ds.idName) { return ds.idName(Model.modelName); @@ -625,9 +625,9 @@ module.exports = function(registry) { }; PersistedModel.setupRemoting = function() { - var PersistedModel = this; - var typeName = PersistedModel.modelName; - var options = PersistedModel.settings; + const PersistedModel = this; + const typeName = PersistedModel.modelName; + const options = PersistedModel.settings; // if there is atleast one updateOnly property, then we set // createOnlyInstance flag in __create__ to indicate loopback-swagger @@ -640,7 +640,7 @@ module.exports = function(registry) { options.replaceOnPUT = options.replaceOnPUT !== false; function setRemoting(scope, name, options) { - var fn = scope[name]; + const fn = scope[name]; fn._delegate = true; options.isStatic = scope === PersistedModel; PersistedModel.remoteMethod(name, options); @@ -662,7 +662,7 @@ module.exports = function(registry) { http: {verb: 'post', path: '/'}, }); - var upsertOptions = { + const upsertOptions = { aliases: ['upsert', 'updateOrCreate'], description: 'Patch an existing model instance or insert a new one ' + 'into the data source.', @@ -683,7 +683,7 @@ module.exports = function(registry) { } setRemoting(PersistedModel, 'patchOrCreate', upsertOptions); - var replaceOrCreateOptions = { + const replaceOrCreateOptions = { description: 'Replace an existing model instance or insert a new one into the data source.', accessType: 'WRITE', accepts: [ @@ -741,10 +741,10 @@ module.exports = function(registry) { return cb(); } if (!ctx.result.exists) { - var modelName = ctx.method.sharedClass.name; - var id = ctx.getArgByName('id'); - var msg = 'Unknown "' + modelName + '" id "' + id + '".'; - var error = new Error(msg); + const modelName = ctx.method.sharedClass.name; + const id = ctx.getArgByName('id'); + const msg = 'Unknown "' + modelName + '" id "' + id + '".'; + const error = new Error(msg); error.statusCode = error.status = 404; error.code = 'MODEL_NOT_FOUND'; cb(error); @@ -772,7 +772,7 @@ module.exports = function(registry) { rest: {after: convertNullToNotFoundError}, }); - var replaceByIdOptions = { + const replaceByIdOptions = { description: 'Replace attributes for a model instance and persist it into the data source.', accessType: 'WRITE', accepts: [ @@ -889,7 +889,7 @@ module.exports = function(registry) { http: {verb: 'get', path: '/count'}, }); - var updateAttributesOptions = { + const updateAttributesOptions = { aliases: ['updateAttributes'], description: 'Patch attributes for a model instance and persist it into ' + 'the data source.', @@ -1038,7 +1038,7 @@ module.exports = function(registry) { */ PersistedModel.diff = function(since, remoteChanges, callback) { - var Change = this.getChangeModel(); + const Change = this.getChangeModel(); Change.diff(this.modelName, since, remoteChanges, callback); }; @@ -1064,9 +1064,9 @@ module.exports = function(registry) { filter = {}; } - var idName = this.dataSource.idName(this.modelName); - var Change = this.getChangeModel(); - var model = this; + const idName = this.dataSource.idName(this.modelName); + const Change = this.getChangeModel(); + const model = this; const changeFilter = this.createChangeFilter(since, filter); filter = filter || {}; @@ -1078,13 +1078,13 @@ module.exports = function(registry) { Change.find(changeFilter, function(err, changes) { if (err) return callback(err); if (!Array.isArray(changes) || changes.length === 0) return callback(null, []); - var ids = changes.map(function(change) { + const ids = changes.map(function(change) { return change.getModelId(); }); filter.where[idName] = {inq: ids}; model.find(filter, function(err, models) { if (err) return callback(err); - var modelIds = models.map(function(m) { + const modelIds = models.map(function(m) { return m[idName].toString(); }); callback(null, changes.filter(function(ch) { @@ -1102,7 +1102,7 @@ module.exports = function(registry) { */ PersistedModel.checkpoint = function(cb) { - var Checkpoint = this.getChangeModel().getCheckpointModel(); + const Checkpoint = this.getChangeModel().getCheckpointModel(); Checkpoint.bumpLastSeq(cb); }; @@ -1115,7 +1115,7 @@ module.exports = function(registry) { */ PersistedModel.currentCheckpoint = function(cb) { - var Checkpoint = this.getChangeModel().getCheckpointModel(); + const Checkpoint = this.getChangeModel().getCheckpointModel(); Checkpoint.current(cb); }; @@ -1136,7 +1136,7 @@ module.exports = function(registry) { */ PersistedModel.replicate = function(since, targetModel, options, callback) { - var lastArg = arguments[arguments.length - 1]; + const lastArg = arguments[arguments.length - 1]; if (typeof lastArg === 'function' && arguments.length > 1) { callback = lastArg; @@ -1157,7 +1157,7 @@ module.exports = function(registry) { options = options || {}; - var sourceModel = this; + const sourceModel = this; callback = callback || utils.createPromiseCallback(); debug('replicating %s since %s to %s since %s', @@ -1181,7 +1181,7 @@ module.exports = function(registry) { // until no changes were replicated, but at most MAX_ATTEMPTS times // to prevent starvation. In most cases, the second run will find no changes // to replicate and we are done. - var MAX_ATTEMPTS = 3; + const MAX_ATTEMPTS = 3; run(1, since); return callback.promise; @@ -1191,7 +1191,7 @@ module.exports = function(registry) { tryReplicate(sourceModel, targetModel, since, options, next); function next(err, conflicts, cps, updates) { - var finished = err || conflicts.length || + const finished = err || conflicts.length || !updates || updates.length === 0 || attempt >= MAX_ATTEMPTS; @@ -1203,10 +1203,10 @@ module.exports = function(registry) { }; function tryReplicate(sourceModel, targetModel, since, options, callback) { - var Change = sourceModel.getChangeModel(); - var TargetChange = targetModel.getChangeModel(); - var changeTrackingEnabled = Change && TargetChange; - var replicationChunkSize = REPLICATION_CHUNK_SIZE; + const Change = sourceModel.getChangeModel(); + const TargetChange = targetModel.getChangeModel(); + const changeTrackingEnabled = Change && TargetChange; + let replicationChunkSize = REPLICATION_CHUNK_SIZE; if (sourceModel.settings && sourceModel.settings.replicationChunkSize) { replicationChunkSize = sourceModel.settings.replicationChunkSize; @@ -1217,9 +1217,9 @@ module.exports = function(registry) { 'You must enable change tracking before replicating' ); - var diff, updates, newSourceCp, newTargetCp; + let diff, updates, newSourceCp, newTargetCp; - var tasks = [ + const tasks = [ checkpoints, getSourceChanges, getDiffFromTarget, @@ -1304,7 +1304,7 @@ module.exports = function(registry) { }); }, function(notUsed, err) { - var conflicts = err && err.details && err.details.conflicts; + const conflicts = err && err.details && err.details.conflicts; if (conflicts && err.statusCode == 409) { diff.conflicts = conflicts; // filter out updates that were not applied @@ -1321,7 +1321,7 @@ module.exports = function(registry) { } function checkpoints() { - var cb = arguments[arguments.length - 1]; + const cb = arguments[arguments.length - 1]; sourceModel.checkpoint(function(err, source) { if (err) return cb(err); newSourceCp = source.seq; @@ -1345,7 +1345,7 @@ module.exports = function(registry) { debug('\t\tnew checkpoints: { source: %j, target: %j }', newSourceCp, newTargetCp); - var conflicts = diff.conflicts.map(function(change) { + const conflicts = diff.conflicts.map(function(change) { return new Change.Conflict( change.modelId, sourceModel, targetModel ); @@ -1356,7 +1356,7 @@ module.exports = function(registry) { } if (callback) { - var newCheckpoints = {source: newSourceCp, target: newTargetCp}; + const newCheckpoints = {source: newSourceCp, target: newTargetCp}; callback(null, conflicts, newCheckpoints, updates); } } @@ -1371,15 +1371,15 @@ module.exports = function(registry) { */ PersistedModel.createUpdates = function(deltas, cb) { - var Change = this.getChangeModel(); - var updates = []; - var Model = this; - var tasks = []; + const Change = this.getChangeModel(); + const updates = []; + const Model = this; + const tasks = []; deltas.forEach(function(change) { change = new Change(change); - var type = change.type(); - var update = {type: type, change: change}; + const type = change.type(); + const update = {type: type, change: change}; switch (type) { case Change.CREATE: case Change.UPDATE: @@ -1423,12 +1423,12 @@ module.exports = function(registry) { */ PersistedModel.bulkUpdate = function(updates, options, callback) { - var tasks = []; - var Model = this; - var Change = this.getChangeModel(); - var conflicts = []; + const tasks = []; + const Model = this; + const Change = this.getChangeModel(); + const conflicts = []; - var lastArg = arguments[arguments.length - 1]; + const lastArg = arguments[arguments.length - 1]; if (typeof lastArg === 'function' && arguments.length > 1) { callback = lastArg; @@ -1444,8 +1444,8 @@ module.exports = function(registry) { if (err) return callback(err); updates.forEach(function(update) { - var id = update.change.modelId; - var current = currentMap[id]; + const id = update.change.modelId; + const current = currentMap[id]; switch (update.type) { case Change.UPDATE: tasks.push(function(cb) { @@ -1480,13 +1480,13 @@ module.exports = function(registry) { }; function buildLookupOfAffectedModelData(Model, updates, callback) { - var idName = Model.dataSource.idName(Model.modelName); - var affectedIds = updates.map(function(u) { return u.change.modelId; }); - var whereAffected = {}; + const idName = Model.dataSource.idName(Model.modelName); + const affectedIds = updates.map(function(u) { return u.change.modelId; }); + const whereAffected = {}; whereAffected[idName] = {inq: affectedIds}; Model.find({where: whereAffected}, function(err, affectedList) { if (err) return callback(err); - var dataLookup = {}; + const dataLookup = {}; affectedList.forEach(function(it) { dataLookup[it[idName]] = it; }); @@ -1495,8 +1495,8 @@ module.exports = function(registry) { } function applyUpdate(Model, id, current, data, change, conflicts, options, cb) { - var Change = Model.getChangeModel(); - var rev = current ? Change.revisionForInst(current) : null; + const Change = Model.getChangeModel(); + const rev = current ? Change.revisionForInst(current) : null; if (rev !== change.prev) { debug('Detected non-rectified change of %s %j', @@ -1515,7 +1515,7 @@ module.exports = function(registry) { Model.updateAll(current.toObject(), data, options, function(err, result) { if (err) return cb(err); - var count = result && result.count; + const count = result && result.count; switch (count) { case 1: // The happy path, exactly one record was updated @@ -1573,7 +1573,7 @@ module.exports = function(registry) { Model.modelName, id); conflicts.push(change); - var Change = Model.getChangeModel(); + const Change = Model.getChangeModel(); return Change.rectifyModelChanges(Model.modelName, [id], cb); } } @@ -1585,8 +1585,8 @@ module.exports = function(registry) { return cb(); } - var Change = Model.getChangeModel(); - var rev = Change.revisionForInst(current); + const Change = Model.getChangeModel(); + const rev = Change.revisionForInst(current); if (rev !== change.prev) { debug('Detected non-rectified change of %s %j', Model.modelName, id); @@ -1599,7 +1599,7 @@ module.exports = function(registry) { Model.deleteAll(current.toObject(), options, function(err, result) { if (err) return cb(err); - var count = result && result.count; + const count = result && result.count; switch (count) { case 1: // The happy path, exactly one record was updated @@ -1640,8 +1640,8 @@ module.exports = function(registry) { */ PersistedModel.getChangeModel = function() { - var changeModel = this.Change; - var isSetup = changeModel && changeModel.dataSource; + const changeModel = this.Change; + const isSetup = changeModel && changeModel.dataSource; assert(isSetup, 'Cannot get a setup Change model for ' + this.modelName); @@ -1657,7 +1657,7 @@ module.exports = function(registry) { */ PersistedModel.getSourceId = function(cb) { - var dataSource = this.dataSource; + const dataSource = this.dataSource; if (!dataSource) { this.once('dataSourceAttached', this.getSourceId.bind(this, cb)); } @@ -1665,7 +1665,7 @@ module.exports = function(registry) { dataSource.connector.name, 'Model.getSourceId: cannot get id without dataSource.connector.name' ); - var id = [dataSource.connector.name, this.modelName].join('-'); + const id = [dataSource.connector.name, this.modelName].join('-'); cb(null, id); }; @@ -1674,17 +1674,17 @@ module.exports = function(registry) { */ PersistedModel.enableChangeTracking = function() { - var Model = this; - var Change = this.Change || this._defineChangeModel(); - var cleanupInterval = Model.settings.changeCleanupInterval || 30000; + const Model = this; + const Change = this.Change || this._defineChangeModel(); + const cleanupInterval = Model.settings.changeCleanupInterval || 30000; assert(this.dataSource, 'Cannot enableChangeTracking(): ' + this.modelName + ' is not attached to a dataSource'); - var idName = this.getIdName(); - var idProp = this.definition.properties[idName]; - var idType = idProp && idProp.type; - var idDefn = idProp && idProp.defaultFn; + const idName = this.getIdName(); + const idProp = this.definition.properties[idName]; + const idType = idProp && idProp.type; + const idDefn = idProp && idProp.defaultFn; if (idType !== String || !(idDefn === 'uuid' || idDefn === 'guid')) { deprecated('The model ' + this.modelName + ' is tracking changes, ' + 'which requires a string id with GUID/UUID default value.'); @@ -1714,8 +1714,8 @@ module.exports = function(registry) { }; function rectifyOnSave(ctx, next) { - var instance = ctx.instance || ctx.currentInstance; - var id = instance ? instance.getId() : + const instance = ctx.instance || ctx.currentInstance; + const id = instance ? instance.getId() : getIdFromWhereByModelId(ctx.Model, ctx.where); if (debug.enabled) { @@ -1740,7 +1740,7 @@ module.exports = function(registry) { } function rectifyOnDelete(ctx, next) { - var id = ctx.instance ? ctx.instance.getId() : + const id = ctx.instance ? ctx.instance.getId() : getIdFromWhereByModelId(ctx.Model, ctx.where); if (debug.enabled) { @@ -1764,10 +1764,10 @@ module.exports = function(registry) { } function getIdFromWhereByModelId(Model, where) { - var idName = Model.getIdName(); + const idName = Model.getIdName(); if (!(idName in where)) return undefined; - var id = where[idName]; + const id = where[idName]; // TODO(bajtos) support object values that are not LB conditions if (typeof id === 'string' || typeof id === 'number') { return id; @@ -1776,7 +1776,7 @@ module.exports = function(registry) { } PersistedModel._defineChangeModel = function() { - var BaseChangeModel = this.registry.getModel('Change'); + const BaseChangeModel = this.registry.getModel('Change'); assert(BaseChangeModel, 'Change model must be defined before enabling change replication'); @@ -1794,7 +1794,7 @@ module.exports = function(registry) { } // Re-attach related models whenever our datasource is changed. - var self = this; + const self = this; this.on('dataSourceAttached', function() { attachRelatedModels(self); }); @@ -1832,17 +1832,17 @@ module.exports = function(registry) { */ PersistedModel.rectifyChange = function(id, callback) { - var Change = this.getChangeModel(); + const Change = this.getChangeModel(); Change.rectifyModelChanges(this.modelName, [id], callback); }; PersistedModel.findLastChange = function(id, cb) { - var Change = this.getChangeModel(); + const Change = this.getChangeModel(); Change.findOne({where: {modelId: id}}, cb); }; PersistedModel.updateLastChange = function(id, data, cb) { - var self = this; + const self = this; this.findLastChange(id, function(err, inst) { if (err) return cb(err); if (!inst) { @@ -1873,9 +1873,9 @@ module.exports = function(registry) { } cb = cb || utils.createPromiseCallback(); - var idName = this.getIdName(); - var Model = this; - var changes = new PassThrough({objectMode: true}); + const idName = this.getIdName(); + const Model = this; + const changes = new PassThrough({objectMode: true}); changes._destroy = function() { changes.end(); @@ -1900,7 +1900,7 @@ module.exports = function(registry) { return cb.promise; function changeHandler(ctx, next) { - var change = createChangeObject(ctx, 'save'); + const change = createChangeObject(ctx, 'save'); if (change) { changes.write(change); } @@ -1909,7 +1909,7 @@ module.exports = function(registry) { } function deleteHandler(ctx, next) { - var change = createChangeObject(ctx, 'delete'); + const change = createChangeObject(ctx, 'delete'); if (change) { changes.write(change); } @@ -1918,13 +1918,13 @@ module.exports = function(registry) { } function createChangeObject(ctx, type) { - var where = ctx.where; - var data = ctx.instance || ctx.data; - var whereId = where && where[idName]; + const where = ctx.where; + let data = ctx.instance || ctx.data; + const whereId = where && where[idName]; // the data includes the id // or the where includes the id - var target; + let target; if (data && (data[idName] || data[idName] === 0)) { target = data[idName]; @@ -1932,18 +1932,18 @@ module.exports = function(registry) { target = where[idName]; } - var hasTarget = target === 0 || !!target; + const hasTarget = target === 0 || !!target; // apply filtering if options is set if (options) { - var filtered = filterNodes([data], options); + const filtered = filterNodes([data], options); if (filtered.length !== 1) { return null; } data = filtered[0]; } - var change = { + const change = { target: target, where: where, data: data, diff --git a/lib/registry.js b/lib/registry.js index c566cdbd..c504b21f 100644 --- a/lib/registry.js +++ b/lib/registry.js @@ -4,14 +4,14 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var g = require('./globalize'); -var assert = require('assert'); -var extend = require('util')._extend; -var juggler = require('loopback-datasource-juggler'); -var debug = require('debug')('loopback:registry'); -var DataSource = juggler.DataSource; -var ModelBuilder = juggler.ModelBuilder; -var deprecated = require('depd')('strong-remoting'); +const g = require('./globalize'); +const assert = require('assert'); +const extend = require('util')._extend; +const juggler = require('loopback-datasource-juggler'); +const debug = require('debug')('loopback:registry'); +const DataSource = juggler.DataSource; +const ModelBuilder = juggler.ModelBuilder; +const deprecated = require('depd')('strong-remoting'); module.exports = Registry; @@ -97,7 +97,7 @@ function Registry() { Registry.prototype.createModel = function(name, properties, options) { if (arguments.length === 1 && typeof name === 'object') { - var config = name; + const config = name; name = config.name; properties = config.properties; options = buildModelOptionsFromConfig(config); @@ -107,10 +107,10 @@ Registry.prototype.createModel = function(name, properties, options) { } options = options || {}; - var BaseModel = options.base || options.super; + let BaseModel = options.base || options.super; if (typeof BaseModel === 'string') { - var baseName = BaseModel; + const baseName = BaseModel; BaseModel = this.findModel(BaseModel); if (!BaseModel) { throw new Error(g.f('Model not found: model `%s` is extending an unknown model `%s`.', @@ -119,7 +119,7 @@ Registry.prototype.createModel = function(name, properties, options) { } BaseModel = BaseModel || this.getModel('PersistedModel'); - var model = BaseModel.extend(name, properties, options); + const model = BaseModel.extend(name, properties, options); model.registry = this; this._defineRemoteMethods(model, model.settings.methods); @@ -128,8 +128,8 @@ Registry.prototype.createModel = function(name, properties, options) { }; function buildModelOptionsFromConfig(config) { - var options = extend({}, config.options); - for (var key in config) { + const options = extend({}, config.options); + for (const key in config) { if (['name', 'properties', 'options'].indexOf(key) !== -1) { // Skip items which have special meaning continue; @@ -152,7 +152,7 @@ function buildModelOptionsFromConfig(config) { * @param {Object} acl */ function addACL(acls, acl) { - for (var i = 0, n = acls.length; i < n; i++) { + for (let i = 0, n = acls.length; i < n; i++) { // Check if there is a matching acl to be overriden if (acls[i].property === acl.property && acls[i].accessType === acl.accessType && @@ -176,14 +176,14 @@ function addACL(acls, acl) { */ Registry.prototype.configureModel = function(ModelCtor, config) { - var settings = ModelCtor.settings; - var modelName = ModelCtor.modelName; + const settings = ModelCtor.settings; + const modelName = ModelCtor.modelName; ModelCtor.config = config; // Relations if (typeof config.relations === 'object' && config.relations !== null) { - var relations = settings.relations = settings.relations || {}; + const relations = settings.relations = settings.relations || {}; Object.keys(config.relations).forEach(function(key) { // FIXME: [rfeng] We probably should check if the relation exists relations[key] = extend(relations[key] || {}, config.relations[key]); @@ -195,7 +195,7 @@ Registry.prototype.configureModel = function(ModelCtor, config) { // ACLs if (Array.isArray(config.acls)) { - var acls = settings.acls = settings.acls || []; + const acls = settings.acls = settings.acls || []; config.acls.forEach(function(acl) { addACL(acls, acl); }); @@ -205,7 +205,7 @@ Registry.prototype.configureModel = function(ModelCtor, config) { } // Settings - var excludedProperties = { + const excludedProperties = { base: true, 'super': true, relations: true, @@ -213,7 +213,7 @@ Registry.prototype.configureModel = function(ModelCtor, config) { dataSource: true, }; if (typeof config.options === 'object' && config.options !== null) { - for (var p in config.options) { + for (const p in config.options) { if (!(p in excludedProperties)) { settings[p] = config.options[p]; } else { @@ -248,9 +248,9 @@ Registry.prototype.configureModel = function(ModelCtor, config) { ); } - var newMethodNames = config.methods && Object.keys(config.methods); - var hasNewMethods = newMethodNames && newMethodNames.length; - var hasDescendants = this.getModelByType(ModelCtor) !== ModelCtor; + const newMethodNames = config.methods && Object.keys(config.methods); + const hasNewMethods = newMethodNames && newMethodNames.length; + const hasDescendants = this.getModelByType(ModelCtor) !== ModelCtor; if (hasNewMethods && hasDescendants) { g.warn( 'Child models of `%s` will not inherit newly defined remote methods %s.', @@ -271,9 +271,9 @@ Registry.prototype._defineRemoteMethods = function(ModelCtor, methods) { } Object.keys(methods).forEach(function(key) { - var meta = methods[key]; - var m = key.match(/^prototype\.(.*)$/); - var isStatic = !m; + let meta = methods[key]; + const m = key.match(/^prototype\.(.*)$/); + const isStatic = !m; if (typeof meta.isStatic !== 'boolean') { key = isStatic ? key : m[1]; @@ -313,7 +313,7 @@ Registry.prototype.findModel = function(modelName) { * @header loopback.getModel(modelName) */ Registry.prototype.getModel = function(modelName) { - var model = this.findModel(modelName); + const model = this.findModel(modelName); if (model) return model; throw new Error(g.f('Model not found: %s', modelName)); @@ -329,8 +329,8 @@ Registry.prototype.getModel = function(modelName) { * @header loopback.getModelByType(modelType) */ Registry.prototype.getModelByType = function(modelType) { - var type = typeof modelType; - var accepted = ['function', 'string']; + const type = typeof modelType; + const accepted = ['function', 'string']; assert(accepted.indexOf(type) > -1, 'The model type must be a constructor or model name'); @@ -339,8 +339,8 @@ Registry.prototype.getModelByType = function(modelType) { modelType = this.getModel(modelType); } - var models = this.modelBuilder.models; - for (var m in models) { + const models = this.modelBuilder.models; + for (const m in models) { if (models[m].prototype instanceof modelType) { return models[m]; } @@ -359,15 +359,15 @@ Registry.prototype.getModelByType = function(modelType) { */ Registry.prototype.createDataSource = function(name, options) { - var self = this; + const self = this; - var ds = new DataSource(name, options, self.modelBuilder); + const ds = new DataSource(name, options, self.modelBuilder); ds.createModel = function(name, properties, settings) { settings = settings || {}; - var BaseModel = settings.base || settings.super; + let BaseModel = settings.base || settings.super; if (!BaseModel) { // Check the connector types - var connectorTypes = ds.getTypes(); + const connectorTypes = ds.getTypes(); if (Array.isArray(connectorTypes) && connectorTypes.indexOf('db') !== -1) { // Only set up the base model to PersistedModel if the connector is DB BaseModel = self.PersistedModel; @@ -376,13 +376,13 @@ Registry.prototype.createDataSource = function(name, options) { } settings.base = BaseModel; } - var ModelCtor = self.createModel(name, properties, settings); + const ModelCtor = self.createModel(name, properties, settings); ModelCtor.attachTo(ds); return ModelCtor; }; if (ds.settings && ds.settings.defaultForType) { - var msg = g.f('{{DataSource}} option {{"defaultForType"}} is no longer supported'); + const msg = g.f('{{DataSource}} option {{"defaultForType"}} is no longer supported'); throw new Error(msg); } @@ -398,7 +398,7 @@ Registry.prototype.createDataSource = function(name, options) { Registry.prototype.memory = function(name) { name = name || 'default'; - var memory = ( + let memory = ( this._memoryDataSources || (this._memoryDataSources = {}) )[name]; diff --git a/lib/runtime.js b/lib/runtime.js index 52169976..03b5de10 100644 --- a/lib/runtime.js +++ b/lib/runtime.js @@ -10,7 +10,7 @@ */ 'use strict'; -var runtime = exports; +const runtime = exports; /** * True if running in a browser environment; false otherwise. diff --git a/lib/server-app.js b/lib/server-app.js index 98e46824..24ea05e0 100644 --- a/lib/server-app.js +++ b/lib/server-app.js @@ -4,20 +4,20 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var g = require('./globalize'); -var assert = require('assert'); -var express = require('express'); -var merge = require('util')._extend; -var mergePhaseNameLists = require('loopback-phase').mergePhaseNameLists; -var debug = require('debug')('loopback:app'); -var stableSortInPlace = require('stable').inplace; +const g = require('./globalize'); +const assert = require('assert'); +const express = require('express'); +const merge = require('util')._extend; +const mergePhaseNameLists = require('loopback-phase').mergePhaseNameLists; +const debug = require('debug')('loopback:app'); +const stableSortInPlace = require('stable').inplace; -var BUILTIN_MIDDLEWARE = {builtin: true}; +const BUILTIN_MIDDLEWARE = {builtin: true}; -var proto = {}; +const proto = {}; module.exports = function loopbackExpress() { - var app = express(); + const app = express(); app.__expressLazyRouter = app.lazyrouter; merge(app, proto); return app; @@ -64,23 +64,23 @@ proto.middlewareFromConfig = function(factory, config) { if (config.enabled === false) return; - var params = config.params; + let params = config.params; if (params === undefined) { params = []; } else if (!Array.isArray(params)) { params = [params]; } - var handler = factory.apply(null, params); + let handler = factory.apply(null, params); // Check if methods/verbs filter exists - var verbs = config.methods || config.verbs; + let verbs = config.methods || config.verbs; if (Array.isArray(verbs)) { verbs = verbs.map(function(verb) { return verb && verb.toUpperCase(); }); if (verbs.indexOf('ALL') === -1) { - var originalHandler = handler; + const originalHandler = handler; if (handler.length <= 3) { // Regular handler handler = function(req, res, next) { @@ -145,7 +145,7 @@ proto.defineMiddlewarePhases = function(nameOrArray) { mergePhaseNameLists(this._requestHandlingPhases, nameOrArray); } else { // add the new phase before 'routes' - var routesIx = this._requestHandlingPhases.indexOf('routes'); + const routesIx = this._requestHandlingPhases.indexOf('routes'); this._requestHandlingPhases.splice(routesIx - 1, 0, nameOrArray); } @@ -181,10 +181,10 @@ proto.middleware = function(name, paths, handler) { paths = '/'; } - var fullPhaseName = name; - var handlerName = handler.name || ''; + const fullPhaseName = name; + const handlerName = handler.name || ''; - var m = name.match(/^(.+):(before|after)$/); + const m = name.match(/^(.+):(before|after)$/); if (m) { name = m[1]; } @@ -197,7 +197,7 @@ proto.middleware = function(name, paths, handler) { this._skipLayerSorting = true; this.use(paths, handler); - var layer = this._findLayerByHandler(handler); + const layer = this._findLayerByHandler(handler); if (layer) { // Set the phase name for sorting layer.phase = fullPhaseName; @@ -223,7 +223,7 @@ proto._findLayerByHandler = function(handler) { // Other handlers can be added to the stack, for example, // NewRelic adds sentinel handler, and AppDynamics adds // some additional proxy info. We need to search the stack - for (var k = this._router.stack.length - 1; k >= 0; k--) { + for (let k = this._router.stack.length - 1; k >= 0; k--) { const isOriginal = this._router.stack[k].handle === handler; const isNewRelic = this._router.stack[k].handle['__NR_original'] === handler; const isAppDynamics = this._router.stack[k].handle['__appdynamicsProxyInfo__'] && @@ -234,7 +234,7 @@ proto._findLayerByHandler = function(handler) { } else { // Aggressively check if the original handler has been wrapped // into a new function with a property pointing to the original handler - for (var p in this._router.stack[k].handle) { + for (const p in this._router.stack[k].handle) { if (this._router.stack[k].handle[p] === handler) { return this._router.stack[k]; } @@ -246,12 +246,12 @@ proto._findLayerByHandler = function(handler) { // Install our custom PhaseList-based handler into the app proto.lazyrouter = function() { - var self = this; + const self = this; if (self._router) return; self.__expressLazyRouter(); - var router = self._router; + const router = self._router; // Mark all middleware added by Router ctor as builtin // The sorting algo will keep them at beginning of the list @@ -261,14 +261,14 @@ proto.lazyrouter = function() { router.__expressUse = router.use; router.use = function useAndSort() { - var retval = this.__expressUse.apply(this, arguments); + const retval = this.__expressUse.apply(this, arguments); self._sortLayersByPhase(); return retval; }; router.__expressRoute = router.route; router.route = function routeAndSort() { - var retval = this.__expressRoute.apply(this, arguments); + const retval = this.__expressRoute.apply(this, arguments); self._sortLayersByPhase(); return retval; }; @@ -282,19 +282,19 @@ proto.lazyrouter = function() { proto._sortLayersByPhase = function() { if (this._skipLayerSorting) return; - var phaseOrder = {}; + const phaseOrder = {}; this._requestHandlingPhases.forEach(function(name, ix) { phaseOrder[name + ':before'] = ix * 3; phaseOrder[name] = ix * 3 + 1; phaseOrder[name + ':after'] = ix * 3 + 2; }); - var router = this._router; + const router = this._router; stableSortInPlace(router.stack, compareLayers); function compareLayers(left, right) { - var leftPhase = left.phase; - var rightPhase = right.phase; + const leftPhase = left.phase; + const rightPhase = right.phase; if (leftPhase === rightPhase) return 0; diff --git a/lib/utils.js b/lib/utils.js index 29075a31..c48a3c81 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -10,12 +10,12 @@ exports.uploadInChunks = uploadInChunks; exports.downloadInChunks = downloadInChunks; exports.concatResults = concatResults; -var Promise = require('bluebird'); -var async = require('async'); +const Promise = require('bluebird'); +const async = require('async'); function createPromiseCallback() { - var cb; - var promise = new Promise(function(resolve, reject) { + let cb; + const promise = new Promise(function(resolve, reject) { cb = function(err, data) { if (err) return reject(err); return resolve(data); @@ -40,23 +40,23 @@ function throwPromiseNotDefined() { * @param {Function} cb - the callback */ function uploadInChunks(largeArray, chunkSize, processFunction, cb) { - var chunkArrays = []; + const chunkArrays = []; if (!chunkSize || chunkSize < 1 || largeArray.length <= chunkSize) { // if chunking not required processFunction(largeArray, cb); } else { // copying so that the largeArray object does not get affected during splice - var copyOfLargeArray = [].concat(largeArray); + const copyOfLargeArray = [].concat(largeArray); // chunking to smaller arrays while (copyOfLargeArray.length > 0) { chunkArrays.push(copyOfLargeArray.splice(0, chunkSize)); } - var tasks = chunkArrays.map(function(chunkArray) { + const tasks = chunkArrays.map(function(chunkArray) { return function(previousResults, chunkCallback) { - var lastArg = arguments[arguments.length - 1]; + const lastArg = arguments[arguments.length - 1]; if (typeof lastArg === 'function') { chunkCallback = lastArg; @@ -92,7 +92,7 @@ function uploadInChunks(largeArray, chunkSize, processFunction, cb) { * @param {Function} cb - the callback */ function downloadInChunks(filter, chunkSize, processFunction, cb) { - var results = []; + let results = []; filter = filter ? JSON.parse(JSON.stringify(filter)) : {}; if (!chunkSize || chunkSize < 1) { diff --git a/package.json b/package.json index 790d4d83..9d4702f7 100644 --- a/package.json +++ b/package.json @@ -64,26 +64,25 @@ }, "devDependencies": { "browserify": "^16.5.0", - "chai": "^3.5.0", + "chai": "^4.2.0", "cookie-parser": "^1.3.4", "coveralls": "^3.0.2", - "dirty-chai": "^1.2.2", - "eslint": "^5.3.0", - "eslint-config-loopback": "^12.0.0", - "eslint-plugin-mocha": "^5.1.0", + "dirty-chai": "^2.0.1", + "eslint": "^6.5.1", + "eslint-config-loopback": "^13.1.0", "express-session": "^1.14.0", "grunt": "^1.0.1", "grunt-browserify": "^5.0.0", "grunt-cli": "^1.2.0", - "grunt-contrib-uglify": "^3.4.0", + "grunt-contrib-uglify": "^4.0.1", "grunt-contrib-watch": "^1.0.0", - "grunt-eslint": "^21.0.0", + "grunt-eslint": "^22.0.0", "grunt-karma": "^3.0.2", "grunt-mocha-test": "^0.13.3", "is-docker": "^2.0.0", "karma": "^4.1.0", "karma-browserify": "^6.0.0", - "karma-chrome-launcher": "^2.2.0", + "karma-chrome-launcher": "^3.1.0", "karma-es6-shim": "^1.0.0", "karma-firefox-launcher": "^1.0.0", "karma-html2js-preprocessor": "^1.0.0", @@ -92,14 +91,14 @@ "karma-script-launcher": "^1.0.0", "loopback-boot": "^2.7.0", "loopback-context": "^1.0.0", - "mocha": "^5.2.0", + "mocha": "^6.2.1", "nyc": "^14.1.1", - "sinon": "^6.1.4", + "sinon": "^7.5.0", "sinon-chai": "^3.2.0", "strong-error-handler": "^3.0.0", "strong-task-emitter": "^0.0.8", - "supertest": "^3.0.0", - "which": "^1.3.1" + "supertest": "^4.0.2", + "which": "^2.0.1" }, "repository": { "type": "git", diff --git a/server/middleware/context.js b/server/middleware/context.js index 0086c9ba..b5575fe1 100644 --- a/server/middleware/context.js +++ b/server/middleware/context.js @@ -4,7 +4,7 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var g = require('../../lib/globalize'); +const g = require('../../lib/globalize'); module.exports = function() { throw new Error(g.f( diff --git a/server/middleware/favicon.js b/server/middleware/favicon.js index f2b343c1..2c6b3050 100644 --- a/server/middleware/favicon.js +++ b/server/middleware/favicon.js @@ -4,8 +4,8 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var favicon = require('serve-favicon'); -var path = require('path'); +const favicon = require('serve-favicon'); +const path = require('path'); /** * Serve the LoopBack favicon. diff --git a/server/middleware/rest.js b/server/middleware/rest.js index 413ef5b3..34c0619e 100644 --- a/server/middleware/rest.js +++ b/server/middleware/rest.js @@ -8,9 +8,9 @@ */ 'use strict'; -var g = require('../../lib/globalize'); -var loopback = require('../../lib/loopback'); -var async = require('async'); +const g = require('../../lib/globalize'); +const loopback = require('../../lib/loopback'); +const async = require('async'); /*! * Export the middleware. @@ -30,17 +30,17 @@ module.exports = rest; */ function rest() { - var handlers; // Cached handlers + let handlers; // Cached handlers return function restApiHandler(req, res, next) { - var app = req.app; - var registry = app.registry; + const app = req.app; + const registry = app.registry; if (!handlers) { handlers = []; - var remotingOptions = app.get('remoting') || {}; + const remotingOptions = app.get('remoting') || {}; - var contextOptions = remotingOptions.context; + const contextOptions = remotingOptions.context; if (contextOptions !== undefined && contextOptions !== false) { throw new Error(g.f( '%s was removed in version 3.0. See %s for more details.', @@ -50,7 +50,7 @@ function rest() { } if (app.isAuthEnabled) { - var AccessToken = registry.getModelByType('AccessToken'); + const AccessToken = registry.getModelByType('AccessToken'); handlers.push(loopback.token({model: AccessToken, app: app})); } diff --git a/server/middleware/status.js b/server/middleware/status.js index 29402bf8..06004023 100644 --- a/server/middleware/status.js +++ b/server/middleware/status.js @@ -24,7 +24,7 @@ module.exports = status; * @header loopback.status() */ function status() { - var started = new Date(); + const started = new Date(); return function(req, res) { res.send({ diff --git a/server/middleware/token.js b/server/middleware/token.js index 167a1386..dc2b274f 100644 --- a/server/middleware/token.js +++ b/server/middleware/token.js @@ -8,10 +8,10 @@ */ 'use strict'; -var g = require('../../lib/globalize'); -var loopback = require('../../lib/loopback'); -var assert = require('assert'); -var debug = require('debug')('loopback:middleware:token'); +const g = require('../../lib/globalize'); +const loopback = require('../../lib/loopback'); +const assert = require('assert'); +const debug = require('debug')('loopback:middleware:token'); /*! * Export the middleware. @@ -28,7 +28,7 @@ function rewriteUserLiteral(req, currentUserLiteral, next) { if (req.accessToken && req.accessToken.userId) { // Replace /me/ with /current-user-id/ - var urlBeforeRewrite = req.url; + const urlBeforeRewrite = req.url; req.url = req.url.replace(literalRegExp, '/' + req.accessToken.userId + '$1'); @@ -43,7 +43,7 @@ function rewriteUserLiteral(req, currentUserLiteral, next) { req.url, currentUserLiteral ); - var e = new Error(g.f('Authorization Required')); + const e = new Error(g.f('Authorization Required')); e.status = e.statusCode = 401; e.code = 'AUTHORIZATION_REQUIRED'; return next(e); @@ -97,9 +97,9 @@ function escapeRegExp(str) { function token(options) { options = options || {}; - var TokenModel; + let TokenModel; - var currentUserLiteral = options.currentUserLiteral; + let currentUserLiteral = options.currentUserLiteral; if (currentUserLiteral && (typeof currentUserLiteral !== 'string')) { debug('Set currentUserLiteral to \'me\' as the value is not a string.'); currentUserLiteral = 'me'; @@ -111,12 +111,12 @@ function token(options) { if (options.bearerTokenBase64Encoded === undefined) { options.bearerTokenBase64Encoded = true; } - var enableDoublecheck = !!options.enableDoublecheck; - var overwriteExistingToken = !!options.overwriteExistingToken; + const enableDoublecheck = !!options.enableDoublecheck; + const overwriteExistingToken = !!options.overwriteExistingToken; return function(req, res, next) { - var app = req.app; - var registry = app.registry; + const app = req.app; + const registry = app.registry; if (!TokenModel) { TokenModel = registry.getModel(options.model || 'AccessToken'); } @@ -141,7 +141,7 @@ function token(options) { TokenModel.findForRequest(req, options, function(err, token) { req.accessToken = token || null; - var ctx = req.loopbackContext; + const ctx = req.loopbackContext; if (ctx && ctx.active) ctx.set('accessToken', token); if (err) return next(err); diff --git a/server/middleware/url-not-found.js b/server/middleware/url-not-found.js index 513b421e..0e36f656 100644 --- a/server/middleware/url-not-found.js +++ b/server/middleware/url-not-found.js @@ -18,7 +18,7 @@ module.exports = urlNotFound; */ function urlNotFound() { return function raiseUrlNotFoundError(req, res, next) { - var error = new Error('Cannot ' + req.method + ' ' + req.url); + const error = new Error('Cannot ' + req.method + ' ' + req.url); error.status = 404; next(error); }; diff --git a/test/access-control.integration.js b/test/access-control.integration.js index 7dcbea14..653fd395 100644 --- a/test/access-control.integration.js +++ b/test/access-control.integration.js @@ -4,15 +4,15 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../'); -var lt = require('./helpers/loopback-testing-helper'); -var path = require('path'); -var ACCESS_CONTROL_APP = path.join(__dirname, 'fixtures', 'access-control'); -var app = require(path.join(ACCESS_CONTROL_APP, 'server/server.js')); -var assert = require('assert'); -var USER = {email: 'test@test.test', password: 'test'}; -var CURRENT_USER = {email: 'current@test.test', password: 'test'}; -var debug = require('debug')('loopback:test:access-control.integration'); +const loopback = require('../'); +const lt = require('./helpers/loopback-testing-helper'); +const path = require('path'); +const ACCESS_CONTROL_APP = path.join(__dirname, 'fixtures', 'access-control'); +const app = require(path.join(ACCESS_CONTROL_APP, 'server/server.js')); +const assert = require('assert'); +const USER = {email: 'test@test.test', password: 'test'}; +const CURRENT_USER = {email: 'current@test.test', password: 'test'}; +const debug = require('debug')('loopback:test:access-control.integration'); describe('access control - integration', function() { lt.beforeEach.withApp(app); @@ -110,7 +110,7 @@ describe('access control - integration', function() { this.res.statusCode, this.res.headers, this.res.text); - var user = this.res.body; + const user = this.res.body; assert.equal(user.password, undefined); }); }); @@ -137,7 +137,7 @@ describe('access control - integration', function() { return '/api/users/' + this.randomUser.id; } - var userCounter; + var userCounter; // eslint-disable-line no-var function newUserData() { userCounter = userCounter ? ++userCounter : 1; @@ -149,14 +149,14 @@ describe('access control - integration', function() { }); describe('/banks', function() { - var SPECIAL_USER = {email: 'special@test.test', password: 'test'}; + const SPECIAL_USER = {email: 'special@test.test', password: 'test'}; // define dynamic role that would only grant access when the authenticated user's email is equal to // SPECIAL_USER's email before(function() { - var roleModel = app.registry.getModel('Role'); - var userModel = app.registry.getModel('user'); + const roleModel = app.registry.getModel('Role'); + const userModel = app.registry.getModel('user'); roleModel.registerResolver('$dynamic-role', function(role, context, callback) { if (!(context && context.accessToken && context.accessToken.userId)) { @@ -164,7 +164,7 @@ describe('access control - integration', function() { if (callback) callback(null, false); }); } - var accessToken = context.accessToken; + const accessToken = context.accessToken; userModel.findById(accessToken.userId, function(err, user) { if (err) { return callback(err, false); @@ -210,9 +210,9 @@ describe('access control - integration', function() { }); describe('/accounts with replaceOnPUT true', function() { - var count = 0; + let count = 0; before(function() { - var roleModel = loopback.getModelByType(loopback.Role); + const roleModel = loopback.getModelByType(loopback.Role); roleModel.registerResolver('$dummy', function(role, context, callback) { process.nextTick(function() { if (context.remotingContext) { @@ -250,9 +250,9 @@ describe('access control - integration', function() { lt.it.shouldBeDeniedWhenCalledByUser(CURRENT_USER, 'PATCH', urlForAccount); lt.describe.whenLoggedInAsUser(CURRENT_USER, function() { - var actId; + let actId; beforeEach(function(done) { - var self = this; + const self = this; // Create an account under the given user app.models.accountWithReplaceOnPUTtrue.create({ userId: self.user.id, @@ -314,9 +314,9 @@ describe('access control - integration', function() { lt.it.shouldBeDeniedWhenCalledByUser(CURRENT_USER, 'PATCH', urlForAccount); lt.describe.whenLoggedInAsUser(CURRENT_USER, function() { - var actId; + let actId; beforeEach(function(done) { - var self = this; + const self = this; // Create an account under the given user app.models.accountWithReplaceOnPUTfalse.create({ userId: self.user.id, diff --git a/test/access-token.test.js b/test/access-token.test.js index 6b5fbe1a..87193f92 100644 --- a/test/access-token.test.js +++ b/test/access-token.test.js @@ -4,20 +4,20 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var expect = require('./helpers/expect'); -var cookieParser = require('cookie-parser'); -var LoopBackContext = require('loopback-context'); -var contextMiddleware = require('loopback-context').perRequest; -var loopback = require('../'); -var extend = require('util')._extend; -var session = require('express-session'); -var request = require('supertest'); +const assert = require('assert'); +const expect = require('./helpers/expect'); +const cookieParser = require('cookie-parser'); +const LoopBackContext = require('loopback-context'); +const contextMiddleware = require('loopback-context').perRequest; +const loopback = require('../'); +const extend = require('util')._extend; +const session = require('express-session'); +const request = require('supertest'); -var Token, ACL, User, TestModel; +let Token, ACL, User, TestModel; describe('loopback.token(options)', function() { - var app; + let app; beforeEach(function(done) { app = loopback({localRegistry: true, loadBuiltinModels: true}); app.dataSource('db', {connector: 'memory'}); @@ -52,7 +52,7 @@ describe('loopback.token(options)', function() { }); it('defaults to built-in AccessToken model', function() { - var BuiltInToken = app.registry.getModel('AccessToken'); + const BuiltInToken = app.registry.getModel('AccessToken'); app.model(BuiltInToken, {dataSource: 'db'}); app.enableAuth({dataSource: 'db'}); @@ -140,13 +140,13 @@ describe('loopback.token(options)', function() { it('does not search default keys when searchDefaultTokenKeys is false', function(done) { - var tokenId = this.token.id; - var app = createTestApp( + const tokenId = this.token.id; + const app = createTestApp( this.token, {token: {searchDefaultTokenKeys: false}}, done ); - var agent = request.agent(app); + const agent = request.agent(app); // Set the token cookie agent.get('/token').expect(200).end(function(err, res) { @@ -165,7 +165,7 @@ describe('loopback.token(options)', function() { it('populates req.token from an authorization header with bearer token with base64', function(done) { - var token = this.token.id; + let token = this.token.id; token = 'Bearer ' + new Buffer(token).toString('base64'); createTestAppAndRequest(this.token, done) .get('/') @@ -175,7 +175,7 @@ describe('loopback.token(options)', function() { }); it('populates req.token from an authorization header with bearer token', function(done) { - var token = this.token.id; + let token = this.token.id; token = 'Bearer ' + token; createTestAppAndRequest(this.token, {token: {bearerTokenBase64Encoded: false}}, done) .get('/') @@ -186,7 +186,7 @@ describe('loopback.token(options)', function() { describe('populating req.token from HTTP Basic Auth formatted authorization header', function() { it('parses "standalone-token"', function(done) { - var token = this.token.id; + let token = this.token.id; token = 'Basic ' + new Buffer(token).toString('base64'); createTestAppAndRequest(this.token, done) .get('/') @@ -196,7 +196,7 @@ describe('loopback.token(options)', function() { }); it('parses "token-and-empty-password:"', function(done) { - var token = this.token.id + ':'; + let token = this.token.id + ':'; token = 'Basic ' + new Buffer(token).toString('base64'); createTestAppAndRequest(this.token, done) .get('/') @@ -206,7 +206,7 @@ describe('loopback.token(options)', function() { }); it('parses "ignored-user:token-is-password"', function(done) { - var token = 'username:' + this.token.id; + let token = 'username:' + this.token.id; token = 'Basic ' + new Buffer(token).toString('base64'); createTestAppAndRequest(this.token, done) .get('/') @@ -216,7 +216,7 @@ describe('loopback.token(options)', function() { }); it('parses "token-is-username:ignored-password"', function(done) { - var token = this.token.id + ':password'; + let token = this.token.id + ':password'; token = 'Basic ' + new Buffer(token).toString('base64'); createTestAppAndRequest(this.token, done) .get('/') @@ -227,7 +227,7 @@ describe('loopback.token(options)', function() { }); it('populates req.token from a secure cookie', function(done) { - var app = createTestApp(this.token, done); + const app = createTestApp(this.token, done); request(app) .get('/token') @@ -240,8 +240,8 @@ describe('loopback.token(options)', function() { }); it('populates req.token from a header or a secure cookie', function(done) { - var app = createTestApp(this.token, done); - var id = this.token.id; + const app = createTestApp(this.token, done); + const id = this.token.id; request(app) .get('/token') .end(function(err, res) { @@ -255,9 +255,9 @@ describe('loopback.token(options)', function() { it('rewrites url for the current user literal at the end without query', function(done) { - var app = createTestApp(this.token, done); - var id = this.token.id; - var userId = this.token.userId; + const app = createTestApp(this.token, done); + const id = this.token.id; + const userId = this.token.userId; request(app) .get('/users/me') .set('authorization', id) @@ -271,9 +271,9 @@ describe('loopback.token(options)', function() { it('rewrites url for the current user literal at the end with query', function(done) { - var app = createTestApp(this.token, done); - var id = this.token.id; - var userId = this.token.userId; + const app = createTestApp(this.token, done); + const id = this.token.id; + const userId = this.token.userId; request(app) .get('/users/me?state=1') .set('authorization', id) @@ -287,9 +287,9 @@ describe('loopback.token(options)', function() { it('rewrites url for the current user literal in the middle', function(done) { - var app = createTestApp(this.token, done); - var id = this.token.id; - var userId = this.token.userId; + const app = createTestApp(this.token, done); + const id = this.token.id; + const userId = this.token.userId; request(app) .get('/users/me/1') .set('authorization', id) @@ -303,7 +303,7 @@ describe('loopback.token(options)', function() { it('generates a 401 on a current user literal route without an authToken', function(done) { - var app = createTestApp(null, done); + const app = createTestApp(null, done); request(app) .get('/users/me') .set('authorization', null) @@ -313,7 +313,7 @@ describe('loopback.token(options)', function() { it('generates a 401 on a current user literal route with empty authToken', function(done) { - var app = createTestApp(null, done); + const app = createTestApp(null, done); request(app) .get('/users/me') .set('authorization', '') @@ -323,7 +323,7 @@ describe('loopback.token(options)', function() { it('generates a 401 on a current user literal route with invalid authToken', function(done) { - var app = createTestApp(this.token, done); + const app = createTestApp(this.token, done); request(app) .get('/users/me') .set('Authorization', 'invald-token-id') @@ -332,7 +332,7 @@ describe('loopback.token(options)', function() { }); it('skips when req.token is already present', function(done) { - var tokenStub = {id: 'stub id'}; + const tokenStub = {id: 'stub id'}; app.use(function(req, res, next) { req.accessToken = tokenStub; @@ -358,7 +358,7 @@ describe('loopback.token(options)', function() { describe('loading multiple instances of token middleware', function() { it('skips when req.token is already present and no further options are set', function(done) { - var tokenStub = {id: 'stub id'}; + const tokenStub = {id: 'stub id'}; app.use(function(req, res, next) { req.accessToken = tokenStub; @@ -384,7 +384,7 @@ describe('loopback.token(options)', function() { it('does not overwrite valid existing token (has "id" property) ' + ' when overwriteExistingToken is falsy', function(done) { - var tokenStub = {id: 'stub id'}; + const tokenStub = {id: 'stub id'}; app.use(function(req, res, next) { req.accessToken = tokenStub; @@ -413,7 +413,7 @@ describe('loopback.token(options)', function() { it('overwrites invalid existing token (is !== undefined and has no "id" property) ' + ' when enableDoublecheck is true', function(done) { - var token = this.token; + const token = this.token; app.use(function(req, res, next) { req.accessToken = null; next(); @@ -446,8 +446,8 @@ describe('loopback.token(options)', function() { it('overwrites existing token when enableDoublecheck ' + 'and overwriteExistingToken options are truthy', function(done) { - var token = this.token; - var tokenStub = {id: 'stub id'}; + const token = this.token; + const tokenStub = {id: 'stub id'}; app.use(function(req, res, next) { req.accessToken = tokenStub; @@ -521,7 +521,7 @@ describe('AccessToken', function() { it('allows eternal tokens when enabled by User.allowEternalTokens', function(done) { - var Token = givenLocalTokenModel(); + const Token = givenLocalTokenModel(); // Overwrite User settings - enable eternal tokens Token.app.models.User.settings.allowEternalTokens = true; @@ -541,8 +541,8 @@ describe('AccessToken', function() { beforeEach(createTestingToken); it('supports two-arg variant with no options', function(done) { - var expectedTokenId = this.token.id; - var req = mockRequest({ + const expectedTokenId = this.token.id; + const req = mockRequest({ headers: {'authorization': expectedTokenId}, }); @@ -556,14 +556,14 @@ describe('AccessToken', function() { }); it('allows getIdForRequest() to be overridden', function(done) { - var expectedTokenId = this.token.id; - var current = Token.getIdForRequest; - var called = false; + const expectedTokenId = this.token.id; + const current = Token.getIdForRequest; + let called = false; Token.getIdForRequest = function(req, options) { called = true; return expectedTokenId; }; - var req = mockRequest({ + const req = mockRequest({ headers: {'authorization': 'dummy'}, }); @@ -579,16 +579,16 @@ describe('AccessToken', function() { }); it('allows resolve() to be overridden', function(done) { - var expectedTokenId = this.token.id; - var current = Token.resolve; - var called = false; + const expectedTokenId = this.token.id; + const current = Token.resolve; + let called = false; Token.resolve = function(id, cb) { called = true; process.nextTick(function() { cb(null, {id: expectedTokenId}); }); }; - var req = mockRequest({ + const req = mockRequest({ headers: {'authorization': expectedTokenId}, }); @@ -622,7 +622,7 @@ describe('AccessToken', function() { }); describe('app.enableAuth()', function() { - var app; + let app; beforeEach(function setupAuthWithModels() { app = loopback({localRegistry: true, loadBuiltinModels: true}); app.dataSource('db', {connector: 'memory'}); @@ -653,7 +653,7 @@ describe('app.enableAuth()', function() { return done(err); } - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert(errorResponse); assert.equal(errorResponse.code, 'AUTHORIZATION_REQUIRED'); @@ -671,7 +671,7 @@ describe('app.enableAuth()', function() { return done(err); } - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert(errorResponse); assert.equal(errorResponse.code, 'ACCESS_DENIED'); @@ -689,7 +689,7 @@ describe('app.enableAuth()', function() { return done(err); } - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert(errorResponse); assert.equal(errorResponse.code, 'MODEL_NOT_FOUND'); @@ -707,7 +707,7 @@ describe('app.enableAuth()', function() { return done(err); } - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert(errorResponse); assert.equal(errorResponse.code, 'AUTHORIZATION_REQUIRED'); @@ -716,9 +716,9 @@ describe('app.enableAuth()', function() { }); it('stores token in the context', function(done) { - var TestModel = app.registry.createModel('TestModel', {base: 'Model'}); + const TestModel = app.registry.createModel('TestModel', {base: 'Model'}); TestModel.getToken = function(cb) { - var ctx = LoopBackContext.getCurrentContext(); + const ctx = LoopBackContext.getCurrentContext(); cb(null, ctx && ctx.get('accessToken') || null); }; TestModel.remoteMethod('getToken', { @@ -733,7 +733,7 @@ describe('app.enableAuth()', function() { app.use(loopback.token({model: Token})); app.use(loopback.rest()); - var token = this.token; + const token = this.token; request(app) .get('/TestModels/token?_format=json') .set('authorization', token.id) @@ -772,7 +772,7 @@ describe('app.enableAuth()', function() { }); function createTestingToken(done) { - var test = this; + const test = this; Token.create({userId: '123'}, function(err, token) { if (err) return done(err); @@ -783,7 +783,7 @@ function createTestingToken(done) { } function createTestAppAndRequest(testToken, settings, done) { - var app = createTestApp(testToken, settings, done); + const app = createTestApp(testToken, settings, done); return request(app); } @@ -793,14 +793,14 @@ function createTestApp(testToken, settings, done) { settings = {}; } - var appSettings = settings.app || {}; - var modelSettings = settings.model || {}; - var tokenSettings = extend({ + const appSettings = settings.app || {}; + const modelSettings = settings.model || {}; + const tokenSettings = extend({ model: Token, currentUserLiteral: 'me', }, settings.token); - var app = loopback({localRegistry: true, loadBuiltinModels: true}); + const app = loopback({localRegistry: true, loadBuiltinModels: true}); app.dataSource('db', {connector: 'memory'}); app.use(cookieParser('secret')); @@ -824,7 +824,7 @@ function createTestApp(testToken, settings, done) { res.status(req.accessToken ? 200 : 401).end(); }); app.use('/users/:uid', function(req, res) { - var result = {userId: req.params.uid}; + const result = {userId: req.params.uid}; if (req.query.state) { result.state = req.query.state; } else if (req.url !== '/') { @@ -839,7 +839,7 @@ function createTestApp(testToken, settings, done) { app.set(key, appSettings[key]); }); - var modelOptions = { + const modelOptions = { acls: [ { principalType: 'ROLE', @@ -855,20 +855,20 @@ function createTestApp(testToken, settings, done) { modelOptions[key] = modelSettings[key]; }); - var TestModel = app.registry.createModel('test', {}, modelOptions); + const TestModel = app.registry.createModel('test', {}, modelOptions); app.model(TestModel, {dataSource: 'db'}); return app; } function givenLocalTokenModel() { - var app = loopback({localRegistry: true, loadBuiltinModels: true}); + const app = loopback({localRegistry: true, loadBuiltinModels: true}); app.dataSource('db', {connector: 'memory'}); - var User = app.registry.getModel('User'); + const User = app.registry.getModel('User'); app.model(User, {dataSource: 'db'}); - var Token = app.registry.getModel('AccessToken'); + const Token = app.registry.getModel('AccessToken'); app.model(Token, {dataSource: 'db'}); return Token; diff --git a/test/acl.test.js b/test/acl.test.js index d5662ffc..d0a62663 100644 --- a/test/acl.test.js +++ b/test/acl.test.js @@ -4,24 +4,24 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var expect = require('./helpers/expect'); -var loopback = require('../index'); -var Scope = loopback.Scope; -var ACL = loopback.ACL; -var request = require('supertest'); -var Promise = require('bluebird'); -var supertest = require('supertest'); -var Role = loopback.Role; -var RoleMapping = loopback.RoleMapping; -var User = loopback.User; -var async = require('async'); +const assert = require('assert'); +const expect = require('./helpers/expect'); +const loopback = require('../index'); +const Scope = loopback.Scope; +const ACL = loopback.ACL; +const request = require('supertest'); +const Promise = require('bluebird'); +const supertest = require('supertest'); +const Role = loopback.Role; +const RoleMapping = loopback.RoleMapping; +const User = loopback.User; +const async = require('async'); // Speed up the password hashing algorithm for tests User.settings.saltWorkFactor = 4; -var ds = null; -var testModel; +let ds = null; +let testModel; describe('ACL model', function() { it('provides DEFAULT_SCOPE constant', () => { @@ -144,7 +144,7 @@ describe('security ACLs', function() { }); it('supports checkAccessForContext() returning a promise', function() { - var testModel = ds.createModel('testModel', { + const testModel = ds.createModel('testModel', { acls: [ {principalType: ACL.USER, principalId: 'u001', accessType: ACL.ALL, permission: ACL.ALLOW}, @@ -162,7 +162,7 @@ describe('security ACLs', function() { }); it('should order ACL entries based on the matching score', function() { - var acls = [ + let acls = [ { 'model': 'account', 'accessType': '*', @@ -184,7 +184,7 @@ describe('security ACLs', function() { 'principalType': 'ROLE', 'principalId': '$everyone', }]; - var req = { + const req = { model: 'account', property: 'find', accessType: 'WRITE', @@ -192,7 +192,7 @@ describe('security ACLs', function() { acls = acls.map(function(a) { return new ACL(a); }); - var perm = ACL.resolvePermission(acls, req); + const perm = ACL.resolvePermission(acls, req); // remove the registry from AccessRequest instance to ease asserting delete perm.registry; assert.deepEqual(perm, {model: 'account', @@ -214,7 +214,7 @@ describe('security ACLs', function() { }); it('should order ACL entries based on the matching score even with wildcard req', function() { - var acls = [ + let acls = [ { 'model': 'account', 'accessType': '*', @@ -229,7 +229,7 @@ describe('security ACLs', function() { 'principalType': 'ROLE', 'principalId': '$owner', }]; - var req = { + const req = { model: 'account', property: '*', accessType: 'WRITE', @@ -237,7 +237,7 @@ describe('security ACLs', function() { acls = acls.map(function(a) { return new ACL(a); }); - var perm = ACL.resolvePermission(acls, req); + const perm = ACL.resolvePermission(acls, req); // remove the registry from AccessRequest instance to ease asserting. // Check the above test case for more info. delete perm.registry; @@ -311,7 +311,7 @@ describe('security ACLs', function() { }); it('should honor defaultPermission from the model', function(done) { - var Customer = ds.createModel('Customer', { + const Customer = ds.createModel('Customer', { name: { type: String, acls: [ @@ -347,7 +347,7 @@ describe('security ACLs', function() { }); it('should honor static ACLs from the model', function(done) { - var Customer = ds.createModel('Customer', { + const Customer = ds.createModel('Customer', { name: { type: String, acls: [ @@ -394,7 +394,7 @@ describe('security ACLs', function() { }); it('should filter static ACLs by model/property', function() { - var Model1 = ds.createModel('Model1', { + const Model1 = ds.createModel('Model1', { name: { type: String, acls: [ @@ -415,7 +415,7 @@ describe('security ACLs', function() { ], }); - var staticACLs = ACL.getStaticACLs('Model1', 'name'); + let staticACLs = ACL.getStaticACLs('Model1', 'name'); assert(staticACLs.length === 3); staticACLs = ACL.getStaticACLs('Model1', 'findOne'); @@ -427,16 +427,16 @@ describe('security ACLs', function() { }); it('should check access against LDL, ACL, and Role', function(done) { - var log = function() {}; + const log = function() {}; // Create User.create({name: 'Raymond', email: 'x@y.com', password: 'foobar'}, function(err, user) { log('User: ', user.toObject()); - var userId = user.id; + const userId = user.id; // Define a model with static ACLs - var Customer = ds.createModel('Customer', { + const Customer = ds.createModel('Customer', { name: { type: String, acls: [ @@ -514,10 +514,10 @@ describe('security ACLs', function() { describe('access check', function() { it('should occur before other remote hooks', function(done) { - var app = loopback(); - var MyTestModel = app.registry.createModel('MyTestModel'); - var checkAccessCalled = false; - var beforeHookCalled = false; + const app = loopback(); + const MyTestModel = app.registry.createModel('MyTestModel'); + let checkAccessCalled = false; + let beforeHookCalled = false; app.use(loopback.rest()); app.set('remoting', {errorHandler: {debug: true, log: false}}); @@ -527,9 +527,9 @@ describe('access check', function() { // fake / spy on the checkAccess method MyTestModel.checkAccess = function() { - var cb = arguments[arguments.length - 1]; + const cb = arguments[arguments.length - 1]; checkAccessCalled = true; - var allowed = true; + const allowed = true; cb(null, allowed); }; @@ -554,8 +554,8 @@ describe('access check', function() { }); describe('authorized roles propagation in RemotingContext', function() { - var app, request, accessToken; - var models = {}; + let app, request, accessToken; + let models = {}; beforeEach(setupAppAndRequest); @@ -567,7 +567,7 @@ describe('authorized roles propagation in RemotingContext', function() { ]) .then(makeAuthorizedHttpRequestOnMyTestModel) .then(function() { - var ctx = models.MyTestModel.lastRemotingContext; + const ctx = models.MyTestModel.lastRemotingContext; expect(ctx.args.options.authorizedRoles).to.eql( { $everyone: true, @@ -586,7 +586,7 @@ describe('authorized roles propagation in RemotingContext', function() { ]) .then(makeAuthorizedHttpRequestOnMyTestModel) .then(function() { - var ctx = models.MyTestModel.lastRemotingContext; + const ctx = models.MyTestModel.lastRemotingContext; expect(ctx.args.options.authorizedRoles).to.eql( { $everyone: true, @@ -607,7 +607,7 @@ describe('authorized roles propagation in RemotingContext', function() { ]) .then(makeAuthorizedHttpRequestOnMyTestModel) .then(function() { - var ctx = models.MyTestModel.lastRemotingContext; + const ctx = models.MyTestModel.lastRemotingContext; expect(ctx.args.options.authorizedRoles).to.eql( // '$everyone' is not expected as default permission is DENY {myRole: true} diff --git a/test/app.test.js b/test/app.test.js index 93214bfe..8aafdd96 100644 --- a/test/app.test.js +++ b/test/app.test.js @@ -4,36 +4,36 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var async = require('async'); -var path = require('path'); +const assert = require('assert'); +const async = require('async'); +const path = require('path'); -var http = require('http'); -var express = require('express'); -var loopback = require('../'); -var PersistedModel = loopback.PersistedModel; +const http = require('http'); +const express = require('express'); +const loopback = require('../'); +const PersistedModel = loopback.PersistedModel; -var describe = require('./util/describe'); -var expect = require('./helpers/expect'); -var it = require('./util/it'); -var request = require('supertest'); +const describe = require('./util/describe'); +const expect = require('./helpers/expect'); +const it = require('./util/it'); +const request = require('supertest'); const sinon = require('sinon'); describe('app', function() { - var app; + let app; beforeEach(function() { app = loopback({localRegistry: true, loadBuiltinModels: true}); }); describe.onServer('.middleware(phase, handler)', function() { - var steps; + let steps; beforeEach(function setup() { steps = []; }); it('runs middleware in phases', function(done) { - var PHASES = [ + const PHASES = [ 'initial', 'session', 'auth', 'parse', 'routes', 'files', 'final', ]; @@ -88,10 +88,10 @@ describe('app', function() { return namedHandler(name); } - var myHandler; + let myHandler; app.middleware('routes:before', myHandler = handlerThatAddsHandler('my-handler')); - var found = app._findLayerByHandler(myHandler); + const found = app._findLayerByHandler(myHandler); expect(found).to.be.an('object'); expect(myHandler).to.equal(found.handle); expect(found).have.property('phase', 'routes:before'); @@ -106,13 +106,13 @@ describe('app', function() { it('allows handlers to be wrapped as __NR_handler on express stack', function(done) { - var myHandler = namedHandler('my-handler'); - var wrappedHandler = function(req, res, next) { + const myHandler = namedHandler('my-handler'); + const wrappedHandler = function(req, res, next) { myHandler(req, res, next); }; wrappedHandler['__NR_handler'] = myHandler; app.middleware('routes:before', wrappedHandler); - var found = app._findLayerByHandler(myHandler); + const found = app._findLayerByHandler(myHandler); expect(found).to.be.an('object'); expect(found).have.property('phase', 'routes:before'); executeMiddlewareHandlers(app, function(err) { @@ -126,15 +126,15 @@ describe('app', function() { it('allows handlers to be wrapped as __appdynamicsProxyInfo__ on express stack', function(done) { - var myHandler = namedHandler('my-handler'); - var wrappedHandler = function(req, res, next) { + const myHandler = namedHandler('my-handler'); + const wrappedHandler = function(req, res, next) { myHandler(req, res, next); }; wrappedHandler['__appdynamicsProxyInfo__'] = { orig: myHandler, }; app.middleware('routes:before', wrappedHandler); - var found = app._findLayerByHandler(myHandler); + const found = app._findLayerByHandler(myHandler); expect(found).to.be.an('object'); expect(found).have.property('phase', 'routes:before'); executeMiddlewareHandlers(app, function(err) { @@ -148,13 +148,13 @@ describe('app', function() { it('allows handlers to be wrapped as a property on express stack', function(done) { - var myHandler = namedHandler('my-handler'); - var wrappedHandler = function(req, res, next) { + const myHandler = namedHandler('my-handler'); + const wrappedHandler = function(req, res, next) { myHandler(req, res, next); }; wrappedHandler['__handler'] = myHandler; app.middleware('routes:before', wrappedHandler); - var found = app._findLayerByHandler(myHandler); + const found = app._findLayerByHandler(myHandler); expect(found).to.be.an('object'); expect(found).have.property('phase', 'routes:before'); executeMiddlewareHandlers(app, function(err) { @@ -167,7 +167,7 @@ describe('app', function() { }); it('injects error from previous phases into the router', function(done) { - var expectedError = new Error('expected error'); + const expectedError = new Error('expected error'); app.middleware('initial', function(req, res, next) { steps.push('initial'); @@ -193,7 +193,7 @@ describe('app', function() { }); it('passes unhandled error to callback', function(done) { - var expectedError = new Error('expected error'); + const expectedError = new Error('expected error'); app.middleware('initial', function(req, res, next) { next(expectedError); @@ -207,8 +207,8 @@ describe('app', function() { }); it('passes errors to error handlers in the same phase', function(done) { - var expectedError = new Error('this should be handled by middleware'); - var handledError; + const expectedError = new Error('this should be handled by middleware'); + let handledError; app.middleware('initial', function(req, res, next) { // continue in the next tick, this verifies that the next @@ -298,7 +298,7 @@ describe('app', function() { }); it('exposes express helpers on req and res objects', function(done) { - var req, res; + let req, res; app.middleware('initial', function(rq, rs, next) { req = rq; @@ -336,7 +336,7 @@ describe('app', function() { }); it('sets req.baseUrl and req.originalUrl', function(done) { - var reqProps; + let reqProps; app.middleware('initial', function(req, res, next) { reqProps = {baseUrl: req.baseUrl, originalUrl: req.originalUrl}; @@ -374,7 +374,7 @@ describe('app', function() { // we need at least 9 elements to expose non-stability // of the built-in sort function - var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]; numbers.forEach(function(n) { app.middleware('routes', namedHandler(n)); }); @@ -389,8 +389,8 @@ describe('app', function() { }); it('correctly mounts express apps', function(done) { - var data, mountWasEmitted; - var subapp = express(); + let data, mountWasEmitted; + const subapp = express(); subapp.use(function(req, res, next) { data = { mountpath: req.app.mountpath, @@ -417,10 +417,10 @@ describe('app', function() { }); it('restores req & res on return from mounted express app', function(done) { - var expected = {}; - var actual = {}; + const expected = {}; + const actual = {}; - var subapp = express(); + const subapp = express(); subapp.use(function verifyTestAssumptions(req, res, next) { expect(req.__proto__).to.not.equal(expected.req); expect(res.__proto__).to.not.equal(expected.res); @@ -468,8 +468,8 @@ describe('app', function() { } function getObjectAndPrototypeKeys(obj) { - var result = []; - for (var k in obj) { + const result = []; + for (const k in obj) { result.push(k); } result.sort(); @@ -479,11 +479,11 @@ describe('app', function() { describe.onServer('.middlewareFromConfig', function() { it('provides API for loading middleware from JSON config', function(done) { - var steps = []; - var expectedConfig = {key: 'value'}; + const steps = []; + const expectedConfig = {key: 'value'}; - var handlerFactory = function() { - var args = Array.prototype.slice.apply(arguments); + const handlerFactory = function() { + const args = Array.prototype.slice.apply(arguments); return function(req, res, next) { steps.push(args); @@ -550,7 +550,7 @@ describe('app', function() { }); it('scopes middleware from config to a list of scopes', function(done) { - var steps = []; + const steps = []; app.middlewareFromConfig( function factory() { return function(req, res, next) { @@ -580,7 +580,7 @@ describe('app', function() { }); describe.onServer('.defineMiddlewarePhases(nameOrArray)', function() { - var app; + let app; beforeEach(function() { app = loopback(); }); @@ -626,7 +626,7 @@ describe('app', function() { }); function verifyMiddlewarePhases(names, done) { - var steps = []; + const steps = []; names.forEach(function(it) { app.middleware(it, function(req, res, next) { steps.push(it); @@ -646,7 +646,7 @@ describe('app', function() { }); describe('app.model(Model)', function() { - var app, db, MyTestModel; + let app, db, MyTestModel; beforeEach(function() { app = loopback(); app.set('remoting', {errorHandler: {debug: true, log: false}}); @@ -655,7 +655,7 @@ describe('app', function() { }); it('Expose a `Model` to remote clients', function() { - var Color = PersistedModel.extend('color', {name: String}); + const Color = PersistedModel.extend('color', {name: String}); app.model(Color); Color.attachTo(db); @@ -663,22 +663,22 @@ describe('app', function() { }); it('uses singular name as app.remoteObjects() key', function() { - var Color = PersistedModel.extend('color', {name: String}); + const Color = PersistedModel.extend('color', {name: String}); app.model(Color); Color.attachTo(db); expect(app.remoteObjects()).to.eql({color: Color}); }); it('uses singular name as shared class name', function() { - var Color = PersistedModel.extend('color', {name: String}); + const Color = PersistedModel.extend('color', {name: String}); app.model(Color); Color.attachTo(db); - var classes = app.remotes().classes().map(function(c) { return c.name; }); + const classes = app.remotes().classes().map(function(c) { return c.name; }); expect(classes).to.contain('color'); }); it('registers existing models to app.models', function() { - var Color = db.createModel('color', {name: String}); + const Color = db.createModel('color', {name: String}); app.model(Color); expect(Color.app).to.be.equal(app); expect(Color.shared).to.equal(true); @@ -687,9 +687,9 @@ describe('app', function() { }); it('emits a `modelRemoted` event', function() { - var Color = PersistedModel.extend('color', {name: String}); + const Color = PersistedModel.extend('color', {name: String}); Color.shared = true; - var remotedClass; + let remotedClass; app.on('modelRemoted', function(sharedClass) { remotedClass = sharedClass; }); @@ -699,9 +699,9 @@ describe('app', function() { }); it('emits a `remoteMethodDisabled` event', function() { - var Color = PersistedModel.extend('color', {name: String}); + const Color = PersistedModel.extend('color', {name: String}); Color.shared = true; - var remoteMethodDisabledClass, disabledRemoteMethod; + let remoteMethodDisabledClass, disabledRemoteMethod; app.on('remoteMethodDisabled', function(sharedClass, methodName) { remoteMethodDisabledClass = sharedClass; disabledRemoteMethod = methodName; @@ -716,14 +716,14 @@ describe('app', function() { it('emits a `remoteMethodAdded` event', function() { app.dataSource('db', {connector: 'memory'}); - var Book = app.registry.createModel( + const Book = app.registry.createModel( 'Book', {name: 'string'}, {plural: 'books'} ); app.model(Book, {dataSource: 'db'}); - var Page = app.registry.createModel( + const Page = app.registry.createModel( 'Page', {name: 'string'}, {plural: 'pages'} @@ -732,7 +732,7 @@ describe('app', function() { Book.hasMany(Page); - var remoteMethodAddedClass; + let remoteMethodAddedClass; app.on('remoteMethodAdded', function(sharedClass) { remoteMethodAddedClass = sharedClass; }); @@ -759,14 +759,14 @@ describe('app', function() { }); it('throws error if model typeof string is passed', function() { - var fn = function() { app.model('MyTestModel'); }; + const fn = function() { app.model('MyTestModel'); }; expect(fn).to.throw(/app(\.model|\.registry)/); }); }); describe('app.model(ModelCtor, config)', function() { it('attaches the model to a datasource', function() { - var previousModel = loopback.registry.findModel('TestModel'); + const previousModel = loopback.registry.findModel('TestModel'); app.dataSource('db', {connector: 'memory'}); if (previousModel) { @@ -774,7 +774,7 @@ describe('app', function() { } assert(!previousModel || !previousModel.dataSource); - var TestModel = app.registry.createModel('TestModel'); + const TestModel = app.registry.createModel('TestModel'); app.model(TestModel, {dataSource: 'db'}); expect(app.models.TestModel.dataSource).to.equal(app.dataSources.db); }); @@ -843,10 +843,10 @@ describe('app', function() { describe('app.models', function() { it('is unique per app instance', function() { app.dataSource('db', {connector: 'memory'}); - var Color = app.registry.createModel('Color'); + const Color = app.registry.createModel('Color'); app.model(Color, {dataSource: 'db'}); expect(app.models.Color).to.equal(Color); - var anotherApp = loopback(); + const anotherApp = loopback(); expect(anotherApp.models.Color).to.equal(undefined); }); }); @@ -855,7 +855,7 @@ describe('app', function() { it('is unique per app instance', function() { app.dataSource('ds', {connector: 'memory'}); expect(app.datasources.ds).to.not.equal(undefined); - var anotherApp = loopback(); + const anotherApp = loopback(); expect(anotherApp.datasources.ds).to.equal(undefined); }); }); @@ -886,11 +886,11 @@ describe('app', function() { describe.onServer('listen()', function() { it('starts http server', function(done) { - var app = loopback(); + const app = loopback(); app.set('port', 0); app.get('/', function(req, res) { res.status(200).send('OK'); }); - var server = app.listen(); + const server = app.listen(); expect(server).to.be.an.instanceOf(require('http').Server); @@ -900,7 +900,7 @@ describe('app', function() { }); it('updates port on `listening` event', function(done) { - var app = loopback(); + const app = loopback(); app.set('port', 0); app.listen(function() { @@ -911,12 +911,12 @@ describe('app', function() { }); it('updates `url` on `listening` event', function(done) { - var app = loopback(); + const app = loopback(); app.set('port', 0); app.set('host', undefined); app.listen(function() { - var expectedUrl = 'http://localhost:' + app.get('port') + '/'; + const expectedUrl = 'http://localhost:' + app.get('port') + '/'; expect(app.get('url'), 'url').to.equal(expectedUrl); done(); @@ -924,7 +924,7 @@ describe('app', function() { }); it('forwards to http.Server.listen on more than one arg', function(done) { - var app = loopback(); + const app = loopback(); app.set('port', 1); app.listen(0, '127.0.0.1', function() { expect(app.get('port'), 'port').to.not.equal(0).and.not.equal(1); @@ -935,7 +935,7 @@ describe('app', function() { }); it('forwards to http.Server.listen when the single arg is not a function', function(done) { - var app = loopback(); + const app = loopback(); app.set('port', 1); app.listen(0).on('listening', function() { expect(app.get('port'), 'port') .to.not.equal(0).and.not.equal(1); @@ -945,7 +945,7 @@ describe('app', function() { }); it('uses app config when no parameter is supplied', function(done) { - var app = loopback(); + const app = loopback(); // Http listens on all interfaces by default // Custom host serves as an indicator whether // the value was used by app.listen @@ -967,26 +967,26 @@ describe('app', function() { }); it('auto-configures required models to provided dataSource', function() { - var AUTH_MODELS = ['User', 'ACL', 'AccessToken', 'Role', 'RoleMapping']; - var app = loopback({localRegistry: true, loadBuiltinModels: true}); + const AUTH_MODELS = ['User', 'ACL', 'AccessToken', 'Role', 'RoleMapping']; + const app = loopback({localRegistry: true, loadBuiltinModels: true}); require('../lib/builtin-models')(app.registry); - var db = app.dataSource('db', {connector: 'memory'}); + const db = app.dataSource('db', {connector: 'memory'}); app.enableAuth({dataSource: 'db'}); expect(Object.keys(app.models)).to.include.members(AUTH_MODELS); AUTH_MODELS.forEach(function(m) { - var Model = app.models[m]; + const Model = app.models[m]; expect(Model.dataSource, m + '.dataSource').to.equal(db); expect(Model.shared, m + '.shared').to.equal(m === 'User'); }); }); it('detects already configured subclass of a required model', function() { - var app = loopback({localRegistry: true, loadBuiltinModels: true}); - var db = app.dataSource('db', {connector: 'memory'}); - var Customer = app.registry.createModel('Customer', {}, {base: 'User'}); + const app = loopback({localRegistry: true, loadBuiltinModels: true}); + const db = app.dataSource('db', {connector: 'memory'}); + const Customer = app.registry.createModel('Customer', {}, {base: 'User'}); app.model(Customer, {dataSource: 'db'}); // Fix AccessToken's "belongsTo user" relation to use our new Customer model @@ -1001,7 +1001,7 @@ describe('app', function() { describe.onServer('app.get(\'/\', loopback.status())', function() { it('should return the status of the application', function(done) { - var app = loopback(); + const app = loopback(); app.get('/', loopback.status()); request(app) .get('/') @@ -1013,7 +1013,7 @@ describe('app', function() { expect(res.body).to.have.property('started'); expect(res.body.uptime, 'uptime').to.be.gte(0); - var elapsed = Date.now() - Number(new Date(res.body.started)); + const elapsed = Date.now() - Number(new Date(res.body.started)); // elapsed should be a small positive number... expect(elapsed, 'elapsed').to.be.within(0, 300); @@ -1026,7 +1026,7 @@ describe('app', function() { describe('app.connectors', function() { it('is unique per app instance', function() { app.connectors.foo = 'bar'; - var anotherApp = loopback(); + const anotherApp = loopback(); expect(anotherApp.connectors.foo).to.equal(undefined); }); @@ -1069,8 +1069,8 @@ describe('app', function() { }); it('is unique per app instance', function() { - var app1 = loopback(); - var app2 = loopback(); + const app1 = loopback(); + const app2 = loopback(); expect(app1.settings).to.not.equal(app2.settings); @@ -1080,18 +1080,18 @@ describe('app', function() { }); it('exposes loopback as a property', function() { - var app = loopback(); + const app = loopback(); expect(app.loopback).to.equal(loopback); }); function setupUserModels(app, options, done) { app.dataSource('db', {connector: 'memory'}); - var UserAccount = app.registry.createModel( + const UserAccount = app.registry.createModel( 'UserAccount', {name: 'string'}, options ); - var UserRole = app.registry.createModel( + const UserRole = app.registry.createModel( 'UserRole', {name: 'string'} ); @@ -1108,7 +1108,7 @@ describe('app', function() { } describe('Model-level normalizeHttpPath option', function() { - var app; + let app; beforeEach(function() { app = loopback(); }); @@ -1144,7 +1144,7 @@ describe('app', function() { }); }); describe('app-level normalizeHttpPath option', function() { - var app; + let app; beforeEach(function() { app = loopback(); }); @@ -1179,7 +1179,7 @@ describe('app', function() { }); describe('Model-level and app-level normalizeHttpPath options', function() { - var app; + let app; beforeEach(function() { app = loopback(); }); @@ -1203,8 +1203,8 @@ describe('app', function() { }); function executeMiddlewareHandlers(app, urlPath, callback) { - var handlerError = undefined; - var server = http.createServer(function(req, res) { + let handlerError = undefined; + const server = http.createServer(function(req, res) { app.handle(req, res, function(err) { if (err) { handlerError = err; diff --git a/test/change-stream.test.js b/test/change-stream.test.js index 8cf2b5eb..f48aa395 100644 --- a/test/change-stream.test.js +++ b/test/change-stream.test.js @@ -4,17 +4,17 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var expect = require('./helpers/expect'); -var sinon = require('sinon'); -var loopback = require('../'); +const expect = require('./helpers/expect'); +const sinon = require('sinon'); +const loopback = require('../'); describe('PersistedModel.createChangeStream()', function() { describe('configured to source changes locally', function() { before(function() { - var test = this; - var app = loopback({localRegistry: true}); - var ds = app.dataSource('ds', {connector: 'memory'}); - var Score = app.registry.createModel('Score'); + const test = this; + const app = loopback({localRegistry: true}); + const ds = app.dataSource('ds', {connector: 'memory'}); + const Score = app.registry.createModel('Score'); this.Score = app.model(Score, { dataSource: 'ds', changeDataSource: false, // use only local observers @@ -24,7 +24,7 @@ describe('PersistedModel.createChangeStream()', function() { afterEach(verifyObserversRemoval); it('should detect create', function(done) { - var Score = this.Score; + const Score = this.Score; Score.createChangeStream(function(err, changes) { changes.on('data', function(change) { @@ -38,7 +38,7 @@ describe('PersistedModel.createChangeStream()', function() { }); it('should detect update', function(done) { - var Score = this.Score; + const Score = this.Score; Score.create({team: 'foo'}, function(err, newScore) { Score.createChangeStream(function(err, changes) { changes.on('data', function(change) { @@ -55,7 +55,7 @@ describe('PersistedModel.createChangeStream()', function() { }); it('should detect delete', function(done) { - var Score = this.Score; + const Score = this.Score; Score.create({team: 'foo'}, function(err, newScore) { Score.createChangeStream(function(err, changes) { changes.on('data', function(change) { @@ -103,9 +103,9 @@ describe('PersistedModel.createChangeStream()', function() { }); it('should not emit changes after destroy', function(done) { - var Score = this.Score; + const Score = this.Score; - var spy = sinon.spy(); + const spy = sinon.spy(); Score.createChangeStream(function(err, changes) { changes.on('data', function() { @@ -123,7 +123,7 @@ describe('PersistedModel.createChangeStream()', function() { }); function verifyObserversRemoval() { - var Score = this.Score; + const Score = this.Score; expect(Score._observers['after save']).to.be.empty(); expect(Score._observers['after delete']).to.be.empty(); } @@ -132,10 +132,10 @@ describe('PersistedModel.createChangeStream()', function() { // TODO(ritch) implement multi-server support describe.skip('configured to source changes using pubsub', function() { before(function() { - var test = this; - var app = loopback({localRegistry: true}); - var db = app.dataSource('ds', {connector: 'memory'}); - var ps = app.dataSource('ps', { + const test = this; + const app = loopback({localRegistry: true}); + const db = app.dataSource('ds', {connector: 'memory'}); + const ps = app.dataSource('ps', { host: 'localhost', port: '12345', connector: 'pubsub', @@ -148,7 +148,7 @@ describe('PersistedModel.createChangeStream()', function() { }); it('should detect a change', function(done) { - var Score = this.Score; + const Score = this.Score; Score.createChangeStream(function(err, changes) { changes.on('data', function(change) { diff --git a/test/change.test.js b/test/change.test.js index 58556297..07dc1753 100644 --- a/test/change.test.js +++ b/test/change.test.js @@ -4,16 +4,16 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var async = require('async'); -var expect = require('./helpers/expect'); -var loopback = require('../'); +const assert = require('assert'); +const async = require('async'); +const expect = require('./helpers/expect'); +const loopback = require('../'); describe('Change', function() { let Change, TestModel; beforeEach(function() { - var memory = loopback.createDataSource({ + const memory = loopback.createDataSource({ connector: loopback.Memory, }); TestModel = loopback.PersistedModel.extend('ChangeTestModel', @@ -29,7 +29,7 @@ describe('Change', function() { }); beforeEach(function(done) { - var test = this; + const test = this; test.data = { foo: 'bar', }; @@ -52,13 +52,13 @@ describe('Change', function() { describe('change.id', function() { it('should be a hash of the modelName and modelId', function() { - var change = new Change({ + const change = new Change({ rev: 'abc', modelName: 'foo', modelId: 'bar', }); - var hash = Change.hash([change.modelName, change.modelId].join('-')); + const hash = Change.hash([change.modelName, change.modelId].join('-')); assert.equal(change.id, hash); }); @@ -67,7 +67,7 @@ describe('Change', function() { describe('Change.rectifyModelChanges(modelName, modelIds, callback)', function() { describe('using an existing untracked model', function() { beforeEach(function(done) { - var test = this; + const test = this; Change.rectifyModelChanges(this.modelName, [this.modelId], function(err, trackedChanges) { if (err) return done(err); @@ -76,7 +76,7 @@ describe('Change', function() { }); it('should create an entry', function(done) { - var test = this; + const test = this; Change.find(function(err, trackedChanges) { assert.equal(trackedChanges[0].modelId, test.modelId.toString()); @@ -97,7 +97,7 @@ describe('Change', function() { describe('Change.rectifyModelChanges - promise variant', function() { describe('using an existing untracked model', function() { beforeEach(function(done) { - var test = this; + const test = this; Change.rectifyModelChanges(this.modelName, [this.modelId]) .then(function(trackedChanges) { done(); @@ -106,7 +106,7 @@ describe('Change', function() { }); it('should create an entry', function(done) { - var test = this; + const test = this; Change.find() .then(function(trackedChanges) { assert.equal(trackedChanges[0].modelId, test.modelId.toString()); @@ -131,7 +131,7 @@ describe('Change', function() { describe('Change.findOrCreateChange(modelName, modelId, callback)', function() { describe('when a change doesnt exist', function() { beforeEach(function(done) { - var test = this; + const test = this; Change.findOrCreateChange(this.modelName, this.modelId, function(err, result) { if (err) return done(err); @@ -142,7 +142,7 @@ describe('Change', function() { }); it('should create an entry', function(done) { - var test = this; + const test = this; Change.findById(this.result.id, function(err, change) { if (err) return done(err); @@ -155,7 +155,7 @@ describe('Change', function() { describe('when a change doesnt exist - promise variant', function() { beforeEach(function(done) { - var test = this; + const test = this; Change.findOrCreateChange(this.modelName, this.modelId) .then(function(result) { test.result = result; @@ -166,7 +166,7 @@ describe('Change', function() { }); it('should create an entry', function(done) { - var test = this; + const test = this; Change.findById(this.result.id, function(err, change) { if (err) return done(err); @@ -179,7 +179,7 @@ describe('Change', function() { describe('when a change does exist', function() { beforeEach(function(done) { - var test = this; + const test = this; Change.create({ modelName: test.modelName, modelId: test.modelId, @@ -191,7 +191,7 @@ describe('Change', function() { }); beforeEach(function(done) { - var test = this; + const test = this; Change.findOrCreateChange(this.modelName, this.modelId, function(err, result) { if (err) return done(err); @@ -202,7 +202,7 @@ describe('Change', function() { }); it('should find the entry', function(done) { - var test = this; + const test = this; assert.equal(test.existingChange.id, test.result.id); done(); @@ -211,7 +211,7 @@ describe('Change', function() { }); describe('change.rectify(callback)', function() { - var change; + let change; beforeEach(function(done) { Change.findOrCreate( { @@ -227,7 +227,7 @@ describe('Change', function() { }); it('should create a new change with the correct revision', function(done) { - var test = this; + const test = this; change.rectify(function(err, ch) { assert.equal(ch.rev, test.revisionForModel); @@ -238,9 +238,9 @@ describe('Change', function() { // This test is a low-level equivalent of the test in replication.test.js // called "replicates multiple updates within the same CP" it('should merge updates within the same checkpoint', function(done) { - var test = this; - var originalRev = this.revisionForModel; - var cp; + const test = this; + const originalRev = this.revisionForModel; + let cp; async.series([ rectify, @@ -274,7 +274,7 @@ describe('Change', function() { } function update(next) { - var model = test.model; + const model = test.model; model.name += 'updated'; model.save(function(err) { @@ -286,9 +286,9 @@ describe('Change', function() { }); it('should not change checkpoint when rev is the same', function(done) { - var test = this; - var originalCheckpoint = change.checkpoint; - var originalRev = change.rev; + const test = this; + const originalCheckpoint = change.checkpoint; + const originalRev = change.rev; TestModel.checkpoint(function(err, inst) { if (err) return done(err); @@ -306,7 +306,7 @@ describe('Change', function() { }); describe('change.rectify - promise variant', function() { - var change; + let change; beforeEach(function(done) { Change.findOrCreateChange(this.modelName, this.modelId) .then(function(ch) { @@ -318,7 +318,7 @@ describe('Change', function() { }); it('should create a new change with the correct revision', function(done) { - var test = this; + const test = this; change.rectify() .then(function(ch) { assert.equal(ch.rev, test.revisionForModel); @@ -330,8 +330,8 @@ describe('Change', function() { describe('change.currentRevision(callback)', function() { it('should get the correct revision', function(done) { - var test = this; - var change = new Change({ + const test = this; + const change = new Change({ modelName: this.modelName, modelId: this.modelId, }); @@ -346,8 +346,8 @@ describe('Change', function() { describe('change.currentRevision - promise variant', function() { it('should get the correct revision', function(done) { - var test = this; - var change = new Change({ + const test = this; + const change = new Change({ modelName: this.modelName, modelId: this.modelId, }); @@ -365,8 +365,8 @@ describe('Change', function() { describe('Change.hash(str)', function() { // todo(ritch) test other hashing algorithms it('should hash the given string', function() { - var str = 'foo'; - var hash = Change.hash(str); + const str = 'foo'; + const hash = Change.hash(str); assert(hash !== str); assert(typeof hash === 'string'); }); @@ -374,54 +374,54 @@ describe('Change', function() { describe('Change.revisionForInst(inst)', function() { it('should return the same revision for the same data', function() { - var a = { + const a = { b: { b: ['c', 'd'], c: ['d', 'e'], }, }; - var b = { + const b = { b: { c: ['d', 'e'], b: ['c', 'd'], }, }; - var aRev = Change.revisionForInst(a); - var bRev = Change.revisionForInst(b); + const aRev = Change.revisionForInst(a); + const bRev = Change.revisionForInst(b); assert.equal(aRev, bRev); }); }); describe('change.type()', function() { it('CREATE', function() { - var change = new Change({ + const change = new Change({ rev: this.revisionForModel, }); assert.equal(Change.CREATE, change.type()); }); it('UPDATE', function() { - var change = new Change({ + const change = new Change({ rev: this.revisionForModel, prev: this.revisionForModel, }); assert.equal(Change.UPDATE, change.type()); }); it('DELETE', function() { - var change = new Change({ + const change = new Change({ prev: this.revisionForModel, }); assert.equal(Change.DELETE, change.type()); }); it('UNKNOWN', function() { - var change = new Change(); + const change = new Change(); assert.equal(Change.UNKNOWN, change.type()); }); }); describe('change.getModelCtor()', function() { it('should get the correct model class', function() { - var change = new Change({ + const change = new Change({ modelName: this.modelName, }); @@ -431,11 +431,11 @@ describe('Change', function() { describe('change.equals(otherChange)', function() { it('should return true when the change is equal', function() { - var change = new Change({ + const change = new Change({ rev: this.revisionForModel, }); - var otherChange = new Change({ + const otherChange = new Change({ rev: this.revisionForModel, }); @@ -443,13 +443,13 @@ describe('Change', function() { }); it('should return true when both changes are deletes', function() { - var REV = 'foo'; - var change = new Change({ + const REV = 'foo'; + const change = new Change({ rev: null, prev: REV, }); - var otherChange = new Change({ + const otherChange = new Change({ rev: undefined, prev: REV, }); @@ -463,11 +463,11 @@ describe('Change', function() { describe('change.isBasedOn(otherChange)', function() { it('should return true when the change is based on the other', function() { - var change = new Change({ + const change = new Change({ prev: this.revisionForModel, }); - var otherChange = new Change({ + const otherChange = new Change({ rev: this.revisionForModel, }); @@ -485,7 +485,7 @@ describe('Change', function() { }); it('should return delta and conflict lists', function(done) { - var remoteChanges = [ + const remoteChanges = [ // an update => should result in a delta {rev: 'foo2', prev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1}, // no change => should not result in a delta / conflict @@ -505,7 +505,7 @@ describe('Change', function() { }); it('should return delta and conflict lists - promise variant', function(done) { - var remoteChanges = [ + const remoteChanges = [ // an update => should result in a delta {rev: 'foo2', prev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1}, // no change => should not result in a delta / conflict @@ -525,7 +525,7 @@ describe('Change', function() { }); it('should set "prev" to local revision in non-conflicting delta', function(done) { - var updateRecord = { + const updateRecord = { rev: 'foo-new', prev: 'foo', modelName: this.modelName, @@ -537,7 +537,7 @@ describe('Change', function() { expect(diff.conflicts, 'conflicts').to.have.length(0); expect(diff.deltas, 'deltas').to.have.length(1); - var actual = diff.deltas[0].toObject(); + const actual = diff.deltas[0].toObject(); delete actual.id; expect(actual).to.eql({ checkpoint: 2, @@ -552,7 +552,7 @@ describe('Change', function() { }); it('should set "prev" to local revision in remote-only delta', function(done) { - var updateRecord = { + const updateRecord = { rev: 'foo-new', prev: 'foo-prev', modelName: this.modelName, @@ -566,7 +566,7 @@ describe('Change', function() { expect(diff.conflicts, 'conflicts').to.have.length(0); expect(diff.deltas, 'deltas').to.have.length(1); - var actual = diff.deltas[0].toObject(); + const actual = diff.deltas[0].toObject(); delete actual.id; expect(actual).to.eql({ checkpoint: 2, @@ -581,7 +581,7 @@ describe('Change', function() { }); it('should set "prev" to null for a new instance', function(done) { - var updateRecord = { + const updateRecord = { rev: 'new-rev', prev: 'new-prev', modelName: this.modelName, @@ -594,7 +594,7 @@ describe('Change', function() { expect(diff.conflicts).to.have.length(0); expect(diff.deltas).to.have.length(1); - var actual = diff.deltas[0].toObject(); + const actual = diff.deltas[0].toObject(); delete actual.id; expect(actual).to.eql({ checkpoint: 2, @@ -614,7 +614,7 @@ describe('Change with with custom properties', function() { let Change, TestModel; beforeEach(function() { - let memory = loopback.createDataSource({ + const memory = loopback.createDataSource({ connector: loopback.Memory, }); @@ -630,7 +630,7 @@ describe('Change with with custom properties', function() { this.modelName = TestModel.modelName; TestModel.prototype.fillCustomChangeProperties = function(change, cb) { - var inst = this; + const inst = this; if (inst && inst.tenantId) { change.tenantId = inst.tenantId; diff --git a/test/checkpoint.test.js b/test/checkpoint.test.js index c7fefe35..67108d18 100644 --- a/test/checkpoint.test.js +++ b/test/checkpoint.test.js @@ -4,16 +4,16 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var async = require('async'); -var loopback = require('../'); -var expect = require('./helpers/expect'); +const async = require('async'); +const loopback = require('../'); +const expect = require('./helpers/expect'); -var Checkpoint = loopback.Checkpoint.extend('TestCheckpoint'); +const Checkpoint = loopback.Checkpoint.extend('TestCheckpoint'); describe('Checkpoint', function() { describe('bumpLastSeq() and current()', function() { beforeEach(function() { - var memory = loopback.createDataSource({ + const memory = loopback.createDataSource({ connector: loopback.Memory, }); Checkpoint.attachTo(memory); diff --git a/test/context-options.test.js b/test/context-options.test.js index 82930b2d..a9241739 100644 --- a/test/context-options.test.js +++ b/test/context-options.test.js @@ -5,12 +5,12 @@ 'use strict'; -var expect = require('chai').expect; -var loopback = require('..'); -var supertest = require('supertest'); +const expect = require('chai').expect; +const loopback = require('..'); +const supertest = require('supertest'); describe('OptionsFromRemotingContext', function() { - var app, request, accessToken, userId, Product, actualOptions; + let app, request, accessToken, userId, Product, actualOptions; beforeEach(setupAppAndRequest); beforeEach(resetActualOptions); @@ -133,7 +133,7 @@ describe('OptionsFromRemotingContext', function() { // despite the fact that under the hood a method on "modelTo" is called. context('hasManyThrough', function() { - var Category, ThroughModel; + let Category, ThroughModel; beforeEach(givenCategoryHasManyProductsThroughAnotherModel); beforeEach(givenCategoryAndProduct); @@ -242,7 +242,7 @@ describe('OptionsFromRemotingContext', function() { }); context('hasOne', function() { - var Category; + let Category; beforeEach(givenCategoryHasOneProduct); beforeEach(givenCategoryId1); @@ -313,7 +313,7 @@ describe('OptionsFromRemotingContext', function() { }); context('belongsTo', function() { - var Category; + let Category; beforeEach(givenCategoryBelongsToProduct); @@ -382,7 +382,7 @@ describe('OptionsFromRemotingContext', function() { } function observeOptionsBeforeSave() { - var Model = arguments[0] || Product; + const Model = arguments[0] || Product; Model.observe('before save', function(ctx, next) { actualOptions = ctx.options; next(); @@ -390,7 +390,7 @@ describe('OptionsFromRemotingContext', function() { } function observeOptionsBeforeDelete() { - var Model = arguments[0] || Product; + const Model = arguments[0] || Product; Model.observe('before delete', function(ctx, next) { actualOptions = ctx.options; next(); @@ -398,7 +398,7 @@ describe('OptionsFromRemotingContext', function() { } function observeOptionsOnAccess() { - var Model = arguments[0] || Product; + const Model = arguments[0] || Product; Model.observe('access', function(ctx, next) { actualOptions = ctx.options; next(); diff --git a/test/data-source.test.js b/test/data-source.test.js index 18ffe752..00240566 100644 --- a/test/data-source.test.js +++ b/test/data-source.test.js @@ -4,11 +4,11 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var loopback = require('../'); +const assert = require('assert'); +const loopback = require('../'); describe('DataSource', function() { - var memory; + let memory; beforeEach(function() { memory = loopback.createDataSource({ @@ -20,7 +20,7 @@ describe('DataSource', function() { describe('dataSource.createModel(name, properties, settings)', function() { it('Define a model and attach it to a `DataSource`', function() { - var Color = memory.createModel('color', {name: String}); + const Color = memory.createModel('color', {name: String}); assert.isFunc(Color, 'find'); assert.isFunc(Color, 'findById'); assert.isFunc(Color, 'findOne'); @@ -45,31 +45,31 @@ describe('DataSource', function() { }); it('should honor settings.base', function() { - var Base = memory.createModel('base'); - var Color = memory.createModel('color', {name: String}, {base: Base}); + const Base = memory.createModel('base'); + const Color = memory.createModel('color', {name: String}, {base: Base}); assert(Color.prototype instanceof Base); assert.equal(Color.base, Base); }); it('should use loopback.PersistedModel as the base for DBs', function() { - var Color = memory.createModel('color', {name: String}); + const Color = memory.createModel('color', {name: String}); assert(Color.prototype instanceof loopback.PersistedModel); assert.equal(Color.base, loopback.PersistedModel); }); it('should use loopback.Model as the base for non DBs', function() { // Mock up a non-DB connector - var Connector = function() { + const Connector = function() { }; Connector.prototype.getTypes = function() { return ['rest']; }; - var ds = loopback.createDataSource({ + const ds = loopback.createDataSource({ connector: new Connector(), }); - var Color = ds.createModel('color', {name: String}); + const Color = ds.createModel('color', {name: String}); assert(Color.prototype instanceof Color.registry.getModel('Model')); assert.equal(Color.base.modelName, 'PersistedModel'); }); @@ -77,7 +77,7 @@ describe('DataSource', function() { describe.skip('PersistedModel Methods', function() { it('List the enabled and disabled methods', function() { - var TestModel = loopback.PersistedModel.extend('TestPersistedModel'); + const TestModel = loopback.PersistedModel.extend('TestPersistedModel'); TestModel.attachTo(loopback.memory()); // assert the defaults @@ -109,9 +109,9 @@ describe('DataSource', function() { existsAndShared('reload', false); function existsAndShared(Model, name, isRemoteEnabled, isProto) { - var scope = isProto ? Model.prototype : Model; - var fn = scope[name]; - var actuallyEnabled = Model.getRemoteMethod(name); + const scope = isProto ? Model.prototype : Model; + const fn = scope[name]; + const actuallyEnabled = Model.getRemoteMethod(name); assert(fn, name + ' should be defined!'); assert(actuallyEnabled === isRemoteEnabled, name + ' ' + (isRemoteEnabled ? 'should' : 'should not') + @@ -121,7 +121,7 @@ describe('DataSource', function() { }); }); -var assertValidDataSource = function(dataSource) { +function assertValidDataSource(dataSource) { // has methods assert.isFunc(dataSource, 'createModel'); assert.isFunc(dataSource, 'discoverModelDefinitions'); @@ -130,7 +130,7 @@ var assertValidDataSource = function(dataSource) { assert.isFunc(dataSource, 'disableRemote'); assert.isFunc(dataSource, 'defineOperation'); assert.isFunc(dataSource, 'operations'); -}; +} assert.isFunc = function(obj, name) { assert(obj, 'cannot assert function ' + name + ' on object that doesnt exist'); diff --git a/test/e2e/remote-connector.e2e.js b/test/e2e/remote-connector.e2e.js index 76c6401a..b7ab8fb8 100644 --- a/test/e2e/remote-connector.e2e.js +++ b/test/e2e/remote-connector.e2e.js @@ -4,16 +4,16 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var path = require('path'); -var loopback = require('../../'); -var models = require('../fixtures/e2e/models'); -var TestModel = models.TestModel; -var assert = require('assert'); +const path = require('path'); +const loopback = require('../../'); +const models = require('../fixtures/e2e/models'); +const TestModel = models.TestModel; +const assert = require('assert'); describe('RemoteConnector', function() { before(function() { // setup the remote connector - var ds = loopback.createDataSource({ + const ds = loopback.createDataSource({ url: 'http://127.0.0.1:3000/api', connector: loopback.Remote, }); @@ -33,7 +33,7 @@ describe('RemoteConnector', function() { }); it('should be able to call save', function(done) { - var m = new TestModel({ + const m = new TestModel({ foo: 'bar', }); m.save(function(err, data) { diff --git a/test/e2e/replication.e2e.js b/test/e2e/replication.e2e.js index 5db799b0..c29d308a 100644 --- a/test/e2e/replication.e2e.js +++ b/test/e2e/replication.e2e.js @@ -4,29 +4,29 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var path = require('path'); -var loopback = require('../../'); -var models = require('../fixtures/e2e/models'); -var TestModel = models.TestModel; -var LocalTestModel = TestModel.extend('LocalTestModel', {}, { +const path = require('path'); +const loopback = require('../../'); +const models = require('../fixtures/e2e/models'); +const TestModel = models.TestModel; +const LocalTestModel = TestModel.extend('LocalTestModel', {}, { trackChanges: true, }); -var assert = require('assert'); +const assert = require('assert'); describe('Replication', function() { before(function() { // setup the remote connector - var ds = loopback.createDataSource({ + const ds = loopback.createDataSource({ url: 'http://127.0.0.1:3000/api', connector: loopback.Remote, }); TestModel.attachTo(ds); - var memory = loopback.memory(); + const memory = loopback.memory(); LocalTestModel.attachTo(memory); }); it('should replicate local data to the remote', function(done) { - var RANDOM = Math.random(); + const RANDOM = Math.random(); LocalTestModel.create({ n: RANDOM, diff --git a/test/email.test.js b/test/email.test.js index 1c2895c7..bbab095e 100644 --- a/test/email.test.js +++ b/test/email.test.js @@ -4,35 +4,35 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../'); -var MyEmail; -var assert = require('assert'); -var MailConnector = require('../lib/connectors/mail'); +const loopback = require('../'); +let MyEmail; +const assert = require('assert'); +const MailConnector = require('../lib/connectors/mail'); describe('Email connector', function() { it('should set up SMTP', function() { - var connector = new MailConnector({transports: [ + const connector = new MailConnector({transports: [ {type: 'smtp', service: 'gmail'}, ]}); assert(connector.transportForName('smtp')); }); it('should set up DIRECT', function() { - var connector = new MailConnector({transports: [ + const connector = new MailConnector({transports: [ {type: 'direct', name: 'localhost'}, ]}); assert(connector.transportForName('direct')); }); it('should set up STUB', function() { - var connector = new MailConnector({transports: [ + const connector = new MailConnector({transports: [ {type: 'stub', service: 'gmail'}, ]}); assert(connector.transportForName('stub')); }); it('should set up a single transport for SMTP', function() { - var connector = new MailConnector({transport: + const connector = new MailConnector({transport: {type: 'smtp', service: 'gmail'}, }); @@ -40,7 +40,7 @@ describe('Email connector', function() { }); it('should set up a aliased transport for SMTP', function() { - var connector = new MailConnector({transport: + const connector = new MailConnector({transport: {type: 'smtp', service: 'ses-us-east-1', alias: 'ses-smtp'}, }); @@ -51,7 +51,7 @@ describe('Email connector', function() { describe('Email and SMTP', function() { beforeEach(function() { MyEmail = loopback.Email.extend('my-email'); - var ds = loopback.createDataSource('email', { + const ds = loopback.createDataSource('email', { connector: loopback.Mail, transports: [{type: 'STUB'}], }); @@ -65,7 +65,7 @@ describe('Email and SMTP', function() { describe('MyEmail', function() { it('MyEmail.send(options, callback)', function(done) { - var options = { + const options = { to: 'to@to.com', from: 'from@from.com', subject: 'subject', @@ -84,7 +84,7 @@ describe('Email and SMTP', function() { }); it('myEmail.send(callback)', function(done) { - var message = new MyEmail({ + const message = new MyEmail({ to: 'to@to.com', from: 'from@from.com', subject: 'subject', diff --git a/test/error-handler.test.js b/test/error-handler.test.js index a5286bba..80671e14 100644 --- a/test/error-handler.test.js +++ b/test/error-handler.test.js @@ -4,11 +4,11 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../'); -var app; -var assert = require('assert'); -var request = require('supertest'); -var expect = require('./helpers/expect'); +const loopback = require('../'); +let app; +const assert = require('assert'); +const request = require('supertest'); +const expect = require('./helpers/expect'); describe('loopback.errorHandler(options)', function() { it('should throw a descriptive error', function() { diff --git a/test/fixtures/access-control/server/server.js b/test/fixtures/access-control/server/server.js index 04916229..02b58058 100644 --- a/test/fixtures/access-control/server/server.js +++ b/test/fixtures/access-control/server/server.js @@ -4,17 +4,17 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../../..'); -var boot = require('loopback-boot'); -var app = module.exports = loopback({ +const loopback = require('../../../..'); +const boot = require('loopback-boot'); +const app = module.exports = loopback({ localRegistry: true, loadBuiltinModels: true, }); -var errorHandler = require('strong-error-handler'); +const errorHandler = require('strong-error-handler'); boot(app, __dirname); -var apiPath = '/api'; +const apiPath = '/api'; app.use(loopback.token({model: app.models.accessToken})); app.use(apiPath, loopback.rest()); diff --git a/test/fixtures/e2e/server/models.js b/test/fixtures/e2e/server/models.js index c6c915bd..9c22fda7 100644 --- a/test/fixtures/e2e/server/models.js +++ b/test/fixtures/e2e/server/models.js @@ -4,8 +4,8 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../../../index'); -var PersistedModel = loopback.PersistedModel; +const loopback = require('../../../../index'); +const PersistedModel = loopback.PersistedModel; exports.TestModel = PersistedModel.extend('TestModel', {}, { trackChanges: true, diff --git a/test/fixtures/e2e/server/server.js b/test/fixtures/e2e/server/server.js index 2acbbf1b..ae7c8f2a 100644 --- a/test/fixtures/e2e/server/server.js +++ b/test/fixtures/e2e/server/server.js @@ -4,12 +4,12 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../../../index'); -var app = module.exports = loopback({localRegistry: true}); -var models = require('./models'); -var TestModel = models.TestModel; +const loopback = require('../../../../index'); +const app = module.exports = loopback({localRegistry: true}); +const models = require('./models'); +const TestModel = models.TestModel; -var apiPath = '/api'; +const apiPath = '/api'; app.use(apiPath, loopback.rest()); TestModel.attachTo(loopback.memory()); diff --git a/test/fixtures/shared-methods/both-configs-set/server/server.js b/test/fixtures/shared-methods/both-configs-set/server/server.js index 882316e0..fae174a7 100644 --- a/test/fixtures/shared-methods/both-configs-set/server/server.js +++ b/test/fixtures/shared-methods/both-configs-set/server/server.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var boot = require('loopback-boot'); -var loopback = require('../../../../../index'); +const boot = require('loopback-boot'); +const loopback = require('../../../../../index'); -var app = module.exports = loopback(); +const app = module.exports = loopback(); boot(app, __dirname); app.use(loopback.rest()); diff --git a/test/fixtures/shared-methods/config-default-false/server/server.js b/test/fixtures/shared-methods/config-default-false/server/server.js index 882316e0..fae174a7 100644 --- a/test/fixtures/shared-methods/config-default-false/server/server.js +++ b/test/fixtures/shared-methods/config-default-false/server/server.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var boot = require('loopback-boot'); -var loopback = require('../../../../../index'); +const boot = require('loopback-boot'); +const loopback = require('../../../../../index'); -var app = module.exports = loopback(); +const app = module.exports = loopback(); boot(app, __dirname); app.use(loopback.rest()); diff --git a/test/fixtures/shared-methods/config-default-true/server/server.js b/test/fixtures/shared-methods/config-default-true/server/server.js index 882316e0..fae174a7 100644 --- a/test/fixtures/shared-methods/config-default-true/server/server.js +++ b/test/fixtures/shared-methods/config-default-true/server/server.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var boot = require('loopback-boot'); -var loopback = require('../../../../../index'); +const boot = require('loopback-boot'); +const loopback = require('../../../../../index'); -var app = module.exports = loopback(); +const app = module.exports = loopback(); boot(app, __dirname); app.use(loopback.rest()); diff --git a/test/fixtures/shared-methods/config-defined-false/server/server.js b/test/fixtures/shared-methods/config-defined-false/server/server.js index 882316e0..fae174a7 100644 --- a/test/fixtures/shared-methods/config-defined-false/server/server.js +++ b/test/fixtures/shared-methods/config-defined-false/server/server.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var boot = require('loopback-boot'); -var loopback = require('../../../../../index'); +const boot = require('loopback-boot'); +const loopback = require('../../../../../index'); -var app = module.exports = loopback(); +const app = module.exports = loopback(); boot(app, __dirname); app.use(loopback.rest()); diff --git a/test/fixtures/shared-methods/config-defined-true/server/server.js b/test/fixtures/shared-methods/config-defined-true/server/server.js index 882316e0..fae174a7 100644 --- a/test/fixtures/shared-methods/config-defined-true/server/server.js +++ b/test/fixtures/shared-methods/config-defined-true/server/server.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var boot = require('loopback-boot'); -var loopback = require('../../../../../index'); +const boot = require('loopback-boot'); +const loopback = require('../../../../../index'); -var app = module.exports = loopback(); +const app = module.exports = loopback(); boot(app, __dirname); app.use(loopback.rest()); diff --git a/test/fixtures/shared-methods/model-config-default-false/server/server.js b/test/fixtures/shared-methods/model-config-default-false/server/server.js index 882316e0..fae174a7 100644 --- a/test/fixtures/shared-methods/model-config-default-false/server/server.js +++ b/test/fixtures/shared-methods/model-config-default-false/server/server.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var boot = require('loopback-boot'); -var loopback = require('../../../../../index'); +const boot = require('loopback-boot'); +const loopback = require('../../../../../index'); -var app = module.exports = loopback(); +const app = module.exports = loopback(); boot(app, __dirname); app.use(loopback.rest()); diff --git a/test/fixtures/shared-methods/model-config-default-true/server/server.js b/test/fixtures/shared-methods/model-config-default-true/server/server.js index 882316e0..fae174a7 100644 --- a/test/fixtures/shared-methods/model-config-default-true/server/server.js +++ b/test/fixtures/shared-methods/model-config-default-true/server/server.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var boot = require('loopback-boot'); -var loopback = require('../../../../../index'); +const boot = require('loopback-boot'); +const loopback = require('../../../../../index'); -var app = module.exports = loopback(); +const app = module.exports = loopback(); boot(app, __dirname); app.use(loopback.rest()); diff --git a/test/fixtures/shared-methods/model-config-defined-false/server/server.js b/test/fixtures/shared-methods/model-config-defined-false/server/server.js index 882316e0..fae174a7 100644 --- a/test/fixtures/shared-methods/model-config-defined-false/server/server.js +++ b/test/fixtures/shared-methods/model-config-defined-false/server/server.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var boot = require('loopback-boot'); -var loopback = require('../../../../../index'); +const boot = require('loopback-boot'); +const loopback = require('../../../../../index'); -var app = module.exports = loopback(); +const app = module.exports = loopback(); boot(app, __dirname); app.use(loopback.rest()); diff --git a/test/fixtures/shared-methods/model-config-defined-true/server/server.js b/test/fixtures/shared-methods/model-config-defined-true/server/server.js index 882316e0..fae174a7 100644 --- a/test/fixtures/shared-methods/model-config-defined-true/server/server.js +++ b/test/fixtures/shared-methods/model-config-defined-true/server/server.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var boot = require('loopback-boot'); -var loopback = require('../../../../../index'); +const boot = require('loopback-boot'); +const loopback = require('../../../../../index'); -var app = module.exports = loopback(); +const app = module.exports = loopback(); boot(app, __dirname); app.use(loopback.rest()); diff --git a/test/fixtures/simple-integration-app/server/server.js b/test/fixtures/simple-integration-app/server/server.js index a966c097..b9873a3a 100644 --- a/test/fixtures/simple-integration-app/server/server.js +++ b/test/fixtures/simple-integration-app/server/server.js @@ -4,13 +4,13 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../../../index'); -var boot = require('loopback-boot'); -var app = module.exports = loopback({localRegistry: true}); -var errorHandler = require('strong-error-handler'); +const loopback = require('../../../../index'); +const boot = require('loopback-boot'); +const app = module.exports = loopback({localRegistry: true}); +const errorHandler = require('strong-error-handler'); boot(app, __dirname); -var apiPath = '/api'; +const apiPath = '/api'; app.use(apiPath, loopback.rest()); app.use(loopback.urlNotFound()); app.use(errorHandler()); diff --git a/test/fixtures/user-integration-app/server/server.js b/test/fixtures/user-integration-app/server/server.js index bf1bae39..ed5a0dc1 100644 --- a/test/fixtures/user-integration-app/server/server.js +++ b/test/fixtures/user-integration-app/server/server.js @@ -4,18 +4,18 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../../../index'); -var boot = require('loopback-boot'); -var app = module.exports = loopback({ +const loopback = require('../../../../index'); +const boot = require('loopback-boot'); +const app = module.exports = loopback({ localRegistry: true, loadBuiltinModels: true, }); -var errorHandler = require('strong-error-handler'); +const errorHandler = require('strong-error-handler'); app.enableAuth(); boot(app, __dirname); app.use(loopback.token({model: app.models.AccessToken})); -var apiPath = '/api'; +const apiPath = '/api'; app.use(apiPath, loopback.rest()); app.use(loopback.urlNotFound()); app.use(errorHandler()); diff --git a/test/geo-point.test.js b/test/geo-point.test.js index de317844..cb611ebe 100644 --- a/test/geo-point.test.js +++ b/test/geo-point.test.js @@ -4,16 +4,16 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var loopback = require('../'); -var GeoPoint = loopback.GeoPoint; +const assert = require('assert'); +const loopback = require('../'); +const GeoPoint = loopback.GeoPoint; describe('GeoPoint', function() { describe('geoPoint.distanceTo(geoPoint, options)', function() { it('Get the distance to another `GeoPoint`', function() { - var here = new GeoPoint({lat: 10, lng: 10}); - var there = new GeoPoint({lat: 5, lng: 5}); - var distance = here.distanceTo(there, {type: 'meters'}); + const here = new GeoPoint({lat: 10, lng: 10}); + const there = new GeoPoint({lat: 5, lng: 5}); + const distance = here.distanceTo(there, {type: 'meters'}); assert.equal(Math.floor(distance), 782777); }); @@ -21,9 +21,9 @@ describe('GeoPoint', function() { describe('GeoPoint.distanceBetween(a, b, options)', function() { it('Get the distance between two points', function() { - var here = new GeoPoint({lat: 10, lng: 10}); - var there = new GeoPoint({lat: 5, lng: 5}); - var distance = GeoPoint.distanceBetween(here, there, {type: 'feet'}); + const here = new GeoPoint({lat: 10, lng: 10}); + const there = new GeoPoint({lat: 5, lng: 5}); + const distance = GeoPoint.distanceBetween(here, there, {type: 'feet'}); assert.equal(Math.floor(distance), 2568169); }); @@ -31,32 +31,32 @@ describe('GeoPoint', function() { describe('GeoPoint()', function() { it('Create from string', function() { - var point = new GeoPoint('1.234,5.678'); + const point = new GeoPoint('1.234,5.678'); assert.equal(point.lat, 1.234); assert.equal(point.lng, 5.678); - var point2 = new GeoPoint('1.222, 5.333'); + const point2 = new GeoPoint('1.222, 5.333'); assert.equal(point2.lat, 1.222); assert.equal(point2.lng, 5.333); - var point3 = new GeoPoint('1.333, 5.111'); + const point3 = new GeoPoint('1.333, 5.111'); assert.equal(point3.lat, 1.333); assert.equal(point3.lng, 5.111); }); it('Serialize as string', function() { - var str = '1.234,5.678'; - var point = new GeoPoint(str); + const str = '1.234,5.678'; + const point = new GeoPoint(str); assert.equal(point.toString(), str); }); it('Create from array', function() { - var point = new GeoPoint([5.555, 6.777]); + const point = new GeoPoint([5.555, 6.777]); assert.equal(point.lat, 5.555); assert.equal(point.lng, 6.777); }); it('Create as Model property', function() { - var Model = loopback.createModel('geo-model', { + const Model = loopback.createModel('geo-model', { geo: {type: 'GeoPoint'}, }); - var m = new Model({ + const m = new Model({ geo: '1.222,3.444', }); diff --git a/test/helpers/expect.js b/test/helpers/expect.js index dc40aa79..0931b6c9 100644 --- a/test/helpers/expect.js +++ b/test/helpers/expect.js @@ -5,7 +5,7 @@ 'use strict'; -var chai = require('chai'); +const chai = require('chai'); chai.use(require('dirty-chai')); chai.use(require('sinon-chai')); diff --git a/test/helpers/loopback-testing-helper.js b/test/helpers/loopback-testing-helper.js index 9b2dde7b..e480a36a 100644 --- a/test/helpers/loopback-testing-helper.js +++ b/test/helpers/loopback-testing-helper.js @@ -4,21 +4,21 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var _describe = {}; -var _it = {}; -var _beforeEach = {}; -var helpers = { +const _describe = {}; +const _it = {}; +const _beforeEach = {}; +const helpers = { describe: _describe, it: _it, beforeEach: _beforeEach, }; module.exports = helpers; -var assert = require('assert'); -var request = require('supertest'); -var chai = require('chai'); -var expect = chai.expect; -var sinon = require('sinon'); +const assert = require('assert'); +const request = require('supertest'); +const chai = require('chai'); +const expect = chai.expect; +const sinon = require('sinon'); chai.use(require('sinon-chai')); _beforeEach.withApp = function(app) { @@ -29,7 +29,7 @@ _beforeEach.withApp = function(app) { beforeEach(function(done) { this.app = app; - var _request = this.request = request(app); + const _request = this.request = request(app); this.post = _request.post; this.get = _request.get; this.put = _request.put; @@ -45,14 +45,14 @@ _beforeEach.withApp = function(app) { }; _beforeEach.withArgs = function() { - var args = Array.prototype.slice.call(arguments, 0); + const args = Array.prototype.slice.call(arguments, 0); beforeEach(function() { this.args = args; }); }; _beforeEach.givenModel = function(modelName, attrs, optionalHandler) { - var modelKey = modelName; + let modelKey = modelName; if (typeof attrs === 'function') { optionalHandler = attrs; @@ -66,9 +66,9 @@ _beforeEach.givenModel = function(modelName, attrs, optionalHandler) { attrs = attrs || {}; beforeEach(function(done) { - var test = this; - var app = this.app; - var model = app.models[modelName]; + const test = this; + const app = this.app; + const model = app.models[modelName]; app.set('remoting', {errorHandler: {debug: true, log: false}}); assert(model, 'cannot get model of name ' + modelName + ' from app.models'); @@ -108,7 +108,7 @@ _beforeEach.givenUser = function(attrs, optionalHandler) { _beforeEach.givenLoggedInUser = function(credentials, optionalHandler) { _beforeEach.givenUser(credentials, function(done) { - var test = this; + const test = this; this.user.constructor.login(credentials, function(err, token) { if (err) { done(err); @@ -121,7 +121,7 @@ _beforeEach.givenLoggedInUser = function(credentials, optionalHandler) { }); afterEach(function(done) { - var test = this; + const test = this; this.loggedInAccessToken.destroy(function(err) { if (err) return done(err); @@ -146,7 +146,7 @@ _describe.whenCalledRemotely = function(verb, url, data, cb) { data = null; } - var urlStr = url; + let urlStr = url; if (typeof url === 'function') { urlStr = '/'; } @@ -159,11 +159,11 @@ _describe.whenCalledRemotely = function(verb, url, data, cb) { this.remotely = true; this.verb = verb.toUpperCase(); this.url = this.url || url; - var methodForVerb = verb.toLowerCase(); + let methodForVerb = verb.toLowerCase(); if (methodForVerb === 'delete') methodForVerb = 'del'; if (this.request === undefined) { - var msg = 'App is not specified. ' + + const msg = 'App is not specified. ' + 'Please use lt.beforeEach.withApp to specify the app.'; throw new Error(msg); } @@ -175,13 +175,13 @@ _describe.whenCalledRemotely = function(verb, url, data, cb) { this.http.set('authorization', this.loggedInAccessToken.id); } if (data) { - var payload = data; + let payload = data; if (typeof data === 'function') payload = data.call(this); this.http.send(payload); } this.req = this.http.req; - var test = this; + const test = this; this.http.end(function(err) { test.req = test.http.req; test.res = test.http.response; @@ -236,7 +236,7 @@ _it.shouldBeAllowed = function() { _it.shouldBeDenied = function() { it('should not be allowed', function() { assert(this.res); - var expectedStatus = this.aclErrorStatus || + const expectedStatus = this.aclErrorStatus || this.app && this.app.get('aclErrorStatus') || 401; expect(this.res.statusCode).to.equal(expectedStatus); diff --git a/test/helpers/use-english.js b/test/helpers/use-english.js index bec0d0ed..9091de72 100644 --- a/test/helpers/use-english.js +++ b/test/helpers/use-english.js @@ -5,7 +5,7 @@ 'use strict'; -var env = process.env; +const env = process.env; // delete any user-provided language settings delete env.LC_ALL; diff --git a/test/hidden-properties.test.js b/test/hidden-properties.test.js index 9d35ef2c..96f2d929 100644 --- a/test/hidden-properties.test.js +++ b/test/hidden-properties.test.js @@ -4,21 +4,21 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var loopback = require('../'); -var request = require('supertest'); +const assert = require('assert'); +const loopback = require('../'); +const request = require('supertest'); describe('hidden properties', function() { beforeEach(function(done) { - var app = this.app = loopback(); - var Product = this.Product = loopback.PersistedModel.extend( + const app = this.app = loopback(); + const Product = this.Product = loopback.PersistedModel.extend( 'product', {}, {hidden: ['secret']} ); Product.attachTo(loopback.memory()); - var Category = this.Category = loopback.PersistedModel.extend('category'); + const Category = this.Category = loopback.PersistedModel.extend('category'); Category.attachTo(loopback.memory()); Category.hasMany(Product); @@ -37,7 +37,7 @@ describe('hidden properties', function() { }); afterEach(function(done) { - var Product = this.Product; + const Product = this.Product; this.Category.destroyAll(function() { Product.destroyAll(done); }); @@ -51,7 +51,7 @@ describe('hidden properties', function() { .end(function(err, res) { if (err) return done(err); - var product = res.body[0]; + const product = res.body[0]; assert.equal(product.secret, undefined); done(); @@ -59,7 +59,7 @@ describe('hidden properties', function() { }); it('should hide a property of nested models', function(done) { - var app = this.app; + const app = this.app; request(app) .get('/categories?filter[include]=products') .expect('Content-Type', /json/) @@ -67,8 +67,8 @@ describe('hidden properties', function() { .end(function(err, res) { if (err) return done(err); - var category = res.body[0]; - var product = category.products[0]; + const category = res.body[0]; + const product = category.products[0]; assert.equal(product.secret, undefined); done(); diff --git a/test/integration.test.js b/test/integration.test.js index 9b396697..0c8103e8 100644 --- a/test/integration.test.js +++ b/test/integration.test.js @@ -4,15 +4,15 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var expect = require('./helpers/expect'); -var loopback = require('../'); -var net = require('net'); +const expect = require('./helpers/expect'); +const loopback = require('../'); +const net = require('net'); describe('loopback application', function() { it('pauses request stream during authentication', function(done) { // This test reproduces the issue reported in // https://github.com/strongloop/loopback-storage-service/issues/7 - var app = loopback(); + const app = loopback(); setupAppWithStreamingMethod(); app.listen(0, function() { @@ -37,7 +37,7 @@ describe('loopback application', function() { app.dataSource('db', { connector: loopback.Memory, }); - var db = app.datasources.db; + const db = app.datasources.db; loopback.User.attachTo(db); loopback.AccessToken.attachTo(db); @@ -45,10 +45,10 @@ describe('loopback application', function() { loopback.ACL.attachTo(db); loopback.User.hasMany(loopback.AccessToken, {as: 'accessTokens'}); - var Streamer = app.registry.createModel('Streamer'); + const Streamer = app.registry.createModel('Streamer'); app.model(Streamer, {dataSource: 'db'}); Streamer.read = function(req, res, cb) { - var body = new Buffer(0); + let body = new Buffer(0); req.on('data', function(chunk) { body += chunk; }); @@ -75,8 +75,8 @@ describe('loopback application', function() { } function sendHttpRequestInOnePacket(port, reqString, cb) { - var socket = net.createConnection(port); - var response = new Buffer(0); + const socket = net.createConnection(port); + let response = new Buffer(0); socket.on('data', function(chunk) { response += chunk; diff --git a/test/key-value-model.test.js b/test/key-value-model.test.js index adf2b3f4..54a8a04b 100644 --- a/test/key-value-model.test.js +++ b/test/key-value-model.test.js @@ -4,15 +4,15 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var expect = require('./helpers/expect'); -var http = require('http'); -var loopback = require('..'); -var supertest = require('supertest'); +const expect = require('./helpers/expect'); +const http = require('http'); +const loopback = require('..'); +const supertest = require('supertest'); -var AN_OBJECT_VALUE = {name: 'an-object'}; +const AN_OBJECT_VALUE = {name: 'an-object'}; describe('KeyValueModel', function() { - var request, app, CacheItem; + let request, app, CacheItem; beforeEach(setupAppAndCacheItem); describe('REST API', function() { @@ -156,7 +156,7 @@ describe('KeyValueModel', function() { app.model(CacheItem, {dataSource: 'kv'}); } - var _server, _requestHandler; // eslint-disable-line one-var + let _server, _requestHandler; // eslint-disable-line one-var function setupSharedHttpServer(done) { _server = http.createServer(function(req, res) { app(req, res); diff --git a/test/loopback.test.js b/test/loopback.test.js index 79733345..71560552 100644 --- a/test/loopback.test.js +++ b/test/loopback.test.js @@ -4,17 +4,17 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var it = require('./util/it'); -var describe = require('./util/describe'); -var Domain = require('domain'); -var EventEmitter = require('events').EventEmitter; -var loopback = require('../'); -var expect = require('./helpers/expect'); -var assert = require('assert'); +const it = require('./util/it'); +const describe = require('./util/describe'); +const Domain = require('domain'); +const EventEmitter = require('events').EventEmitter; +const loopback = require('../'); +const expect = require('./helpers/expect'); +const assert = require('assert'); describe('loopback', function() { - var nameCounter = 0; - var uniqueModelName; + let nameCounter = 0; + let uniqueModelName; beforeEach(function() { uniqueModelName = 'TestModel-' + (++nameCounter); @@ -27,7 +27,7 @@ describe('loopback', function() { }); it.onServer('includes `faviconFile`', function() { - var file = loopback.faviconFile; + const file = loopback.faviconFile; expect(file, 'faviconFile').to.not.equal(undefined); expect(require('fs').existsSync(loopback.faviconFile), 'file exists') .to.equal(true); @@ -38,7 +38,7 @@ describe('loopback', function() { }); it.onServer('exports all expected properties', function() { - var EXPECTED = [ + const EXPECTED = [ 'ACL', 'AccessToken', 'Application', @@ -98,7 +98,7 @@ describe('loopback', function() { 'version', ]; - var actual = Object.getOwnPropertyNames(loopback); + const actual = Object.getOwnPropertyNames(loopback); actual.sort(); expect(actual).to.include.members(EXPECTED); }); @@ -106,17 +106,17 @@ describe('loopback', function() { describe('loopback(options)', function() { it('supports localRegistry:true', function() { - var app = loopback({localRegistry: true}); + const app = loopback({localRegistry: true}); expect(app.registry).to.not.equal(loopback.registry); }); it('does not load builtin models into the local registry', function() { - var app = loopback({localRegistry: true}); + const app = loopback({localRegistry: true}); expect(app.registry.findModel('User')).to.equal(undefined); }); it('supports loadBuiltinModels:true', function() { - var app = loopback({localRegistry: true, loadBuiltinModels: true}); + const app = loopback({localRegistry: true, loadBuiltinModels: true}); expect(app.registry.findModel('User')) .to.have.property('modelName', 'User'); }); @@ -124,7 +124,7 @@ describe('loopback', function() { describe('loopback.createDataSource(options)', function() { it('Create a data source with a connector.', function() { - var dataSource = loopback.createDataSource({ + const dataSource = loopback.createDataSource({ connector: loopback.Memory, }); assert(dataSource.connector); @@ -133,24 +133,24 @@ describe('loopback', function() { describe('data source created by loopback', function() { it('should create model extending Model by default', function() { - var dataSource = loopback.createDataSource({ + const dataSource = loopback.createDataSource({ connector: loopback.Memory, }); - var m1 = dataSource.createModel('m1', {}); + const m1 = dataSource.createModel('m1', {}); assert(m1.prototype instanceof loopback.Model); }); }); describe('model created by loopback', function() { it('should extend from Model by default', function() { - var m1 = loopback.createModel('m1', {}); + const m1 = loopback.createModel('m1', {}); assert(m1.prototype instanceof loopback.Model); }); }); describe('loopback.remoteMethod(Model, fn, [options]);', function() { it('Setup a remote method.', function() { - var Product = loopback.createModel('product', {price: Number}); + const Product = loopback.createModel('product', {price: Number}); Product.stats = function(fn) { // ... @@ -175,12 +175,12 @@ describe('loopback', function() { describe('loopback.createModel(name, properties, options)', function() { describe('options.base', function() { it('should extend from options.base', function() { - var MyModel = loopback.createModel('MyModel', {}, { + const MyModel = loopback.createModel('MyModel', {}, { foo: { bar: 'bat', }, }); - var MyCustomModel = loopback.createModel('MyCustomModel', {}, { + const MyCustomModel = loopback.createModel('MyCustomModel', {}, { base: 'MyModel', foo: { bat: 'baz', @@ -194,12 +194,12 @@ describe('loopback', function() { describe('loopback.getModel and getModelByType', function() { it('should be able to get model by name', function() { - var MyModel = loopback.createModel('MyModel', {}, { + const MyModel = loopback.createModel('MyModel', {}, { foo: { bar: 'bat', }, }); - var MyCustomModel = loopback.createModel('MyCustomModel', {}, { + const MyCustomModel = loopback.createModel('MyCustomModel', {}, { base: 'MyModel', foo: { bat: 'baz', @@ -211,12 +211,12 @@ describe('loopback', function() { assert(loopback.getModel(MyModel) === MyModel); }); it('should be able to get model by type', function() { - var MyModel = loopback.createModel('MyModel', {}, { + const MyModel = loopback.createModel('MyModel', {}, { foo: { bar: 'bat', }, }); - var MyCustomModel = loopback.createModel('MyCustomModel', {}, { + const MyCustomModel = loopback.createModel('MyCustomModel', {}, { base: 'MyModel', foo: { bat: 'baz', @@ -233,7 +233,7 @@ describe('loopback', function() { }); it('configures remote methods', function() { - var TestModel = loopback.createModel(uniqueModelName, {}, { + const TestModel = loopback.createModel(uniqueModelName, {}, { methods: { staticMethod: { isStatic: true, @@ -246,7 +246,7 @@ describe('loopback', function() { }, }); - var methodNames = TestModel.sharedClass.methods().map(function(m) { + const methodNames = TestModel.sharedClass.methods().map(function(m) { return m.stringName.replace(/^[^.]+\./, ''); // drop the class name }); @@ -259,7 +259,7 @@ describe('loopback', function() { describe('loopback.createModel(config)', function() { it('creates the model', function() { - var model = loopback.createModel({ + const model = loopback.createModel({ name: uniqueModelName, }); @@ -267,7 +267,7 @@ describe('loopback', function() { }); it('interprets extra first-level keys as options', function() { - var model = loopback.createModel({ + const model = loopback.createModel({ name: uniqueModelName, base: 'User', }); @@ -276,7 +276,7 @@ describe('loopback', function() { }); it('prefers config.options.key over config.key', function() { - var model = loopback.createModel({ + const model = loopback.createModel({ name: uniqueModelName, base: 'User', options: { @@ -290,7 +290,7 @@ describe('loopback', function() { describe('loopback.configureModel(ModelCtor, config)', function() { it('adds new relations', function() { - var model = loopback.Model.extend(uniqueModelName); + const model = loopback.Model.extend(uniqueModelName); loopback.configureModel(model, { dataSource: null, @@ -306,7 +306,7 @@ describe('loopback', function() { }); it('updates existing relations', function() { - var model = loopback.Model.extend(uniqueModelName, {}, { + const model = loopback.Model.extend(uniqueModelName, {}, { relations: { owner: { type: 'belongsTo', @@ -331,8 +331,8 @@ describe('loopback', function() { }); it('updates relations before attaching to a dataSource', function() { - var db = loopback.createDataSource({connector: loopback.Memory}); - var model = loopback.Model.extend(uniqueModelName); + const db = loopback.createDataSource({connector: loopback.Memory}); + const model = loopback.Model.extend(uniqueModelName); // This test used to work because User model was already attached // by other tests via `loopback.autoAttach()` @@ -352,13 +352,13 @@ describe('loopback', function() { }, }); - var owner = model.prototype.owner; + const owner = model.prototype.owner; expect(owner, 'model.prototype.owner').to.be.a('function'); expect(owner._targetClass).to.equal('User'); }); it('adds new acls', function() { - var model = loopback.Model.extend(uniqueModelName, {}, { + const model = loopback.Model.extend(uniqueModelName, {}, { acls: [ { property: 'find', @@ -402,7 +402,7 @@ describe('loopback', function() { }); it('updates existing acls', function() { - var model = loopback.Model.extend(uniqueModelName, {}, { + const model = loopback.Model.extend(uniqueModelName, {}, { acls: [ { property: 'find', @@ -439,12 +439,12 @@ describe('loopback', function() { }); it('updates existing settings', function() { - var model = loopback.Model.extend(uniqueModelName, {}, { + const model = loopback.Model.extend(uniqueModelName, {}, { ttl: 10, emailVerificationRequired: false, }); - var baseName = model.settings.base.name; + const baseName = model.settings.base.name; loopback.configureModel(model, { dataSource: null, @@ -465,7 +465,7 @@ describe('loopback', function() { }); it('configures remote methods', function() { - var TestModel = loopback.createModel(uniqueModelName); + const TestModel = loopback.createModel(uniqueModelName); loopback.configureModel(TestModel, { dataSource: null, methods: { @@ -480,7 +480,7 @@ describe('loopback', function() { }, }); - var methodNames = TestModel.sharedClass.methods().map(function(m) { + const methodNames = TestModel.sharedClass.methods().map(function(m) { return m.stringName.replace(/^[^.]+\./, ''); // drop the class name }); @@ -493,14 +493,14 @@ describe('loopback', function() { describe('loopback object', function() { it('inherits properties from express', function() { - var express = require('express'); - for (var i in express) { + const express = require('express'); + for (const i in express) { expect(loopback).to.have.property(i, express[i]); } }); it('exports all built-in models', function() { - var expectedModelNames = [ + const expectedModelNames = [ 'Email', 'User', 'Application', @@ -530,7 +530,7 @@ describe('loopback', function() { } it('treats method names that don\'t start with "prototype." as "isStatic:true"', function() { - var TestModel = loopback.createModel(uniqueModelName); + const TestModel = loopback.createModel(uniqueModelName); loopback.configureModel(TestModel, { dataSource: null, methods: { @@ -540,13 +540,13 @@ describe('loopback', function() { }, }); - var methodNames = getAllMethodNamesWithoutClassName(TestModel); + const methodNames = getAllMethodNamesWithoutClassName(TestModel); expect(methodNames).to.include('staticMethod'); }); it('treats method names starting with "prototype." as "isStatic:false"', function() { - var TestModel = loopback.createModel(uniqueModelName); + const TestModel = loopback.createModel(uniqueModelName); loopback.configureModel(TestModel, { dataSource: null, methods: { @@ -556,13 +556,15 @@ describe('loopback', function() { }, }); - var methodNames = getAllMethodNamesWithoutClassName(TestModel); + const methodNames = getAllMethodNamesWithoutClassName(TestModel); expect(methodNames).to.include('prototype.instanceMethod'); }); - it('throws an error when "isStatic:true" and method name starts with "prototype."', function() { - var TestModel = loopback.createModel(uniqueModelName); + // Skip this test in browsers because strong-globalize is not removing + // `{{` and `}}` control characters from the string. + it.onServer('throws when "isStatic:true" and method name starts with "prototype."', function() { + const TestModel = loopback.createModel(uniqueModelName); expect(function() { loopback.configureModel(TestModel, { dataSource: null, @@ -573,12 +575,12 @@ describe('loopback', function() { }, }, }); - }).to.throw(Error, new Error('Remoting metadata for' + TestModel.modelName + - ' "isStatic" does not match new method name-based style.')); + }).to.throw(Error, 'Remoting metadata for ' + TestModel.modelName + + '.prototype.instanceMethod "isStatic" does not match new method name-based style.'); }); it('use "isStatic:true" if method name does not start with "prototype."', function() { - var TestModel = loopback.createModel(uniqueModelName); + const TestModel = loopback.createModel(uniqueModelName); loopback.configureModel(TestModel, { dataSource: null, methods: { @@ -589,13 +591,13 @@ describe('loopback', function() { }, }); - var methodNames = getAllMethodNamesWithoutClassName(TestModel); + const methodNames = getAllMethodNamesWithoutClassName(TestModel); expect(methodNames).to.include('staticMethod'); }); it('use "isStatic:false" if method name starts with "prototype."', function() { - var TestModel = loopback.createModel(uniqueModelName); + const TestModel = loopback.createModel(uniqueModelName); loopback.configureModel(TestModel, { dataSource: null, methods: { @@ -606,19 +608,19 @@ describe('loopback', function() { }, }); - var methodNames = getAllMethodNamesWithoutClassName(TestModel); + const methodNames = getAllMethodNamesWithoutClassName(TestModel); expect(methodNames).to.include('prototype.instanceMethod'); }); }); describe('Remote method inheritance', function() { - var app; + let app; beforeEach(setupLoopback); it('inherits remote methods defined via createModel', function() { - var Base = app.registry.createModel('Base', {}, { + const Base = app.registry.createModel('Base', {}, { methods: { greet: { http: {path: '/greet'}, @@ -626,7 +628,7 @@ describe('loopback', function() { }, }); - var MyCustomModel = app.registry.createModel('MyCustomModel', {}, { + const MyCustomModel = app.registry.createModel('MyCustomModel', {}, { base: 'Base', methods: { hello: { @@ -634,14 +636,14 @@ describe('loopback', function() { }, }, }); - var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel); + const methodNames = getAllMethodNamesWithoutClassName(MyCustomModel); expect(methodNames).to.include('greet'); expect(methodNames).to.include('hello'); }); it('same remote method with different metadata should override parent', function() { - var Base = app.registry.createModel('Base', {}, { + const Base = app.registry.createModel('Base', {}, { methods: { greet: { http: {path: '/greet'}, @@ -649,7 +651,7 @@ describe('loopback', function() { }, }); - var MyCustomModel = app.registry.createModel('MyCustomModel', {}, { + const MyCustomModel = app.registry.createModel('MyCustomModel', {}, { base: 'Base', methods: { greet: { @@ -657,9 +659,9 @@ describe('loopback', function() { }, }, }); - var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel); - var baseMethod = Base.sharedClass.findMethodByName('greet'); - var customMethod = MyCustomModel.sharedClass.findMethodByName('greet'); + const methodNames = getAllMethodNamesWithoutClassName(MyCustomModel); + const baseMethod = Base.sharedClass.findMethodByName('greet'); + const customMethod = MyCustomModel.sharedClass.findMethodByName('greet'); // Base Method expect(baseMethod.http).to.eql({path: '/greet'}); @@ -674,7 +676,7 @@ describe('loopback', function() { }); it('does not inherit remote methods defined via configureModel', function() { - var Base = app.registry.createModel('Base'); + const Base = app.registry.createModel('Base'); app.registry.configureModel(Base, { dataSource: null, methods: { @@ -684,7 +686,7 @@ describe('loopback', function() { }, }); - var MyCustomModel = app.registry.createModel('MyCustomModel', {}, { + const MyCustomModel = app.registry.createModel('MyCustomModel', {}, { base: 'Base', methods: { hello: { @@ -692,7 +694,7 @@ describe('loopback', function() { }, }, }); - var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel); + const methodNames = getAllMethodNamesWithoutClassName(MyCustomModel); expect(methodNames).to.not.include('greet'); expect(methodNames).to.include('hello'); @@ -700,8 +702,8 @@ describe('loopback', function() { it('does not inherit remote methods defined via configureModel after child model ' + 'was created', function() { - var Base = app.registry.createModel('Base'); - var MyCustomModel = app.registry.createModel('MyCustomModel', {}, { + const Base = app.registry.createModel('Base'); + const MyCustomModel = app.registry.createModel('MyCustomModel', {}, { base: 'Base', }); @@ -722,8 +724,8 @@ describe('loopback', function() { }, }, }); - var baseMethodNames = getAllMethodNamesWithoutClassName(Base); - var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel); + const baseMethodNames = getAllMethodNamesWithoutClassName(Base); + const methodNames = getAllMethodNamesWithoutClassName(MyCustomModel); expect(baseMethodNames).to.include('greet'); expect(methodNames).to.not.include('greet'); @@ -742,12 +744,12 @@ describe('loopback', function() { }); describe('Hiding shared methods', function() { - var app; + let app; beforeEach(setupLoopback); it('hides remote methods using fixed method names', function() { - var TestModel = app.registry.createModel(uniqueModelName); + const TestModel = app.registry.createModel(uniqueModelName); app.model(TestModel, { dataSource: null, methods: { @@ -765,7 +767,7 @@ describe('loopback', function() { }, }); - var publicMethods = getSharedMethods(TestModel); + const publicMethods = getSharedMethods(TestModel); expect(publicMethods).not.to.include.members([ 'staticMethod', @@ -773,7 +775,7 @@ describe('loopback', function() { }); it('hides remote methods using a glob pattern', function() { - var TestModel = app.registry.createModel(uniqueModelName); + const TestModel = app.registry.createModel(uniqueModelName); app.model(TestModel, { dataSource: null, methods: { @@ -795,7 +797,7 @@ describe('loopback', function() { }, }); - var publicMethods = getSharedMethods(TestModel); + const publicMethods = getSharedMethods(TestModel); expect(publicMethods).to.include.members([ 'staticMethod', @@ -806,7 +808,7 @@ describe('loopback', function() { }); it('hides all remote methods using *', function() { - var TestModel = app.registry.createModel(uniqueModelName); + const TestModel = app.registry.createModel(uniqueModelName); app.model(TestModel, { dataSource: null, methods: { @@ -828,7 +830,7 @@ describe('loopback', function() { }, }); - var publicMethods = getSharedMethods(TestModel); + const publicMethods = getSharedMethods(TestModel); expect(publicMethods).to.be.empty(); }); diff --git a/test/memory.test.js b/test/memory.test.js index 44e1f0c2..3ae36fba 100644 --- a/test/memory.test.js +++ b/test/memory.test.js @@ -4,14 +4,14 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var loopback = require('../'); +const assert = require('assert'); +const loopback = require('../'); describe('Memory Connector', function() { it('Create a model using the memory connector', function(done) { // use the built in memory function // to create a memory data source - var memory = loopback.memory(); + let memory = loopback.memory(); // or create it using the standard // data source creation api @@ -21,12 +21,12 @@ describe('Memory Connector', function() { // create a model using the // memory data source - var properties = { + const properties = { name: String, price: Number, }; - var Product = memory.createModel('product', properties); + const Product = memory.createModel('product', properties); Product.create([ {name: 'apple', price: 0.79}, diff --git a/test/model.application.test.js b/test/model.application.test.js index 8ab3d408..d8eba8be 100644 --- a/test/model.application.test.js +++ b/test/model.application.test.js @@ -4,12 +4,12 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require(('../')); -var assert = require('assert'); -var Application = loopback.Application; +const loopback = require(('../')); +const assert = require('assert'); +const Application = loopback.Application; describe('Application', function() { - var registeredApp = null; + let registeredApp = null; before(function attachToMemory() { Application.attachTo(loopback.memory()); @@ -18,7 +18,7 @@ describe('Application', function() { it('honors `application.register` - callback variant', function(done) { Application.register('rfeng', 'MyTestApp', {description: 'My test application'}, function(err, result) { - var app = result; + const app = result; assert.equal(app.owner, 'rfeng'); assert.equal(app.name, 'MyTestApp'); assert.equal(app.description, 'My test application'); @@ -31,7 +31,7 @@ describe('Application', function() { Application.register('rfeng', 'MyTestApp', {description: 'My test application'}) .then(function(result) { - var app = result; + const app = result; assert.equal(app.owner, 'rfeng'); assert.equal(app.name, 'MyTestApp'); assert.equal(app.description, 'My test application'); @@ -47,7 +47,7 @@ describe('Application', function() { Application.create({owner: 'rfeng', name: 'MyApp1', description: 'My first mobile application'}, function(err, result) { - var app = result; + const app = result; assert.equal(app.owner, 'rfeng'); assert.equal(app.name, 'MyApp1'); assert.equal(app.description, 'My first mobile application'); @@ -90,7 +90,7 @@ describe('Application', function() { }, }}, function(err, result) { - var app = result; + const app = result; assert.deepEqual(app.pushSettings.toObject(), { apns: { production: false, @@ -119,7 +119,7 @@ describe('Application', function() { beforeEach(function(done) { Application.register('rfeng', 'MyApp2', {description: 'My second mobile application'}, function(err, result) { - var app = result; + const app = result; assert.equal(app.owner, 'rfeng'); assert.equal(app.name, 'MyApp2'); assert.equal(app.description, 'My second mobile application'); @@ -138,7 +138,7 @@ describe('Application', function() { it('Reset keys', function(done) { Application.resetKeys(registeredApp.id, function(err, result) { - var app = result; + const app = result; assert.equal(app.owner, 'rfeng'); assert.equal(app.name, 'MyApp2'); assert.equal(app.description, 'My second mobile application'); @@ -165,7 +165,7 @@ describe('Application', function() { it('Reset keys - promise variant', function(done) { Application.resetKeys(registeredApp.id) .then(function(result) { - var app = result; + const app = result; assert.equal(app.owner, 'rfeng'); assert.equal(app.name, 'MyApp2'); assert.equal(app.description, 'My second mobile application'); @@ -194,7 +194,7 @@ describe('Application', function() { it('Reset keys without create a new instance', function(done) { Application.resetKeys(registeredApp.id, function(err, result) { - var app = result; + const app = result; assert(app.id); assert(app.id === registeredApp.id); registeredApp = app; @@ -206,7 +206,7 @@ describe('Application', function() { it('Reset keys without create a new instance - promise variant', function(done) { Application.resetKeys(registeredApp.id) .then(function(result) { - var app = result; + const app = result; assert(app.id); assert(app.id === registeredApp.id); registeredApp = app; @@ -307,12 +307,12 @@ describe('Application', function() { describe('Application subclass', function() { it('should use subclass model name', function(done) { - var MyApp = Application.extend('MyApp'); - var ds = loopback.createDataSource({connector: loopback.Memory}); + const MyApp = Application.extend('MyApp'); + const ds = loopback.createDataSource({connector: loopback.Memory}); MyApp.attachTo(ds); MyApp.register('rfeng', 'MyApp123', {description: 'My 123 mobile application'}, function(err, result) { - var app = result; + const app = result; assert.equal(app.owner, 'rfeng'); assert.equal(app.name, 'MyApp123'); assert.equal(app.description, 'My 123 mobile application'); diff --git a/test/model.test.js b/test/model.test.js index bdebedc0..fd4076a1 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -4,18 +4,18 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var async = require('async'); -var describe = require('./util/describe'); -var loopback = require('../'); -var ACL = loopback.ACL; -var defineModelTestsWithDataSource = require('./util/model-tests'); -var PersistedModel = loopback.PersistedModel; -var Promise = require('bluebird'); -var TaskEmitter = require('strong-task-emitter'); -var request = require('supertest'); +const assert = require('assert'); +const async = require('async'); +const describe = require('./util/describe'); +const loopback = require('../'); +const ACL = loopback.ACL; +const defineModelTestsWithDataSource = require('./util/model-tests'); +const PersistedModel = loopback.PersistedModel; +const Promise = require('bluebird'); +const TaskEmitter = require('strong-task-emitter'); +const request = require('supertest'); -var expect = require('./helpers/expect'); +const expect = require('./helpers/expect'); describe('Model / PersistedModel', function() { defineModelTestsWithDataSource({ @@ -26,7 +26,7 @@ describe('Model / PersistedModel', function() { describe('Model.validatesUniquenessOf(property, options)', function() { it('Ensure the value for `property` is unique', function(done) { - var User = PersistedModel.extend('ValidatedUser', { + const User = PersistedModel.extend('ValidatedUser', { 'first': String, 'last': String, 'age': Number, @@ -36,7 +36,7 @@ describe('Model / PersistedModel', function() { 'email': String, }); - var dataSource = loopback.createDataSource({ + const dataSource = loopback.createDataSource({ connector: loopback.Memory, }); @@ -44,8 +44,8 @@ describe('Model / PersistedModel', function() { User.validatesUniquenessOf('email', {message: 'email is not unique'}); - var joe = new User({email: 'joe@joe.com'}); - var joe2 = new User({email: 'joe@joe.com'}); + const joe = new User({email: 'joe@joe.com'}); + const joe2 = new User({email: 'joe@joe.com'}); joe.save(function() { joe2.save(function(err) { @@ -60,8 +60,8 @@ describe('Model / PersistedModel', function() { describe('Model.attachTo(dataSource)', function() { it('Attach a model to a [DataSource](#data-source)', function() { - var MyModel = loopback.createModel('my-model', {name: String}); - var dataSource = loopback.createDataSource({ + const MyModel = loopback.createModel('my-model', {name: String}); + const dataSource = loopback.createDataSource({ connector: loopback.Memory, }); @@ -76,7 +76,7 @@ describe('Model / PersistedModel', function() { }); describe.onServer('Remote Methods', function() { - var User, Post, dataSource, app; + let User, Post, dataSource, app; beforeEach(function() { app = loopback({localRegistry: true, loadBuiltinModels: true}); @@ -132,7 +132,7 @@ describe.onServer('Remote Methods', function() { describe('Model.create(data, callback)', function() { it('creates model', function(done) { - var anObject = {first: 'June'}; + const anObject = {first: 'June'}; request(app) .post('/users') // sends an object @@ -149,7 +149,7 @@ describe.onServer('Remote Methods', function() { // batch create must be tested with a remote request because there are // coercion being done on strong-remoting side it('creates array of models', function(done) { - var arrayOfObjects = [ + const arrayOfObjects = [ {first: 'John'}, {first: 'Jane'}, ]; request(app) @@ -161,8 +161,8 @@ describe.onServer('Remote Methods', function() { .end(function(err, res) { if (err) return done(err); expect(res.body.length).to.eql(2); - expect(res.body).to.have.deep.property('[0].first', 'John'); - expect(res.body).to.have.deep.property('[1].first', 'Jane'); + expect(res.body).to.have.nested.property('[0].first', 'John'); + expect(res.body).to.have.nested.property('[1].first', 'Jane'); done(); }); }); @@ -170,7 +170,7 @@ describe.onServer('Remote Methods', function() { it('creates related models', function(done) { User.create({first: 'Bob'}, function(err, res) { expect(res).to.have.property('id'); - var aPost = {title: 'A story', content: 'Once upon a time'}; + const aPost = {title: 'A story', content: 'Once upon a time'}; request(app) .post('/users/' + res.id + '/posts') .send(aPost) @@ -189,7 +189,7 @@ describe.onServer('Remote Methods', function() { it('creates array of hasMany models', function(done) { User.create({first: 'Bob'}, function(err, res) { expect(res).to.have.property('id'); - var twoPosts = [ + const twoPosts = [ {title: 'One story', content: 'Content #1'}, {title: 'Two story', content: 'Content #2'}, ]; @@ -201,21 +201,21 @@ describe.onServer('Remote Methods', function() { .end(function(err, result) { if (err) return done(err); expect(result.body.length).to.eql(2); - expect(result.body).to.have.deep.property('[0].title', 'One story'); - expect(result.body).to.have.deep.property('[1].title', 'Two story'); + expect(result.body).to.have.nested.property('[0].title', 'One story'); + expect(result.body).to.have.nested.property('[1].title', 'Two story'); done(); }); }); }); it('rejects array of obj input for hasOne relation', function(done) { - var Friend = app.registry.createModel('friend', {name: String}); + const Friend = app.registry.createModel('friend', {name: String}); app.model(Friend, {dataSource: 'db'}); User.hasOne(Friend); User.create({first: 'Bob'}, function(err, res) { expect(res).to.have.property('id'); - var twoFriends = [ + const twoFriends = [ {name: 'bob'}, {name: 'rob'}, ]; @@ -226,7 +226,7 @@ describe.onServer('Remote Methods', function() { .expect(400) .end(function(err, result) { if (err) return done(err); - var resError = result.body.error; + const resError = result.body.error; expect(resError.message).to.match(/value(.*?)not(.*?)object(\.?)/i); done(); }); @@ -258,14 +258,14 @@ describe.onServer('Remote Methods', function() { describe('Model.upsertWithWhere(where, data, callback)', function() { it('Updates when a Model instance is retreived from data source', function(done) { - var taskEmitter = new TaskEmitter(); + const taskEmitter = new TaskEmitter(); taskEmitter .task(User, 'create', {first: 'jill', second: 'pill'}) .task(User, 'create', {first: 'bob', second: 'sob'}) .on('done', function() { User.upsertWithWhere({second: 'pill'}, {second: 'jones'}, function(err, user) { if (err) return done(err); - var id = user.id; + const id = user.id; User.findById(id, function(err, user) { if (err) return done(err); assert.equal(user.second, 'jones'); @@ -276,13 +276,13 @@ describe.onServer('Remote Methods', function() { }); it('Creates when no Model instance is retreived from data source', function(done) { - var taskEmitter = new TaskEmitter(); + const taskEmitter = new TaskEmitter(); taskEmitter .task(User, 'create', {first: 'simon', second: 'somers'}) .on('done', function() { User.upsertWithWhere({first: 'somers'}, {first: 'Simon'}, function(err, user) { if (err) return done(err); - var id = user.id; + const id = user.id; User.findById(id, function(err, user) { if (err) return done(err); assert.equal(user.first, 'Simon'); @@ -315,7 +315,7 @@ describe.onServer('Remote Methods', function() { .end(function(err, res) { if (err) return done(err); - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert(errorResponse); assert.equal(errorResponse.code, 'MODEL_NOT_FOUND'); @@ -332,7 +332,7 @@ describe.onServer('Remote Methods', function() { .end(function(err, res) { if (err) return done(err); - var userId = res.body.id; + const userId = res.body.id; assert(userId); request(app) .get('/users/' + userId + '?filter[fields]=first') @@ -358,7 +358,7 @@ describe.onServer('Remote Methods', function() { .end(function(err, res) { if (err) return done(err); - var userId = res.body.id; + const userId = res.body.id; assert(userId); request(app) .post('/users/' + userId + '/posts') @@ -368,7 +368,7 @@ describe.onServer('Remote Methods', function() { .end(function(err, res) { if (err) return done(err); - var post = res.body; + const post = res.body; request(app) .get('/users/' + userId + '?filter[include]=posts') .expect('Content-Type', /json/) @@ -389,7 +389,7 @@ describe.onServer('Remote Methods', function() { describe('Model.beforeRemote(name, fn)', function() { it('Run a function before a remote method is called by a client', function(done) { - var hookCalled = false; + let hookCalled = false; User.beforeRemote('create', function(ctx, user, next) { hookCalled = true; @@ -413,7 +413,7 @@ describe.onServer('Remote Methods', function() { }); it('Does not stop the hook chain after returning a promise', function(done) { - var hooksCalled = []; + const hooksCalled = []; User.beforeRemote('create', function() { hooksCalled.push('first'); @@ -441,8 +441,8 @@ describe.onServer('Remote Methods', function() { describe('Model.afterRemote(name, fn)', function() { it('Run a function after a remote method is called by a client', function(done) { - var beforeCalled = false; - var afterCalled = false; + let beforeCalled = false; + let afterCalled = false; User.beforeRemote('create', function(ctx, user, next) { assert(!afterCalled); @@ -476,7 +476,7 @@ describe.onServer('Remote Methods', function() { describe('Model.afterRemoteError(name, fn)', function() { it('runs the function when method fails', function(done) { - var actualError = 'hook not called'; + let actualError = 'hook not called'; User.afterRemoteError('login', function(ctx, next) { actualError = ctx.error; @@ -498,7 +498,7 @@ describe.onServer('Remote Methods', function() { describe('Remote Method invoking context', function() { describe('ctx.req', function() { it('The express ServerRequest object', function(done) { - var hookCalled = false; + let hookCalled = false; User.beforeRemote('create', function(ctx, user, next) { hookCalled = true; @@ -530,7 +530,7 @@ describe.onServer('Remote Methods', function() { describe('ctx.res', function() { it('The express ServerResponse object', function(done) { - var hookCalled = false; + let hookCalled = false; User.beforeRemote('create', function(ctx, user, next) { hookCalled = true; @@ -563,15 +563,15 @@ describe.onServer('Remote Methods', function() { describe('Model.hasMany(Model)', function() { it('Define a one to many relationship', function(done) { - var Book = dataSource.createModel('book', {title: String, author: String}); - var Chapter = dataSource.createModel('chapter', {title: String}); + const Book = dataSource.createModel('book', {title: String, author: String}); + const Chapter = dataSource.createModel('chapter', {title: String}); // by referencing model Book.hasMany(Chapter); Book.create({title: 'Into the Wild', author: 'Jon Krakauer'}, function(err, book) { // using 'chapters' scope for build: - var c = book.chapters.build({title: 'Chapter 1'}); + const c = book.chapters.build({title: 'Chapter 1'}); book.chapters.create({title: 'Chapter 2'}, function() { c.save(function() { Chapter.count({bookId: book.id}, function(err, count) { @@ -591,7 +591,7 @@ describe.onServer('Remote Methods', function() { describe('Model.properties', function() { it('Normalized properties passed in originally by loopback.createModel()', function() { - var props = { + const props = { s: String, n: {type: 'Number'}, o: {type: 'String', min: 10, max: 100}, @@ -599,11 +599,11 @@ describe.onServer('Remote Methods', function() { g: loopback.GeoPoint, }; - var MyModel = loopback.createModel('foo', props); + const MyModel = loopback.createModel('foo', props); Object.keys(MyModel.definition.properties).forEach(function(key) { - var p = MyModel.definition.properties[key]; - var o = MyModel.definition.properties[key]; + const p = MyModel.definition.properties[key]; + const o = MyModel.definition.properties[key]; assert(p); assert(o); assert(typeof p.type === 'function'); @@ -622,7 +622,7 @@ describe.onServer('Remote Methods', function() { describe('Model.extend()', function() { it('Create a new model by extending an existing model', function() { - var User = loopback.PersistedModel.extend('test-user', { + const User = loopback.PersistedModel.extend('test-user', { email: String, }); @@ -634,7 +634,7 @@ describe.onServer('Remote Methods', function() { return 'foo'; }; - var MyUser = User.extend('my-user', { + const MyUser = User.extend('my-user', { a: String, b: String, }); @@ -642,7 +642,7 @@ describe.onServer('Remote Methods', function() { assert.equal(MyUser.prototype.bar, User.prototype.bar); assert.equal(MyUser.foo, User.foo); - var user = new MyUser({ + const user = new MyUser({ email: 'foo@bar.com', a: 'foo', b: 'bar', @@ -656,21 +656,21 @@ describe.onServer('Remote Methods', function() { describe('Model.extend() events', function() { it('create isolated emitters for subclasses', function() { - var User1 = loopback.createModel('User1', { + const User1 = loopback.createModel('User1', { 'first': String, 'last': String, }); - var User2 = loopback.createModel('User2', { + const User2 = loopback.createModel('User2', { 'name': String, }); - var user1Triggered = false; + let user1Triggered = false; User1.once('x', function(event) { user1Triggered = true; }); - var user2Triggered = false; + let user2Triggered = false; User2.once('x', function(event) { user2Triggered = true; }); @@ -703,7 +703,7 @@ describe.onServer('Remote Methods', function() { function shouldReturn(methodName, expectedAccessType) { describe(methodName, function() { it('should return ' + expectedAccessType, function() { - var remoteMethod = {name: methodName}; + const remoteMethod = {name: methodName}; assert.equal( User._getAccessTypeForMethod(remoteMethod), expectedAccessType @@ -715,8 +715,8 @@ describe.onServer('Remote Methods', function() { describe('Model.getChangeModel()', function() { it('Get the Change Model', function() { - var UserChange = User.getChangeModel(); - var change = new UserChange(); + const UserChange = User.getChangeModel(); + const change = new UserChange(); assert(change instanceof app.registry.getModel('Change')); }); }); @@ -733,12 +733,12 @@ describe.onServer('Remote Methods', function() { describe('Model.checkpoint(callback)', function() { it('Create a checkpoint', function(done) { - var Checkpoint = User.getChangeModel().getCheckpointModel(); - var tasks = [ + const Checkpoint = User.getChangeModel().getCheckpointModel(); + const tasks = [ getCurrentCheckpoint, checkpoint, ]; - var result, current; + let result, current; async.series(tasks, function(err) { if (err) return done(err); @@ -766,11 +766,11 @@ describe.onServer('Remote Methods', function() { describe('Model._getACLModel()', function() { it('should return the subclass of ACL', function() { - var Model = require('../').Model; - var originalValue = Model._ACL(); - var acl = ACL.extend('acl'); + const Model = require('../').Model; + const originalValue = Model._ACL(); + const acl = ACL.extend('acl'); Model._ACL(null); // Reset the ACL class for the base model - var model = Model._ACL(); + const model = Model._ACL(); Model._ACL(originalValue); // Reset the value back assert.equal(model, acl); }); @@ -778,21 +778,21 @@ describe.onServer('Remote Methods', function() { describe('PersistedModel remote methods', function() { it('includes all aliases', function() { - var app = loopback(); - var model = PersistedModel.extend('PersistedModelForAliases'); + const app = loopback(); + const model = PersistedModel.extend('PersistedModelForAliases'); app.dataSource('db', {connector: 'memory'}); app.model(model, {dataSource: 'db'}); // this code is used by loopback-sdk-angular codegen - var metadata = app.handler('rest') + const metadata = app.handler('rest') .adapter .getClasses() .filter(function(c) { return c.name === model.modelName; })[0]; - var methodNames = []; + let methodNames = []; metadata.methods.forEach(function(method) { methodNames.push(method.name); - var aliases = method.sharedMethod.aliases; + let aliases = method.sharedMethod.aliases; if (method.name.indexOf('prototype.') === 0) { aliases = aliases.map(function(alias) { return 'prototype.' + alias; @@ -826,13 +826,13 @@ describe.onServer('Remote Methods', function() { }); it('emits a `remoteMethodDisabled` event', function() { - var app = loopback(); - var model = PersistedModel.extend('TestModelForDisablingRemoteMethod'); + const app = loopback(); + const model = PersistedModel.extend('TestModelForDisablingRemoteMethod'); app.dataSource('db', {connector: 'memory'}); app.model(model, {dataSource: 'db'}); - var callbackSpy = require('sinon').spy(); - var TestModel = app.models.TestModelForDisablingRemoteMethod; + const callbackSpy = require('sinon').spy(); + const TestModel = app.models.TestModelForDisablingRemoteMethod; TestModel.on('remoteMethodDisabled', callbackSpy); TestModel.disableRemoteMethod('findOne', true); @@ -840,13 +840,13 @@ describe.onServer('Remote Methods', function() { }); it('emits a `remoteMethodDisabled` event from disableRemoteMethodByName', function() { - var app = loopback(); - var model = PersistedModel.extend('TestModelForDisablingRemoteMethod'); + const app = loopback(); + const model = PersistedModel.extend('TestModelForDisablingRemoteMethod'); app.dataSource('db', {connector: 'memory'}); app.model(model, {dataSource: 'db'}); - var callbackSpy = require('sinon').spy(); - var TestModel = app.models.TestModelForDisablingRemoteMethod; + const callbackSpy = require('sinon').spy(); + const TestModel = app.models.TestModelForDisablingRemoteMethod; TestModel.on('remoteMethodDisabled', callbackSpy); TestModel.disableRemoteMethodByName('findOne'); @@ -854,17 +854,17 @@ describe.onServer('Remote Methods', function() { }); it('emits a `remoteMethodAdded` event', function() { - var app = loopback(); + const app = loopback(); app.dataSource('db', {connector: 'memory'}); - var User = app.registry.getModel('User'); + const User = app.registry.getModel('User'); app.model(User, {dataSource: 'db'}); - var Token = app.registry.getModel('AccessToken'); + const Token = app.registry.getModel('AccessToken'); app.model(Token, {dataSource: 'db'}); - var callbackSpy = require('sinon').spy(); - var TestModel = app.models.User; + const callbackSpy = require('sinon').spy(); + const TestModel = app.models.User; TestModel.on('remoteMethodAdded', callbackSpy); TestModel.nestRemoting('accessTokens'); @@ -873,13 +873,13 @@ describe.onServer('Remote Methods', function() { }); it('emits a `remoteMethodAdded` event from remoteMethod', function() { - var app = loopback(); - var model = PersistedModel.extend('TestModelForAddingRemoteMethod'); + const app = loopback(); + const model = PersistedModel.extend('TestModelForAddingRemoteMethod'); app.dataSource('db', {connector: 'memory'}); app.model(model, {dataSource: 'db'}); - var callbackSpy = require('sinon').spy(); - var TestModel = app.models.TestModelForAddingRemoteMethod; + const callbackSpy = require('sinon').spy(); + const TestModel = app.models.TestModelForAddingRemoteMethod; TestModel.on('remoteMethodAdded', callbackSpy); TestModel.remoteMethod('getTest', { accepts: {arg: 'options', type: 'object', http: 'optionsFromRequest'}, @@ -891,7 +891,7 @@ describe.onServer('Remote Methods', function() { }); describe('Model.getApp(cb)', function() { - var app, TestModel; + let app, TestModel; beforeEach(function setup() { app = loopback(); TestModel = loopback.createModel('TestModelForGetApp'); // unique name @@ -924,7 +924,7 @@ describe.onServer('Remote Methods', function() { }); describe('Model.createOptionsFromRemotingContext', function() { - var app, TestModel, accessToken, actualOptions; + let app, TestModel, accessToken, actualOptions; before(setupAppAndRequest); before(createUserAndAccessToken); @@ -1055,8 +1055,8 @@ describe.onServer('Remote Methods', function() { } function createUserAndAccessToken() { - var CREDENTIALS = {email: 'context@example.com', password: 'pass'}; - var User = app.registry.getModel('User'); + const CREDENTIALS = {email: 'context@example.com', password: 'pass'}; + const User = app.registry.getModel('User'); return User.create(CREDENTIALS) .then(function(u) { return User.login(CREDENTIALS); diff --git a/test/multiple-user-principal-types.test.js b/test/multiple-user-principal-types.test.js index 0ab93551..7ea99a17 100644 --- a/test/multiple-user-principal-types.test.js +++ b/test/multiple-user-principal-types.test.js @@ -4,13 +4,13 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var expect = require('./helpers/expect'); -var loopback = require('../'); -var ctx = require('../lib/access-context'); -var extend = require('util')._extend; -var AccessContext = ctx.AccessContext; -var Principal = ctx.Principal; -var Promise = require('bluebird'); +const expect = require('./helpers/expect'); +const loopback = require('../'); +const ctx = require('../lib/access-context'); +const extend = require('util')._extend; +const AccessContext = ctx.AccessContext; +const Principal = ctx.Principal; +const Promise = require('bluebird'); const waitForEvent = require('./helpers/wait-for-event'); const supertest = require('supertest'); const loggers = require('./helpers/error-loggers'); @@ -19,8 +19,8 @@ const logServerErrorsOtherThan = loggers.logServerErrorsOtherThan; describe('Multiple users with custom principalType', function() { this.timeout(10000); - var commonCredentials = {email: 'foo@bar.com', password: 'bar'}; - var app, OneUser, AnotherUser, AccessToken, Role, + const commonCredentials = {email: 'foo@bar.com', password: 'bar'}; + let app, OneUser, AnotherUser, AccessToken, Role, userFromOneModel, userFromAnotherModel, userRole, userOneBaseContext; beforeEach(function setupAppAndModels() { @@ -30,7 +30,7 @@ describe('Multiple users with custom principalType', function() { app.set('remoting', {rest: {handleErrors: false}}); app.dataSource('db', {connector: 'memory'}); - var userModelOptions = { + const userModelOptions = { base: 'User', // forceId is set to false for the purpose of updating the same affected user within the // `Email Update` test cases. @@ -118,7 +118,7 @@ describe('Multiple users with custom principalType', function() { describe('User.logout', function() { it('logs out a user from user model 1 without logging out user from model 2', function() { - var tokenOfOneUser; + let tokenOfOneUser; return Promise.all([ OneUser.login(commonCredentials), AnotherUser.login(commonCredentials), @@ -131,7 +131,7 @@ describe('Multiple users with custom principalType', function() { return AccessToken.find({}); }) .then(function(allTokens) { - var data = allTokens.map(function(token) { + const data = allTokens.map(function(token) { return {userId: token.userId, principalType: token.principalType}; }); expect(data).to.eql([ @@ -144,7 +144,7 @@ describe('Multiple users with custom principalType', function() { describe('Password Reset', function() { describe('User.resetPassword(options)', function() { - var options = { + const options = { email: 'foo@bar.com', redirect: 'http://foobar.com/reset-password', }; @@ -172,7 +172,7 @@ describe('Multiple users with custom principalType', function() { }); describe('AccessToken (session) invalidation when changing email', function() { - var anotherUserFromOneModel; + let anotherUserFromOneModel; it('impact only the related user', function() { return OneUser.create({email: 'original@example.com', password: 'bar'}) @@ -192,7 +192,7 @@ describe('Multiple users with custom principalType', function() { return AccessToken.find({'order': 'principalType ASC'}); }) .then(function(allTokens) { - var data = allTokens.map(function(token) { + const data = allTokens.map(function(token) { return {userId: token.userId, principalType: token.principalType}; }); expect(data).to.eql([ @@ -205,7 +205,7 @@ describe('Multiple users with custom principalType', function() { }); describe('AccessContext', function() { - var ThirdUser, userFromThirdModel, accessContext; + let ThirdUser, userFromThirdModel, accessContext; beforeEach(function() { accessContext = new AccessContext({registry: OneUser.registry}); @@ -221,7 +221,7 @@ describe('Multiple users with custom principalType', function() { {type: Principal.SCOPE}, {type: OneUser.modelName, id: userFromOneModel.id}, ]); - var user = accessContext.getUser(); + const user = accessContext.getUser(); expect(user).to.eql({ id: userFromOneModel.id, principalType: OneUser.modelName, @@ -237,7 +237,7 @@ describe('Multiple users with custom principalType', function() { {type: 'invalidModelName'}, {type: OneUser.modelName, id: userFromOneModel.id}, ]); - var user = accessContext.getUser(); + const user = accessContext.getUser(); expect(user).to.eql({ id: userFromOneModel.id, principalType: OneUser.modelName, @@ -251,7 +251,7 @@ describe('Multiple users with custom principalType', function() { return ThirdUser.create(commonCredentials) .then(function(userFromThirdModel) { accessContext.addPrincipal(ThirdUser.modelName, userFromThirdModel.id); - var user = accessContext.getUser(); + const user = accessContext.getUser(); expect(user).to.eql({ id: userFromThirdModel.id, principalType: ThirdUser.modelName, @@ -272,7 +272,7 @@ describe('Multiple users with custom principalType', function() { describe('Role model', function() { this.timeout(10000); - var RoleMapping, ACL, user; + let RoleMapping, ACL, user; beforeEach(function() { ACL = app.registry.getModel('ACL'); @@ -374,7 +374,7 @@ describe('Multiple users with custom principalType', function() { describe('$owner', function() { it('supports legacy behavior with relations', function() { - var Album = app.registry.createModel('Album', { + const Album = app.registry.createModel('Album', { name: String, userId: Number, }, { @@ -390,7 +390,7 @@ describe('Multiple users with custom principalType', function() { return Album.create({name: 'album', userId: userFromOneModel.id}) .then(function(album) { - var validContext = { + const validContext = { principalType: OneUser.modelName, principalId: userFromOneModel.id, model: Album, @@ -406,7 +406,7 @@ describe('Multiple users with custom principalType', function() { // With multiple users config, we cannot resolve a user based just on // his id, as many users from different models could have the same id. it('legacy behavior resolves false without belongsTo relation', function() { - var Album = app.registry.createModel('Album', { + const Album = app.registry.createModel('Album', { name: String, userId: Number, owner: Number, @@ -419,7 +419,7 @@ describe('Multiple users with custom principalType', function() { owner: userFromOneModel.id, }) .then(function(album) { - var authContext = { + const authContext = { principalType: OneUser.modelName, principalId: userFromOneModel.id, model: Album, @@ -433,7 +433,7 @@ describe('Multiple users with custom principalType', function() { }); it('legacy behavior resolves false if owner has incorrect principalType', function() { - var Album = app.registry.createModel('Album', { + const Album = app.registry.createModel('Album', { name: String, userId: Number, }, { @@ -449,12 +449,12 @@ describe('Multiple users with custom principalType', function() { return Album.create({name: 'album', userId: userFromOneModel.id}) .then(function(album) { - var invalidPrincipalTypes = [ + const invalidPrincipalTypes = [ 'invalidContextName', 'USER', AnotherUser.modelName, ]; - var invalidContexts = invalidPrincipalTypes.map(principalType => { + const invalidContexts = invalidPrincipalTypes.map(principalType => { return { principalType, principalId: userFromOneModel.id, @@ -485,12 +485,12 @@ describe('Multiple users with custom principalType', function() { function() { // passing {ownerRelations: true} will enable the new $owner role resolver // with any belongsTo relation allowing to resolve truthy - var Message = createModelWithOptions( + const Message = createModelWithOptions( 'ModelWithAllRelations', {ownerRelations: true} ); - var messages = [ + const messages = [ {content: 'firstMessage', customerId: userFromOneModel.id}, { content: 'secondMessage', @@ -552,7 +552,7 @@ describe('Multiple users with custom principalType', function() { // helpers function isOwnerForMessage(user, msg) { - var accessContext = { + const accessContext = { principalType: user.constructor.modelName, principalId: user.id, model: msg.constructor, @@ -569,7 +569,7 @@ describe('Multiple users with custom principalType', function() { } function createModelWithOptions(name, options) { - var baseOptions = { + const baseOptions = { relations: { sender: { type: 'belongsTo', @@ -584,7 +584,7 @@ describe('Multiple users with custom principalType', function() { }, }; options = extend(baseOptions, options); - var Model = app.registry.createModel( + const Model = app.registry.createModel( name, {content: String, senderType: String}, options @@ -768,7 +768,7 @@ describe('Multiple users with custom principalType', function() { // helpers function createUserModel(app, name, options) { - var model = app.registry.createModel(Object.assign({name: name}, options)); + const model = app.registry.createModel(Object.assign({name: name}, options)); app.model(model, {dataSource: 'db'}); model.setMaxListeners(0); // allow many User.afterRemote's to be called return model; diff --git a/test/registries.test.js b/test/registries.test.js index fdc4cc87..02b94f2a 100644 --- a/test/registries.test.js +++ b/test/registries.test.js @@ -4,16 +4,16 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var expect = require('./helpers/expect'); -var loopback = require('../'); +const assert = require('assert'); +const expect = require('./helpers/expect'); +const loopback = require('../'); describe('Registry', function() { describe('createModel', function() { it('should throw error upon extending non-exist base model', function() { - var app = loopback(); - var props = {}; - var opts = {base: 'nonexistent'}; + const app = loopback(); + const props = {}; + const opts = {base: 'nonexistent'}; expect(function() { app.registry.createModel('aModel', props, opts); }) .to.throw(/model\s`aModel`(.*)unknown\smodel\s`nonexistent`/); }); @@ -21,26 +21,26 @@ describe('Registry', function() { describe('one per app', function() { it('should allow two apps to reuse the same model name', function(done) { - var appFoo = loopback(); - var appBar = loopback(); - var modelName = 'MyModel'; - var subModelName = 'Sub' + modelName; - var settings = {base: 'PersistedModel'}; + const appFoo = loopback(); + const appBar = loopback(); + const modelName = 'MyModel'; + const subModelName = 'Sub' + modelName; + const settings = {base: 'PersistedModel'}; appFoo.set('perAppRegistries', true); appBar.set('perAppRegistries', true); - var dsFoo = appFoo.dataSource('dsFoo', {connector: 'memory'}); - var dsBar = appFoo.dataSource('dsBar', {connector: 'memory'}); + const dsFoo = appFoo.dataSource('dsFoo', {connector: 'memory'}); + const dsBar = appFoo.dataSource('dsBar', {connector: 'memory'}); - var FooModel = appFoo.registry.createModel(modelName, {}, settings); + const FooModel = appFoo.registry.createModel(modelName, {}, settings); appFoo.model(FooModel, {dataSource: dsFoo}); - var FooSubModel = appFoo.registry.createModel(subModelName, {}, settings); + const FooSubModel = appFoo.registry.createModel(subModelName, {}, settings); appFoo.model(FooSubModel, {dataSource: dsFoo}); - var BarModel = appBar.registry.createModel(modelName, {}, settings); + const BarModel = appBar.registry.createModel(modelName, {}, settings); appBar.model(BarModel, {dataSource: dsBar}); - var BarSubModel = appBar.registry.createModel(subModelName, {}, settings); + const BarSubModel = appBar.registry.createModel(subModelName, {}, settings); appBar.model(BarSubModel, {dataSource: dsBar}); FooModel.hasMany(FooSubModel); diff --git a/test/relations.integration.js b/test/relations.integration.js index b8b77f87..ecaa3985 100644 --- a/test/relations.integration.js +++ b/test/relations.integration.js @@ -4,15 +4,15 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../'); -var lt = require('./helpers/loopback-testing-helper'); -var path = require('path'); -var SIMPLE_APP = path.join(__dirname, 'fixtures', 'simple-integration-app'); -var app = require(path.join(SIMPLE_APP, 'server/server.js')); -var assert = require('assert'); -var expect = require('./helpers/expect'); -var debug = require('debug')('loopback:test:relations.integration'); -var async = require('async'); +const loopback = require('../'); +const lt = require('./helpers/loopback-testing-helper'); +const path = require('path'); +const SIMPLE_APP = path.join(__dirname, 'fixtures', 'simple-integration-app'); +const app = require(path.join(SIMPLE_APP, 'server/server.js')); +const assert = require('assert'); +const expect = require('./helpers/expect'); +const debug = require('debug')('loopback:test:relations.integration'); +const async = require('async'); describe('relations - integration', function() { lt.beforeEach.withApp(app); @@ -32,9 +32,9 @@ describe('relations - integration', function() { describe('polymorphicHasMany', function() { before(function defineProductAndCategoryModels() { - var Team = app.registry.createModel('Team', {name: 'string'}); - var Reader = app.registry.createModel('Reader', {name: 'string'}); - var Picture = app.registry.createModel('Picture', + const Team = app.registry.createModel('Team', {name: 'string'}); + const Reader = app.registry.createModel('Reader', {name: 'string'}); + const Picture = app.registry.createModel('Picture', {name: 'string', imageableId: 'number', imageableType: 'string'}); app.model(Team, {dataSource: 'db'}); @@ -56,7 +56,7 @@ describe('relations - integration', function() { }); before(function createEvent(done) { - var test = this; + const test = this; app.models.Team.create({name: 'Team 1'}, function(err, team) { if (err) return done(err); @@ -80,7 +80,7 @@ describe('relations - integration', function() { }); it('includes the related child model', function(done) { - var url = '/api/readers/' + this.reader.id; + const url = '/api/readers/' + this.reader.id; this.get(url) .query({'filter': {'include': 'pictures'}}) .expect(200, function(err, res) { @@ -97,7 +97,7 @@ describe('relations - integration', function() { }); it('includes the related parent model', function(done) { - var url = '/api/pictures'; + const url = '/api/pictures'; this.get(url) .query({'filter': {'include': 'imageable'}}) .expect(200, function(err, res) { @@ -112,7 +112,7 @@ describe('relations - integration', function() { }); it('includes related models scoped to the related parent model', function(done) { - var url = '/api/pictures'; + const url = '/api/pictures'; this.get(url) .query({'filter': {'include': { 'relation': 'imageable', @@ -227,7 +227,7 @@ describe('relations - integration', function() { describe('PUT /api/store/:id/widgets/:fk', function() { beforeEach(function(done) { - var self = this; + const self = this; this.store.widgets.create({ name: this.widgetName, }, function(err, widget) { @@ -237,7 +237,7 @@ describe('relations - integration', function() { }); }); it('does not add default properties to request body', function(done) { - var self = this; + const self = this; self.request.put(self.url) .send({active: true}) .end(function(err) { @@ -254,7 +254,7 @@ describe('relations - integration', function() { describe('/stores/:id/widgets/:fk - 200', function() { beforeEach(function(done) { - var self = this; + const self = this; this.store.widgets.create({ name: this.widgetName, }, function(err, widget) { @@ -328,7 +328,7 @@ describe('relations - integration', function() { describe('/widgets/:id/store', function() { beforeEach(function(done) { - var self = this; + const self = this; this.store.widgets.create({ name: this.widgetName, }, function(err, widget) { @@ -348,7 +348,7 @@ describe('relations - integration', function() { describe('hasMany through', function() { function setup(connecting, cb) { - var root = {}; + const root = {}; async.series([ // Clean up models @@ -401,7 +401,7 @@ describe('relations - integration', function() { describe('PUT /physicians/:id/patients/rel/:fk', function() { before(function(done) { - var self = this; + const self = this; setup(false, function(err, root) { self.url = root.relUrl; self.patient = root.patient; @@ -419,7 +419,7 @@ describe('relations - integration', function() { }); it('should create a record in appointment', function(done) { - var self = this; + const self = this; app.models.appointment.find(function(err, apps) { assert.equal(apps.length, 1); assert.equal(apps[0].patientId, self.patient.id); @@ -429,7 +429,7 @@ describe('relations - integration', function() { }); it('should connect physician to patient', function(done) { - var self = this; + const self = this; self.physician.patients(function(err, patients) { assert.equal(patients.length, 1); assert.equal(patients[0].id, self.patient.id); @@ -442,7 +442,7 @@ describe('relations - integration', function() { describe('PUT /physicians/:id/patients/rel/:fk with data', function() { before(function(done) { - var self = this; + const self = this; setup(false, function(err, root) { self.url = root.relUrl; self.patient = root.patient; @@ -452,8 +452,8 @@ describe('relations - integration', function() { }); }); - var NOW = Date.now(); - var data = {date: new Date(NOW)}; + const NOW = Date.now(); + const data = {date: new Date(NOW)}; lt.describe.whenCalledRemotely('PUT', '/api/physicians/:id/patients/rel/:fk', data, function() { it('should succeed with statusCode 200', function() { @@ -464,7 +464,7 @@ describe('relations - integration', function() { }); it('should create a record in appointment', function(done) { - var self = this; + const self = this; app.models.appointment.find(function(err, apps) { assert.equal(apps.length, 1); assert.equal(apps[0].patientId, self.patient.id); @@ -476,7 +476,7 @@ describe('relations - integration', function() { }); it('should connect physician to patient', function(done) { - var self = this; + const self = this; self.physician.patients(function(err, patients) { assert.equal(patients.length, 1); assert.equal(patients[0].id, self.patient.id); @@ -489,7 +489,7 @@ describe('relations - integration', function() { describe('HEAD /physicians/:id/patients/rel/:fk', function() { before(function(done) { - var self = this; + const self = this; setup(true, function(err, root) { self.url = root.relUrl; self.patient = root.patient; @@ -508,7 +508,7 @@ describe('relations - integration', function() { describe('HEAD /physicians/:id/patients/rel/:fk that does not exist', function() { before(function(done) { - var self = this; + const self = this; setup(true, function(err, root) { self.url = '/api/physicians/' + root.physician.id + '/patients/rel/' + '999'; @@ -528,7 +528,7 @@ describe('relations - integration', function() { describe('DELETE /physicians/:id/patients/rel/:fk', function() { before(function(done) { - var self = this; + const self = this; setup(true, function(err, root) { self.url = root.relUrl; self.patient = root.patient; @@ -539,7 +539,7 @@ describe('relations - integration', function() { }); it('should create a record in appointment', function(done) { - var self = this; + const self = this; app.models.appointment.find(function(err, apps) { assert.equal(apps.length, 1); assert.equal(apps[0].patientId, self.patient.id); @@ -549,7 +549,7 @@ describe('relations - integration', function() { }); it('should connect physician to patient', function(done) { - var self = this; + const self = this; self.physician.patients(function(err, patients) { assert.equal(patients.length, 1); assert.equal(patients[0].id, self.patient.id); @@ -564,7 +564,7 @@ describe('relations - integration', function() { }); it('should remove the record in appointment', function(done) { - var self = this; + const self = this; app.models.appointment.find(function(err, apps) { assert.equal(apps.length, 0); @@ -573,7 +573,7 @@ describe('relations - integration', function() { }); it('should remove the connection between physician and patient', function(done) { - var self = this; + const self = this; // Need to refresh the cache self.physician.patients(true, function(err, patients) { assert.equal(patients.length, 0); @@ -586,7 +586,7 @@ describe('relations - integration', function() { describe('GET /physicians/:id/patients/:fk', function() { before(function(done) { - var self = this; + const self = this; setup(true, function(err, root) { self.url = '/api/physicians/' + root.physician.id + '/patients/' + root.patient.id; @@ -607,7 +607,7 @@ describe('relations - integration', function() { describe('DELETE /physicians/:id/patients/:fk', function() { before(function(done) { - var self = this; + const self = this; setup(true, function(err, root) { self.url = '/api/physicians/' + root.physician.id + '/patients/' + root.patient.id; @@ -624,7 +624,7 @@ describe('relations - integration', function() { }); it('should remove the record in appointment', function(done) { - var self = this; + const self = this; app.models.appointment.find(function(err, apps) { assert.equal(apps.length, 0); @@ -633,7 +633,7 @@ describe('relations - integration', function() { }); it('should remove the connection between physician and patient', function(done) { - var self = this; + const self = this; // Need to refresh the cache self.physician.patients(true, function(err, patients) { assert.equal(patients.length, 0); @@ -643,7 +643,7 @@ describe('relations - integration', function() { }); it('should remove the record in patient', function(done) { - var self = this; + const self = this; app.models.patient.find(function(err, patients) { assert.equal(patients.length, 0); @@ -659,11 +659,11 @@ describe('relations - integration', function() { // Disable "Warning: overriding remoting type product" this.app.remotes()._typeRegistry._options.warnWhenOverridingType = false; - var product = app.registry.createModel( + const product = app.registry.createModel( 'product', {id: 'string', name: 'string'} ); - var category = app.registry.createModel( + const category = app.registry.createModel( 'category', {id: 'string', name: 'string'} ); @@ -677,7 +677,7 @@ describe('relations - integration', function() { lt.beforeEach.givenModel('category'); beforeEach(function createProductsInCategory(done) { - var test = this; + const test = this; this.category.products.create({ name: 'a-product', }, function(err, product) { @@ -704,7 +704,7 @@ describe('relations - integration', function() { it.skip('allows to find related objects via where filter', function(done) { // TODO https://github.com/strongloop/loopback-datasource-juggler/issues/94 - var expectedProduct = this.product; + const expectedProduct = this.product; this.get('/api/products?filter[where][categoryId]=' + this.category.id) .expect(200, function(err, res) { if (err) return done(err); @@ -721,7 +721,7 @@ describe('relations - integration', function() { }); it('allows to find related object via URL scope', function(done) { - var expectedProduct = this.product; + const expectedProduct = this.product; this.get('/api/categories/' + this.category.id + '/products') .expect(200, function(err, res) { if (err) return done(err); @@ -738,8 +738,8 @@ describe('relations - integration', function() { }); it('includes requested related models in `find`', function(done) { - var expectedProduct = this.product; - var url = '/api/categories/findOne?filter[where][id]=' + + const expectedProduct = this.product; + const url = '/api/categories/findOne?filter[where][id]=' + this.category.id + '&filter[include]=products'; this.get(url) @@ -760,9 +760,9 @@ describe('relations - integration', function() { it.skip('includes requested related models in `findById`', function(done) { // TODO https://github.com/strongloop/loopback-datasource-juggler/issues/93 - var expectedProduct = this.product; + const expectedProduct = this.product; // Note: the URL format is not final - var url = '/api/categories/' + this.category.id + '?include=products'; + const url = '/api/categories/' + this.category.id + '?include=products'; this.get(url) .expect(200, function(err, res) { @@ -783,14 +783,14 @@ describe('relations - integration', function() { describe('embedsOne', function() { before(function defineGroupAndPosterModels() { - var group = app.registry.createModel( + const group = app.registry.createModel( 'group', {name: 'string'}, {plural: 'groups'} ); app.model(group, {dataSource: 'db'}); - var poster = app.registry.createModel( + const poster = app.registry.createModel( 'poster', {url: 'string'} ); @@ -800,7 +800,7 @@ describe('relations - integration', function() { }); before(function createImage(done) { - var test = this; + const test = this; app.models.group.create({name: 'Group 1'}, function(err, group) { if (err) return done(err); @@ -816,7 +816,7 @@ describe('relations - integration', function() { }); it('creates an embedded model', function(done) { - var url = '/api/groups/' + this.group.id + '/cover'; + const url = '/api/groups/' + this.group.id + '/cover'; this.post(url) .send({url: 'http://image.url'}) @@ -830,7 +830,7 @@ describe('relations - integration', function() { }); it('includes the embedded models', function(done) { - var url = '/api/groups/' + this.group.id; + const url = '/api/groups/' + this.group.id; this.get(url) .expect(200, function(err, res) { @@ -846,7 +846,7 @@ describe('relations - integration', function() { }); it('returns the embedded model', function(done) { - var url = '/api/groups/' + this.group.id + '/cover'; + const url = '/api/groups/' + this.group.id + '/cover'; this.get(url) .expect(200, function(err, res) { @@ -861,7 +861,7 @@ describe('relations - integration', function() { }); it('updates an embedded model', function(done) { - var url = '/api/groups/' + this.group.id + '/cover'; + const url = '/api/groups/' + this.group.id + '/cover'; this.put(url) .send({url: 'http://changed.url'}) @@ -873,7 +873,7 @@ describe('relations - integration', function() { }); it('returns the updated embedded model', function(done) { - var url = '/api/groups/' + this.group.id + '/cover'; + const url = '/api/groups/' + this.group.id + '/cover'; this.get(url) .expect(200, function(err, res) { @@ -888,26 +888,26 @@ describe('relations - integration', function() { }); it('deletes an embedded model', function(done) { - var url = '/api/groups/' + this.group.id + '/cover'; + const url = '/api/groups/' + this.group.id + '/cover'; this.del(url).expect(204, done); }); it('deleted the embedded model', function(done) { - var url = '/api/groups/' + this.group.id + '/cover'; + const url = '/api/groups/' + this.group.id + '/cover'; this.get(url).expect(404, done); }); }); describe('embedsMany', function() { before(function defineProductAndCategoryModels() { - var todoList = app.registry.createModel( + const todoList = app.registry.createModel( 'todoList', {name: 'string'}, {plural: 'todo-lists'} ); app.model(todoList, {dataSource: 'db'}); - var todoItem = app.registry.createModel( + const todoItem = app.registry.createModel( 'todoItem', {content: 'string'}, {forceId: false} ); @@ -917,7 +917,7 @@ describe('relations - integration', function() { }); before(function createTodoList(done) { - var test = this; + const test = this; app.models.todoList.create({name: 'List A'}, function(err, list) { if (err) return done(err); @@ -934,7 +934,7 @@ describe('relations - integration', function() { }); it('includes the embedded models', function(done) { - var url = '/api/todo-lists/' + this.todoList.id; + const url = '/api/todo-lists/' + this.todoList.id; this.get(url) .expect(200, function(err, res) { @@ -951,7 +951,7 @@ describe('relations - integration', function() { }); it('returns the embedded models', function(done) { - var url = '/api/todo-lists/' + this.todoList.id + '/items'; + const url = '/api/todo-lists/' + this.todoList.id + '/items'; this.get(url) .expect(200, function(err, res) { @@ -967,7 +967,7 @@ describe('relations - integration', function() { }); it('filters the embedded models', function(done) { - var url = '/api/todo-lists/' + this.todoList.id + '/items'; + let url = '/api/todo-lists/' + this.todoList.id + '/items'; url += '?filter[where][id]=2'; this.get(url) @@ -983,9 +983,9 @@ describe('relations - integration', function() { }); it('creates embedded models', function(done) { - var url = '/api/todo-lists/' + this.todoList.id + '/items'; + const url = '/api/todo-lists/' + this.todoList.id + '/items'; - var expected = {content: 'Todo 3', id: 3}; + const expected = {content: 'Todo 3', id: 3}; this.post(url) .send({content: 'Todo 3'}) @@ -997,7 +997,7 @@ describe('relations - integration', function() { }); it('includes the created embedded model', function(done) { - var url = '/api/todo-lists/' + this.todoList.id + '/items'; + const url = '/api/todo-lists/' + this.todoList.id + '/items'; this.get(url) .expect(200, function(err, res) { @@ -1014,7 +1014,7 @@ describe('relations - integration', function() { }); it('returns an embedded model by (internal) id', function(done) { - var url = '/api/todo-lists/' + this.todoList.id + '/items/3'; + const url = '/api/todo-lists/' + this.todoList.id + '/items/3'; this.get(url) .expect(200, function(err, res) { @@ -1029,8 +1029,8 @@ describe('relations - integration', function() { }); it('removes an embedded model', function(done) { - var expectedProduct = this.product; - var url = '/api/todo-lists/' + this.todoList.id + '/items/2'; + const expectedProduct = this.product; + const url = '/api/todo-lists/' + this.todoList.id + '/items/2'; this.del(url) .expect(200, function(err, res) { @@ -1039,7 +1039,7 @@ describe('relations - integration', function() { }); it('returns the embedded models - verify', function(done) { - var url = '/api/todo-lists/' + this.todoList.id + '/items'; + const url = '/api/todo-lists/' + this.todoList.id + '/items'; this.get(url) .expect(200, function(err, res) { @@ -1055,7 +1055,7 @@ describe('relations - integration', function() { }); it('returns a 404 response when embedded model is not found', function(done) { - var url = '/api/todo-lists/' + this.todoList.id + '/items/2'; + const url = '/api/todo-lists/' + this.todoList.id + '/items/2'; this.get(url).expect(404, function(err, res) { if (err) return done(err); @@ -1068,7 +1068,7 @@ describe('relations - integration', function() { }); it.skip('checks if an embedded model exists - ok', function(done) { - var url = '/api/todo-lists/' + this.todoList.id + '/items/3'; + const url = '/api/todo-lists/' + this.todoList.id + '/items/3'; this.head(url) .expect(200, function(err, res) { @@ -1077,7 +1077,7 @@ describe('relations - integration', function() { }); it.skip('checks if an embedded model exists - fail', function(done) { - var url = '/api/todo-lists/' + this.todoList.id + '/items/2'; + const url = '/api/todo-lists/' + this.todoList.id + '/items/2'; this.head(url) .expect(404, function(err, res) { @@ -1088,19 +1088,19 @@ describe('relations - integration', function() { describe('referencesMany', function() { before(function defineProductAndCategoryModels() { - var recipe = app.registry.createModel( + const recipe = app.registry.createModel( 'recipe', {name: 'string'} ); app.model(recipe, {dataSource: 'db'}); - var ingredient = app.registry.createModel( + const ingredient = app.registry.createModel( 'ingredient', {name: 'string'} ); app.model(ingredient, {dataSource: 'db'}); - var photo = app.registry.createModel( + const photo = app.registry.createModel( 'photo', {name: 'string'} ); @@ -1114,7 +1114,7 @@ describe('relations - integration', function() { }); before(function createRecipe(done) { - var test = this; + const test = this; app.models.recipe.create({name: 'Recipe'}, function(err, recipe) { if (err) return done(err); @@ -1130,7 +1130,7 @@ describe('relations - integration', function() { }); before(function createIngredient(done) { - var test = this; + const test = this; app.models.ingredient.create({name: 'Sugar'}, function(err, ing) { test.ingredient2 = ing.id; @@ -1139,7 +1139,7 @@ describe('relations - integration', function() { }); after(function(done) { - var app = this.app; + const app = this.app; app.models.recipe.destroyAll(function() { app.models.ingredient.destroyAll(function() { app.models.photo.destroyAll(done); @@ -1148,8 +1148,8 @@ describe('relations - integration', function() { }); it('keeps an array of ids', function(done) { - var url = '/api/recipes/' + this.recipe.id; - var test = this; + const url = '/api/recipes/' + this.recipe.id; + const test = this; this.get(url) .expect(200, function(err, res) { @@ -1163,8 +1163,8 @@ describe('relations - integration', function() { }); it('creates referenced models', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/ingredients'; - var test = this; + const url = '/api/recipes/' + this.recipe.id + '/ingredients'; + const test = this; this.post(url) .send({name: 'Butter'}) @@ -1177,8 +1177,8 @@ describe('relations - integration', function() { }); it('has created models', function(done) { - var url = '/api/ingredients'; - var test = this; + const url = '/api/ingredients'; + const test = this; this.get(url) .expect(200, function(err, res) { @@ -1195,8 +1195,8 @@ describe('relations - integration', function() { }); it('returns the referenced models', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/ingredients'; - var test = this; + const url = '/api/recipes/' + this.recipe.id + '/ingredients'; + const test = this; this.get(url) .expect(200, function(err, res) { @@ -1212,9 +1212,9 @@ describe('relations - integration', function() { }); it('filters the referenced models', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/ingredients'; + let url = '/api/recipes/' + this.recipe.id + '/ingredients'; url += '?filter[where][name]=Butter'; - var test = this; + const test = this; this.get(url) .expect(200, function(err, res) { @@ -1229,9 +1229,9 @@ describe('relations - integration', function() { }); it('includes the referenced models', function(done) { - var url = '/api/recipes/findOne?filter[where][id]=' + this.recipe.id; + let url = '/api/recipes/findOne?filter[where][id]=' + this.recipe.id; url += '&filter[include]=ingredients'; - var test = this; + const test = this; this.get(url) .expect(200, function(err, res) { @@ -1250,9 +1250,9 @@ describe('relations - integration', function() { }); it('returns a referenced model by id', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/ingredients/'; + let url = '/api/recipes/' + this.recipe.id + '/ingredients/'; url += this.ingredient3; - var test = this; + const test = this; this.get(url) .expect(200, function(err, res) { @@ -1267,10 +1267,10 @@ describe('relations - integration', function() { }); it('keeps an array of ids - verify', function(done) { - var url = '/api/recipes/' + this.recipe.id; - var test = this; + const url = '/api/recipes/' + this.recipe.id; + const test = this; - var expected = [test.ingredient1, test.ingredient3]; + const expected = [test.ingredient1, test.ingredient3]; this.get(url) .expect(200, function(err, res) { @@ -1284,8 +1284,8 @@ describe('relations - integration', function() { }); it('destroys a referenced model', function(done) { - var expectedProduct = this.product; - var url = '/api/recipes/' + this.recipe.id + '/ingredients/'; + const expectedProduct = this.product; + let url = '/api/recipes/' + this.recipe.id + '/ingredients/'; url += this.ingredient3; this.del(url) @@ -1295,8 +1295,8 @@ describe('relations - integration', function() { }); it('has destroyed a referenced model', function(done) { - var url = '/api/ingredients'; - var test = this; + const url = '/api/ingredients'; + const test = this; this.get(url) .expect(200, function(err, res) { @@ -1312,8 +1312,8 @@ describe('relations - integration', function() { }); it('returns the referenced models without the deleted one', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/ingredients'; - var test = this; + const url = '/api/recipes/' + this.recipe.id + '/ingredients'; + const test = this; this.get(url) .expect(200, function(err, res) { @@ -1328,9 +1328,9 @@ describe('relations - integration', function() { }); it('creates/links a reference by id', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/ingredients'; + let url = '/api/recipes/' + this.recipe.id + '/ingredients'; url += '/rel/' + this.ingredient2; - var test = this; + const test = this; this.put(url) .expect(200, function(err, res) { @@ -1343,8 +1343,8 @@ describe('relations - integration', function() { }); it('returns the referenced models - verify', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/ingredients'; - var test = this; + const url = '/api/recipes/' + this.recipe.id + '/ingredients'; + const test = this; this.get(url) .expect(200, function(err, res) { @@ -1360,9 +1360,9 @@ describe('relations - integration', function() { }); it('removes/unlinks a reference by id', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/ingredients'; + let url = '/api/recipes/' + this.recipe.id + '/ingredients'; url += '/rel/' + this.ingredient1; - var test = this; + const test = this; this.del(url) .expect(200, function(err, res) { @@ -1371,8 +1371,8 @@ describe('relations - integration', function() { }); it('returns the referenced models without the unlinked one', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/ingredients'; - var test = this; + const url = '/api/recipes/' + this.recipe.id + '/ingredients'; + const test = this; this.get(url) .expect(200, function(err, res) { @@ -1387,8 +1387,8 @@ describe('relations - integration', function() { }); it('has not destroyed an unlinked model', function(done) { - var url = '/api/ingredients'; - var test = this; + const url = '/api/ingredients'; + const test = this; this.get(url) .expect(200, function(err, res) { @@ -1404,7 +1404,7 @@ describe('relations - integration', function() { }); it('uses a custom relation path', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/image'; + const url = '/api/recipes/' + this.recipe.id + '/image'; this.get(url) .expect(200, function(err, res) { @@ -1418,7 +1418,7 @@ describe('relations - integration', function() { }); it.skip('checks if a referenced model exists - ok', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/ingredients/'; + let url = '/api/recipes/' + this.recipe.id + '/ingredients/'; url += this.ingredient1; this.head(url) @@ -1428,7 +1428,7 @@ describe('relations - integration', function() { }); it.skip('checks if an referenced model exists - fail', function(done) { - var url = '/api/recipes/' + this.recipe.id + '/ingredients/'; + let url = '/api/recipes/' + this.recipe.id + '/ingredients/'; url += this.ingredient3; this.head(url) @@ -1442,35 +1442,35 @@ describe('relations - integration', function() { let accessOptions; before(function defineModels() { - var Book = app.registry.createModel( + const Book = app.registry.createModel( 'Book', {name: 'string'}, {plural: 'books'} ); app.model(Book, {dataSource: 'db'}); - var Page = app.registry.createModel( + const Page = app.registry.createModel( 'Page', {name: 'string'}, {plural: 'pages'} ); app.model(Page, {dataSource: 'db'}); - var Image = app.registry.createModel( + const Image = app.registry.createModel( 'Image', {name: 'string'}, {plural: 'images'} ); app.model(Image, {dataSource: 'db'}); - var Note = app.registry.createModel( + const Note = app.registry.createModel( 'Note', {text: 'string'}, {plural: 'notes'} ); app.model(Note, {dataSource: 'db'}); - var Chapter = app.registry.createModel( + const Chapter = app.registry.createModel( 'Chapter', {name: 'string'}, {plural: 'chapters'} @@ -1523,7 +1523,7 @@ describe('relations - integration', function() { }); before(function createBook(done) { - var test = this; + const test = this; app.models.Book.create({name: 'Book 1'}, function(err, book) { if (err) return done(err); @@ -1545,7 +1545,7 @@ describe('relations - integration', function() { }); before(function createChapters(done) { - var test = this; + const test = this; test.book.chapters.create({name: 'Chapter 1'}, function(err, chapter) { if (err) return done(err); @@ -1560,7 +1560,7 @@ describe('relations - integration', function() { }); before(function createCover(done) { - var test = this; + const test = this; app.models.Image.create({name: 'Cover 1', book: test.book}, function(err, image) { if (err) return done(err); @@ -1572,7 +1572,7 @@ describe('relations - integration', function() { }); it('has regular relationship routes - pages', function(done) { - var test = this; + const test = this; this.get('/api/books/' + test.book.id + '/pages') .expect(200, function(err, res) { if (err) return done(err); @@ -1586,7 +1586,7 @@ describe('relations - integration', function() { }); it('has regular relationship routes - notes', function(done) { - var test = this; + const test = this; this.get('/api/pages/' + test.page.id + '/notes/' + test.note.id) .expect(200, function(err, res) { if (err) return done(err); @@ -1601,13 +1601,13 @@ describe('relations - integration', function() { }); it('has a basic error handler', function(done) { - var test = this; + const test = this; this.get('/api/books/unknown/pages/' + test.page.id + '/notes') .expect(404, function(err, res) { if (err) return done(err); expect(res.body.error).to.be.an('object'); - var expected = 'could not find a model with id unknown'; + const expected = 'could not find a model with id unknown'; expect(res.body.error.message).to.equal(expected); expect(res.body.error.code).to.be.equal('MODEL_NOT_FOUND'); @@ -1616,7 +1616,7 @@ describe('relations - integration', function() { }); it('enables nested relationship routes - belongsTo find', function(done) { - var test = this; + const test = this; this.get('/api/images/' + test.image.id + '/book/pages') .end(function(err, res) { if (err) return done(err); @@ -1630,7 +1630,7 @@ describe('relations - integration', function() { }); it('enables nested relationship routes - belongsTo findById', function(done) { - var test = this; + const test = this; this.get('/api/images/' + test.image.id + '/book/pages/' + test.page.id) .expect(200) .end(function(err, res) { @@ -1644,7 +1644,7 @@ describe('relations - integration', function() { }); it('enables nested relationship routes - hasMany find', function(done) { - var test = this; + const test = this; this.get('/api/books/' + test.book.id + '/pages/' + test.page.id + '/notes') .expect(200, function(err, res) { if (err) return done(err); @@ -1658,7 +1658,7 @@ describe('relations - integration', function() { }); it('enables nested relationship routes - hasMany findById', function(done) { - var test = this; + const test = this; this.get('/api/books/' + test.book.id + '/pages/' + test.page.id + '/notes/' + test.note.id) .expect(200, function(err, res) { if (err) return done(err); @@ -1681,13 +1681,13 @@ describe('relations - integration', function() { }); it('should nest remote hooks of ModelTo - hasMany findById', function(done) { - var test = this; + const test = this; this.get('/api/books/' + test.book.id + '/chapters/' + test.chapter.id + '/notes/' + test.cnote.id) .expect(200, function(err, res) { if (err) return done(err); - expect(res.headers['x-before']).to.empty(); - expect(res.headers['x-after']).to.empty(); + expect(res.headers['x-before']).to.be.undefined(); + expect(res.headers['x-after']).to.be.undefined(); done(); }); @@ -1696,7 +1696,7 @@ describe('relations - integration', function() { it('should have proper http.path for remoting', function() { [app.models.Book, app.models.Image].forEach(function(Model) { Model.sharedClass.methods().forEach(function(method) { - var http = Array.isArray(method.http) ? method.http : [method.http]; + const http = Array.isArray(method.http) ? method.http : [method.http]; http.forEach(function(opt) { // destroyAll has been shared but missing http property if (opt.path === undefined) return; @@ -1708,7 +1708,7 @@ describe('relations - integration', function() { }); it('should catch error if nested function throws', function(done) { - var test = this; + const test = this; this.get('/api/books/' + test.book.id + '/pages/' + this.page.id + '/throws') .end(function(err, res) { if (err) return done(err); @@ -1725,10 +1725,10 @@ describe('relations - integration', function() { }); describe('hasOne', function() { - var cust; + let cust; before(function createCustomer(done) { - var test = this; + const test = this; app.models.customer.create({name: 'John'}, function(err, c) { if (err) return done(err); @@ -1739,7 +1739,7 @@ describe('relations - integration', function() { }); after(function(done) { - var self = this; + const self = this; this.app.models.customer.destroyAll(function(err) { if (err) return done(err); @@ -1748,7 +1748,7 @@ describe('relations - integration', function() { }); it('should create the referenced model', function(done) { - var url = '/api/customers/' + cust.id + '/profile'; + const url = '/api/customers/' + cust.id + '/profile'; this.post(url) .send({points: 10}) @@ -1763,7 +1763,7 @@ describe('relations - integration', function() { }); it('should find the referenced model', function(done) { - var url = '/api/customers/' + cust.id + '/profile'; + const url = '/api/customers/' + cust.id + '/profile'; this.get(url) .expect(200, function(err, res) { if (err) return done(err); @@ -1776,7 +1776,7 @@ describe('relations - integration', function() { }); it('should not create the referenced model twice', function(done) { - var url = '/api/customers/' + cust.id + '/profile'; + const url = '/api/customers/' + cust.id + '/profile'; this.post(url) .send({points: 20}) .expect(500, function(err, res) { @@ -1785,7 +1785,7 @@ describe('relations - integration', function() { }); it('should update the referenced model', function(done) { - var url = '/api/customers/' + cust.id + '/profile'; + const url = '/api/customers/' + cust.id + '/profile'; this.put(url) .send({points: 100}) .expect(200, function(err, res) { @@ -1799,7 +1799,7 @@ describe('relations - integration', function() { }); it('should delete the referenced model', function(done) { - var url = '/api/customers/' + cust.id + '/profile'; + const url = '/api/customers/' + cust.id + '/profile'; this.del(url) .expect(204, function(err, res) { done(err); @@ -1807,7 +1807,7 @@ describe('relations - integration', function() { }); it('should not find the referenced model', function(done) { - var url = '/api/customers/' + cust.id + '/profile'; + const url = '/api/customers/' + cust.id + '/profile'; this.get(url) .expect(404, function(err, res) { done(err); diff --git a/test/remote-connector.test.js b/test/remote-connector.test.js index 4b8196a5..44152e6f 100644 --- a/test/remote-connector.test.js +++ b/test/remote-connector.test.js @@ -4,18 +4,18 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var loopback = require('../'); -var defineModelTestsWithDataSource = require('./util/model-tests'); +const assert = require('assert'); +const loopback = require('../'); +const defineModelTestsWithDataSource = require('./util/model-tests'); describe('RemoteConnector', function() { this.timeout(10000); - var remoteApp, remote; + let remoteApp, remote; defineModelTestsWithDataSource({ beforeEach: function(done) { - var test = this; + const test = this; remoteApp = loopback(); remoteApp.set('remoting', { errorHandler: {debug: true, log: false}, @@ -40,7 +40,7 @@ describe('RemoteConnector', function() { enableRemoteReplication: true, onDefine: function(Model) { - var ServerModel = Model.extend('Server' + Model.modelName, {}, { + const ServerModel = Model.extend('Server' + Model.modelName, {}, { plural: Model.pluralModelName, // This is the model running on the server & attached to a real // datasource, that's the place where to keep track of changes @@ -54,13 +54,13 @@ describe('RemoteConnector', function() { }); beforeEach(function(done) { - var test = this; + const test = this; remoteApp = this.remoteApp = loopback(); remoteApp.set('remoting', { types: {warnWhenOverridingType: false}, }); remoteApp.use(loopback.rest()); - var ServerModel = this.ServerModel = loopback.PersistedModel.extend('TestModel'); + const ServerModel = this.ServerModel = loopback.PersistedModel.extend('TestModel'); remoteApp.model(ServerModel); @@ -76,11 +76,11 @@ describe('RemoteConnector', function() { }); it('should support the save method', function(done) { - var calledServerCreate = false; - var RemoteModel = loopback.PersistedModel.extend('TestModel'); + let calledServerCreate = false; + const RemoteModel = loopback.PersistedModel.extend('TestModel'); RemoteModel.attachTo(this.remote); - var ServerModel = this.ServerModel; + const ServerModel = this.ServerModel; ServerModel.create = function(data, options, cb) { calledServerCreate = true; @@ -90,7 +90,7 @@ describe('RemoteConnector', function() { ServerModel.setupRemoting(); - var m = new RemoteModel({foo: 'bar'}); + const m = new RemoteModel({foo: 'bar'}); m.save(function(err, inst) { if (err) return done(err); diff --git a/test/remoting-coercion.test.js b/test/remoting-coercion.test.js index e0656ff6..38cbcea8 100644 --- a/test/remoting-coercion.test.js +++ b/test/remoting-coercion.test.js @@ -4,17 +4,17 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var loopback = require('../'); -var request = require('supertest'); +const assert = require('assert'); +const loopback = require('../'); +const request = require('supertest'); describe('remoting coercion', function() { it('should coerce arguments based on the type', function(done) { - var called = false; - var app = loopback(); + let called = false; + const app = loopback(); app.use(loopback.rest()); - var TestModel = app.registry.createModel('TestModel', + const TestModel = app.registry.createModel('TestModel', {}, {base: 'Model'}); app.model(TestModel, {public: true}); diff --git a/test/remoting.integration.js b/test/remoting.integration.js index a41305db..411798ff 100644 --- a/test/remoting.integration.js +++ b/test/remoting.integration.js @@ -4,13 +4,13 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../'); -var lt = require('./helpers/loopback-testing-helper'); -var path = require('path'); -var SIMPLE_APP = path.join(__dirname, 'fixtures', 'simple-integration-app'); -var app = require(path.join(SIMPLE_APP, 'server/server.js')); -var assert = require('assert'); -var expect = require('./helpers/expect'); +const loopback = require('../'); +const lt = require('./helpers/loopback-testing-helper'); +const path = require('path'); +const SIMPLE_APP = path.join(__dirname, 'fixtures', 'simple-integration-app'); +const app = require(path.join(SIMPLE_APP, 'server/server.js')); +const assert = require('assert'); +const expect = require('./helpers/expect'); describe('remoting - integration', function() { lt.beforeEach.withApp(app); @@ -22,21 +22,21 @@ describe('remoting - integration', function() { describe('app.remotes.options', function() { it('should load remoting options', function() { - var remotes = app.remotes(); + const remotes = app.remotes(); assert.deepEqual(remotes.options, {'json': {'limit': '1kb', 'strict': false}, 'urlencoded': {'limit': '8kb', 'extended': true}, 'errorHandler': {'debug': true, log: false}}); }); it('rest handler', function() { - var handler = app.handler('rest'); + const handler = app.handler('rest'); assert(handler); }); it('should accept request that has entity below 1kb', function(done) { // Build an object that is smaller than 1kb - var name = ''; - for (var i = 0; i < 256; i++) { + let name = ''; + for (let i = 0; i < 256; i++) { name += '11'; } this.http = this.post('/api/stores'); @@ -55,8 +55,8 @@ describe('remoting - integration', function() { it('should reject request that has entity beyond 1kb', function(done) { // Build an object that is larger than 1kb - var name = ''; - for (var i = 0; i < 2048; i++) { + let name = ''; + for (let i = 0; i < 2048; i++) { name += '11111111111'; } this.http = this.post('/api/stores'); @@ -79,10 +79,10 @@ describe('remoting - integration', function() { it('has expected remote methods with default model.settings.replaceOnPUT' + 'set to true (3.x)', function() { - var storeClass = findClass('store'); - var methods = getFormattedMethodsExcludingRelations(storeClass.methods); + const storeClass = findClass('store'); + const methods = getFormattedMethodsExcludingRelations(storeClass.methods); - var expectedMethods = [ + const expectedMethods = [ 'create(data:object:store):store POST /stores', 'patchOrCreate(data:object:store):store PATCH /stores', 'replaceOrCreate(data:object:store):store PUT /stores', @@ -106,10 +106,10 @@ describe('remoting - integration', function() { }); it('has expected remote methods for scopes', function() { - var storeClass = findClass('store'); - var methods = getFormattedScopeMethods(storeClass.methods); + const storeClass = findClass('store'); + const methods = getFormattedScopeMethods(storeClass.methods); - var expectedMethods = [ + const expectedMethods = [ '__get__superStores(filter:object):store GET /stores/superStores', '__create__superStores(data:object:store):store POST /stores/superStores', '__delete__superStores() DELETE /stores/superStores', @@ -121,10 +121,10 @@ describe('remoting - integration', function() { it('should have correct signatures for belongsTo methods', function() { - var widgetClass = findClass('widget'); - var methods = getFormattedPrototypeMethods(widgetClass.methods); + const widgetClass = findClass('widget'); + const methods = getFormattedPrototypeMethods(widgetClass.methods); - var expectedMethods = [ + const expectedMethods = [ 'prototype.__get__store(refresh:boolean):store ' + 'GET /widgets/:id/store', ]; @@ -133,10 +133,10 @@ describe('remoting - integration', function() { it('should have correct signatures for hasMany methods', function() { - var storeClass = findClass('store'); - var methods = getFormattedPrototypeMethods(storeClass.methods); + const storeClass = findClass('store'); + const methods = getFormattedPrototypeMethods(storeClass.methods); - var expectedMethods = [ + const expectedMethods = [ 'prototype.__findById__widgets(fk:any):widget ' + 'GET /stores/:id/widgets/:fk', 'prototype.__destroyById__widgets(fk:any) ' + @@ -157,10 +157,10 @@ describe('remoting - integration', function() { it('should have correct signatures for hasMany-through methods', function() { // jscs:disable validateIndentation - var physicianClass = findClass('physician'); - var methods = getFormattedPrototypeMethods(physicianClass.methods); + const physicianClass = findClass('physician'); + const methods = getFormattedPrototypeMethods(physicianClass.methods); - var expectedMethods = [ + const expectedMethods = [ 'prototype.__findById__patients(fk:any):patient ' + 'GET /physicians/:id/patients/:fk', 'prototype.__destroyById__patients(fk:any) ' + @@ -187,9 +187,9 @@ describe('remoting - integration', function() { }); it('has upsertWithWhere remote method', function() { - var storeClass = findClass('store'); - var methods = getFormattedMethodsExcludingRelations(storeClass.methods); - var expectedMethods = [ + const storeClass = findClass('store'); + const methods = getFormattedMethodsExcludingRelations(storeClass.methods); + const expectedMethods = [ 'upsertWithWhere(where:object,data:object:store):store POST /stores/upsertWithWhere', ]; expect(methods).to.include.members(expectedMethods); @@ -198,21 +198,21 @@ describe('remoting - integration', function() { describe('createOnlyInstance', function() { it('sets createOnlyInstance to true if id is generated and forceId is not set to false', function() { - var storeClass = findClass('store'); - var createMethod = getCreateMethod(storeClass.methods); + const storeClass = findClass('store'); + const createMethod = getCreateMethod(storeClass.methods); assert(createMethod.accepts[0].createOnlyInstance === true); }); it('sets createOnlyInstance to false if forceId is set to false in the model', function() { - var customerClass = findClass('customerforceidfalse'); - var createMethod = getCreateMethod(customerClass.methods); + const customerClass = findClass('customerforceidfalse'); + const createMethod = getCreateMethod(customerClass.methods); assert(createMethod.accepts[0].createOnlyInstance === false); }); it('sets createOnlyInstance based on target model for scoped or related methods', function() { - var userClass = findClass('user'); - var createMethod = userClass.methods.find(function(m) { + const userClass = findClass('user'); + const createMethod = userClass.methods.find(function(m) { return (m.name === 'prototype.__create__accessTokens'); }); assert(createMethod.accepts[0].createOnlyInstance === false); @@ -229,10 +229,10 @@ describe('With model.settings.replaceOnPUT false', function() { it('should have expected remote methods', function() { - var storeClass = findClass('storeWithReplaceOnPUTfalse'); - var methods = getFormattedMethodsExcludingRelations(storeClass.methods); + const storeClass = findClass('storeWithReplaceOnPUTfalse'); + const methods = getFormattedMethodsExcludingRelations(storeClass.methods); - var expectedMethods = [ + const expectedMethods = [ 'create(data:object:storeWithReplaceOnPUTfalse):storeWithReplaceOnPUTfalse POST /stores-updating', 'patchOrCreate(data:object:storeWithReplaceOnPUTfalse):storeWithReplaceOnPUTfalse PUT /stores-updating', 'patchOrCreate(data:object:storeWithReplaceOnPUTfalse):storeWithReplaceOnPUTfalse PATCH /stores-updating', @@ -266,10 +266,10 @@ describe('With model.settings.replaceOnPUT true', function() { it('should have expected remote methods', function() { - var storeClass = findClass('storeWithReplaceOnPUTtrue'); - var methods = getFormattedMethodsExcludingRelations(storeClass.methods); + const storeClass = findClass('storeWithReplaceOnPUTtrue'); + const methods = getFormattedMethodsExcludingRelations(storeClass.methods); - var expectedMethods = [ + const expectedMethods = [ 'patchOrCreate(data:object:storeWithReplaceOnPUTtrue):storeWithReplaceOnPUTtrue PATCH /stores-replacing', 'replaceOrCreate(data:object:storeWithReplaceOnPUTtrue):storeWithReplaceOnPUTtrue POST /stores-replacing/replaceOrCreate', 'replaceOrCreate(data:object:storeWithReplaceOnPUTtrue):storeWithReplaceOnPUTtrue PUT /stores-replacing', @@ -283,11 +283,11 @@ describe('With model.settings.replaceOnPUT true', function() { }); function formatReturns(m) { - var returns = m.returns; + const returns = m.returns; if (!returns || returns.length === 0) { return ''; } - var type = returns[0].type; + let type = returns[0].type; // handle anonymous type definitions, e.g // { arg: 'info', type: { count: 'number' } } @@ -298,9 +298,9 @@ function formatReturns(m) { } function formatMethod(m) { - var arr = []; - var endpoints = m.getEndpoints(); - for (var i = 0; i < endpoints.length; i++) { + const arr = []; + const endpoints = m.getEndpoints(); + for (let i = 0; i < endpoints.length; i++) { arr.push([ m.name, '(', diff --git a/test/replication.rest.test.js b/test/replication.rest.test.js index f8f0ab4c..f0d423e3 100644 --- a/test/replication.rest.test.js +++ b/test/replication.rest.test.js @@ -4,25 +4,25 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var async = require('async'); -var debug = require('debug')('test'); -var extend = require('util')._extend; -var loopback = require('../'); -var expect = require('./helpers/expect'); -var supertest = require('supertest'); +const async = require('async'); +const debug = require('debug')('test'); +const extend = require('util')._extend; +const loopback = require('../'); +const expect = require('./helpers/expect'); +const supertest = require('supertest'); describe('Replication over REST', function() { this.timeout(10000); - var ALICE = {id: 'a', username: 'alice', email: 'a@t.io', password: 'p'}; - var PETER = {id: 'p', username: 'peter', email: 'p@t.io', password: 'p'}; - var EMERY = {id: 'e', username: 'emery', email: 'e@t.io', password: 'p'}; + const ALICE = {id: 'a', username: 'alice', email: 'a@t.io', password: 'p'}; + const PETER = {id: 'p', username: 'peter', email: 'p@t.io', password: 'p'}; + const EMERY = {id: 'e', username: 'emery', email: 'e@t.io', password: 'p'}; /* eslint-disable one-var */ - var serverApp, serverUrl, ServerUser, ServerCar, serverCars; - var aliceId, peterId, aliceToken, peterToken, emeryToken, request; - var clientApp, LocalUser, LocalCar, RemoteUser, RemoteCar, clientCars; - var conflictedCarId; + let serverApp, serverUrl, ServerUser, ServerCar, serverCars; + let aliceId, peterId, aliceToken, peterToken, emeryToken, request; + let clientApp, LocalUser, LocalCar, RemoteUser, RemoteCar, clientCars; + let conflictedCarId; /* eslint-enable one-var */ before(setupServer); @@ -177,7 +177,7 @@ describe('Replication over REST', function() { }); describe('conflict resolution with model-level permissions', function() { - var LocalConflict, RemoteConflict; + let LocalConflict, RemoteConflict; before(function setupConflictModels() { LocalConflict = LocalCar.getChangeModel().Conflict; @@ -189,7 +189,7 @@ describe('Replication over REST', function() { describe('as anonymous user', function() { it('rejects resolve() on the client', function(done) { // simulate replication Client->Server - var conflict = new LocalConflict( + const conflict = new LocalConflict( conflictedCarId, LocalCar, RemoteCar @@ -199,7 +199,7 @@ describe('Replication over REST', function() { it('rejects resolve() on the server', function(done) { // simulate replication Server->Client - var conflict = new RemoteConflict( + const conflict = new RemoteConflict( conflictedCarId, RemoteCar, LocalCar @@ -215,7 +215,7 @@ describe('Replication over REST', function() { it('allows resolve() on the client', function(done) { // simulate replication Client->Server - var conflict = new LocalConflict( + const conflict = new LocalConflict( conflictedCarId, LocalCar, RemoteCar @@ -225,7 +225,7 @@ describe('Replication over REST', function() { it('rejects resolve() on the server', function(done) { // simulate replication Server->Client - var conflict = new RemoteConflict( + const conflict = new RemoteConflict( conflictedCarId, RemoteCar, LocalCar @@ -332,7 +332,7 @@ describe('Replication over REST', function() { if (conflicts.length) return done(conflictError(conflicts)); LocalUser.find(function(err, users) { - var userNames = users.map(function(u) { return u.username; }); + const userNames = users.map(function(u) { return u.username; }); expect(userNames).to.eql([ALICE.username]); done(); @@ -413,11 +413,11 @@ describe('Replication over REST', function() { } }); - var USER_PROPS = { + const USER_PROPS = { id: {type: 'string', id: true}, }; - var USER_OPTS = { + const USER_OPTS = { base: 'User', plural: 'Users', // use the same REST path in all models trackChanges: true, @@ -427,13 +427,13 @@ describe('Replication over REST', function() { saltWorkFactor: 4, }; - var CAR_PROPS = { + const CAR_PROPS = { id: {type: 'string', id: true, defaultFn: 'guid'}, model: {type: 'string', required: true}, maker: {type: 'string'}, }; - var CAR_OPTS = { + const CAR_OPTS = { base: 'PersistedModel', plural: 'Cars', // use the same REST path in all models trackChanges: true, @@ -477,7 +477,7 @@ describe('Replication over REST', function() { // Setup a custom access-token model that is not shared // with the client app - var ServerToken = serverApp.registry.createModel('ServerToken', {}, { + const ServerToken = serverApp.registry.createModel('ServerToken', {}, { base: 'AccessToken', relations: { user: { @@ -531,7 +531,7 @@ describe('Replication over REST', function() { // model. This causes the in-process replication to work differently // than client-server replication. // As a workaround, we manually setup unique Checkpoint for ClientModel. - var ClientCheckpoint = clientApp.registry.createModel({ + const ClientCheckpoint = clientApp.registry.createModel({ name: 'ClientCheckpoint', base: 'Checkpoint', }); @@ -545,7 +545,7 @@ describe('Replication over REST', function() { LocalCar.Change.Checkpoint = ClientCheckpoint; clientApp.model(LocalCar, {dataSource: 'db'}); - var remoteOpts = createRemoteModelOpts(USER_OPTS); + let remoteOpts = createRemoteModelOpts(USER_OPTS); RemoteUser = clientApp.registry.createModel('RemoteUser', USER_PROPS, remoteOpts); clientApp.model(RemoteUser, {dataSource: 'remote'}); @@ -690,7 +690,7 @@ describe('Replication over REST', function() { } function conflictError(conflicts) { - var err = new Error('Unexpected conflicts\n' + + const err = new Error('Unexpected conflicts\n' + conflicts.map(JSON.stringify).join('\n')); err.name = 'ConflictError'; } diff --git a/test/replication.test.js b/test/replication.test.js index e97aeb40..5a8efea9 100644 --- a/test/replication.test.js +++ b/test/replication.test.js @@ -4,26 +4,26 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var async = require('async'); -var loopback = require('../'); -var Change = loopback.Change; -var defineModelTestsWithDataSource = require('./util/model-tests'); -var PersistedModel = loopback.PersistedModel; -var expect = require('./helpers/expect'); -var debug = require('debug')('test'); -var runtime = require('./../lib/runtime'); +const assert = require('assert'); +const async = require('async'); +const loopback = require('../'); +const Change = loopback.Change; +const defineModelTestsWithDataSource = require('./util/model-tests'); +const PersistedModel = loopback.PersistedModel; +const expect = require('./helpers/expect'); +const debug = require('debug')('test'); +const runtime = require('./../lib/runtime'); describe('Replication / Change APIs', function() { this.timeout(10000); - var dataSource, SourceModel, TargetModel, useSinceFilter; - var tid = 0; // per-test unique id used e.g. to build unique model names + let dataSource, SourceModel, TargetModel, useSinceFilter; + let tid = 0; // per-test unique id used e.g. to build unique model names beforeEach(function() { tid++; useSinceFilter = false; - var test = this; + const test = this; dataSource = this.dataSource = loopback.createDataSource({ connector: loopback.Memory, }); @@ -45,7 +45,7 @@ describe('Replication / Change APIs', function() { // model. This causes the in-process replication to work differently // than client-server replication. // As a workaround, we manually setup unique Checkpoint for TargetModel. - var TargetChange = TargetModel.Change; + const TargetChange = TargetModel.Change; TargetChange.Checkpoint = loopback.Checkpoint.extend('TargetCheckpoint'); TargetChange.Checkpoint.attachTo(dataSource); @@ -66,7 +66,7 @@ describe('Replication / Change APIs', function() { describe('cleanup check for enableChangeTracking', function() { describe('when no changeCleanupInterval set', function() { it('should call rectifyAllChanges if running on server', function(done) { - var calls = mockRectifyAllChanges(SourceModel); + const calls = mockRectifyAllChanges(SourceModel); SourceModel.enableChangeTracking(); if (runtime.isServer) { @@ -80,7 +80,7 @@ describe('Replication / Change APIs', function() { }); describe('when changeCleanupInterval set to -1', function() { - var Model; + let Model; beforeEach(function() { Model = this.Model = PersistedModel.extend( 'Model-' + tid, @@ -92,7 +92,7 @@ describe('Replication / Change APIs', function() { }); it('should not call rectifyAllChanges', function(done) { - var calls = mockRectifyAllChanges(Model); + const calls = mockRectifyAllChanges(Model); Model.enableChangeTracking(); expect(calls).to.eql([]); done(); @@ -100,7 +100,7 @@ describe('Replication / Change APIs', function() { }); describe('when changeCleanupInterval set to 10000', function() { - var Model; + let Model; beforeEach(function() { Model = this.Model = PersistedModel.extend( 'Model-' + tid, @@ -112,7 +112,7 @@ describe('Replication / Change APIs', function() { }); it('should call rectifyAllChanges if running on server', function(done) { - var calls = mockRectifyAllChanges(Model); + const calls = mockRectifyAllChanges(Model); Model.enableChangeTracking(); if (runtime.isServer) { expect(calls).to.eql(['rectifyAllChanges']); @@ -125,7 +125,7 @@ describe('Replication / Change APIs', function() { }); function mockRectifyAllChanges(Model) { - var calls = []; + const calls = []; Model.rectifyAllChanges = function(cb) { calls.push('rectifyAllChanges'); @@ -138,7 +138,7 @@ describe('Replication / Change APIs', function() { describe('optimization check rectifyChange Vs rectifyAllChanges', function() { beforeEach(function initialData(done) { - var data = [{name: 'John', surname: 'Doe'}, {name: 'Jane', surname: 'Roe'}]; + const data = [{name: 'John', surname: 'Doe'}, {name: 'Jane', surname: 'Roe'}]; async.waterfall([ function(callback) { SourceModel.create(data, callback); @@ -151,7 +151,7 @@ describe('Replication / Change APIs', function() { }); it('should call rectifyAllChanges if no id is passed for rectifyOnDelete', function(done) { - var calls = mockSourceModelRectify(); + const calls = mockSourceModelRectify(); SourceModel.destroyAll({name: 'John'}, function(err, data) { if (err) return done(err); @@ -162,8 +162,8 @@ describe('Replication / Change APIs', function() { }); it('should call rectifyAllChanges if no id is passed for rectifyOnSave', function(done) { - var calls = mockSourceModelRectify(); - var newData = {'name': 'Janie'}; + const calls = mockSourceModelRectify(); + const newData = {'name': 'Janie'}; SourceModel.update({name: 'Jane'}, newData, function(err, data) { if (err) return done(err); @@ -175,7 +175,7 @@ describe('Replication / Change APIs', function() { it('rectifyOnDelete for Delete should call rectifyChange instead of rectifyAllChanges', function(done) { - var calls = mockTargetModelRectify(); + const calls = mockTargetModelRectify(); async.waterfall([ function(callback) { SourceModel.destroyAll({name: 'John'}, callback); @@ -195,8 +195,8 @@ describe('Replication / Change APIs', function() { it('rectifyOnSave for Update should call rectifyChange instead of rectifyAllChanges', function(done) { - var calls = mockTargetModelRectify(); - var newData = {'name': 'Janie'}; + const calls = mockTargetModelRectify(); + const newData = {'name': 'Janie'}; async.waterfall([ function(callback) { SourceModel.update({name: 'Jane'}, newData, callback); @@ -216,8 +216,8 @@ describe('Replication / Change APIs', function() { it('rectifyOnSave for Create should call rectifyChange instead of rectifyAllChanges', function(done) { - var calls = mockTargetModelRectify(); - var newData = [{name: 'Janie', surname: 'Doe'}]; + const calls = mockTargetModelRectify(); + const newData = [{name: 'Janie', surname: 'Doe'}]; async.waterfall([ function(callback) { SourceModel.create(newData, callback); @@ -236,7 +236,7 @@ describe('Replication / Change APIs', function() { }); function mockSourceModelRectify() { - var calls = []; + const calls = []; SourceModel.rectifyChange = function(id, cb) { calls.push('rectifyChange'); @@ -252,7 +252,7 @@ describe('Replication / Change APIs', function() { } function mockTargetModelRectify() { - var calls = []; + const calls = []; TargetModel.rectifyChange = function(id, cb) { calls.push('rectifyChange'); @@ -270,7 +270,7 @@ describe('Replication / Change APIs', function() { describe('Model.changes(since, filter, callback)', function() { it('Get changes since the given checkpoint', function(done) { - var test = this; + const test = this; this.SourceModel.create({name: 'foo'}, function(err) { if (err) return done(err); @@ -285,7 +285,7 @@ describe('Replication / Change APIs', function() { }); it('excludes changes from older checkpoints', function(done) { - var FUTURE_CHECKPOINT = 999; + const FUTURE_CHECKPOINT = 999; SourceModel.create({name: 'foo'}, function(err) { if (err) return done(err); @@ -302,8 +302,8 @@ describe('Replication / Change APIs', function() { describe('Model.replicate(since, targetModel, options, callback)', function() { it('Replicate data using the target model', function(done) { - var test = this; - var options = {}; + const test = this; + const options = {}; this.SourceModel.create({name: 'foo'}, function(err) { if (err) return done(err); @@ -319,8 +319,8 @@ describe('Replication / Change APIs', function() { }); it('Replicate data using the target model - promise variant', function(done) { - var test = this; - var options = {}; + const test = this; + const options = {}; this.SourceModel.create({name: 'foo'}, function(err) { if (err) return done(err); @@ -403,7 +403,7 @@ describe('Replication / Change APIs', function() { // Because the "since" filter is just an optimization, // there isn't really any observable behaviour we could // check to assert correct implementation. - var diffSince = []; + const diffSince = []; spyAndStoreSinceArg(TargetModel, 'diff', diffSince); SourceModel.replicate(10, TargetModel, function(err) { @@ -419,7 +419,7 @@ describe('Replication / Change APIs', function() { // Because the "since" filter is just an optimization, // there isn't really any observable behaviour we could // check to assert correct implementation. - var diffSince = []; + const diffSince = []; spyAndStoreSinceArg(TargetModel, 'diff', diffSince); SourceModel.replicate(10, TargetModel, {}) @@ -434,13 +434,13 @@ describe('Replication / Change APIs', function() { }); it('uses different "since" value for source and target', function(done) { - var sourceSince = []; - var targetSince = []; + const sourceSince = []; + const targetSince = []; spyAndStoreSinceArg(SourceModel, 'changes', sourceSince); spyAndStoreSinceArg(TargetModel, 'diff', targetSince); - var since = {source: 1, target: 2}; + const since = {source: 1, target: 2}; SourceModel.replicate(since, TargetModel, function(err) { if (err) return done(err); @@ -452,13 +452,13 @@ describe('Replication / Change APIs', function() { }); it('uses different "since" value for source and target - promise variant', function(done) { - var sourceSince = []; - var targetSince = []; + const sourceSince = []; + const targetSince = []; spyAndStoreSinceArg(SourceModel, 'changes', sourceSince); spyAndStoreSinceArg(TargetModel, 'diff', targetSince); - var since = {source: 1, target: 2}; + const since = {source: 1, target: 2}; SourceModel.replicate(since, TargetModel, {}) .then(function() { expect(sourceSince).to.eql([1]); @@ -478,7 +478,7 @@ describe('Replication / Change APIs', function() { SourceModel.create({id: 'racer'}, cb); }); - var lastCp; + let lastCp; async.series([ function buildSomeDataToReplicate(next) { SourceModel.create({id: 'init'}, next); @@ -522,7 +522,7 @@ describe('Replication / Change APIs', function() { }); it('returns new current checkpoints to callback', function(done) { - var sourceCp, targetCp; + let sourceCp, targetCp; async.series([ bumpSourceCheckpoint, bumpTargetCheckpoint, @@ -603,7 +603,7 @@ describe('Replication / Change APIs', function() { }, function replicateWith3rdPartyModifyingData(next) { setupRaceConditionInReplication(function(cb) { - var connector = TargetModel.dataSource.connector; + const connector = TargetModel.dataSource.connector; if (connector.updateAttributes.length <= 4) { connector.updateAttributes( TargetModel.modelName, @@ -628,7 +628,7 @@ describe('Replication / Change APIs', function() { function(err, conflicts, cps, updates) { if (err) return next(err); - var conflictedIds = getPropValue(conflicts || [], 'modelId'); + const conflictedIds = getPropValue(conflicts || [], 'modelId'); expect(conflictedIds).to.eql(['1']); // resolve the conflict using ours @@ -648,7 +648,7 @@ describe('Replication / Change APIs', function() { // of UPDATE is fixed to correctly remove properties createModel(SourceModel, {id: '1', name: 'source'}), function replicateWith3rdPartyModifyingData(next) { - var connector = TargetModel.dataSource.connector; + const connector = TargetModel.dataSource.connector; setupRaceConditionInReplication(function(cb) { if (connector.create.length <= 3) { connector.create( @@ -672,7 +672,7 @@ describe('Replication / Change APIs', function() { function(err, conflicts, cps, updates) { if (err) return next(err); - var conflictedIds = getPropValue(conflicts || [], 'modelId'); + const conflictedIds = getPropValue(conflicts || [], 'modelId'); expect(conflictedIds).to.eql(['1']); // resolve the conflict using ours @@ -695,7 +695,7 @@ describe('Replication / Change APIs', function() { }, function replicateWith3rdPartyModifyingData(next) { setupRaceConditionInReplication(function(cb) { - var connector = TargetModel.dataSource.connector; + const connector = TargetModel.dataSource.connector; if (connector.updateAttributes.length <= 4) { connector.updateAttributes( TargetModel.modelName, @@ -720,7 +720,7 @@ describe('Replication / Change APIs', function() { function(err, conflicts, cps, updates) { if (err) return next(err); - var conflictedIds = getPropValue(conflicts || [], 'modelId'); + const conflictedIds = getPropValue(conflicts || [], 'modelId'); expect(conflictedIds).to.eql(['1']); // resolve the conflict using ours @@ -742,7 +742,7 @@ describe('Replication / Change APIs', function() { SourceModel.deleteById('1', next); }, function setup3rdPartyModifyingData(next) { - var connector = TargetModel.dataSource.connector; + const connector = TargetModel.dataSource.connector; setupRaceConditionInReplication(function(cb) { if (connector.destroy.length <= 3) { connector.destroy( @@ -772,9 +772,9 @@ describe('Replication / Change APIs', function() { describe('conflict detection - both updated', function() { beforeEach(function(done) { - var SourceModel = this.SourceModel; - var TargetModel = this.TargetModel; - var test = this; + const SourceModel = this.SourceModel; + const TargetModel = this.TargetModel; + const test = this; test.createInitalData(createConflict); @@ -820,7 +820,7 @@ describe('Replication / Change APIs', function() { }); }); it('conflict.changes()', function(done) { - var test = this; + const test = this; this.conflict.changes(function(err, sourceChange, targetChange) { assert.equal(typeof sourceChange.id, 'string'); assert.equal(typeof targetChange.id, 'string'); @@ -832,7 +832,7 @@ describe('Replication / Change APIs', function() { }); }); it('conflict.models()', function(done) { - var test = this; + const test = this; this.conflict.models(function(err, source, target) { assert.deepEqual(source.toJSON(), { id: test.model.id, @@ -850,9 +850,9 @@ describe('Replication / Change APIs', function() { describe('conflict detection - source deleted', function() { beforeEach(function(done) { - var SourceModel = this.SourceModel; - var TargetModel = this.TargetModel; - var test = this; + const SourceModel = this.SourceModel; + const TargetModel = this.TargetModel; + const test = this; test.createInitalData(createConflict); @@ -900,7 +900,7 @@ describe('Replication / Change APIs', function() { }); }); it('conflict.changes()', function(done) { - var test = this; + const test = this; this.conflict.changes(function(err, sourceChange, targetChange) { assert.equal(typeof sourceChange.id, 'string'); assert.equal(typeof targetChange.id, 'string'); @@ -912,7 +912,7 @@ describe('Replication / Change APIs', function() { }); }); it('conflict.models()', function(done) { - var test = this; + const test = this; this.conflict.models(function(err, source, target) { assert.equal(source, null); assert.deepEqual(target.toJSON(), { @@ -927,9 +927,9 @@ describe('Replication / Change APIs', function() { describe('conflict detection - target deleted', function() { beforeEach(function(done) { - var SourceModel = this.SourceModel; - var TargetModel = this.TargetModel; - var test = this; + const SourceModel = this.SourceModel; + const TargetModel = this.TargetModel; + const test = this; test.createInitalData(createConflict); @@ -976,7 +976,7 @@ describe('Replication / Change APIs', function() { }); }); it('conflict.changes()', function(done) { - var test = this; + const test = this; this.conflict.changes(function(err, sourceChange, targetChange) { assert.equal(typeof sourceChange.id, 'string'); assert.equal(typeof targetChange.id, 'string'); @@ -988,7 +988,7 @@ describe('Replication / Change APIs', function() { }); }); it('conflict.models()', function(done) { - var test = this; + const test = this; this.conflict.models(function(err, source, target) { assert.equal(target, null); assert.deepEqual(source.toJSON(), { @@ -1003,9 +1003,9 @@ describe('Replication / Change APIs', function() { describe('conflict detection - both deleted', function() { beforeEach(function(done) { - var SourceModel = this.SourceModel; - var TargetModel = this.TargetModel; - var test = this; + const SourceModel = this.SourceModel; + const TargetModel = this.TargetModel; + const test = this; test.createInitalData(createConflict); @@ -1059,7 +1059,7 @@ describe('Replication / Change APIs', function() { givenReplicatedInstance(function(err, created) { if (err) return done(err); - var data = created.toObject(); + const data = created.toObject(); created.name = 'updated'; SourceModel.updateOrCreate(created, function(err, inst) { if (err) return done(err); @@ -1214,7 +1214,7 @@ describe('Replication / Change APIs', function() { if (err) return cb(err); expect(pendingChanges, 'list of changes').to.have.length(1); - var change = pendingChanges[0].toObject(); + const change = pendingChanges[0].toObject(); expect(change).to.have.property('checkpoint', cp); // sanity check expect(change).to.have.property('modelName', SourceModel.modelName); // NOTE(bajtos) Change.modelId is always String @@ -1228,7 +1228,7 @@ describe('Replication / Change APIs', function() { }); describe('complex setup', function() { - var sourceInstance, sourceInstanceId, AnotherModel; + let sourceInstance, sourceInstanceId, AnotherModel; beforeEach(function createReplicatedInstance(done) { async.series([ @@ -1256,7 +1256,7 @@ describe('Replication / Change APIs', function() { // model. This causes the in-process replication to work differently // than client-server replication. // As a workaround, we manually setup unique Checkpoint for AnotherModel. - var AnotherChange = AnotherModel.Change; + const AnotherChange = AnotherModel.Change; AnotherChange.Checkpoint = loopback.Checkpoint.extend('AnotherCheckpoint'); AnotherChange.Checkpoint.attachTo(dataSource); @@ -1298,7 +1298,7 @@ describe('Replication / Change APIs', function() { }); describe('clientA-server-clientB', function() { - var ClientA, Server, ClientB; + let ClientA, Server, ClientB; beforeEach(function() { ClientA = SourceModel; @@ -1606,8 +1606,8 @@ describe('Replication / Change APIs', function() { }); describe('ensure options object is set on context during bulkUpdate', function() { - var syncPropertyExists = false; - var OptionsSourceModel; + let syncPropertyExists = false; + let OptionsSourceModel; beforeEach(function() { OptionsSourceModel = PersistedModel.extend( @@ -1629,8 +1629,8 @@ describe('Replication / Change APIs', function() { }); it('bulkUpdate should call Model updates with the provided options object', function(done) { - var testData = {name: 'Janie', surname: 'Doe'}; - var updates = [ + const testData = {name: 'Janie', surname: 'Doe'}; + const updates = [ { data: null, change: null, @@ -1638,7 +1638,7 @@ describe('Replication / Change APIs', function() { }, ]; - var options = { + const options = { sync: true, }; @@ -1666,8 +1666,8 @@ describe('Replication / Change APIs', function() { describe('ensure bulkUpdate works with just 2 args', function() { it('bulkUpdate should successfully finish without options', function(done) { - var testData = {name: 'Janie', surname: 'Doe'}; - var updates = [{ + const testData = {name: 'Janie', surname: 'Doe'}; + const updates = [{ data: null, change: null, type: 'create', @@ -1694,7 +1694,7 @@ describe('Replication / Change APIs', function() { describe('Replication with chunking', function() { beforeEach(function() { - var test = this; + const test = this; SourceModel = this.SourceModel = PersistedModel.extend( 'SourceModel-' + tid, {id: {id: true, type: String, defaultFn: 'guid'}}, @@ -1709,7 +1709,7 @@ describe('Replication / Change APIs', function() { {trackChanges: true, replicationChunkSize: 1} ); - var TargetChange = TargetModel.Change; + const TargetChange = TargetModel.Change; TargetChange.Checkpoint = loopback.Checkpoint.extend('TargetCheckpoint'); TargetChange.Checkpoint.attachTo(dataSource); @@ -1720,9 +1720,9 @@ describe('Replication / Change APIs', function() { describe('Model.replicate(since, targetModel, options, callback)', function() { it('calls bulkUpdate multiple times', function(done) { - var test = this; - var options = {}; - var calls = mockBulkUpdate(TargetModel); + const test = this; + const options = {}; + const calls = mockBulkUpdate(TargetModel); SourceModel.create([{name: 'foo'}, {name: 'bar'}], function(err) { if (err) return done(err); @@ -1742,7 +1742,7 @@ describe('Replication / Change APIs', function() { describe('Replication without chunking', function() { beforeEach(function() { - var test = this; + const test = this; SourceModel = this.SourceModel = PersistedModel.extend( 'SourceModel-' + tid, {id: {id: true, type: String, defaultFn: 'guid'}}, @@ -1757,7 +1757,7 @@ describe('Replication / Change APIs', function() { {trackChanges: true} ); - var TargetChange = TargetModel.Change; + const TargetChange = TargetModel.Change; TargetChange.Checkpoint = loopback.Checkpoint.extend('TargetCheckpoint'); TargetChange.Checkpoint.attachTo(dataSource); @@ -1768,9 +1768,9 @@ describe('Replication / Change APIs', function() { describe('Model.replicate(since, targetModel, options, callback)', function() { it('calls bulkUpdate only once', function(done) { - var test = this; - var options = {}; - var calls = mockBulkUpdate(TargetModel); + const test = this; + const options = {}; + const calls = mockBulkUpdate(TargetModel); SourceModel.create([{name: 'foo'}, {name: 'bar'}], function(err) { if (err) return done(err); @@ -1789,9 +1789,9 @@ describe('Replication / Change APIs', function() { }); function mockBulkUpdate(modelToMock) { - var calls = []; + const calls = []; - var originalBulkUpdateFunction = modelToMock.bulkUpdate; + const originalBulkUpdateFunction = modelToMock.bulkUpdate; modelToMock.bulkUpdate = function(since, filter, callback) { calls.push('bulkUpdate'); @@ -1801,14 +1801,14 @@ describe('Replication / Change APIs', function() { return calls; } - var _since = {}; + const _since = {}; function replicate(source, target, since, next) { if (typeof since === 'function') { next = since; since = undefined; } - var sinceIx = source.modelName + ':to:' + target.modelName; + const sinceIx = source.modelName + ':to:' + target.modelName; if (since === undefined) { since = useSinceFilter ? _since[sinceIx] || -1 : @@ -1854,11 +1854,11 @@ describe('Replication / Change APIs', function() { } function setupRaceConditionInReplication(fn) { - var bulkUpdate = TargetModel.bulkUpdate; + const bulkUpdate = TargetModel.bulkUpdate; TargetModel.bulkUpdate = function(data, options, cb) { // simulate the situation when a 3rd party modifies the database // while a replication run is in progress - var self = this; + const self = this; fn(function(err) { if (err) return cb(err); @@ -1889,7 +1889,7 @@ describe('Replication / Change APIs', function() { } function spyAndStoreSinceArg(Model, methodName, store) { - var orig = Model[methodName]; + const orig = Model[methodName]; Model[methodName] = function(since) { store.push(since); orig.apply(this, arguments); @@ -1908,7 +1908,7 @@ describe('Replication / Change APIs', function() { function assertTargetModelEqualsSourceModel(conflicts, sourceModel, targetModel, done) { - var sourceData, targetData; + let sourceData, targetData; assert(conflicts.length === 0); async.parallel([ @@ -1940,13 +1940,13 @@ describe('Replication / Change APIs', function() { describe('Replication / Change APIs with custom change properties', function() { this.timeout(10000); - var dataSource, useSinceFilter, SourceModel, TargetModel, startingCheckpoint; - var tid = 0; // per-test unique id used e.g. to build unique model names + let dataSource, useSinceFilter, SourceModel, TargetModel, startingCheckpoint; + let tid = 0; // per-test unique id used e.g. to build unique model names beforeEach(function() { tid++; useSinceFilter = false; - var test = this; + const test = this; dataSource = this.dataSource = loopback.createDataSource({ connector: loopback.Memory, @@ -1994,7 +1994,7 @@ describe('Replication / Change APIs with custom change properties', function() { } ); - var ChangeModelForTarget = TargetModel.Change; + const ChangeModelForTarget = TargetModel.Change; ChangeModelForTarget.Checkpoint = loopback.Checkpoint.extend('TargetCheckpoint'); ChangeModelForTarget.Checkpoint.attachTo(dataSource); @@ -2005,8 +2005,8 @@ describe('Replication / Change APIs with custom change properties', function() { describe('Model._defineChangeModel()', function() { it('defines change model with custom properties', function() { - var changeModel = SourceModel.getChangeModel(); - var changeModelProperties = changeModel.definition.properties; + const changeModel = SourceModel.getChangeModel(); + const changeModelProperties = changeModel.definition.properties; expect(changeModelProperties).to.have.property('customProperty'); }); @@ -2016,7 +2016,7 @@ describe('Replication / Change APIs with custom change properties', function() { beforeEach(givenSomeSourceModelInstances); it('queries changes using customized filter', function(done) { - var filterUsed = mockChangeFind(this.SourceModel); + const filterUsed = mockChangeFind(this.SourceModel); SourceModel.changes( startingCheckpoint, @@ -2057,7 +2057,7 @@ describe('Replication / Change APIs with custom change properties', function() { }); function mockChangeFind(Model) { - var filterUsed = []; + const filterUsed = []; Model.getChangeModel().find = function(filter, cb) { filterUsed.push(filter); diff --git a/test/rest.middleware.test.js b/test/rest.middleware.test.js index 84797d58..13878d9b 100644 --- a/test/rest.middleware.test.js +++ b/test/rest.middleware.test.js @@ -4,22 +4,22 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var expect = require('./helpers/expect'); -var loopback = require('../'); -var path = require('path'); -var request = require('supertest'); +const assert = require('assert'); +const expect = require('./helpers/expect'); +const loopback = require('../'); +const path = require('path'); +const request = require('supertest'); describe('loopback.rest', function() { this.timeout(10000); - var app, MyModel; + let app, MyModel; beforeEach(function() { // override the global app object provided by test/support.js // and create a local one that does not share state with other tests app = loopback({localRegistry: true, loadBuiltinModels: true}); app.set('remoting', {errorHandler: {debug: true, log: false}}); - var db = app.dataSource('db', {connector: 'memory'}); + const db = app.dataSource('db', {connector: 'memory'}); MyModel = app.registry.createModel('MyModel'); MyModel.attachTo(db); }); @@ -54,7 +54,7 @@ describe('loopback.rest', function() { .end(function(err, res) { if (err) return done(err); - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert(errorResponse); assert.equal(errorResponse.code, 'MODEL_NOT_FOUND'); @@ -121,10 +121,10 @@ describe('loopback.rest', function() { }); it('should honour `remoting.rest.supportedTypes`', function(done) { - var app = loopback({localRegistry: true}); + const app = loopback({localRegistry: true}); // NOTE it is crucial to set `remoting` before creating any models - var supportedTypes = ['json', 'application/javascript', 'text/javascript']; + const supportedTypes = ['json', 'application/javascript', 'text/javascript']; app.set('remoting', {rest: {supportedTypes: supportedTypes}}); app.model(MyModel); @@ -137,7 +137,7 @@ describe('loopback.rest', function() { }); it('allows models to provide a custom HTTP path', function(done) { - var CustomModel = app.registry.createModel('CustomModel', + const CustomModel = app.registry.createModel('CustomModel', {name: String}, {http: {'path': 'domain1/CustomModelPath'}}); @@ -148,7 +148,7 @@ describe('loopback.rest', function() { }); it('should report 200 for url-encoded HTTP path', function(done) { - var CustomModel = app.registry.createModel('CustomModel', + const CustomModel = app.registry.createModel('CustomModel', {name: String}, {http: {path: 'domain%20one/CustomModelPath'}}); @@ -174,7 +174,7 @@ describe('loopback.rest', function() { }); it('does not include loopback.token when auth not enabled', function(done) { - var User = givenUserModelWithAuth(); + const User = givenUserModelWithAuth(); User.getToken = function(req, cb) { cb(null, req.accessToken ? req.accessToken.id : null); }; @@ -261,9 +261,9 @@ describe('loopback.rest', function() { }); function givenUserModelWithAuth() { - var AccessToken = app.registry.getModel('AccessToken'); + const AccessToken = app.registry.getModel('AccessToken'); app.model(AccessToken, {dataSource: 'db'}); - var User = app.registry.getModel('User'); + const User = app.registry.getModel('User'); // Speed up the password hashing algorithm for tests User.settings.saltWorkFactor = 4; app.model(User, {dataSource: 'db'}); @@ -281,8 +281,8 @@ describe('loopback.rest', function() { } function givenLoggedInUser(cb, done) { - var credentials = {email: 'user@example.com', password: 'pwd'}; - var User = app.models.User; + const credentials = {email: 'user@example.com', password: 'pwd'}; + const User = app.models.User; User.create(credentials, function(err, user) { if (err) return done(err); @@ -300,14 +300,14 @@ describe('loopback.rest', function() { describe('with specific definitions in model-config.json', function() { it('should not be exposed when the definition value is false', function(done) { - var app = require(getFixturePath('model-config-defined-false')); + const app = require(getFixturePath('model-config-defined-false')); request(app) .get('/todos') .expect(404, done); }); it('should be exposed when the definition value is true', function(done) { - var app = require(getFixturePath('model-config-defined-true')); + const app = require(getFixturePath('model-config-defined-true')); request(app) .get('/todos') .expect(200, done); @@ -317,14 +317,14 @@ describe('loopback.rest', function() { describe('with default definitions in model-config.json', function() { it('should not be exposed when the definition value is false', function(done) { - var app = require(getFixturePath('model-config-default-false')); + const app = require(getFixturePath('model-config-default-false')); request(app) .get('/todos') .expect(404, done); }); it('should be exposed when the definition value is true', function(done) { - var app = require(getFixturePath('model-config-default-true')); + const app = require(getFixturePath('model-config-default-true')); app.models.Todo.create([ {content: 'a'}, {content: 'b'}, @@ -347,7 +347,7 @@ describe('loopback.rest', function() { describe('with specific definitions in config.json', function() { it('should not be exposed when the definition value is false', function(done) { - var app = require(getFixturePath('config-defined-false')); + const app = require(getFixturePath('config-defined-false')); request(app) .get('/todos') .expect(404, done); @@ -355,7 +355,7 @@ describe('loopback.rest', function() { it('should be exposed when the definition value is true', function(done) { - var app = require(getFixturePath('config-defined-true')); + const app = require(getFixturePath('config-defined-true')); request(app) .get('/todos') .expect(200, done); @@ -365,14 +365,14 @@ describe('loopback.rest', function() { describe('with default definitions in config.json', function() { it('should not be exposed when the definition value is false', function(done) { - var app = require(getFixturePath('config-default-false')); + const app = require(getFixturePath('config-default-false')); request(app) .get('/todos') .expect(404, done); }); it('should be exposed when the definition value is true', function(done) { - var app = require(getFixturePath('config-default-true')); + const app = require(getFixturePath('config-default-true')); app.models.Todo.create([ {content: 'a'}, {content: 'b'}, @@ -399,7 +399,7 @@ describe('loopback.rest', function() { describe.skip('with definitions in both config.json and model-config.json', function() { it('should prioritize the settings in model-config.json', function(done) { - var app = require(getFixturePath('both-configs-set')); + const app = require(getFixturePath('both-configs-set')); request(app) .del('/todos') .expect(404, done); @@ -407,7 +407,7 @@ describe('loopback.rest', function() { it('should fall back to config.json settings if setting is not found in' + 'model-config.json', function(done) { - var app = require(getFixturePath('both-configs-set')); + const app = require(getFixturePath('both-configs-set')); request(app) .get('/todos') .expect(404, done); diff --git a/test/role-mapping.test.js b/test/role-mapping.test.js index a2d043d2..cfe3a5a4 100644 --- a/test/role-mapping.test.js +++ b/test/role-mapping.test.js @@ -4,15 +4,15 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var expect = require('./helpers/expect'); -var loopback = require('../'); -var Promise = require('bluebird'); +const expect = require('./helpers/expect'); +const loopback = require('../'); +const Promise = require('bluebird'); describe('role-mapping model', function() { this.timeout(10000); - var app, oneUser, anApp, aRole; - var models = {}; + let app, oneUser, anApp, aRole; + const models = {}; beforeEach(function() { app = loopback({localRegistry: true, loadBuiltinModels: true}); @@ -39,7 +39,7 @@ describe('role-mapping model', function() { // helper function setupModel(modelName) { - var model = app.registry.getModel(modelName); + const model = app.registry.getModel(modelName); app.model(model, {dataSource: 'db'}); models[modelName] = model; } diff --git a/test/role.test.js b/test/role.test.js index ba3e5024..23d72a55 100644 --- a/test/role.test.js +++ b/test/role.test.js @@ -4,13 +4,13 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var sinon = require('sinon'); -var loopback = require('../index'); -var async = require('async'); -var extend = require('util')._extend; -var expect = require('./helpers/expect'); -var Promise = require('bluebird'); +const assert = require('assert'); +const sinon = require('sinon'); +const loopback = require('../index'); +const async = require('async'); +const extend = require('util')._extend; +const expect = require('./helpers/expect'); +const Promise = require('bluebird'); function checkResult(err, result) { assert(!err); @@ -19,7 +19,7 @@ function checkResult(err, result) { describe('role model', function() { this.timeout(10000); - var app, Role, RoleMapping, User, Application, ACL; + let app, Role, RoleMapping, User, Application, ACL; beforeEach(function() { // Use local app registry to ensure models are isolated to avoid @@ -153,7 +153,7 @@ describe('role model', function() { Role.create({name: 'userRole'}, function(err, role) { expect(err).to.exist(); expect(err).to.have.property('name', 'ValidationError'); - expect(err).to.have.deep.property('details.codes.name'); + expect(err).to.have.nested.property('details.codes.name'); expect(err.details.codes.name).to.contain('uniqueness'); expect(err).to.have.property('statusCode', 422); @@ -324,12 +324,12 @@ describe('role model', function() { }); it('supports isInRole() returning a Promise', function(done) { - var userData = {name: 'Raymond', email: 'x@y.com', password: 'foobar'}; + const userData = {name: 'Raymond', email: 'x@y.com', password: 'foobar'}; User.create(userData, function(err, user) { if (err) return done(err); Role.create({name: 'userRole'}, function(err, role) { if (err) return done(err); - var principalData = { + const principalData = { principalType: RoleMapping.USER, principalId: user.id, }; @@ -347,12 +347,12 @@ describe('role model', function() { }); it('supports getRole() returning a Promise', function(done) { - var userData = {name: 'Raymond', email: 'x@y.com', password: 'foobar'}; + const userData = {name: 'Raymond', email: 'x@y.com', password: 'foobar'}; User.create(userData, function(err, user) { if (err) return done(err); Role.create({name: 'userRole'}, function(err, role) { if (err) return done(err); - var principalData = { + const principalData = { principalType: RoleMapping.USER, principalId: user.id, }; @@ -374,8 +374,8 @@ describe('role model', function() { }); it('should be properly authenticated with 0 userId', function(done) { - var userData = {name: 'Raymond', email: 'x@y.com', password: 'foobar', id: 0}; - var TestUser = app.registry.createModel({ + const userData = {name: 'Raymond', email: 'x@y.com', password: 'foobar', id: 0}; + const TestUser = app.registry.createModel({ name: 'TestUser', base: 'User', // forceId is set to false so we can create a user with a known ID, @@ -444,7 +444,7 @@ describe('role model', function() { }); }); - var Album = app.registry.createModel('Album', { + const Album = app.registry.createModel('Album', { name: String, userId: Number, }, { @@ -541,7 +541,7 @@ describe('role model', function() { function(next) { Album.create({name: 'Album 1', userId: user.id}, function(err, album1) { if (err) return done(err); - var role = { + let role = { principalType: ACL.USER, principalId: user.id, model: Album, id: album1.id, }; @@ -569,16 +569,16 @@ describe('role model', function() { }); describe('$owner role resolver', function() { - var sender, receiver; - var users = [ + let sender, receiver; + const users = [ {username: 'sender', email: 'sender@example.com', password: 'pass'}, {username: 'receiver', email: 'receiver@example.com', password: 'pass'}, ]; describe('ownerRelations not set (legacy behaviour)', () => { it('resolves the owner via property "userId"', function() { - var user; - var Album = app.registry.createModel('Album', { + let user; + const Album = app.registry.createModel('Album', { name: String, userId: Number, }); @@ -601,8 +601,8 @@ describe('role model', function() { }); it('resolves the owner via property "owner"', function() { - var user; - var Album = app.registry.createModel('Album', { + let user; + const Album = app.registry.createModel('Album', { name: String, owner: Number, }); @@ -627,11 +627,11 @@ describe('role model', function() { it('resolves the owner via a belongsTo relation', function() { // passing no options will result calling // the legacy $owner role resolver behavior - var Message = givenModelWithSenderReceiverRelations('ModelWithNoOptions'); + const Message = givenModelWithSenderReceiverRelations('ModelWithNoOptions'); return givenUsers() .then(() => { - var messages = [ + const messages = [ {content: 'firstMessage', senderId: sender.id}, {content: 'secondMessage', receiverId: receiver.id}, {content: 'thirdMessage'}, @@ -658,8 +658,8 @@ describe('role model', function() { }); it('resolves as false without belongsTo relation', function() { - var user; - var Album = app.registry.createModel( + let user; + const Album = app.registry.createModel( 'Album', { name: String, @@ -691,14 +691,14 @@ describe('role model', function() { it('resolves the owner using the corrent belongsTo relation', function() { // passing {ownerRelations: true} will enable the new $owner role resolver // with any belongsTo relation allowing to resolve truthy - var Message = givenModelWithSenderReceiverRelations( + const Message = givenModelWithSenderReceiverRelations( 'ModelWithAllRelations', {ownerRelations: true} ); return givenUsers() .then(() => { - var messages = [ + const messages = [ {content: 'firstMessage', senderId: sender.id}, {content: 'secondMessage', receiverId: receiver.id}, {content: 'thirdMessage'}, @@ -727,14 +727,14 @@ describe('role model', function() { function() { // passing {ownerRelations: true} will enable the new $owner role resolver // with a specified list of belongsTo relations allowing to resolve truthy - var Message = givenModelWithSenderReceiverRelations( + const Message = givenModelWithSenderReceiverRelations( 'ModelWithCoercedRelations', {ownerRelations: ['receiver']} ); return givenUsers() .then(() => { - var messages = [ + const messages = [ {content: 'firstMessage', senderId: sender.id}, {content: 'secondMessage', receiverId: receiver.id}, {content: 'thirdMessage'}, @@ -771,7 +771,7 @@ describe('role model', function() { } function isOwnerForMessage(user, msg) { - var accessContext = { + const accessContext = { principalType: ACL.USER, principalId: user.id, model: msg.constructor, @@ -788,7 +788,7 @@ describe('role model', function() { } function givenModelWithSenderReceiverRelations(name, options) { - var baseOptions = { + const baseOptions = { relations: { sender: { type: 'belongsTo', @@ -803,7 +803,7 @@ describe('role model', function() { }, }; options = extend(baseOptions, options); - var Model = app.registry.createModel( + const Model = app.registry.createModel( name, {content: String}, options @@ -843,7 +843,7 @@ describe('role model', function() { }); describe('isMappedToRole', function() { - var user, app, role; + let user, app, role; beforeEach(function(done) { User.create({ @@ -873,7 +873,7 @@ describe('role model', function() { if (err) return done(err); role = r; - var principals = [ + const principals = [ { principalType: ACL.USER, principalId: user.id, @@ -999,7 +999,7 @@ describe('role model', function() { }); describe('listByPrincipalType', function() { - var sandbox; + let sandbox; beforeEach(function() { sandbox = sinon.sandbox.create(); @@ -1010,27 +1010,26 @@ describe('role model', function() { }); it('should fetch all models assigned to the role', function(done) { - var principalTypesToModels = {}; - var runs = 0; - var mappings; + const principalTypesToModels = {}; + let runs = 0; principalTypesToModels[RoleMapping.USER] = User; principalTypesToModels[RoleMapping.APPLICATION] = Application; principalTypesToModels[RoleMapping.ROLE] = Role; - mappings = Object.keys(principalTypesToModels); + const mappings = Object.keys(principalTypesToModels); mappings.forEach(function(principalType) { - var Model = principalTypesToModels[principalType]; + const Model = principalTypesToModels[principalType]; Model.create({name: 'test', email: 'x@y.com', password: 'foobar'}, function(err, model) { if (err) return done(err); - var uniqueRoleName = 'testRoleFor' + principalType; + const uniqueRoleName = 'testRoleFor' + principalType; Role.create({name: uniqueRoleName}, function(err, role) { if (err) return done(err); role.principals.create({principalType: principalType, principalId: model.id}, function(err, p) { if (err) return done(err); - var pluralName = Model.pluralModelName.toLowerCase(); + const pluralName = Model.pluralModelName.toLowerCase(); role[pluralName](function(err, models) { if (err) return done(err); assert.equal(models.length, 1); @@ -1046,16 +1045,16 @@ describe('role model', function() { }); it('should fetch all models only assigned to the role', function(done) { - var principalTypesToModels = {}; - var mappings; + const principalTypesToModels = {}; principalTypesToModels[RoleMapping.USER] = User; principalTypesToModels[RoleMapping.APPLICATION] = Application; principalTypesToModels[RoleMapping.ROLE] = Role; - mappings = Object.keys(principalTypesToModels); + + const mappings = Object.keys(principalTypesToModels); async.each(mappings, function(principalType, eachCallback) { - var Model = principalTypesToModels[principalType]; + const Model = principalTypesToModels[principalType]; async.waterfall([ // Create models @@ -1072,8 +1071,8 @@ describe('role model', function() { // Create Roles function(models, next) { - var uniqueRoleName = 'testRoleFor' + principalType; - var otherUniqueRoleName = 'otherTestRoleFor' + principalType; + const uniqueRoleName = 'testRoleFor' + principalType; + const otherUniqueRoleName = 'otherTestRoleFor' + principalType; Role.create([ {name: uniqueRoleName}, {name: otherUniqueRoleName}], @@ -1111,8 +1110,8 @@ describe('role model', function() { // Run tests against unique Role function(models, roles, principles, next) { - var pluralName = Model.pluralModelName.toLowerCase(); - var uniqueRole = roles[0]; + const pluralName = Model.pluralModelName.toLowerCase(); + const uniqueRole = roles[0]; uniqueRole[pluralName](function(err, models) { if (err) return done(err); assert.equal(models.length, 1); @@ -1133,7 +1132,7 @@ describe('role model', function() { role.principals.create({principalType: RoleMapping.USER, principalId: user.id}, function(err, p) { if (err) return done(err); - var query = {fields: ['id', 'name']}; + const query = {fields: ['id', 'name']}; sandbox.spy(User, 'find'); role.users(query, function(err, users) { if (err) return done(err); @@ -1149,12 +1148,12 @@ describe('role model', function() { }); it('supports Promise API', function(done) { - var userData = {name: 'Raymond', email: 'x@y.com', password: 'foobar'}; + const userData = {name: 'Raymond', email: 'x@y.com', password: 'foobar'}; User.create(userData, function(err, user) { if (err) return done(err); Role.create({name: 'userRole'}, function(err, role) { if (err) return done(err); - var principalData = { + const principalData = { principalType: RoleMapping.USER, principalId: user.id, }; @@ -1162,7 +1161,7 @@ describe('role model', function() { if (err) return done(err); role.users() .then(function(users) { - var userIds = users.map(function(u) { return u.id; }); + const userIds = users.map(function(u) { return u.id; }); expect(userIds).to.eql([user.id]); done(); }) @@ -1175,19 +1174,19 @@ describe('role model', function() { describe('isOwner', function() { it('supports app-local model registry', function(done) { - var app = loopback({localRegistry: true, loadBuiltinModels: true}); + const app = loopback({localRegistry: true, loadBuiltinModels: true}); app.dataSource('db', {connector: 'memory'}); // attach all auth-related models to 'db' datasource app.enableAuth({dataSource: 'db'}); - var Role = app.models.Role; - var User = app.models.User; + const Role = app.models.Role; + const User = app.models.User; // Speed up the password hashing algorithm for tests User.settings.saltWorkFactor = 4; - var u = app.registry.findModel('User'); - var credentials = {email: 'test@example.com', password: 'pass'}; + const u = app.registry.findModel('User'); + const credentials = {email: 'test@example.com', password: 'pass'}; User.create(credentials, function(err, user) { if (err) return done(err); @@ -1202,7 +1201,7 @@ describe('role model', function() { }); it('supports Promise API', function(done) { - var credentials = {email: 'test@example.com', password: 'pass'}; + const credentials = {email: 'test@example.com', password: 'pass'}; User.create(credentials, function(err, user) { if (err) return done(err); diff --git a/test/user.integration.js b/test/user.integration.js index 526a7f9e..c9eda550 100644 --- a/test/user.integration.js +++ b/test/user.integration.js @@ -4,12 +4,12 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../'); -var lt = require('./helpers/loopback-testing-helper'); -var path = require('path'); -var SIMPLE_APP = path.join(__dirname, 'fixtures', 'user-integration-app'); -var app = require(path.join(SIMPLE_APP, 'server/server.js')); -var expect = require('./helpers/expect'); +const loopback = require('../'); +const lt = require('./helpers/loopback-testing-helper'); +const path = require('path'); +const SIMPLE_APP = path.join(__dirname, 'fixtures', 'user-integration-app'); +const app = require(path.join(SIMPLE_APP, 'server/server.js')); +const expect = require('./helpers/expect'); const Promise = require('bluebird'); const waitForEvent = require('./helpers/wait-for-event'); @@ -33,7 +33,7 @@ describe('users - integration', function() { }); describe('base-user', function() { - var userId, accessToken; + let userId, accessToken; it('should create a new user', function(done) { this.post('/api/users') @@ -49,7 +49,7 @@ describe('users - integration', function() { }); it('should log into the user', function(done) { - var url = '/api/users/login'; + const url = '/api/users/login'; this.post(url) .send({username: 'x', email: 'x@y.com', password: 'x'}) @@ -97,7 +97,7 @@ describe('users - integration', function() { }); it('should create post for a given user', function(done) { - var url = '/api/users/' + userId + '/posts?access_token=' + accessToken; + const url = '/api/users/' + userId + '/posts?access_token=' + accessToken; this.post(url) .send({title: 'T1', content: 'C1'}) .expect(200, function(err, res) { @@ -114,13 +114,13 @@ describe('users - integration', function() { // FIXME: [rfeng] The test is passing if run alone. But it fails with // `npm test` as the loopback models are polluted by other tests it('should prevent access tokens from being included', function(done) { - var url = '/api/posts?filter={"include":{"user":"accessTokens"}}'; + const url = '/api/posts?filter={"include":{"user":"accessTokens"}}'; this.get(url) .expect(200, function(err, res) { if (err) return done(err); expect(res.body).to.have.property('length', 1); - var post = res.body[0]; + const post = res.body[0]; expect(post.user).to.have.property('username', 'x'); expect(post.user).to.not.have.property('accessTokens'); @@ -129,8 +129,8 @@ describe('users - integration', function() { }); it('should preserve current session when invalidating tokens', function(done) { - var url = '/api/users/' + userId; - var self = this; + const url = '/api/users/' + userId; + const self = this; this.patch(url) .send({email: 'new@example.com'}) .set('Authorization', accessToken) @@ -274,10 +274,10 @@ describe('users - integration', function() { }); describe('sub-user', function() { - var userId, accessToken; + let userId, accessToken; it('should create a new user', function(done) { - var url = '/api/myUsers'; + const url = '/api/myUsers'; this.post(url) .send({username: 'x', email: 'x@y.com', password: 'x'}) @@ -292,7 +292,7 @@ describe('users - integration', function() { }); it('should log into the user', function(done) { - var url = '/api/myUsers/login'; + const url = '/api/myUsers/login'; this.post(url) .send({username: 'x', email: 'x@y.com', password: 'x'}) @@ -307,7 +307,7 @@ describe('users - integration', function() { }); it('should create blog for a given user', function(done) { - var url = '/api/myUsers/' + userId + '/blogs?access_token=' + accessToken; + const url = '/api/myUsers/' + userId + '/blogs?access_token=' + accessToken; this.post(url) .send({title: 'T1', content: 'C1'}) .expect(200, function(err, res) { @@ -325,13 +325,13 @@ describe('users - integration', function() { }); it('should prevent access tokens from being included', function(done) { - var url = '/api/blogs?filter={"include":{"user":"accessTokens"}}'; + const url = '/api/blogs?filter={"include":{"user":"accessTokens"}}'; this.get(url) .expect(200, function(err, res) { if (err) return done(err); expect(res.body).to.have.property('length', 1); - var blog = res.body[0]; + const blog = res.body[0]; expect(blog.user).to.have.property('username', 'x'); expect(blog.user).to.not.have.property('accessTokens'); diff --git a/test/user.test.js b/test/user.test.js index 2ab2f535..a7f31fae 100644 --- a/test/user.test.js +++ b/test/user.test.js @@ -4,41 +4,41 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var expect = require('./helpers/expect'); -var request = require('supertest'); -var loopback = require('../'); -var async = require('async'); -var url = require('url'); -var extend = require('util')._extend; +const assert = require('assert'); +const expect = require('./helpers/expect'); +const request = require('supertest'); +const loopback = require('../'); +const async = require('async'); +const url = require('url'); +const extend = require('util')._extend; const Promise = require('bluebird'); const waitForEvent = require('./helpers/wait-for-event'); -var User, AccessToken; +let User, AccessToken; describe('User', function() { this.timeout(10000); - var validCredentialsEmail = 'foo@bar.com'; - var validCredentials = {email: validCredentialsEmail, password: 'bar'}; - var validCredentialsEmailVerified = { + const validCredentialsEmail = 'foo@bar.com'; + const validCredentials = {email: validCredentialsEmail, password: 'bar'}; + const validCredentialsEmailVerified = { email: 'foo1@bar.com', password: 'bar1', emailVerified: true}; - var validCredentialsEmailVerifiedOverREST = { + const validCredentialsEmailVerifiedOverREST = { email: 'foo2@bar.com', password: 'bar2', emailVerified: true}; - var validCredentialsWithRealm = { + const validCredentialsWithRealm = { email: 'foo3@bar.com', password: 'bar', realm: 'foobar'}; - var validCredentialsWithTTL = {email: 'foo@bar.com', password: 'bar', ttl: 3600}; - var validCredentialsWithTTLAndScope = { + const validCredentialsWithTTL = {email: 'foo@bar.com', password: 'bar', ttl: 3600}; + const validCredentialsWithTTLAndScope = { email: 'foo@bar.com', password: 'bar', ttl: 3600, scope: 'all'}; - var validMixedCaseEmailCredentials = {email: 'Foo@bar.com', password: 'bar'}; - var invalidCredentials = {email: 'foo1@bar.com', password: 'invalid'}; - var incompleteCredentials = {password: 'bar1'}; - var validCredentialsUser, validCredentialsEmailVerifiedUser, user; + const validMixedCaseEmailCredentials = {email: 'Foo@bar.com', password: 'bar'}; + const invalidCredentials = {email: 'foo1@bar.com', password: 'invalid'}; + const incompleteCredentials = {password: 'bar1'}; + let validCredentialsUser, validCredentialsEmailVerifiedUser, user; // Create a local app variable to prevent clashes with the global // variable shared by all tests. While this should not be necessary if // the tests were written correctly, it turns out that's not the case :( - var app = null; + let app = null; beforeEach(function setupAppAndModels() { // override the global app object provided by test/support.js @@ -52,7 +52,7 @@ describe('User', function() { connector: loopback.Mail, transports: [{type: 'STUB'}], }); - var Email = app.registry.getModel('Email'); + const Email = app.registry.getModel('Email'); app.model(Email, {dataSource: 'email'}); // attach User and related models @@ -167,7 +167,7 @@ describe('User', function() { // will change in future versions where password will be optional by default it('Password is required', function(done) { - var u = new User({email: '123@456.com'}); + const u = new User({email: '123@456.com'}); User.create({email: 'c@d.com'}, function(err) { assert(err); @@ -252,19 +252,19 @@ describe('User', function() { }); it('Hashes the given password', function() { - var u = new User({username: 'foo', password: 'bar'}); + const u = new User({username: 'foo', password: 'bar'}); assert(u.password !== 'bar'); }); it('does not hash the password if it\'s already hashed', function() { - var u1 = new User({username: 'foo', password: 'bar'}); + const u1 = new User({username: 'foo', password: 'bar'}); assert(u1.password !== 'bar'); - var u2 = new User({username: 'foo', password: u1.password}); + const u2 = new User({username: 'foo', password: u1.password}); assert(u2.password === u1.password); }); it('invalidates the user\'s accessToken when the user is deleted By id', function(done) { - var usersId; + let usersId; async.series([ function(next) { User.create({email: 'b@c.com', password: 'bar'}, function(err, user) { @@ -319,8 +319,8 @@ describe('User', function() { }); it('invalidates the user\'s accessToken when the user is deleted all', function(done) { - var userIds = []; - var users; + let userIds = []; + let users; async.series([ function(next) { User.create([ @@ -371,7 +371,7 @@ describe('User', function() { }); describe('custom password hash', function() { - var defaultHashPassword, defaultValidatePassword; + let defaultHashPassword, defaultValidatePassword; beforeEach(function() { defaultHashPassword = User.hashPassword; @@ -396,7 +396,7 @@ describe('User', function() { it('Reports invalid password', function() { try { - var u = new User({username: 'foo', password: 'aa'}); + const u = new User({username: 'foo', password: 'aa'}); assert(false, 'Error should have been thrown'); } catch (e) { // Ignore @@ -404,7 +404,7 @@ describe('User', function() { }); it('Hashes the given password', function() { - var u = new User({username: 'foo', password: 'bar'}); + const u = new User({username: 'foo', password: 'bar'}); assert(u.password === 'BAR'); }); }); @@ -426,9 +426,9 @@ describe('User', function() { }); describe('Password length validation', function() { - var pass72Char = new Array(70).join('a') + '012'; - var pass73Char = pass72Char + '3'; - var passTooLong = pass72Char + 'WXYZ1234'; + const pass72Char = new Array(70).join('a') + '012'; + const pass73Char = pass72Char + '3'; + const passTooLong = pass72Char + 'WXYZ1234'; it('rejects empty passwords creation', function(done) { User.create({email: 'b@c.com', password: ''}, function(err) { @@ -492,7 +492,7 @@ describe('User', function() { it('rejects a new user with password longer than 72 characters', function(done) { try { - var u = new User({username: 'foo', password: pass73Char}); + const u = new User({username: 'foo', password: pass73Char}); assert(false, 'Error should have been thrown'); } catch (e) { expect(e).to.match(/password entered was too long/); @@ -597,7 +597,7 @@ describe('User', function() { it('Should be able to use query filters (email case-sensitivity off)', function(done) { User.settings.caseSensitiveEmail = false; - var insensitiveUser = {email: 'insensitive@example.com', password: 'abc'}; + const insensitiveUser = {email: 'insensitive@example.com', password: 'abc'}; User.create(insensitiveUser, function(err, user) { User.find({where: {email: {inq: [insensitiveUser.email]}, @@ -612,7 +612,7 @@ describe('User', function() { it('Should be able to use query filters (email case-sensitivity on)', function(done) { User.settings.caseSensitiveEmail = true; - var sensitiveUser = {email: 'senSiTive@example.com', password: 'abc'}; + const sensitiveUser = {email: 'senSiTive@example.com', password: 'abc'}; User.create(sensitiveUser, function(err, user) { User.find({where: {email: {inq: [sensitiveUser.email]}, @@ -729,7 +729,7 @@ describe('User', function() { }); it('Login a user using a custom createAccessToken', function(done) { - var createToken = User.prototype.createAccessToken; // Save the original method + const createToken = User.prototype.createAccessToken; // Save the original method // Override createAccessToken User.prototype.createAccessToken = function(ttl, cb) { // Reduce the ttl by half for testing purpose @@ -754,7 +754,7 @@ describe('User', function() { it('Login a user using a custom createAccessToken with options', function(done) { - var createToken = User.prototype.createAccessToken; // Save the original method + const createToken = User.prototype.createAccessToken; // Save the original method // Override createAccessToken User.prototype.createAccessToken = function(ttl, options, cb) { // Reduce the ttl by half for testing purpose @@ -837,7 +837,7 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var accessToken = res.body; + const accessToken = res.body; assertGoodToken(accessToken, validCredentialsUser); assert(accessToken.user === undefined); @@ -855,7 +855,7 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert.equal(errorResponse.code, 'LOGIN_FAILED'); done(); @@ -871,7 +871,7 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert.equal(errorResponse.code, 'USERNAME_EMAIL_REQUIRED'); done(); @@ -888,7 +888,7 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert.equal(errorResponse.code, 'USERNAME_EMAIL_REQUIRED'); done(); @@ -904,7 +904,7 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var token = res.body; + const token = res.body; expect(token.user, 'body.user').to.not.equal(undefined); expect(token.user, 'body.user') .to.have.property('email', validCredentials.email); @@ -922,7 +922,7 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var token = res.body; + const token = res.body; expect(token.user, 'body.user').to.not.equal(undefined); expect(token.user, 'body.user') .to.have.property('email', validCredentials.email); @@ -933,9 +933,9 @@ describe('User', function() { it('allows login with password too long but created in old LB version', function(done) { - var bcrypt = require('bcryptjs'); - var longPassword = new Array(80).join('a'); - var oldHash = bcrypt.hashSync(longPassword, bcrypt.genSaltSync(1)); + const bcrypt = require('bcryptjs'); + const longPassword = new Array(80).join('a'); + const oldHash = bcrypt.hashSync(longPassword, bcrypt.genSaltSync(1)); User.create({email: 'b@c.com', password: oldHash}, function(err) { if (err) return done(err); @@ -1047,7 +1047,7 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var accessToken = res.body; + const accessToken = res.body; assertGoodToken(accessToken, validCredentialsEmailVerifiedUser); assert(accessToken.user === undefined); @@ -1070,7 +1070,7 @@ describe('User', function() { // strongloop/loopback#931 // error message should be "login failed" // and not "login failed as the email has not been verified" - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert(errorResponse && !/verified/.test(errorResponse.message), 'expecting "login failed" error message, received: "' + errorResponse.message + '"'); assert.equal(errorResponse.code, 'LOGIN_FAILED'); @@ -1091,10 +1091,10 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var errorResponse = res.body.error; + const errorResponse = res.body.error; // extracting code and details error response - let errorExcerpts = { + const errorExcerpts = { code: errorResponse.code, details: errorResponse.details, }; @@ -1112,7 +1112,7 @@ describe('User', function() { }); describe('User.login requiring realm', function() { - var User, AccessToken; + let User, AccessToken; beforeEach(function() { User = app.registry.createModel('RealmUser', {}, { @@ -1136,57 +1136,57 @@ describe('User', function() { User.setMaxListeners(0); }); - var realm1User = { + const realm1User = { realm: 'realm1', username: 'foo100', email: 'foo100@bar.com', password: 'pass100', }; - var realm2User = { + const realm2User = { realm: 'realm2', username: 'foo100', email: 'foo100@bar.com', password: 'pass200', }; - var credentialWithoutRealm = { + const credentialWithoutRealm = { username: 'foo100', email: 'foo100@bar.com', password: 'pass100', }; - var credentialWithBadPass = { + const credentialWithBadPass = { realm: 'realm1', username: 'foo100', email: 'foo100@bar.com', password: 'pass001', }; - var credentialWithBadRealm = { + const credentialWithBadRealm = { realm: 'realm3', username: 'foo100', email: 'foo100@bar.com', password: 'pass100', }; - var credentialWithRealm = { + const credentialWithRealm = { realm: 'realm1', username: 'foo100', password: 'pass100', }; - var credentialRealmInUsername = { + const credentialRealmInUsername = { username: 'realm1:foo100', password: 'pass100', }; - var credentialRealmInEmail = { + const credentialRealmInEmail = { email: 'realm1:foo100@bar.com', password: 'pass100', }; - var user1 = null; + let user1 = null; beforeEach(function(done) { User.create(realm1User, function(err, u) { if (err) return done(err); @@ -1326,7 +1326,7 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var accessToken = res.body; + const accessToken = res.body; assertGoodToken(accessToken, validCredentialsUser); fn(null, accessToken.id); @@ -1375,7 +1375,7 @@ describe('User', function() { describe('user.hasPassword(plain, fn)', function() { it('Determine if the password matches the stored password', function(done) { - var u = new User({username: 'foo', password: 'bar'}); + const u = new User({username: 'foo', password: 'bar'}); u.hasPassword('bar', function(err, isMatch) { assert(isMatch, 'password doesnt match'); @@ -1384,7 +1384,7 @@ describe('User', function() { }); it('Determine if the password matches the stored password - promise variant', function(done) { - var u = new User({username: 'foo', password: 'bar'}); + const u = new User({username: 'foo', password: 'bar'}); u.hasPassword('bar') .then(function(isMatch) { assert(isMatch, 'password doesnt match'); @@ -1397,7 +1397,7 @@ describe('User', function() { }); it('should match a password when saved', function(done) { - var u = new User({username: 'a', password: 'b', email: 'z@z.net'}); + const u = new User({username: 'a', password: 'b', email: 'z@z.net'}); u.save(function(err, user) { User.findById(user.pk, function(err, uu) { @@ -1679,7 +1679,7 @@ describe('User', function() { type: 'email', from: 'test@example.com', }; - var verifyOptions = Object.assign({}, defaultOptions); + const verifyOptions = Object.assign({}, defaultOptions); const user = new User({ email: 'example@example.com', password: 'pass', @@ -1696,7 +1696,7 @@ describe('User', function() { from: 'test@example.com', }; User.settings.verifyOptions = Object.assign({}, defaultOptions); - var verifyOptions = User.getVerifyOptions(); + const verifyOptions = User.getVerifyOptions(); verifyOptions.from = 'newTest@example.com'; verifyOptions.test = 'test'; expect(User.getVerifyOptions()).to.eql(defaultOptions); @@ -1727,7 +1727,7 @@ describe('User', function() { assert(result.email); assert(result.email.response); assert(result.token); - var msg = result.email.response.toString('utf-8'); + const msg = result.email.response.toString('utf-8'); assert(~msg.indexOf('/api/test-users/confirm')); assert(~msg.indexOf('To: bar@bat.com')); @@ -1754,7 +1754,7 @@ describe('User', function() { assert(result.email); assert(result.email.response); assert(result.token); - var msg = result.email.response.toString('utf-8'); + const msg = result.email.response.toString('utf-8'); assert(~msg.indexOf('/api/test-users/confirm')); assert(~msg.indexOf('To: bar@bat.com')); @@ -1811,7 +1811,7 @@ describe('User', function() { assert(result.email); assert(result.email.response); assert(result.token); - var msg = result.email.response.toString('utf-8'); + const msg = result.email.response.toString('utf-8'); assert(~msg.indexOf('/api/test-users/confirm')); assert(~msg.indexOf('custom template')); assert(~msg.indexOf('To: bar@bat.com')); @@ -1889,7 +1889,7 @@ describe('User', function() { assert(result.email.response); assert(result.token); assert.equal(result.token, 'token-123456'); - var msg = result.email.response.toString('utf-8'); + const msg = result.email.response.toString('utf-8'); assert(~msg.indexOf('token-123456')); done(); @@ -1947,7 +1947,7 @@ describe('User', function() { }); user.verify(verifyOptions, function(err, result) { - var msg = result.email.response.toString('utf-8'); + const msg = result.email.response.toString('utf-8'); assert(~msg.indexOf('http://myapp.org:3000/')); done(); @@ -1974,7 +1974,7 @@ describe('User', function() { }); user.verify(verifyOptions, function(err, result) { - var msg = result.email.response.toString('utf-8'); + const msg = result.email.response.toString('utf-8'); assert(~msg.indexOf('http://myapp.org/')); done(); @@ -2002,7 +2002,7 @@ describe('User', function() { }); user.verify(verifyOptions, function(err, result) { - var msg = result.email.response.toString('utf-8'); + const msg = result.email.response.toString('utf-8'); assert(~msg.indexOf('https://myapp.org:3000/')); done(); @@ -2030,7 +2030,7 @@ describe('User', function() { }); user.verify(verifyOptions, function(err, result) { - var msg = result.email.response.toString('utf-8'); + const msg = result.email.response.toString('utf-8'); assert(~msg.indexOf('https://myapp.org/')); done(); @@ -2049,19 +2049,19 @@ describe('User', function() { }); it('hides verification tokens from user JSON', function(done) { - var user = new User({ + const user = new User({ email: 'bar@bat.com', password: 'bar', verificationToken: 'a-token', }); - var data = user.toJSON(); + const data = user.toJSON(); assert(!('verificationToken' in data)); done(); }); it('squashes "//" when restApiRoot is "/"', function(done) { - var emailBody; + let emailBody; User.afterRemote('create', function(ctx, user, next) { assert(user, 'afterRemote should include result'); @@ -2092,7 +2092,7 @@ describe('User', function() { }); it('removes "verifyOptions.template" from Email payload', function() { - var MailerMock = { + const MailerMock = { send: function(verifyOptions, cb) { cb(null, verifyOptions); }, }; verifyOptions.mailer = MailerMock; @@ -2117,7 +2117,7 @@ describe('User', function() { return user.verify(verifyOptions) .then(() => actualVerifyHref) .then(verifyHref => { - var parsed = url.parse(verifyHref, true); + const parsed = url.parse(verifyHref, true); expect(parsed.query.redirect, 'redirect query') .to.equal('#/some-path?a=1&b=2'); }); @@ -2258,7 +2258,7 @@ describe('User', function() { }); describe('User.confirm(options, fn)', function() { - var verifyOptions; + let verifyOptions; function testConfirm(testFunc, done) { User.afterRemote('create', function(ctx, user, next) { @@ -2352,7 +2352,7 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert(errorResponse); assert.equal(errorResponse.code, 'USER_NOT_FOUND'); @@ -2371,7 +2371,7 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert(errorResponse); assert.equal(errorResponse.code, 'INVALID_TOKEN'); @@ -2384,7 +2384,7 @@ describe('User', function() { describe('Password Reset', function() { describe('User.resetPassword(options, cb)', function() { - var options = { + const options = { email: 'foo@bar.com', redirect: 'http://foobar.com/reset-password', }; @@ -2422,7 +2422,7 @@ describe('User', function() { }); it('Checks that options exist', function(done) { - var calledBack = false; + let calledBack = false; User.resetPassword(options, function() { calledBack = true; @@ -2438,7 +2438,7 @@ describe('User', function() { }); it('Creates a temp accessToken to allow a user to change password', function(done) { - var calledBack = false; + let calledBack = false; User.resetPassword({ email: options.email, @@ -2484,7 +2484,7 @@ describe('User', function() { .end(function(err, res) { if (err) return done(err); - var errorResponse = res.body.error; + const errorResponse = res.body.error; assert(errorResponse); assert.equal(errorResponse.code, 'EMAIL_REQUIRED'); @@ -2546,7 +2546,7 @@ describe('User', function() { }); describe('User.resetPassword(options, cb) requiring realm', function() { - var realmUser; + let realmUser; beforeEach(function(done) { User.create(validCredentialsWithRealm, function(err, u) { @@ -2571,7 +2571,7 @@ describe('User', function() { }); it('Creates a temp accessToken to allow user in realm to change password', function(done) { - var calledBack = false; + let calledBack = false; User.resetPassword({ email: realmUser.email, @@ -2600,10 +2600,10 @@ describe('User', function() { }); describe('AccessToken (session) invalidation', function() { - var user, originalUserToken1, originalUserToken2, newUserCreated; - var currentEmailCredentials = {email: 'original@example.com', password: 'bar'}; - var updatedEmailCredentials = {email: 'updated@example.com', password: 'bar'}; - var newUserCred = {email: 'newuser@example.com', password: 'newpass'}; + let user, originalUserToken1, originalUserToken2, newUserCreated; + const currentEmailCredentials = {email: 'original@example.com', password: 'bar'}; + const updatedEmailCredentials = {email: 'updated@example.com', password: 'bar'}; + const newUserCred = {email: 'newuser@example.com', password: 'newpass'}; beforeEach('create user then login', function createAndLogin(done) { async.series([ @@ -2748,7 +2748,7 @@ describe('User', function() { }); it('keeps sessions AS IS if non-email property is changed using updateAll', function(done) { - var userPartial; + let userPartial; async.series([ function createPartialUser(next) { User.create( @@ -2798,7 +2798,7 @@ describe('User', function() { }); it('preserves other users\' sessions if their email is untouched', function(done) { - var user1, user2, user3; + let user1, user2, user3; async.series([ function(next) { User.create({email: 'user1@example.com', password: 'u1pass'}, function(err, u1) { @@ -2861,7 +2861,7 @@ describe('User', function() { }); it('invalidates correct sessions after changing email using updateAll', function(done) { - var userSpecial, userNormal; + let userSpecial, userNormal; async.series([ function createSpecialUser(next) { User.create( @@ -2907,12 +2907,12 @@ describe('User', function() { }); it('preserves current session', function(done) { - var options = {accessToken: originalUserToken1}; + const options = {accessToken: originalUserToken1}; user.updateAttribute('email', 'new@example.com', options, function(err) { if (err) return done(err); AccessToken.find({where: {userId: user.pk}}, function(err, tokens) { if (err) return done(err); - var tokenIds = tokens.map(function(t) { return t.id; }); + const tokenIds = tokens.map(function(t) { return t.id; }); expect(tokenIds).to.eql([originalUserToken1.id]); done(); }); @@ -2920,8 +2920,8 @@ describe('User', function() { }); it('forwards the "options" argument', function(done) { - var options = {testFlag: true}; - var observedOptions = []; + const options = {testFlag: true}; + const observedOptions = []; saveObservedOptionsForHook('access', User); saveObservedOptionsForHook('before delete', AccessToken); @@ -2951,7 +2951,7 @@ describe('User', function() { }); it('preserves other user sessions if their password is untouched', function(done) { - var user1, user2, user1Token; + let user1, user2, user1Token; async.series([ function(next) { User.create({email: 'user1@example.com', password: 'u1pass'}, function(err, u1) { @@ -3024,9 +3024,9 @@ describe('User', function() { function assertPreservedTokens(done) { AccessToken.find({where: {userId: user.pk}}, function(err, tokens) { if (err) return done(err); - var actualIds = tokens.map(function(t) { return t.id; }); + const actualIds = tokens.map(function(t) { return t.id; }); actualIds.sort(); - var expectedIds = [originalUserToken1.id, originalUserToken2.id]; + const expectedIds = [originalUserToken1.id, originalUserToken2.id]; expectedIds.sort(); expect(actualIds).to.eql(expectedIds); done(); @@ -3043,8 +3043,8 @@ describe('User', function() { }); describe('Verification after updating email', function() { - var NEW_EMAIL = 'updated@example.com'; - var userInstance; + const NEW_EMAIL = 'updated@example.com'; + let userInstance; beforeEach(createOriginalUser); @@ -3115,7 +3115,7 @@ describe('User', function() { }); function createOriginalUser(done) { - var userData = { + const userData = { email: 'original@example.com', password: 'bar', emailVerified: true, @@ -3132,7 +3132,7 @@ describe('User', function() { it('allows resetPassword by email if email verification is required and done', function(done) { User.settings.emailVerificationRequired = true; - var email = validCredentialsEmailVerified.email; + const email = validCredentialsEmailVerified.email; User.resetPassword({email: email}, function(err, info) { if (err) return done(err); @@ -3143,7 +3143,7 @@ describe('User', function() { it('disallows resetPassword by email if email verification is required and not done', function(done) { User.settings.emailVerificationRequired = true; - var email = validCredentialsEmail; + const email = validCredentialsEmail; User.resetPassword({email: email}, function(err) { assert(err); @@ -3156,7 +3156,7 @@ describe('User', function() { it('allows resetPassword by email if email verification is not required', function(done) { User.settings.emailVerificationRequired = false; - var email = validCredentialsEmail; + const email = validCredentialsEmail; User.resetPassword({email: email}, function(err) { if (err) return done(err); @@ -3178,7 +3178,7 @@ describe('User', function() { }); describe('ttl', function() { - var User2; + let User2; beforeEach(function() { User2 = loopback.User.extend('User2', {}, {ttl: 10}); }); diff --git a/test/util/describe.js b/test/util/describe.js index e767a202..7d865af5 100644 --- a/test/util/describe.js +++ b/test/util/describe.js @@ -4,7 +4,7 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../'); +const loopback = require('../../'); module.exports = describe; diff --git a/test/util/it.js b/test/util/it.js index b270e444..b6c6d737 100644 --- a/test/util/it.js +++ b/test/util/it.js @@ -4,7 +4,7 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var loopback = require('../../'); +const loopback = require('../../'); module.exports = it; diff --git a/test/util/model-tests.js b/test/util/model-tests.js index 39511d96..623aae59 100644 --- a/test/util/model-tests.js +++ b/test/util/model-tests.js @@ -4,35 +4,35 @@ // License text available at https://opensource.org/licenses/MIT 'use strict'; -var assert = require('assert'); -var async = require('async'); -var describe = require('./describe'); -var loopback = require('../../'); -var ACL = loopback.ACL; -var Change = loopback.Change; -var PersistedModel = loopback.PersistedModel; -var RemoteObjects = require('strong-remoting'); -var TaskEmitter = require('strong-task-emitter'); +const assert = require('assert'); +const async = require('async'); +const describe = require('./describe'); +const loopback = require('../../'); +const ACL = loopback.ACL; +const Change = loopback.Change; +const PersistedModel = loopback.PersistedModel; +const RemoteObjects = require('strong-remoting'); +const TaskEmitter = require('strong-task-emitter'); module.exports = function defineModelTestsWithDataSource(options) { describe('Model Tests', function() { - var User, dataSource; + let User, dataSource; if (options.beforeEach) { beforeEach(options.beforeEach); } beforeEach(function() { - var test = this; + const test = this; // setup a model / datasource dataSource = this.dataSource || loopback.createDataSource(options.dataSource); - var extend = PersistedModel.extend; + const extend = PersistedModel.extend; // create model hook PersistedModel.extend = function() { - var extendedModel = extend.apply(PersistedModel, arguments); + const extendedModel = extend.apply(PersistedModel, arguments); if (options.onDefine) { options.onDefine.call(test, extendedModel); @@ -65,7 +65,7 @@ module.exports = function defineModelTestsWithDataSource(options) { describe('Model.validatesPresenceOf(properties...)', function() { it('Require a model to include a property to be considered valid', function() { User.validatesPresenceOf('first', 'last', 'age'); - var joe = new User({first: 'joe'}); + const joe = new User({first: 'joe'}); assert(joe.isValid() === false, 'model should not validate'); assert(joe.errors.last, 'should have a missing last error'); assert(joe.errors.age, 'should have a missing age error'); @@ -75,7 +75,7 @@ module.exports = function defineModelTestsWithDataSource(options) { describe('Model.validatesLengthOf(property, options)', function() { it('Require a property length to be within a specified range', function() { User.validatesLengthOf('password', {min: 5, message: {min: 'Password is too short'}}); - var joe = new User({password: '1234'}); + const joe = new User({password: '1234'}); assert(joe.isValid() === false, 'model should not be valid'); assert(joe.errors.password, 'should have password error'); }); @@ -84,7 +84,7 @@ module.exports = function defineModelTestsWithDataSource(options) { describe('Model.validatesInclusionOf(property, options)', function() { it('Require a value for `property` to be in the specified array', function() { User.validatesInclusionOf('gender', {in: ['male', 'female']}); - var foo = new User({gender: 'bar'}); + const foo = new User({gender: 'bar'}); assert(foo.isValid() === false, 'model should not be valid'); assert(foo.errors.gender, 'should have gender error'); }); @@ -93,9 +93,9 @@ module.exports = function defineModelTestsWithDataSource(options) { describe('Model.validatesExclusionOf(property, options)', function() { it('Require a value for `property` to not exist in the specified array', function() { User.validatesExclusionOf('domain', {in: ['www', 'billing', 'admin']}); - var foo = new User({domain: 'www'}); - var bar = new User({domain: 'billing'}); - var bat = new User({domain: 'admin'}); + const foo = new User({domain: 'www'}); + const bar = new User({domain: 'billing'}); + const bat = new User({domain: 'admin'}); assert(foo.isValid() === false); assert(bar.isValid() === false); assert(bat.isValid() === false); @@ -108,9 +108,9 @@ module.exports = function defineModelTestsWithDataSource(options) { describe('Model.validatesNumericalityOf(property, options)', function() { it('Require a value for `property` to be a specific type of `Number`', function() { User.validatesNumericalityOf('age', {int: true}); - var joe = new User({age: 10.2}); + const joe = new User({age: 10.2}); assert(joe.isValid() === false); - var bob = new User({age: 0}); + const bob = new User({age: 0}); assert(bob.isValid() === true); assert(joe.errors.age, 'model should have an age error'); }); @@ -119,15 +119,15 @@ module.exports = function defineModelTestsWithDataSource(options) { describe('myModel.isValid()', function() { it('Validate the model instance', function() { User.validatesNumericalityOf('age', {int: true}); - var user = new User({first: 'joe', age: 'flarg'}); - var valid = user.isValid(); + const user = new User({first: 'joe', age: 'flarg'}); + const valid = user.isValid(); assert(valid === false); assert(user.errors.age, 'model should have age error'); }); it('Asynchronously validate the model', function(done) { User.validatesNumericalityOf('age', {int: true}); - var user = new User({first: 'joe', age: 'flarg'}); + const user = new User({first: 'joe', age: 'flarg'}); user.isValid(function(valid) { assert(valid === false); assert(user.errors.age, 'model should have age error'); @@ -150,7 +150,7 @@ module.exports = function defineModelTestsWithDataSource(options) { describe('model.save([options], [callback])', function() { it('Save an instance of a Model to the attached data source', function(done) { - var joe = new User({first: 'Joe', last: 'Bob'}); + const joe = new User({first: 'Joe', last: 'Bob'}); joe.save(function(err, user) { assert(user.id); assert(!err); diff --git a/test/utils.test.js b/test/utils.test.js index 8ded3d9a..7e2fe003 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -5,14 +5,14 @@ 'use strict'; -var utils = require('../lib/utils'); -var assert = require('assert'); +const utils = require('../lib/utils'); +const assert = require('assert'); describe('Utils', function() { describe('uploadInChunks', function() { it('calls process function for each chunk', function(done) { - var largeArray = ['item1', 'item2', 'item3']; - var calls = []; + const largeArray = ['item1', 'item2', 'item3']; + const calls = []; utils.uploadInChunks(largeArray, 1, function processFunction(array, cb) { calls.push(array); @@ -25,8 +25,8 @@ describe('Utils', function() { }); it('calls process function only once when array is smaller than chunk size', function(done) { - var largeArray = ['item1', 'item2']; - var calls = []; + const largeArray = ['item1', 'item2']; + const calls = []; utils.uploadInChunks(largeArray, 3, function processFunction(array, cb) { calls.push(array); @@ -39,7 +39,7 @@ describe('Utils', function() { }); it('concats results from each call to the process function', function(done) { - var largeArray = ['item1', 'item2', 'item3', 'item4']; + const largeArray = ['item1', 'item2', 'item3', 'item4']; utils.uploadInChunks(largeArray, 2, function processFunction(array, cb) { cb(null, array); @@ -52,7 +52,7 @@ describe('Utils', function() { }); describe('downloadInChunks', function() { - var largeArray, calls, chunkSize, skip; + let largeArray, calls, chunkSize, skip; beforeEach(function() { largeArray = ['item1', 'item2', 'item3']; @@ -63,9 +63,9 @@ describe('Utils', function() { function processFunction(filter, cb) { calls.push(Object.assign({}, filter)); - var results = []; + const results = []; - for (var i = 0; i < chunkSize; i++) { + for (let i = 0; i < chunkSize; i++) { if (largeArray[skip + i]) { results.push(largeArray[skip + i]); } @@ -76,7 +76,7 @@ describe('Utils', function() { } it('calls process function with the correct filter', function(done) { - var expectedFilters = [{skip: 0, limit: chunkSize}, {skip: chunkSize, limit: chunkSize}]; + const expectedFilters = [{skip: 0, limit: chunkSize}, {skip: chunkSize, limit: chunkSize}]; utils.downloadInChunks({}, chunkSize, processFunction, function finished(err) { if (err) return done(err); assert.deepEqual(calls, expectedFilters); @@ -95,22 +95,22 @@ describe('Utils', function() { describe('concatResults', function() { it('concats regular arrays', function() { - var array1 = ['item1', 'item2']; - var array2 = ['item3', 'item4']; + const array1 = ['item1', 'item2']; + const array2 = ['item3', 'item4']; - var concatResults = utils.concatResults(array1, array2); + const concatResults = utils.concatResults(array1, array2); assert.deepEqual(concatResults, ['item1', 'item2', 'item3', 'item4']); }); it('concats objects containing arrays', function() { - var object1 = {deltas: [{change: 'change 1'}], conflict: []}; - var object2 = {deltas: [{change: 'change 2'}], conflict: [{conflict: 'conflict 1'}]}; - var expectedResults = { + const object1 = {deltas: [{change: 'change 1'}], conflict: []}; + const object2 = {deltas: [{change: 'change 2'}], conflict: [{conflict: 'conflict 1'}]}; + const expectedResults = { deltas: [{change: 'change 1'}, {change: 'change 2'}], conflict: [{conflict: 'conflict 1'}], }; - var concatResults = utils.concatResults(object1, object2); + const concatResults = utils.concatResults(object1, object2); assert.deepEqual(concatResults, expectedResults); }); });