diff --git a/CountItems/CountWorker.js b/CountItems/CountWorker.js index f60da543..7887ea29 100644 --- a/CountItems/CountWorker.js +++ b/CountItems/CountWorker.js @@ -5,6 +5,7 @@ const monitoring = require('../utils/monitoring'); const { deserializeBigInts, serializeBigInts } = require('./utils/utils'); const PENSIEVE = 'PENSIEVE'; + class CountWorker { constructor(params) { this.log = params.log; @@ -66,12 +67,16 @@ class CountWorker { if (!this.client.client) { return callback(new Error('NotConnected')); } - // 'fromObj' expects that the website configuration is an instance of - // WebsiteConfiguration as it is not used in CountItems, we nullify it. - if (bucketInfoObj._websiteConfiguration) { - Object.assign(bucketInfoObj, { _websiteConfiguration: null }); + const bucketInfoData = bucketInfoObj.bucketInfo || bucketInfoObj; + // 'fromObj' expects class-backed fields to already be instances. + // They are not used in CountItems, so we nullify unsupported serialized fields. + if (bucketInfoData._websiteConfiguration) { + bucketInfoData._websiteConfiguration = null; + } + if (bucketInfoData._bucketLoggingStatus) { + bucketInfoData._bucketLoggingStatus = null; } - const bucketInfo = BucketInfo.fromObj(bucketInfoObj.bucketInfo || bucketInfoObj); + const bucketInfo = BucketInfo.fromObj(bucketInfoData); const bucketName = bucketInfo.getName(); this.log.info(`${process.pid} handling ${bucketName}`); return async.waterfall([ diff --git a/package.json b/package.json index 886bb11a..d1791434 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "s3utils", - "version": "1.17.11", + "version": "1.17.12", "engines": { "node": ">= 22" }, diff --git a/tests/unit/CountItems/CountWorker.js b/tests/unit/CountItems/CountWorker.js index 846df3e0..f28a8b9b 100644 --- a/tests/unit/CountItems/CountWorker.js +++ b/tests/unit/CountItems/CountWorker.js @@ -223,6 +223,42 @@ describe('CountItems::CountWorker', () => { }); }); + test('should nullify unsupported serialized bucket info fields', done => { + const testSendFn = jest.fn(); + const w = new CountWorker({ + log: new DummyLogger(), + sendFn: testSendFn, + client: mongoMock, + }); + const bucketInfo = { + _name: 'test-bucket', + _owner: 'any', + _ownerDisplayName: 'any', + _creationDate: Date.now().toString(), + _websiteConfiguration: { + _indexDocument: 'index.html', + }, + _bucketLoggingStatus: { + _loggingEnabled: { + TargetBucket: 'target-bucket', + TargetPrefix: 'logs/', + }, + }, + }; + w.getIsTransient = jest.fn((bucketInfo, cb) => cb(null, true)); + mongoMock.setup.mockImplementationOnce(cb => cb()); + mongoMock.close.mockImplementationOnce(cb => cb()); + mongoMock.client.isConnected.mockImplementationOnce(() => false); + mongoMock.getObjectMDStats.mockImplementationOnce((_a, _b, _c, _d, cb) => cb(null, { value: 42 })); + w.countItems(bucketInfo, (err, results) => { + expect(err).toBeNull(); + expect(results).toEqual({ value: 42 }); + expect(bucketInfo._websiteConfiguration).toBeNull(); + expect(bucketInfo._bucketLoggingStatus).toBeNull(); + done(); + }); + }); + describe('CountWorker.getIsTransient method', () => { let worker; let mockBucketInfo;