UNPKG

postman-runtime

Version:

Underlying library of executing Postman Collections (used by Newman)

1,149 lines (1,034 loc) 202 kB
var _ = require('lodash'), request = require('postman-request'), expect = require('chai').expect, runtime = require('../../index'), zlib = require('zlib'), sdk = require('postman-collection'); describe('Requester', function () { describe('Option Redirect', function () { it('should be able to avoid redirects', function (mochaDone) { var errored = false, runner = new runtime.Runner(), rawCollection = { 'variables': [], 'info': { 'name': 'NewmanSetNextRequest', '_postman_id': 'd6f7bb29-2258-4e1b-9576-b2315cf5b77e', 'description': '', 'schema': 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json' }, 'item': [ { 'id': 'bf0a6006-c987-253a-525d-9f6be7071210', 'name': 'First Request', 'event': [ { 'listen': 'test', 'script': { 'type': 'text/javascript', 'exec': 'tests[\'worked\'] = responseCode.code === 302;' } } ], 'request': { 'url': 'https://postman-echo.com/redirect-to?url=https://postman-echo.com/get', 'method': 'GET' } } ] }, collection = new sdk.Collection(rawCollection), testables = { iterationsStarted: [], iterationsComplete: [], itemsStarted: {}, itemsComplete: {} }, // populate during the run, and then perform tests on it, at the end. /** * Since each callback runs in a separate callstack, this helper function * ensures that any errors are forwarded to mocha * * @param func */ check = function (func) { try { func(); } catch (e) { (errored = true) && mochaDone(e); } }; runner.run(collection, { iterationCount: 1, requester: { followRedirects: false } }, function (err, run) { var runStore = {}; // Used for validations *during* the run. Cursor increments, etc. expect(err).to.be.null; run.start({ start: function (err, cursor) { check(function () { expect(err).to.be.null; expect(cursor).to.deep.include({ position: 0, iteration: 0, length: 1, cycles: 1, eof: false, empty: false, bof: true, cr: false }); expect(cursor).to.have.property('ref'); // Set this to true, and verify at the end, so that the test will fail even if this // callback is never called. testables.started = true; }); }, beforeIteration: function (err, cursor) { check(function () { expect(err).to.be.null; testables.iterationsStarted.push(cursor.iteration); runStore.iteration = cursor.iteration; }); }, iteration: function (err, cursor) { check(function () { expect(err).to.be.null; expect(cursor).to.have.property('iteration', runStore.iteration); testables.iterationsComplete.push(cursor.iteration); }); }, beforeItem: function (err, cursor, item) { check(function () { expect(err).to.be.null; testables.itemsStarted[cursor.iteration] = testables.itemsStarted[cursor.iteration] || []; testables.itemsStarted[cursor.iteration].push(item); runStore.position = cursor.position; runStore.ref = cursor.ref; }); }, item: function (err, cursor, item) { check(function () { expect(err).to.be.null; expect(cursor).to.deep.include({ position: runStore.position, ref: runStore.ref }); testables.itemsComplete[cursor.iteration] = testables.itemsComplete[cursor.iteration] || []; testables.itemsComplete[cursor.iteration].push(item); }); }, beforePrerequest: function (err, cursor, events) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(events).to.be.empty; }); }, prerequest: function (err, cursor, results) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(results).to.be.empty; }); }, beforeTest: function (err, cursor, events) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(events).to.have.lengthOf(1); }); }, test: function (err, cursor, results) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(results).to.have.lengthOf(1); var result = results[0], scriptResult = results[0]; expect(result.error).to.be.undefined; expect(scriptResult).to.deep.nested.include({ 'result.target': 'test' }); }); }, beforeRequest: function (err, cursor) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); }); }, request: function (err, cursor, response, request) { check(function () { expect(err).to.be.null; expect(request.url.toString()).to.be.ok; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(response).to.have.property('code', 302); expect(request).to.be.ok; }); }, done: function (err) { check(function () { expect(err).to.be.null; !errored && mochaDone(); }); } }); }); }); it('should follow redirects by default', function (mochaDone) { var errored = false, runner = new runtime.Runner(), rawCollection = { 'variables': [], 'info': { 'name': 'NewmanSetNextRequest', '_postman_id': 'd6f7bb29-2258-4e1b-9576-b2315cf5b77e', 'description': '', 'schema': 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json' }, 'item': [ { 'id': 'bf0a6006-c987-253a-525d-9f6be7071210', 'name': 'First Request', 'event': [ { 'listen': 'test', 'script': { 'type': 'text/javascript', 'exec': 'tests[\'worked\'] = responseCode.code === 302;' } } ], 'request': { 'url': 'https://postman-echo.com/redirect-to?url=https://postman-echo.com/get', 'method': 'GET' } } ] }, collection = new sdk.Collection(rawCollection), testables = { iterationsStarted: [], iterationsComplete: [], itemsStarted: {}, itemsComplete: {} }, // populate during the run, and then perform tests on it, at the end. /** * Since each callback runs in a separate callstack, this helper function * ensures that any errors are forwarded to mocha * * @param func */ check = function (func) { try { func(); } catch (e) { (errored = true) && mochaDone(e); } }; runner.run(collection, { iterationCount: 1 // This is set to true by default, so commented out // requester: { // followRedirects: true // } }, function (err, run) { var runStore = {}; // Used for validations *during* the run. Cursor increments, etc. expect(err).to.be.null; run.start({ start: function (err, cursor) { check(function () { expect(err).to.be.null; expect(cursor).to.deep.include({ position: 0, iteration: 0, length: 1, cycles: 1, eof: false, empty: false, bof: true, cr: false }); expect(cursor).to.have.property('ref'); // Set this to true, and verify at the end, so that the test will fail even if this // callback is never called. testables.started = true; }); }, beforeIteration: function (err, cursor) { check(function () { expect(err).to.be.null; testables.iterationsStarted.push(cursor.iteration); runStore.iteration = cursor.iteration; }); }, iteration: function (err, cursor) { check(function () { expect(err).to.be.null; expect(cursor).to.have.property('iteration', runStore.iteration); testables.iterationsComplete.push(cursor.iteration); }); }, beforeItem: function (err, cursor, item) { check(function () { expect(err).to.be.null; testables.itemsStarted[cursor.iteration] = testables.itemsStarted[cursor.iteration] || []; testables.itemsStarted[cursor.iteration].push(item); runStore.position = cursor.position; runStore.ref = cursor.ref; }); }, item: function (err, cursor, item) { check(function () { expect(err).to.be.null; expect(cursor).to.deep.include({ position: runStore.position, ref: runStore.ref }); testables.itemsComplete[cursor.iteration] = testables.itemsComplete[cursor.iteration] || []; testables.itemsComplete[cursor.iteration].push(item); }); }, beforePrerequest: function (err, cursor, events) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(events).to.be.empty; }); }, prerequest: function (err, cursor, results) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(results).to.be.empty; }); }, beforeTest: function (err, cursor, events) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(events).to.have.lengthOf(1); }); }, test: function (err, cursor, results) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(results).to.have.lengthOf(1); var result = results[0], scriptResult = results[0]; expect(result.error).to.be.undefined; expect(scriptResult).to.deep.nested.include({ 'result.target': 'test' }); }); }, beforeRequest: function (err, cursor) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); }); }, request: function (err, cursor, response, request) { check(function () { expect(err).to.be.null; expect(request.url.toString()).to.be.ok; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(response).to.have.property('code', 200); expect(request).to.be.ok; }); }, done: function (err) { check(function () { expect(err).to.be.null; !errored && mochaDone(); }); } }); }); }); }); describe('Empty Request body', function () { it('should not send the request body if it is empty in the raw mode', function (mochaDone) { var errored = false, runner = new runtime.Runner(), rawCollection = { 'variables': [], 'info': { 'name': 'EmptyRawBody', '_postman_id': 'd6f7bb29-2258-4e1b-9576-b2315cf5b77e', 'schema': 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json' }, 'item': [ { 'id': 'bf0a6006-c987-253a-525d-9f6be7071210', 'name': 'First Request', 'request': { 'url': 'https://postman-echo.com/post', 'method': 'POST', 'body': { 'mode': 'raw', 'raw': '' } } } ] }, collection = new sdk.Collection(rawCollection), testables = { iterationsStarted: [], iterationsComplete: [], itemsStarted: {}, itemsComplete: {} }, // populate during the run, and then perform tests on it, at the end. /** * Since each callback runs in a separate callstack, this helper function * ensures that any errors are forwarded to mocha * * @param func */ check = function (func) { try { func(); } catch (e) { (errored = true) && mochaDone(e); } }; runner.run(collection, { iterationCount: 1, requester: { followRedirects: false } }, function (err, run) { var runStore = {}; // Used for validations *during* the run. Cursor increments, etc. expect(err).to.be.null; run.start({ start: function (err, cursor) { check(function () { expect(err).to.be.null; expect(cursor).to.deep.include({ position: 0, iteration: 0, length: 1, cycles: 1, eof: false, empty: false, bof: true, cr: false }); expect(cursor).to.have.property('ref'); // Set this to true, and verify at the end, so that the test will fail even if this // callback is never called. testables.started = true; }); }, beforeIteration: function (err, cursor) { check(function () { expect(err).to.be.null; testables.iterationsStarted.push(cursor.iteration); runStore.iteration = cursor.iteration; }); }, iteration: function (err, cursor) { check(function () { expect(err).to.be.null; expect(cursor).to.have.property('iteration', runStore.iteration); testables.iterationsComplete.push(cursor.iteration); }); }, beforeItem: function (err, cursor, item) { check(function () { expect(err).to.be.null; testables.itemsStarted[cursor.iteration] = testables.itemsStarted[cursor.iteration] || []; testables.itemsStarted[cursor.iteration].push(item); runStore.position = cursor.position; runStore.ref = cursor.ref; }); }, item: function (err, cursor, item) { check(function () { expect(err).to.be.null; expect(cursor).to.deep.include({ position: runStore.position, ref: runStore.ref }); testables.itemsComplete[cursor.iteration] = testables.itemsComplete[cursor.iteration] || []; testables.itemsComplete[cursor.iteration].push(item); }); }, beforePrerequest: function (err, cursor, events) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(events).to.be.empty; }); }, prerequest: function (err, cursor, results) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(results).to.be.empty; }); }, beforeTest: function (err, cursor, events) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(events).to.be.empty; }); }, test: function (err, cursor, results) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(results).to.be.empty; }); }, beforeRequest: function (err, cursor) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); }); }, request: function (err, cursor, response, request) { check(function () { expect(err).to.be.null; expect(request.url.toString()).to.be.ok; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(response).to.have.property('code', 200); expect(request).to.be.ok; var body = response.json(); expect(body.args).to.be.empty; expect(body.data).to.be.empty; expect(body.files).to.be.empty; expect(body.form).to.be.empty; }); }, done: function (err) { check(function () { expect(err).to.be.null; !errored && mochaDone(); }); } }); }); }); it('should not send the request body if it is empty in the urlencoded mode', function (mochaDone) { var errored = false, runner = new runtime.Runner(), rawCollection = { 'variables': [], 'info': { 'name': 'EmptyRawBody', '_postman_id': 'd6f7bb29-2258-4e1b-9576-b2315cf5b77e', 'schema': 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json' }, 'item': [ { 'id': 'bf0a6006-c987-253a-525d-9f6be7071210', 'name': 'First Request', 'request': { 'url': 'https://postman-echo.com/post', 'method': 'POST', 'body': { 'mode': 'urlencoded', 'urlencoded': [] } } } ] }, collection = new sdk.Collection(rawCollection), testables = { iterationsStarted: [], iterationsComplete: [], itemsStarted: {}, itemsComplete: {} }, // populate during the run, and then perform tests on it, at the end. /** * Since each callback runs in a separate callstack, this helper function * ensures that any errors are forwarded to mocha * * @param func */ check = function (func) { try { func(); } catch (e) { (errored = true) && mochaDone(e); } }; runner.run(collection, { iterationCount: 1, requester: { followRedirects: false } }, function (err, run) { var runStore = {}; // Used for validations *during* the run. Cursor increments, etc. expect(err).to.be.null; run.start({ start: function (err, cursor) { check(function () { expect(err).to.be.null; expect(cursor).to.deep.include({ position: 0, iteration: 0, length: 1, cycles: 1, eof: false, empty: false, bof: true, cr: false }); expect(cursor).to.have.property('ref'); // Set this to true, and verify at the end, so that the test will fail even if this // callback is never called. testables.started = true; }); }, beforeIteration: function (err, cursor) { check(function () { expect(err).to.be.null; testables.iterationsStarted.push(cursor.iteration); runStore.iteration = cursor.iteration; }); }, iteration: function (err, cursor) { check(function () { expect(err).to.be.null; expect(cursor).to.have.property('iteration', runStore.iteration); testables.iterationsComplete.push(cursor.iteration); }); }, beforeItem: function (err, cursor, item) { check(function () { expect(err).to.be.null; testables.itemsStarted[cursor.iteration] = testables.itemsStarted[cursor.iteration] || []; testables.itemsStarted[cursor.iteration].push(item); runStore.position = cursor.position; runStore.ref = cursor.ref; }); }, item: function (err, cursor, item) { check(function () { expect(err).to.be.null; expect(cursor).to.deep.include({ position: runStore.position, ref: runStore.ref }); testables.itemsComplete[cursor.iteration] = testables.itemsComplete[cursor.iteration] || []; testables.itemsComplete[cursor.iteration].push(item); }); }, beforePrerequest: function (err, cursor, events) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(events).to.be.empty; }); }, prerequest: function (err, cursor, results) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(results).to.be.empty; }); }, beforeTest: function (err, cursor, events) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(events).to.be.empty; }); }, test: function (err, cursor, results) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(results).to.be.empty; }); }, beforeRequest: function (err, cursor) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); }); }, request: function (err, cursor, response, request) { check(function () { expect(err).to.be.null; expect(request.url.toString()).to.be.ok; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(response).to.have.property('code', 200); expect(request).to.be.ok; var body = response.json(); expect(body.args).to.be.empty; expect(body.data).to.be.empty; expect(body.files).to.be.empty; expect(body.form).to.be.empty; }); }, done: function (err) { check(function () { expect(err).to.be.null; !errored && mochaDone(); }); } }); }); }); it('should not send the request body if it is empty in the formdata mode', function (mochaDone) { var errored = false, runner = new runtime.Runner(), rawCollection = { 'variables': [], 'info': { 'name': 'EmptyRawBody', '_postman_id': 'd6f7bb29-2258-4e1b-9576-b2315cf5b77e', 'schema': 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json' }, 'item': [ { 'id': 'bf0a6006-c987-253a-525d-9f6be7071210', 'name': 'First Request', 'request': { 'url': 'https://postman-echo.com/post', 'method': 'POST', 'body': { 'mode': 'formdata', 'formdata': [] } } } ] }, collection = new sdk.Collection(rawCollection), testables = { iterationsStarted: [], iterationsComplete: [], itemsStarted: {}, itemsComplete: {} }, // populate during the run, and then perform tests on it, at the end. /** * Since each callback runs in a separate callstack, this helper function * ensures that any errors are forwarded to mocha * * @param func */ check = function (func) { try { func(); } catch (e) { (errored = true) && mochaDone(e); } }; runner.run(collection, { iterationCount: 1, requester: { followRedirects: false } }, function (err, run) { var runStore = {}; // Used for validations *during* the run. Cursor increments, etc. expect(err).to.be.null; run.start({ start: function (err, cursor) { check(function () { expect(err).to.be.null; expect(cursor).to.deep.include({ position: 0, iteration: 0, length: 1, cycles: 1, eof: false, empty: false, bof: true, cr: false }); expect(cursor).to.have.property('ref'); // Set this to true, and verify at the end, so that the test will fail even if this // callback is never called. testables.started = true; }); }, beforeIteration: function (err, cursor) { check(function () { expect(err).to.be.null; testables.iterationsStarted.push(cursor.iteration); runStore.iteration = cursor.iteration; }); }, iteration: function (err, cursor) { check(function () { expect(err).to.be.null; expect(cursor).to.have.property('iteration', runStore.iteration); testables.iterationsComplete.push(cursor.iteration); }); }, beforeItem: function (err, cursor, item) { check(function () { expect(err).to.be.null; testables.itemsStarted[cursor.iteration] = testables.itemsStarted[cursor.iteration] || []; testables.itemsStarted[cursor.iteration].push(item); runStore.position = cursor.position; runStore.ref = cursor.ref; }); }, item: function (err, cursor, item) { check(function () { expect(err).to.be.null; expect(cursor).to.deep.include({ position: runStore.position, ref: runStore.ref }); testables.itemsComplete[cursor.iteration] = testables.itemsComplete[cursor.iteration] || []; testables.itemsComplete[cursor.iteration].push(item); }); }, beforePrerequest: function (err, cursor, events) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(events).to.be.empty; }); }, prerequest: function (err, cursor, results) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(results).to.be.empty; }); }, beforeTest: function (err, cursor, events) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); // This collection has no pre-request scripts expect(events).to.be.empty; }); }, test: function (err, cursor, results) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(results).to.be.empty; }); }, beforeRequest: function (err, cursor) { check(function () { expect(err).to.be.null; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); }); }, request: function (err, cursor, response, request) { check(function () { expect(err).to.be.null; expect(request.url.toString()).to.be.ok; // Sanity expect(cursor).to.deep.include({ iteration: runStore.iteration, position: runStore.position, ref: runStore.ref }); expect(response).to.have.property('code', 200); expect(request).to.be.ok; var body = response.json(); expect(body.args).to.be.empty; expect(body.data).to.be.empty; expect(body.files).to.be.empty; expect(body.form).to.be.empty; }); }, done: function (err) { check(function () { expect(err).to.be.null; !errored && mochaDone(); }); } }); }); }); }); it('should support multiple headers with the same name', function (mochaDone) { var errored = false, runner = new runtime.Runner(), rawCollection = { 'variables': [], 'info': { 'name': 'TestCollection', '_postman_id': 'd6f7bb29-2258-4e1b-9576-b2315cf5b77e', 'description': '', 'schema': 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json' }, 'item': [ { 'id': 'bf0a6006-c987-253a-525d-9f6be7071210', 'name': 'First Request', 'request': { 'url': 'https://postman-echo.com/headers', 'method': 'GET', 'header': [ { 'key': 'xx', 'value': 'yy' }, { 'key': 'xx', 'value': 'zz' } ] } } ] }, collection = new sdk.Collection(rawCollection), testables = { iterationsStarted: [], iterationsComplete: [], itemsStarted: {}, itemsComplete: {} }, // populate during the run, and then perform tests on it, at the end. /** * Since each callback runs in a separate callstack