From 0c2acbd61a7012ec9633002dc5784f3090ad426f Mon Sep 17 00:00:00 2001 From: exoego Date: Tue, 28 Nov 2023 10:37:56 +0900 Subject: [PATCH] Fix code offenses --- actions/describeTimeToLive.js | 3 +- actions/updateTimeToLive.js | 61 +++++------ db/index.js | 181 ++++++++++++++++++------------- test/updateTimeToLive.js | 186 ++++++++++++++++---------------- validations/updateTimeToLive.js | 4 +- 5 files changed, 234 insertions(+), 201 deletions(-) diff --git a/actions/describeTimeToLive.js b/actions/describeTimeToLive.js index 3423986..37a7edb 100644 --- a/actions/describeTimeToLive.js +++ b/actions/describeTimeToLive.js @@ -5,7 +5,8 @@ module.exports = function describeTimeToLive (store, data, cb) { if (table.TimeToLiveDescription !== null && typeof table.TimeToLiveDescription === 'object') { cb(null, { TimeToLiveDescription: table.TimeToLiveDescription }) - } else { + } + else { cb(null, { TimeToLiveDescription: { TimeToLiveStatus: 'DISABLED' } }) } }) diff --git a/actions/updateTimeToLive.js b/actions/updateTimeToLive.js index d142eb5..5097a6d 100644 --- a/actions/updateTimeToLive.js +++ b/actions/updateTimeToLive.js @@ -1,38 +1,39 @@ -var db = require('../db'); +var db = require('../db') -module.exports = function updateTimeToLive(store, data, cb) { - var key = data.TableName, - TimeToLiveSpecification = data.TimeToLiveSpecification, - tableDb = store.tableDb, - returnValue; +module.exports = function updateTimeToLive (store, data, cb) { + var key = data.TableName, + TimeToLiveSpecification = data.TimeToLiveSpecification, + tableDb = store.tableDb, + returnValue - store.getTable(key, false, function(err, table) { - if (err) return cb(err) + store.getTable(key, false, function (err, table) { + if (err) return cb(err) - if (TimeToLiveSpecification.Enabled) { - if (table.TimeToLiveDescription && table.TimeToLiveDescription.TimeToLiveStatus === 'ENABLED') { - return cb(db.validationError('TimeToLive is already enabled')) - } - table.TimeToLiveDescription = { - AttributeName: TimeToLiveSpecification.AttributeName, - TimeToLiveStatus: 'ENABLED', - } - returnValue = TimeToLiveSpecification - } else { - if (table.TimeToLiveDescription == null || table.TimeToLiveDescription.TimeToLiveStatus === 'DISABLED') { - return cb(db.validationError('TimeToLive is already disabled')) - } + if (TimeToLiveSpecification.Enabled) { + if (table.TimeToLiveDescription && table.TimeToLiveDescription.TimeToLiveStatus === 'ENABLED') { + return cb(db.validationError('TimeToLive is already enabled')) + } + table.TimeToLiveDescription = { + AttributeName: TimeToLiveSpecification.AttributeName, + TimeToLiveStatus: 'ENABLED', + } + returnValue = TimeToLiveSpecification + } + else { + if (table.TimeToLiveDescription == null || table.TimeToLiveDescription.TimeToLiveStatus === 'DISABLED') { + return cb(db.validationError('TimeToLive is already disabled')) + } - table.TimeToLiveDescription = { - TimeToLiveStatus: 'DISABLED', - } - returnValue = {Enabled: false} - } + table.TimeToLiveDescription = { + TimeToLiveStatus: 'DISABLED', + } + returnValue = { Enabled: false } + } - tableDb.put(key, table, function(err) { - if (err) return cb(err) + tableDb.put(key, table, function (err) { + if (err) return cb(err) - cb(null, {TimeToLiveSpecification: returnValue}) - }) + cb(null, { TimeToLiveSpecification: returnValue }) }) + }) } diff --git a/db/index.js b/db/index.js index 698b901..1bebf5f 100644 --- a/db/index.js +++ b/db/index.js @@ -137,50 +137,50 @@ function create (options) { timerIdTtlScanner = setInterval(function () { var currentUnixSeconds = Math.round(Date.now() / 1000) - function logError(err, result) { + function logError (err) { if (err) console.error(err) } lazyStream(tableDb.createKeyStream({}), logError) - .join(function (tableNames) { - tableNames.forEach(function (name) { - getTable(name, false, function (err, table) { - if (err) return - if (!table.TimeToLiveDescription || table.TimeToLiveDescription.TimeToLiveStatus !== 'ENABLED') return - - var keyAttrNames = table.KeySchema.map(function (i) { - return i.AttributeName - }) - var source = { - getItemDb: getItemDb, - getIndexDb: getIndexDb, - } - var itemDb = getItemDb(table.TableName) - var kvStream = lazyStream(itemDb.createReadStream({}), logError) - kvStream = kvStream.filter(function (item) { - var ttl = item.value[table.TimeToLiveDescription.AttributeName] - return ttl && typeof ttl.N === 'string' && currentUnixSeconds > Number(ttl.N) - }) - kvStream.join(function (kvs) { - kvs.forEach(function (kv) { - var itemKey = keyAttrNames.reduce(function (key, attrName) { - key[attrName] = kv.value[attrName] - return key - }, {}) - var data = {TableName: name, Key: itemKey} - var cb = function (err) { - // Noop ? - } - deleteItem(source, data, table, itemDb, kv.key, cb) - }) + .join(function (tableNames) { + tableNames.forEach(function (name) { + getTable(name, false, function (err, table) { + if (err) return + if (!table.TimeToLiveDescription || table.TimeToLiveDescription.TimeToLiveStatus !== 'ENABLED') return + + var keyAttrNames = table.KeySchema.map(function (i) { + return i.AttributeName + }) + var source = { + getItemDb: getItemDb, + getIndexDb: getIndexDb, + } + var itemDb = getItemDb(table.TableName) + var kvStream = lazyStream(itemDb.createReadStream({}), logError) + kvStream = kvStream.filter(function (item) { + var ttl = item.value[table.TimeToLiveDescription.AttributeName] + return ttl && typeof ttl.N === 'string' && currentUnixSeconds > Number(ttl.N) + }) + kvStream.join(function (kvs) { + kvs.forEach(function (kv) { + var itemKey = keyAttrNames.reduce(function (key, attrName) { + key[attrName] = kv.value[attrName] + return key + }, {}) + var data = { TableName: name, Key: itemKey } + var cb = () => { + // Noop ? + } + deleteItem(source, data, table, itemDb, kv.key, cb) }) }) }) }) + }) }, ttlScannerInterval) } - function stopBackgroundJobs() { + function stopBackgroundJobs () { clearInterval(timerIdTtlScanner) } @@ -244,14 +244,15 @@ function validateItem (dataItem, table) { }) } -function deleteItem(store, data, table, itemDb, key, cb) { - itemDb.lock(key, function(release) { +function deleteItem (store, data, table, itemDb, key, cb) { + itemDb.lock(key, function (release) { cb = release(cb) - itemDb.get(key, function(err, existingItem) { + itemDb.get(key, function (err, existingItem) { if (err && err.name !== 'NotFoundError') return cb(err) - if ((err = checkConditional(data, existingItem)) != null) return cb(err) + let conditionalErr = checkConditional(data, existingItem) + if (conditionalErr) return cb(conditionalErr) var returnObj = {} @@ -260,10 +261,10 @@ function deleteItem(store, data, table, itemDb, key, cb) { returnObj.ConsumedCapacity = addConsumedCapacity(data, false, existingItem) - updateIndexes(store, table, existingItem, null, function(err) { + updateIndexes(store, table, existingItem, null, function (err) { if (err) return cb(err) - itemDb.del(key, function(err) { + itemDb.del(key, function (err) { if (err) return cb(err) cb(null, returnObj) }) @@ -272,7 +273,6 @@ function deleteItem(store, data, table, itemDb, key, cb) { }) } -function validateUpdates(attributeUpdates, expressionUpdates, table) { function validateUpdates (attributeUpdates, expressionUpdates, table) { if (attributeUpdates == null && expressionUpdates == null) return @@ -292,7 +292,7 @@ function validateUpdates (attributeUpdates, expressionUpdates, table) { } if (hasKey) { return validationError('One or more parameter values were invalid: ' + - 'Cannot update attribute ' + attr + '. This attribute is part of the key') + 'Cannot update attribute ' + attr + '. This attribute is part of the key') } }) || traverseIndexes(table, function (attr, type, index) { var actualType @@ -312,8 +312,8 @@ function validateUpdates (attributeUpdates, expressionUpdates, table) { } if (actualType != null && actualType != type) { return validationError('One or more parameter values were invalid: ' + - 'Type mismatch for Index Key ' + attr + ' Expected: ' + type + - ' Actual: ' + actualType + ' IndexName: ' + index.IndexName) + 'Type mismatch for Index Key ' + attr + ' Expected: ' + type + + ' Actual: ' + actualType + ' IndexName: ' + index.IndexName) } }) || validateKeyPaths((expressionUpdates || {}).nestedPaths, table) } @@ -324,7 +324,7 @@ function validateKeyPiece (key, attr, type, isHash) { } if (key[attr][type] === '' && (type === 'S' || type === 'B')) { return validationError('One or more parameter values were invalid: ' + - 'The AttributeValue for a key attribute cannot contain an empty ' + (type === 'S' ? 'string' : 'binary') + ' value. Key: ' + attr) + 'The AttributeValue for a key attribute cannot contain an empty ' + (type === 'S' ? 'string' : 'binary') + ' value. Key: ' + attr) } return checkKeySize(key[attr][type], type, isHash) } @@ -334,12 +334,12 @@ function validateKeyPaths (nestedPaths, table) { return traverseKey(table, function (attr) { if (nestedPaths[attr]) { return validationError('Key attributes must be scalars; ' + - 'list random access \'[]\' and map lookup \'.\' are not allowed: Key: ' + attr) + 'list random access \'[]\' and map lookup \'.\' are not allowed: Key: ' + attr) } }) || traverseIndexes(table, function (attr) { if (nestedPaths[attr]) { return validationError('Key attributes must be scalars; ' + - 'list random access \'[]\' and map lookup \'.\' are not allowed: IndexKey: ' + attr) + 'list random access \'[]\' and map lookup \'.\' are not allowed: IndexKey: ' + attr) } }) } @@ -356,12 +356,17 @@ function createKey (item, table, keySchema) { function createIndexKey (item, table, keySchema) { var tableKeyPieces = [] - traverseKey(table, function (attr, type) { tableKeyPieces.push(item[attr][type], type) }) + traverseKey(table, function (attr, type) { + tableKeyPieces.push(item[attr][type], type) + }) return createKey(item, table, keySchema) + hashPrefix.apply(this, tableKeyPieces) } function traverseKey (table, keySchema, visitKey) { - if (typeof keySchema == 'function') { visitKey = keySchema; keySchema = table.KeySchema } + if (typeof keySchema == 'function') { + visitKey = keySchema + keySchema = table.KeySchema + } var i, j, attr, type, found for (i = 0; i < keySchema.length; i++) { attr = keySchema[i].AttributeName @@ -411,10 +416,10 @@ function checkKeySize (keyPiece, type, isHash) { if (type == 'B') keyPiece = Buffer.from(keyPiece, 'base64') if (isHash && keyPiece.length > 2048) return validationError('One or more parameter values were invalid: ' + - 'Size of hashkey has exceeded the maximum size limit of2048 bytes') + 'Size of hashkey has exceeded the maximum size limit of2048 bytes') else if (!isHash && keyPiece.length > 1024) return validationError('One or more parameter values were invalid: ' + - 'Aggregated size of all range keys has exceeded the size limit of 1024 bytes') + 'Aggregated size of all range keys has exceeded the size limit of 1024 bytes') } function toRangeStr (keyPiece, type) { @@ -633,17 +638,25 @@ function valSize (val, type, compress) { if (numDigits == 1 && val.c[0] === 0) return 1 return 1 + Math.ceil(numDigits / 2) + (numDigits % 2 || val.e % 2 ? 0 : 1) + (val.s == -1 ? 1 : 0) case 'SS': - return val.reduce(function (sum, x) { return sum + valSize(x, 'S') }, 0) // eslint-disable-line no-loop-func + return val.reduce(function (sum, x) { + return sum + valSize(x, 'S') + }, 0) // eslint-disable-line no-loop-func case 'BS': - return val.reduce(function (sum, x) { return sum + valSize(x, 'B') }, 0) // eslint-disable-line no-loop-func + return val.reduce(function (sum, x) { + return sum + valSize(x, 'B') + }, 0) // eslint-disable-line no-loop-func case 'NS': - return val.reduce(function (sum, x) { return sum + valSize(x, 'N') }, 0) // eslint-disable-line no-loop-func + return val.reduce(function (sum, x) { + return sum + valSize(x, 'N') + }, 0) // eslint-disable-line no-loop-func case 'NULL': return 1 case 'BOOL': return 1 case 'L': - return 3 + val.reduce(function (sum, val) { return sum + 1 + valSizeWithStorage(val, compress) }, 0) + return 3 + val.reduce(function (sum, val) { + return sum + 1 + valSizeWithStorage(val, compress) + }, 0) case 'M': return 3 + Object.keys(val).length + itemSize(val, compress) } @@ -671,7 +684,9 @@ function addConsumedCapacity (data, isRead, newItem, oldItem) { function valsEqual (val1, val2) { if (Array.isArray(val1) && Array.isArray(val2)) { if (val1.length != val2.length) return false - return val1.every(function (val) { return ~val2.indexOf(val) }) + return val1.every(function (val) { + return ~val2.indexOf(val) + }) } else { return val1 == val2 @@ -703,7 +718,9 @@ function matchesExprFilter (item, expr) { else if (expr.type == 'not') { return !matchesExprFilter(item, expr.args[0]) } - var args = expr.args.map(function (arg) { return resolveArg(arg, item) }) + var args = expr.args.map(function (arg) { + return resolveArg(arg, item) + }) return compare(expr.type == 'function' ? expr.name : expr.type, args[0], args.slice(1)) } @@ -712,7 +729,9 @@ function resolveArg (arg, item) { return mapPath(arg, item) } else if (arg.type == 'function' && arg.name == 'size') { - var args = arg.args.map(function (arg) { return resolveArg(arg, item) }) + var args = arg.args.map(function (arg) { + return resolveArg(arg, item) + }) var val = args[0], length if (!val) { return null @@ -756,26 +775,26 @@ function compare (comp, val, compVals) { case 'LE': case '<=': if (compType != attrType || - (attrType == 'N' && !new Big(attrVal).lte(compVal)) || - (attrType != 'N' && toLexiStr(attrVal, attrType) > toLexiStr(compVal, attrType))) return false + (attrType == 'N' && !new Big(attrVal).lte(compVal)) || + (attrType != 'N' && toLexiStr(attrVal, attrType) > toLexiStr(compVal, attrType))) return false break case 'LT': case '<': if (compType != attrType || - (attrType == 'N' && !new Big(attrVal).lt(compVal)) || - (attrType != 'N' && toLexiStr(attrVal, attrType) >= toLexiStr(compVal, attrType))) return false + (attrType == 'N' && !new Big(attrVal).lt(compVal)) || + (attrType != 'N' && toLexiStr(attrVal, attrType) >= toLexiStr(compVal, attrType))) return false break case 'GE': case '>=': if (compType != attrType || - (attrType == 'N' && !new Big(attrVal).gte(compVal)) || - (attrType != 'N' && toLexiStr(attrVal, attrType) < toLexiStr(compVal, attrType))) return false + (attrType == 'N' && !new Big(attrVal).gte(compVal)) || + (attrType != 'N' && toLexiStr(attrVal, attrType) < toLexiStr(compVal, attrType))) return false break case 'GT': case '>': if (compType != attrType || - (attrType == 'N' && !new Big(attrVal).gt(compVal)) || - (attrType != 'N' && toLexiStr(attrVal, attrType) <= toLexiStr(compVal, attrType))) return false + (attrType == 'N' && !new Big(attrVal).gt(compVal)) || + (attrType != 'N' && toLexiStr(attrVal, attrType) <= toLexiStr(compVal, attrType))) return false break case 'NOT_NULL': case 'attribute_exists': @@ -811,9 +830,9 @@ function compare (comp, val, compVals) { case 'BETWEEN': case 'between': if (!attrVal || compType != attrType || - (attrType == 'N' && (!new Big(attrVal).gte(compVal) || !new Big(attrVal).lte(compVals[1].N))) || - (attrType != 'N' && (toLexiStr(attrVal, attrType) < toLexiStr(compVal, attrType) || - toLexiStr(attrVal, attrType) > toLexiStr(compVals[1][compType], attrType)))) return false + (attrType == 'N' && (!new Big(attrVal).gte(compVal) || !new Big(attrVal).lte(compVals[1].N))) || + (attrType != 'N' && (toLexiStr(attrVal, attrType) < toLexiStr(compVal, attrType) || + toLexiStr(attrVal, attrType) > toLexiStr(compVals[1][compType], attrType)))) return false break case 'attribute_type': if (!attrVal || !valsEqual(attrType, compVal)) return false @@ -897,7 +916,9 @@ function mapPaths (paths, item) { } } } - toSquash.forEach(function (obj) { obj.L = obj.L.filter(Boolean) }) + toSquash.forEach(function (obj) { + obj.L = obj.L.filter(Boolean) + }) return returnItem } @@ -995,10 +1016,14 @@ function queryTable (store, table, data, opts, isLocal, fetchFromItemDb, startKe var queryFilter = data.QueryFilter || data.ScanFilter if (data._filter) { - items = items.filter(function (val) { return matchesExprFilter(val, data._filter.expression) }) + items = items.filter(function (val) { + return matchesExprFilter(val, data._filter.expression) + }) } else if (queryFilter) { - items = items.filter(function (val) { return matchesFilter(val, queryFilter, data.ConditionalOperator) }) + items = items.filter(function (val) { + return matchesFilter(val, queryFilter, data.ConditionalOperator) + }) } var result = { ScannedCount: count } @@ -1042,7 +1067,7 @@ function queryTable (store, table, data, opts, isLocal, fetchFromItemDb, startKe function updateIndexes (store, table, existingItem, item, cb) { if (!existingItem && !item) return cb() var puts = [], deletes = [] - ;[ 'Local', 'Global' ].forEach(function (indexType) { + ;[ 'Local', 'Global' ].forEach(function (indexType) { var indexes = table[indexType + 'SecondaryIndexes'] || [] var actions = getIndexActions(indexes, existingItem, item, table) puts = puts.concat(actions.puts.map(function (action) { @@ -1062,11 +1087,17 @@ function updateIndexes (store, table, existingItem, item, cb) { } function getIndexActions (indexes, existingItem, item, table) { - var puts = [], deletes = [], tableKeys = table.KeySchema.map(function (key) { return key.AttributeName }) + var puts = [], deletes = [], tableKeys = table.KeySchema.map(function (key) { + return key.AttributeName + }) indexes.forEach(function (index) { - var indexKeys = index.KeySchema.map(function (key) { return key.AttributeName }), key = null, itemPieces = item + var indexKeys = index.KeySchema.map(function (key) { + return key.AttributeName + }), key = null, itemPieces = item - if (item && indexKeys.every(function (key) { return item[key] != null })) { + if (item && indexKeys.every(function (key) { + return item[key] != null + })) { if (index.Projection.ProjectionType != 'ALL') { var indexAttrs = indexKeys.concat(tableKeys, index.Projection.NonKeyAttributes || []) itemPieces = indexAttrs.reduce(function (obj, attr) { diff --git a/test/updateTimeToLive.js b/test/updateTimeToLive.js index 41b7567..12396ab 100644 --- a/test/updateTimeToLive.js +++ b/test/updateTimeToLive.js @@ -1,66 +1,66 @@ var helpers = require('./helpers') var target = 'UpdateTimeToLive', - request = helpers.request, - opts = helpers.opts.bind(null, target), - assertType = helpers.assertType.bind(null, target), - assertValidation = helpers.assertValidation.bind(null, target), - assertNotFound = helpers.assertNotFound.bind(null, target) + request = helpers.request, + opts = helpers.opts.bind(null, target), + assertType = helpers.assertType.bind(null, target), + assertValidation = helpers.assertValidation.bind(null, target), + assertNotFound = helpers.assertNotFound.bind(null, target) -describe('updateTimeToLive', function() { +describe('updateTimeToLive', function () { - describe('serializations', function() { + describe('serializations', function () { - it('should return SerializationException when TableName is not a string', function(done) { + it('should return SerializationException when TableName is not a string', function (done) { assertType('TableName', 'String', done) }) - it('should return SerializationException when TimeToLiveSpecification is not a struct', function(done) { + it('should return SerializationException when TimeToLiveSpecification is not a struct', function (done) { assertType('TimeToLiveSpecification', 'FieldStruct', done) }) - it('should return SerializationException when TimeToLiveSpecification.AttributeName is not a string', function(done) { + it('should return SerializationException when TimeToLiveSpecification.AttributeName is not a string', function (done) { assertType('TimeToLiveSpecification.AttributeName', 'String', done) }) - it('should return SerializationException when TimeToLiveSpecification.Enabled is not a boolean', function(done) { + it('should return SerializationException when TimeToLiveSpecification.Enabled is not a boolean', function (done) { assertType('TimeToLiveSpecification.Enabled', 'Boolean', done) }) }) - describe('validations', function() { + describe('validations', function () { - it('should return ValidationException for no TableName', function(done) { + it('should return ValidationException for no TableName', function (done) { assertValidation({}, 'The parameter \'TableName\' is required but was not present in the request', done) }) - it('should return ValidationException for empty TableName', function(done) { - assertValidation({TableName: ''}, + it('should return ValidationException for empty TableName', function (done) { + assertValidation({ TableName: '' }, 'TableName must be at least 3 characters long and at most 255 characters long', done) }) - it('should return ValidationException for short TableName', function(done) { - assertValidation({TableName: 'a;'}, + it('should return ValidationException for short TableName', function (done) { + assertValidation({ TableName: 'a;' }, 'TableName must be at least 3 characters long and at most 255 characters long', done) }) - it('should return ValidationException for long TableName', function(done) { + it('should return ValidationException for long TableName', function (done) { var name = new Array(256 + 1).join('a') - assertValidation({TableName: name}, + assertValidation({ TableName: name }, 'TableName must be at least 3 characters long and at most 255 characters long', done) }) - it('should return ValidationException for invalid chars', function(done) { - assertValidation({TableName: 'abc;'}, + it('should return ValidationException for invalid chars', function (done) { + assertValidation({ TableName: 'abc;' }, '1 validation error detected: ' + 'Value \'abc;\' at \'tableName\' failed to satisfy constraint: ' + 'Member must satisfy regular expression pattern: [a-zA-Z0-9_.-]+', done) }) - it('should return ValidationException for empty TimeToLiveSpecification', function(done) { - assertValidation({TableName: 'abc', TimeToLiveSpecification: {}}, [ + it('should return ValidationException for empty TimeToLiveSpecification', function (done) { + assertValidation({ TableName: 'abc', TimeToLiveSpecification: {} }, [ 'Value null at \'timeToLiveSpecification.enabled\' failed to satisfy constraint: ' + 'Member must not be null', 'Value null at \'timeToLiveSpecification.attributeName\' failed to satisfy constraint: ' + @@ -68,8 +68,8 @@ describe('updateTimeToLive', function() { ], done) }) - it('should return ValidationException for null members in TimeToLiveSpecification', function(done) { - assertValidation({TableName: 'abc', TimeToLiveSpecification: {AttributeName: null, Enabled: null}}, [ + it('should return ValidationException for null members in TimeToLiveSpecification', function (done) { + assertValidation({ TableName: 'abc', TimeToLiveSpecification: { AttributeName: null, Enabled: null } }, [ 'Value null at \'timeToLiveSpecification.attributeName\' failed to satisfy constraint: ' + 'Member must not be null', 'Value null at \'timeToLiveSpecification.enabled\' failed to satisfy constraint: ' + @@ -77,59 +77,59 @@ describe('updateTimeToLive', function() { ], done) }) - it('should return ValidationException for empty TimeToLiveSpecification.AttributeName', function(done) { - assertValidation({TableName: 'abc', - TimeToLiveSpecification: {AttributeName: "", Enabled: true}}, - 'TimeToLiveSpecification.AttributeName must be non empty', done) + it('should return ValidationException for empty TimeToLiveSpecification.AttributeName', function (done) { + assertValidation({ TableName: 'abc', + TimeToLiveSpecification: { AttributeName: '', Enabled: true } }, + 'TimeToLiveSpecification.AttributeName must be non empty', done) }) - it('should return ResourceNotFoundException if table does not exist', function(done) { + it('should return ResourceNotFoundException if table does not exist', function (done) { var name = helpers.randomString() - assertNotFound({TableName: name, - TimeToLiveSpecification: {AttributeName: "id", Enabled: true}}, - 'Requested resource not found: Table: ' + name + ' not found', done) + assertNotFound({ TableName: name, + TimeToLiveSpecification: { AttributeName: 'id', Enabled: true } }, + 'Requested resource not found: Table: ' + name + ' not found', done) }) - it('should return ValidationException for false TimeToLiveSpecification.Enabled when already disabled', function(done) { - assertValidation({TableName: helpers.testHashTable, - TimeToLiveSpecification: {AttributeName: "a", Enabled: false}}, - 'TimeToLive is already disabled', done) + it('should return ValidationException for false TimeToLiveSpecification.Enabled when already disabled', function (done) { + assertValidation({ TableName: helpers.testHashTable, + TimeToLiveSpecification: { AttributeName: 'a', Enabled: false } }, + 'TimeToLive is already disabled', done) }) - it('should return ValidationException for true TimeToLiveSpecification.Enabled when already enabled', function(done) { - request(opts({TableName: helpers.testHashTable, TimeToLiveSpecification: {AttributeName: "a", Enabled: true}}), function(err, res) { + it('should return ValidationException for true TimeToLiveSpecification.Enabled when already enabled', function (done) { + request(opts({ TableName: helpers.testHashTable, TimeToLiveSpecification: { AttributeName: 'a', Enabled: true } }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) - assertValidation({TableName: helpers.testHashTable, - TimeToLiveSpecification: {AttributeName: "a", Enabled: true}}, - 'TimeToLive is already enabled', function(err){ + assertValidation({ TableName: helpers.testHashTable, + TimeToLiveSpecification: { AttributeName: 'a', Enabled: true } }, + 'TimeToLive is already enabled', function (err){ + if (err) return done(err) + // teardown + request(opts({ TableName: helpers.testHashTable, TimeToLiveSpecification: { AttributeName: 'a', Enabled: false } }), function (err, res) { if (err) return done(err) - // teardown - request(opts({TableName: helpers.testHashTable, TimeToLiveSpecification: {AttributeName: "a", Enabled: false}}), function(err, res) { - if (err) return done(err) - res.statusCode.should.equal(200) - done() - }) + res.statusCode.should.equal(200) + done() }) + }) }) }) }) - describe('functionality', function() { - it('should enable when disabled', function(done) { - request(opts({TableName: helpers.testHashTable, TimeToLiveSpecification: {AttributeName: "a", Enabled: true}}), function(err, res) { + describe('functionality', function () { + it('should enable when disabled', function (done) { + request(opts({ TableName: helpers.testHashTable, TimeToLiveSpecification: { AttributeName: 'a', Enabled: true } }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) - res.body.should.eql({TimeToLiveSpecification: {AttributeName: "a", Enabled: true}}) + res.body.should.eql({ TimeToLiveSpecification: { AttributeName: 'a', Enabled: true } }) - request(helpers.opts('DescribeTimeToLive', {TableName: helpers.testHashTable}), function(err, res) { + request(helpers.opts('DescribeTimeToLive', { TableName: helpers.testHashTable }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) - res.body.should.eql({TimeToLiveDescription: {TimeToLiveStatus: "ENABLED", AttributeName: "a"}}) + res.body.should.eql({ TimeToLiveDescription: { TimeToLiveStatus: 'ENABLED', AttributeName: 'a' } }) // teardown - request(opts({TableName: helpers.testHashTable, TimeToLiveSpecification: {AttributeName: "a", Enabled: false}}), function(err, res) { + request(opts({ TableName: helpers.testHashTable, TimeToLiveSpecification: { AttributeName: 'a', Enabled: false } }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) done() @@ -138,102 +138,102 @@ describe('updateTimeToLive', function() { }) }) - it('should disable when enabled', function(done) { - request(opts({TableName: helpers.testHashTable, TimeToLiveSpecification: {AttributeName: "a", Enabled: true}}), function(err, res) { + it('should disable when enabled', function (done) { + request(opts({ TableName: helpers.testHashTable, TimeToLiveSpecification: { AttributeName: 'a', Enabled: true } }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) - res.body.should.eql({TimeToLiveSpecification: {AttributeName: "a", Enabled: true}}) + res.body.should.eql({ TimeToLiveSpecification: { AttributeName: 'a', Enabled: true } }) - request(opts({TableName: helpers.testHashTable, TimeToLiveSpecification: {AttributeName: "a", Enabled: false}}), function(err, res) { + request(opts({ TableName: helpers.testHashTable, TimeToLiveSpecification: { AttributeName: 'a', Enabled: false } }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) - res.body.should.eql({TimeToLiveSpecification: {Enabled: false}}) + res.body.should.eql({ TimeToLiveSpecification: { Enabled: false } }) - request(helpers.opts('DescribeTimeToLive', {TableName: helpers.testHashTable}), function(err, res) { + request(helpers.opts('DescribeTimeToLive', { TableName: helpers.testHashTable }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) - res.body.should.eql({TimeToLiveDescription: {TimeToLiveStatus: "DISABLED"}}) + res.body.should.eql({ TimeToLiveDescription: { TimeToLiveStatus: 'DISABLED' } }) done() }) }) }) }) - it('should delete the expired items from Tables and Indices when TTL is enabled', function(done) { - request(opts({TableName: helpers.testRangeTable, TimeToLiveSpecification: {AttributeName: "TTL", Enabled: true}}), function(err, res) { + it('should delete the expired items from Tables and Indices when TTL is enabled', function (done) { + request(opts({ TableName: helpers.testRangeTable, TimeToLiveSpecification: { AttributeName: 'TTL', Enabled: true } }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) - res.body.should.eql({TimeToLiveSpecification: {AttributeName: "TTL", Enabled: true}}) + res.body.should.eql({ TimeToLiveSpecification: { AttributeName: 'TTL', Enabled: true } }) - var timestampNow = Math.round(Date.now() / 1000); + var timestampNow = Math.round(Date.now() / 1000) var sharedPk = helpers.randomString() var sharedGsiPk = helpers.randomString() var expiredItem = { - a: {S: sharedPk}, - b: {S: helpers.randomString()}, - c: {S: sharedGsiPk}, - d: {S: helpers.randomString()}, - TTL: {N: (timestampNow + 1).toString()}, + a: { S: sharedPk }, + b: { S: helpers.randomString() }, + c: { S: sharedGsiPk }, + d: { S: helpers.randomString() }, + TTL: { N: (timestampNow + 1).toString() }, } var livingItem = { - a: {S: sharedPk}, - b: {S: helpers.randomString()}, - c: {S: sharedGsiPk}, - d: {S: helpers.randomString()}, - TTL: {N: (timestampNow + 1000000).toString()}, + a: { S: sharedPk }, + b: { S: helpers.randomString() }, + c: { S: sharedGsiPk }, + d: { S: helpers.randomString() }, + TTL: { N: (timestampNow + 1000000).toString() }, } var batchWriteItemInput = { RequestItems: {}, } batchWriteItemInput.RequestItems[helpers.testRangeTable] = [ - { PutRequest: { Item: expiredItem }}, - { PutRequest: { Item: livingItem }}, + { PutRequest: { Item: expiredItem } }, + { PutRequest: { Item: livingItem } }, ] - request(helpers.opts('BatchWriteItem', batchWriteItemInput), function(err, res) { + request(helpers.opts('BatchWriteItem', batchWriteItemInput), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) - setTimeout(function(){ + setTimeout(function (){ request(helpers.opts('Query', { TableName: helpers.testRangeTable, - KeyConditionExpression: "a = :a", + KeyConditionExpression: 'a = :a', ExpressionAttributeValues: { - ":a": expiredItem.a, + ':a': expiredItem.a, }, - }), function(err, res) { + }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) - res.body.Items.should.eql([livingItem], 'Expired item should be deleted from table') + res.body.Items.should.eql([ livingItem ], 'Expired item should be deleted from table') request(helpers.opts('Query', { TableName: helpers.testRangeTable, IndexName: 'index1', - KeyConditionExpression: "a = :a", + KeyConditionExpression: 'a = :a', ExpressionAttributeValues: { - ":a": expiredItem.a, + ':a': expiredItem.a, }, - }), function(err, res) { + }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) - res.body.Items.should.eql([livingItem], "Expired Item should be deleted from LSI") + res.body.Items.should.eql([ livingItem ], 'Expired Item should be deleted from LSI') request(helpers.opts('Query', { TableName: helpers.testRangeTable, IndexName: 'index3', - KeyConditionExpression: "c = :c", + KeyConditionExpression: 'c = :c', ExpressionAttributeValues: { - ":c": expiredItem.c, + ':c': expiredItem.c, }, - }), function(err, res) { + }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) - res.body.Items.should.eql([livingItem], "Expired Item should be deleted from GSI") + res.body.Items.should.eql([ livingItem ], 'Expired Item should be deleted from GSI') // teardown request(opts({ TableName: helpers.testRangeTable, - TimeToLiveSpecification: {AttributeName: "TTL", Enabled: false} + TimeToLiveSpecification: { AttributeName: 'TTL', Enabled: false } }), function (err, res) { if (err) return done(err) res.statusCode.should.equal(200) diff --git a/validations/updateTimeToLive.js b/validations/updateTimeToLive.js index 944f8ab..d1f35b9 100644 --- a/validations/updateTimeToLive.js +++ b/validations/updateTimeToLive.js @@ -23,8 +23,8 @@ exports.types = { } -exports.custom = function(data) { +exports.custom = function (data) { if (data.TimeToLiveSpecification.AttributeName === '') { - return 'TimeToLiveSpecification.AttributeName must be non empty'; + return 'TimeToLiveSpecification.AttributeName must be non empty' } }