From e0767cdd5e7abe6553c1640bc1b2e0cd995820cd Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Wed, 27 Mar 2024 12:10:48 +0530 Subject: [PATCH] Add console warning when legacy API is used --- lib/sandbox/execute-context.js | 2 +- lib/sandbox/postman-legacy-interface.js | 38 +++++++++- test/unit/sandbox-libraries/legacy.test.js | 88 ++++++++++++++++++++++ 3 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 test/unit/sandbox-libraries/legacy.test.js diff --git a/lib/sandbox/execute-context.js b/lib/sandbox/execute-context.js index 3fea4d8c..66874c69 100644 --- a/lib/sandbox/execute-context.js +++ b/lib/sandbox/execute-context.js @@ -54,7 +54,7 @@ module.exports = function (scope, code, execution, console, timers, pmapi, onAss execution.return.async = (timers.queueLength() > 0); // call this hook to perform any post script execution tasks - legacy.finish(scope, pmapi, onAssertion); + legacy.finish(scope, pmapi, console, onAssertion); function complete () { // if timers are running, we do not need to proceed with any logic of completing execution. instead we wait diff --git a/lib/sandbox/postman-legacy-interface.js b/lib/sandbox/postman-legacy-interface.js index b0b3ae79..cc1a07d2 100644 --- a/lib/sandbox/postman-legacy-interface.js +++ b/lib/sandbox/postman-legacy-interface.js @@ -380,6 +380,37 @@ module.exports = { globalvars.postman = new (execution.target === TARGET_TEST ? PostmanLegacyTestInterface : PostmanLegacyInterface)(execution, globalvars); + // wrap all globals to ensure we track their usage to show warnings + // on access. + LEGACY_GLOBS.forEach((key) => { + if (typeof globalvars[key] === 'function') { + const fn = globalvars[key]; + + globalvars[key] = function () { + scope.__postman_legacy_api_used = true; + + return fn.apply(this, arguments); + }; + } + else if (typeof globalvars[key] === 'object') { + globalvars[key] = new Proxy(globalvars[key], { + set (target, prop, value) { + scope.__postman_legacy_api_used = true; + + target[prop] = value; + }, + + get (target, prop) { + scope.__postman_legacy_api_used = true; + + return target[prop]; + } + }); + } + }); + + scope.__postman_legacy_api_used = false; + // make a final pass to ensure that the global variables are present @@ -409,13 +440,18 @@ module.exports = { * * @param {Uniscope} scope - * @param {Object} pmapi - + * @param {Object} console - * @param {Function} onAssertion - */ - finish (scope, pmapi, onAssertion) { + finish (scope, pmapi, console, onAssertion) { if (!scope.__postman_legacy_setup) { return; } + if (scope.__postman_legacy_api_used) { + console.warn('Using legacy globals is deprecated.'); + } + raiseAssertionEvent(scope, pmapi, onAssertion); }, diff --git a/test/unit/sandbox-libraries/legacy.test.js b/test/unit/sandbox-libraries/legacy.test.js new file mode 100644 index 00000000..0819fa9d --- /dev/null +++ b/test/unit/sandbox-libraries/legacy.test.js @@ -0,0 +1,88 @@ +describe('sandbox library - legacy', function () { + this.timeout(1000 * 60); + var Sandbox = require('../../../'), + context; + + beforeEach(function (done) { + Sandbox.createContext({}, function (err, ctx) { + context = ctx; + done(err); + }); + }); + + afterEach(function () { + context.dispose(); + context = null; + }); + + it('should not show a warning if no legacy vars used', function (done) { + const consoleSpy = sinon.spy(); + + context.on('console', consoleSpy); + context.execute(` + pm.iterationData.get('foo'); + `, function (err) { + if (err) { + return done(err); + } + + expect(consoleSpy).to.not.be.called; + done(); + }); + }); + + it('should show warning on using legacy vars', function (done) { + const consoleSpy = sinon.spy(); + + context.on('console', consoleSpy); + context.execute(` + data['foo'] = 'bar'; + `, function (err) { + if (err) { + return done(err); + } + + expect(consoleSpy).to.be.calledOnce; + expect(consoleSpy.firstCall.args[1]).to.equal('warn'); + expect(consoleSpy.firstCall.args[2]).to.equal('Using legacy globals is deprecated.'); + done(); + }); + }); + + it('should show a warning on using legacy functions', function (done) { + const consoleSpy = sinon.spy(); + + context.on('console', consoleSpy); + context.execute(` + atob('a'); + `, function (err) { + if (err) { + return done(err); + } + + expect(consoleSpy).to.be.calledOnce; + expect(consoleSpy.firstCall.args[1]).to.equal('warn'); + expect(consoleSpy.firstCall.args[2]).to.equal('Using legacy globals is deprecated.'); + done(); + }); + }); + + it('should show a single warning for one execution', function (done) { + const consoleSpy = sinon.spy(); + + context.on('console', consoleSpy); + context.execute(` + data['foo'] = 'bar'; + environment['foo'] = 'bar'; + `, function (err) { + if (err) { + return done(err); + } + + expect(consoleSpy).to.be.calledOnce; + expect(consoleSpy.firstCall.args[1]).to.equal('warn'); + expect(consoleSpy.firstCall.args[2]).to.equal('Using legacy globals is deprecated.'); + done(); + }); + }); +});