describe('<Unit Test - Netsuite XML API>', function () { before(done => { nsmockup.init(done); }); parallel('XML API - nlapiEscapeXML:', () => { it('xml convert string to xml document', done => { let xmlPath = path.resolve(fileDir + '/help.xml'), xml = fs.readFileSync(xmlPath, 'utf8'), escape = nlapiEscapeXML(xml); should(escape).be.ok(); let txtPath = path.resolve(fileDir + '/help-escape.txt'), txt = fs.readFileSync(txtPath, 'utf8'); should(escape).be.equal(txt); return done(); }); it('xml missing xml', done => { let xml = nlapiEscapeXML(); should(xml).be.equal(''); return done(); }); }); after(done => { nsmockup.destroy(done); }); });
describe('<Unit Test - Netsuite XML API>', function () { before(done => { nsmockup.init(done); }); parallel('XML API - nlapiXMLToString:', () => { it('xml convert string to xml document', done => { let xmlPath = path.resolve(fileDir + '/help.xml'), xml = fs.readFileSync(xmlPath, 'utf8'), xmlDoc = nlapiStringToXML(xml); should(xmlDoc).be.ok(); let str = nlapiXMLToString(xmlDoc); should(str).be.ok(); should(str).be.equal(xml); return done(); }); it('xml missing str', done => { let xml = nlapiXMLToString(); should(xml).not.be.ok(); return done(); }); }); after(done => { nsmockup.destroy(done); }); });
testGroups.forEach(function (tests) { parallel('Running ' + tests.length + ' Parallel Template Validation(s)...', function () { tests.forEach(function (test) { it(test.args[0] + ' & ' + test.args[1] + ' should be valid', function () { // validate template files are in correct place test.args.forEach(function (path) { ensureExists.apply(null, [path]); }); validateMetadata.apply(null, [test.args[2]]); validateParamtersFile.apply(null, [test.args[1]]); return validateTemplate.apply(null, test.args) .then(function () { debug('template validation sucessful, deploying template...'); return deployTemplate.apply(null, test.args); }) .then(function () { // success return assert(true); }) .catch(function (err) { var errorString = 'Template Validiation Failed. Try deploying your template with the commands:\n'; errorString += 'azure group template validate --resource-group (your_group_name) '; errorString += ' --template-file ' + test.args[0] + ' --parameters-file ' + test.args[1] + '\n'; errorString += 'azure group deployment create --resource-group (your_group_name) '; errorString += ' --template-file ' + test.args[0] + ' --parameters-file ' + test.args[1]; assert(false, errorString + ' \n\nServer Error:' + JSON.stringify(err, null, 4)); }); }); }); }); });
describe('<Unit Test - Netsuite XML API>', function () { before(done => { nsmockup.init(done); }); parallel('XML API - nlapiSelectValues:', () => { let xmlDoc; before(done => { let xmlPath = path.resolve(fileDir + '/help.xml'), xml = fs.readFileSync(xmlPath, 'utf8'); xmlDoc = nlapiStringToXML(xml); should(xmlDoc).be.ok(); return done(); }); it('select-values find by xpath', done => { let values = nlapiSelectValues(xmlDoc, '//table'); should(values).be.ok(); should(values.length).have.equal(3); return done(); }); it('select-values missing node', done => { try { nlapiSelectValues(); return done('missing node'); } catch (e) { should(e).have.property('code', 'SSS_NODE_ARG_REQD'); return done(); } }); it('select-values missing xpath', done => { try { nlapiSelectValues(xmlDoc); return done('missing xpath'); } catch (e) { should(e).have.property('code', 'SSS_XPATH_ARG_REQD'); return done(); } }); }); after(done => { nsmockup.destroy(done); }); });
parallel('hapi-sparql plugin', () => { const request = (method, url, headers, content, callback) => { callback(null, { headers: { 'content-type': 'application/json' }, body: {method, url, headers, content}, statusCode: 202 }) } const endpointUrl = 'http://example.org/sparql' const constructQuery = 'CONSTRUCT {?s ?p ?o} WHERE {?s ?p ?o}' const selectQuery = 'SELECT * WHERE {?s ?p ?o}' const updateQuery = 'INSERT {<http://example.org/subject> <http://example.org/predicate> "object"} WHERE {}' it('should reject invalid options', (done) => { const server = new Hapi.Server() server.register({ register, options: {} }, (err) => { expect(err).to.be.ok done() }) }) it('should use endpointUrl as fallback value for updateUrl', (done) => { const server = new Hapi.Server() server.connection() server.register({ register, options: {request, endpointUrl} }, (err) => { expect(err).to.be.not.ok server.route({ method: 'GET', path: '/', handler: { sparql: { type: 'update', query: updateQuery } } }) server.inject('/', (res) => { expect(res.result.url).to.be.equal('http://example.org/sparql') done() }) }) }) it('can have a different updateUrl', (done) => { const server = new Hapi.Server() server.connection() server.register({ register, options: { request, endpointUrl, updateUrl: 'http://another.org/sparql' } }, (err) => { expect(err).to.be.not.ok server.route({ method: 'GET', path: '/', handler: { sparql: { type: 'update', query: updateQuery } } }) server.inject('/', (res) => { expect(res.result.url).to.be.equal('http://another.org/sparql') done() }) }) }) it('bind query params to the query', (done) => { const server = new Hapi.Server() server.connection() server.register({ register, options: {request, endpointUrl} }, (err) => { expect(err).to.be.not.ok server.route({ method: 'GET', path: '/', handler: { sparql: { type: 'select', query: selectQuery } }, config: { validate: { query: { p: Joi.string().uri(), o: Joi.string() } } } }) server.inject({ method: 'GET', url: '/?' + 'p=' + encodeURIComponent('http://example.org') + '&o=' + encodeURIComponent('foo\nbar\rbaz') }, (res) => { expect(res.statusCode).to.be.equal(202, res.result.message) const query = res.result.url.match(/\?query=(.+)/)[1] expect(decodeURIComponent(query)).to.be.equal( 'SELECT * WHERE {?s <http://example.org> "foo\\nbar\\rbaz"}') done() }) }) }) it('can make SELECT query', (done) => { const server = new Hapi.Server() server.connection() server.register({ register, options: {request, endpointUrl} }, (err) => { expect(err).to.be.not.ok server.route({ method: 'GET', path: '/', handler: { sparql: { type: 'select', query: selectQuery } } }) server.inject('/', (res) => { expect(res.statusCode).to.be.equal(202) expect(res.headers['content-type']).to.match(/application\/json/) expect(res.result.method).to.be.equal('GET') expect(res.result.url).to.be.equal( 'http://example.org/sparql?query=' + encodeURIComponent(selectQuery)) done() }) }) }) it('can make CONSTRUCT query', (done) => { const server = new Hapi.Server() server.connection() server.register({ register, options: {request, endpointUrl} }, (err) => { expect(err).to.be.not.ok server.route({ method: 'GET', path: '/', handler: { sparql: { type: 'construct', query: constructQuery } } }) server.inject({ url: '/', headers: { accept: '*/*' } }, (res) => { expect(res.statusCode).to.be.equal(202) expect(res.headers['content-type']).to.match(/application\/json/) expect(res.result.method).to.be.equal('GET') expect(res.result.url).to.be.equal( 'http://example.org/sparql?query=' + encodeURIComponent(constructQuery)) done() }) }) }) it('can make UPDATE query', (done) => { const server = new Hapi.Server() server.connection() server.register({ register, options: {request, endpointUrl} }, (err) => { expect(err).to.be.not.ok server.route({ method: 'GET', path: '/', handler: { sparql: { type: 'update', query: updateQuery } } }) server.inject('/', (res) => { expect(res.statusCode).to.be.equal(202) expect(res.headers['content-type']).to.match(/application\/json/) expect(res.result.method).to.be.equal('POST') expect(res.result.url).to.be.equal('http://example.org/sparql') expect(res.result.content).to.be.equal( 'query=' + encodeURIComponent(updateQuery)) done() }) }) }) it('forwards failed response of failed request', (done) => { const failingRequest = (method, url, headers, content, callback) => { callback(null, { headers: { 'content-type': 'text/plain' }, body: 'invalid query', statusCode: 406 }) } const server = new Hapi.Server() server.connection() server.register({ register, options: { request: failingRequest, endpointUrl } }, (err) => { expect(err).to.be.not.ok server.route({ method: 'GET', path: '/', handler: { sparql: { type: 'select', query: selectQuery } } }) server.inject('/', (res) => { expect(res.result.statusCode).to.be.equal(406) expect(res.headers['content-type']).to.match(/application\/json/) expect(res.result.message).to.be.equal('invalid query') done() }) }) }) it('returns 500 if the connection fails', (done) => { const failingRequest = (method, url, headers, content, callback) => { callback(new Error('Connection failed'), null) } const server = new Hapi.Server() server.connection() server.register({ register, options: { request: failingRequest, endpointUrl } }, (err) => { expect(err).to.be.not.ok server.route({ method: 'GET', path: '/', handler: { sparql: { type: 'select', query: selectQuery } } }) server.inject('/').catch((err) => { expect(err.message).to.be.equal('Connection failed') done() }) }) }) it('returns headers in response', (done) => { const server = new Hapi.Server() server.connection() server.register({ register, options: {request, endpointUrl} }, (err) => { expect(err).to.be.not.ok server.route({ method: 'GET', path: '/', handler: { sparql: { type: 'select', query: selectQuery, headers: { 'Content-Disposition': 'attachment' } } } }) server.inject('/', (res) => { expect(res.statusCode).to.be.equal(202) expect(res.headers['content-disposition']).to.be.equal('attachment') done() }) }) }) })
parallel('Responses should conform to the provided JSON schema of the response', () => { const ajv = new Ajv({}); const server = new Server(`${__dirname}/../../config.example.wikimedia.yaml`); function getToday() { function zeroPad(num) { if (num < 10) { return `0${num}`; } return `${num}`; } const now = new Date(); return `${now.getUTCFullYear()}/${zeroPad(now.getUTCMonth() + 1)}/${zeroPad(now.getUTCDate())}`; } before(() => server.start() .then(() => preq.get({uri: `${server.config.baseURL()}/?spec`})) .then((res) => { Object.keys(res.body.components.schemas).forEach((defName) => { ajv.addSchema(res.body.components.schemas[defName], `#/components/schemas/${defName}`); }); })); after(() => server.stop()); it('should expose valid OpenAPI spec', () => { return preq.get({ uri: `${server.config.baseURL()}/?spec` }) .then((res) => { assert.deepEqual({errors: []}, validator.validate(res.body), 'Spec must have no validation errors'); }); }); it('/feed/featured should conform schema', () => { return preq.get({ uri: `${server.config.baseURL()}/feed/featured/${getToday()}` }) .then((res) => { if (!ajv.validate('#/components/schemas/feed', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); it('/feed/featured should conform schema, ruwiki', () => { return preq.get({ uri: `${server.config.baseURL('ru.wikipedia.org')}/feed/featured/${getToday()}` }) .then((res) => { if (!ajv.validate('#/components/schemas/feed', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); it('/page/summary/{title} should conform schema', () => { return preq.get({ uri: `${server.config.baseURL()}/page/summary/Tank` }) .then((res) => { if (!ajv.validate('#/components/schemas/summary', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); it('/feed/announcements should conform schema', () => { return preq.get({ uri: `${server.config.baseURL()}/feed/announcements` }) .then((res) => { if (!ajv.validate('#/components/schemas/announcementsResponse', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); it('/feed/onthisday should conform schema', () => { return preq.get({ uri: `${server.config.baseURL()}/feed/onthisday/all/01/03` }) .then((res) => { if (!ajv.validate('#/components/schemas/onthisdayResponse', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); it('/page/related should conform schema', () => { return preq.get({ uri: `${server.config.bucketURL()}/related/Tank` }) .then((res) => { if (!ajv.validate('#/components/schemas/related', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); });
parallel('#reduce', function() { it('should sum number by collection of array', function(done) { var order = []; var collection = [1, 3, 2, 4]; async.reduce(collection, 0, reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 10); assert.deepStrictEqual(order, [1, 3, 2, 4]); done(); }); }); it('should get array by collection of array', function(done) { var order = []; var collection = [1, 3, 2, 4]; async.reduce(collection, [], reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, [1, 3, 2, 4]); assert.deepStrictEqual(order, [1, 3, 2, 4]); done(); }); }); it('should sum number by collection of array with passing index', function(done) { var order = []; var collection = [1, 3, 2, 4]; async.reduce(collection, 0, reduceIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 10); assert.deepStrictEqual(order, [ [1, 0], [3, 1], [2, 2], [4, 3] ]); done(); }); }); it('should get object by collection of object', function(done) { var order = []; var collection = { a: 5, b: 3, c: 2 }; async.reduce(collection, {}, reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, { 2: 2, 3: 3, 5: 5 }); assert.deepStrictEqual(order, [5, 3, 2]); done(); }); }); it('should get object by collection of object with passing key', function(done) { var order = []; var collection = { a: 5, b: 3, c: 2 }; async.reduce(collection, {}, reduceIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, { 2: 2, 3: 3, 5: 5 }); assert.deepStrictEqual(order, [ [5, 'a'], [3, 'b'], [2, 'c'] ]); done(); }); }); it('should get object by collection of Set', function(done) { var order = []; var set = new util.Set(); set.add(5); set.add(3); set.add(2); async.reduce(set, {}, reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, { 2: 2, 3: 3, 5: 5 }); assert.deepStrictEqual(order, [5, 3, 2]); done(); }); }); it('should get object by collection of Set with passing key', function(done) { var order = []; var set = new util.Set(); set.add(5); set.add(3); set.add(2); async.reduce(set, {}, reduceIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, { 2: 2, 3: 3, 5: 5 }); assert.deepStrictEqual(order, [ [5, 0], [3, 1], [2, 2] ]); done(); }); }); it('should get object by collection of Map', function(done) { var order = []; var map = new util.Map(); map.set('a', 5); map.set('b', 3); map.set('c', 2); async.reduce(map, {}, reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, { 2: ['c', 2], 3: ['b', 3], 5: ['a', 5] }); assert.deepStrictEqual(order, [ ['a', 5], ['b', 3], ['c', 2] ]); done(); }); }); it('should get object by collection of Map with passing key', function(done) { var order = []; var map = new util.Map(); map.set('a', 5); map.set('b', 3); map.set('c', 2); async.reduce(map, {}, reduceIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, { 2: ['c', 2], 3: ['b', 3], 5: ['a', 5] }); assert.deepStrictEqual(order, [ [['a', 5], 0], [['b', 3], 1], [['c', 2], 2] ]); done(); }); }); it('should execute iterator to series with binding', function(done) { var order = []; var collection = { a: 1.1, b: 3.5, c: 2.6 }; async.reduce(collection, {}, reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, { '1.1': 1.1, '2.6': 2.6, '3.5': 3.5 }); assert.deepStrictEqual(order, [1.1, 3.5, 2.6]); done(); }, Math); }); it('should execute on asynchronous', function(done) { var sync = true; var collection = { a: 1, b: 3, c: 2, d: 4, e: 5 }; var iterator = function(memo, num, key, callback) { callback(null, memo + num); }; async.reduce(collection, 0, iterator, function(err, sum) { if (err) { return done(err); } assert.strictEqual(sync, false); assert.strictEqual(sum, 15); done(); }); sync = false; }); it('should throw error', function(done) { var order = []; var collection = [1, 3, 2, 4]; var iterator = function(memo, num, callback) { setTimeout(function() { memo.push(num); order.push(num); callback(num === 3, memo); }, num * delay); }; async.reduce(collection, [], iterator, function(err, res) { assert.ok(err); assert.deepStrictEqual(res, [1, 3]); assert.deepStrictEqual(order, [1, 3]); done(); }); }); it('should throw error if double callback', function(done) { var errorCallCount = 0; setTimeout(function() { assert.strictEqual(errorCallCount, 4); done(); }, delay); domain.create() .on('error', util.errorChecker) .on('error', function() { errorCallCount++; }) .run(function() { var collection = [1, 3, 2, 4]; var iterator = function(memo, num, callback) { process.nextTick(callback); process.nextTick(callback); }; async.reduce(collection, [], iterator); }); }); it('should avoid double callback', function(done) { var called = false; async.reduce([1, 2, 3], 0, function(memo, item, callback) { try { callback(item); } catch (exception) { try { callback(exception); } catch(e) { assert.ok(e); util.errorChecker(e); done(); } } }, function(err) { assert.ok(err); assert.strictEqual(called, false); called = true; async.nothing(); }); }); it('should return response immediately if array is empty', function(done) { var order = []; var array = []; async.reduce(array, 0, reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 0); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if object is empty', function(done) { var order = []; var object = {}; async.reduce(object, 0, reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 0); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is function', function(done) { var order = []; async.reduce(function() {}, 0, reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 0); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is undefined', function(done) { var order = []; async.reduce(undefined, 0, reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 0); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is null', function(done) { var order = []; async.reduce(null, 0, reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 0); assert.deepStrictEqual(order, []); done(); }); }); it('should work with generator', function(done) { var order = []; var collection = [1, 3, 2, 4]; var gen = util.makeGenerator(collection); async.reduce( gen, 0, reduceIterator(order), function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, 10); done(); } ); }); });
parallel('#createLogger', function() { it('should test logger', function(done) { var fn = function(name) { return function(arg, callback) { assert.equal(arg, name); callback(null, name); }; }; var names = ['log', 'dir', 'test']; var name = names.shift(); var logger = async.createLogger(name); logger(fn(name), name, function(err, res) { if (err) { return done(err); } assert.equal(res, 'log'); name = names.shift(); logger = async.createLogger(name); logger(fn(name), name, function(err, res) { if (err) { return done(err); } assert.equal(res, 'dir'); name = names.shift(); logger = async.createLogger(name); logger(fn(name), name, function(err, res) { if (err) { return done(err); } assert.equal(res, 'test'); done(); }); }); }); }); it('should throw error', function(done) { var fn = function(name) { return function(arg, done, logger) { assert.equal(arg, name); logger('error'); done('error'); }; }; var names = ['log', 'debug', 'info']; var name = names.shift(); var logger = async.createLogger(name); logger(fn(name), name, function(err) { assert.ok(err); done(); }); }); it('should check logger', function(done) { var fn = function(arg, callback) { assert.strictEqual(arg, 'test'); callback(null, 'log', 'test'); done(); }; var logger = async.createLogger('warn'); logger(fn, 'test'); }); });
describe('Access checks', function() { var deletedPageTitle = 'User:Pchelolo/Access_Check_Tests'; var deletedPageOlderRevision = 705347919; var deletedPageRevision = 705347950; var emptyResponse = {'batchcomplete': '', 'query': {'badrevids': {'292466': {'revid': '292466'}}}}; function setUpNockResponse(api, title, revision) { return api.post('') .reply(200, { 'batchcomplete': '', 'query': { 'pages': { '49453581': { 'pageid': 49453581, 'ns': 0, 'title': title, 'contentmodel': 'wikitext', 'pagelanguage': 'en', 'touched': '2015-05-22T08:49:39Z', 'lastrevid': revision, 'length': 2941, 'revisions': [{ 'revid': revision, 'user': '******', 'userid': 3606755, 'timestamp': '2015-03-25T20:29:50Z', 'size': 2941, 'sha1': 'c47571122e00f28402d2a1b75cff77a22e7bfecd', 'contentmodel': 'wikitext', 'comment': 'Test', 'tags': [] }] } } } }); } before(function() { return server.start() // Do a preparation request to force siteinfo fetch so that we don't need to mock it .then(() => P.join( preq.get({ uri: `${server.config.bucketURL}/html/Main_Page` }), preq.get({ uri: `${server.config.labsBucketURL}/html/Main_Page` }) )) // Load in the revisions .then(function() { var api = nock(server.config.apiURL); api = setUpNockResponse(api, deletedPageTitle, deletedPageOlderRevision); api = setUpNockResponse(api, deletedPageTitle, deletedPageRevision); // Need to supply no-cache header to make the summary update synchronous // to avoid races on mocks. Can remove when switched to change propagation return preq.get({ uri: server.config.bucketURL + '/html/' + encodeURIComponent(deletedPageTitle) + '/' + deletedPageOlderRevision, headers: { 'cache-control': 'no-cache' } }) .then(function(res) { assert.deepEqual(res.status, 200); return preq.get({ uri: server.config.bucketURL + '/html/' + encodeURIComponent(deletedPageTitle) + '/' + deletedPageRevision, headers: { 'cache-control': 'no-cache' } }); }) .then(function (res) { assert.deepEqual(res.status, 200); api.done(); }) .finally(function () { nock.cleanAll(); }); }); }); describe('Deleting', () => { it('should understand the page was deleted', function() { var api = nock(server.config.apiURL) // Other requests return nothing as if the page is deleted. .post('').reply(200, emptyResponse); // Fetch the page return preq.get({ uri: server.config.bucketURL + '/title/' + encodeURIComponent(deletedPageTitle), headers: { 'cache-control': 'no-cache' } }) .then(function() { throw new Error('404 should have been returned for a deleted page'); }, function(e) { assert.deepEqual(e.status, 404); assert.contentType(e, 'application/problem+json'); }) .then(function() { api.done(); }) .finally(function() { nock.cleanAll(); }); }); }); function testAccess(content_variant, restriction_type, title, rev) { var name = 'should restrict access to ' + restriction_type + ' page '; name += rev ? 'older revision' : 'latest'; name += ' ' + content_variant; it(name, function() { // Check that access is enforced to html var uri = server.config.bucketURL + '/' + content_variant + '/' + encodeURIComponent(title); if (rev) { uri += '/' + rev; } return preq.get({uri: uri}) .then(function(res) { throw new Error('404 should have been returned for a deleted page'); }, function(e) { assert.deepEqual(e.status, 404); assert.contentType(e, 'application/problem+json'); }); }); } parallel('Checking deletions', () => { it('should restrict access to deleted page latest revision', function() { // This is only required until the hack for no-cache header is in place var api = nock(server.config.apiURL) .post('').reply(200, emptyResponse); return preq.get({uri: server.config.bucketURL + '/revision/' + deletedPageRevision}) .then(function() { throw new Error('404 should have been returned for a deleted page'); }, function(e) { assert.deepEqual(e.status, 404); assert.contentType(e, 'application/problem+json'); }) .then(function() { api.done(); }) .finally(function() { nock.cleanAll(); }); }); it('should restrict access to older revision of a deleted page', function() { // This is only required until the hack for no-cache header is in place var api = nock(server.config.apiURL) .post('').reply(200, emptyResponse); return preq.get({uri: server.config.bucketURL + '/revision/' + deletedPageOlderRevision}) .then(function() { throw new Error('404 should have been returned for a deleted page'); }, function(e) { assert.deepEqual(e.status, 404); assert.contentType(e, 'application/problem+json'); }) .then(function() { api.done(); }) .finally(function() { nock.cleanAll(); }); }); testAccess('html', 'deleted', deletedPageTitle); testAccess('data-parsoid', 'deleted', deletedPageTitle); testAccess('html', 'deleted', deletedPageTitle, deletedPageOlderRevision); testAccess('data-parsoid', 'deleted', deletedPageTitle, deletedPageOlderRevision); testAccess('mobile-sections', 'deleted', deletedPageTitle); testAccess('mobile-sections-lead', 'deleted', deletedPageTitle); testAccess('mobile-sections-remaining', 'deleted', deletedPageTitle); testAccess('summary', 'deleted', deletedPageTitle); }); describe('Undeleting', () => { it('Should understand that the page was undeleted', function() { return preq.get({ uri: server.config.bucketURL + '/title/' + encodeURIComponent(deletedPageTitle), headers: { 'cache-control': 'no-cache' } }) .then(function(res) { assert.deepEqual(res.status, 200); return preq.get({ uri: server.config.bucketURL + '/html/' + encodeURIComponent(deletedPageTitle) + '/' + deletedPageOlderRevision, }); }) .then(function (res) { assert.deepEqual(res.status, 200); }); }); }); describe('Restricting', () => { var pageTitle = 'User:Pchelolo/restriction_testing_mock'; var pageRev = 301375; it('should correctly fetch updated restrictions', function() { var normalRev = { "revid": pageRev, "user": "******", "userid": 6591, "timestamp": "2015-02-03T21:15:55Z", "size": 7700, "contentmodel": "wikitext", "tags": [] }; var normalResponse = { "pageid": 152993, "ns": 3, "title": pageTitle, "contentmodel": "wikitext", "pagelanguage": "en", "pagelanguagehtmlcode": "en", "pagelanguagedir": "ltr", "touched": "2015-12-10T23:41:54Z", "lastrevid": pageRev, "length": 23950, "revisions": [normalRev] }; var restrictedRev = Object.assign({}, normalRev); restrictedRev.texthidden = true; restrictedRev.sha1hidden = true; var restrictedResponse = Object.assign({}, normalResponse); restrictedResponse.revisions = [restrictedRev]; var api = nock(server.config.labsApiURL) .post('').reply(200, { "batchcomplete": "", "query": {"pages": {"45161196": normalResponse}} }).post('').reply(200, { "batchcomplete": "", "query": {"pages": {"45161196": restrictedResponse}} }); // First fetch a non-restricted revision return preq.get({ uri: server.config.labsBucketURL + '/title/' + encodeURIComponent(pageTitle) }) .then(function(res) { assert.deepEqual(res.status, 200); assert.deepEqual(res.body.items.length, 1); // Now fetch update with restrictions return preq.get({ uri: server.config.labsBucketURL + '/title/' + encodeURIComponent(pageTitle), headers: { 'cache-control': 'no-cache' } }); }).then(function() { throw new Error('403 should be thrown'); }, function(e) { assert.deepEqual(e.status, 403); }).then(function() { api.done(); }) .finally(function() { nock.cleanAll(); }); }); it('should store updated restrictions', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/' + encodeURIComponent(pageTitle) }) .then(function() { throw new Error('403 should be thrown'); }, function(e) { assert.deepEqual(e.status, 403); }); }); it('should restrict access to restricted revision html', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/' + encodeURIComponent(pageTitle) + '/' + pageRev }) .then(function() { throw new Error('403 should have been returned for a deleted page'); }, function(e) { assert.deepEqual(e.status, 403); assert.contentType(e, 'application/problem+json'); }); }); it('should allow to view content if restrictions disappeared', function() { return preq.get({ uri: server.config.labsBucketURL + '/title/' + encodeURIComponent(pageTitle), headers: { 'cache-control': 'no-cache' } }) .then(function(res) { assert.deepEqual(res.status, 200); return preq.get({ uri: server.config.labsBucketURL + '/html/' + encodeURIComponent(pageTitle) + '/' + pageRev, }); }) .then(function (res) { assert.deepEqual(res.status, 200); }); }); }); });
describe('Key value buckets', () => { before(() => { return server.start(); }); function randomString(length) { let result = ''; for (let i = 0; i < length / 10; i++) { result += Math.random().toString(36).slice(2); } return result; } function runTests(bucketName) { const bucketBaseURI = `${server.config.baseURL}/buckets/${bucketName}/${bucketName}TestingBucket`; before(() => { return preq.put({ uri: bucketBaseURI }); }); it('stores a content in a bucket and gets it back', () => { const testData = randomString(60000); return preq.put({ uri: `${bucketBaseURI}/Test1`, body: new Buffer(testData) }) .then((res) => { assert.deepEqual(res.status, 201); return preq.get({ uri: `${bucketBaseURI}/Test1` }); }) .then((res) => { assert.deepEqual(res.status, 200); assert.deepEqual(res.body, new Buffer(testData)); }); }); it('assigns etag to a value', () => { const testData = randomString(100); return preq.put({ uri: `${bucketBaseURI}/Test3`, body: new Buffer(testData) }) .then((res) => { assert.deepEqual(res.status, 201); return preq.get({ uri: `${bucketBaseURI}/Test3` }); }) .then((res) => { assert.deepEqual(res.status, 200); assert.ok(res.headers.etag); assert.ok(new RegExp('^"0\/').test(res.headers.etag), true); }); }); it('throws 404 error if key not found', () => { return preq.get({ uri: `${bucketBaseURI}/some_not_existing_key` }) .then(() => { throw new Error('Error should be thrown'); }, (e) => { assert.deepEqual(e.status, 404); }); }); it('key_value should not overwrite same content with ignore_duplicates', () => { const testData = randomString(100); const tids = [ uuid.now().toString(), uuid.now().toString(), uuid.now().toString() ]; return P.each(tids, (tid) => { return preq.put({ uri: `${bucketBaseURI}/List_Test_1`, body: new Buffer(testData), headers: { 'if-none-hash-match': '*' } }) .catch(() => {}); }) .then(() => { return preq.get({ uri: `${bucketBaseURI}/List_Test_1/`, query: { limit: 10 } }); }) .then((res) => { assert.deepEqual(res.status, 200); assert.deepEqual(res.body.items.length, 1); }); }); } parallel('key_value', () => { runTests('key_value'); }); });
describe('Redirects', function() { before(function() { return server.start(); }); parallel('', () => { it('should redirect to a normalized version of a title', function() { return preq.get({ uri: server.config.bucketURL + '/html/Main%20Page?test=mwAQ', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 301); assert.deepEqual(res.headers['location'], 'Main_Page?test=mwAQ'); }); }); it('should preserve parameters while redirecting to a normalized version of a title', function() { return preq.get({ uri: server.config.bucketURL + '/html/Main%20Page/1234?test=mwAQ', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 301); assert.deepEqual(res.headers['location'], '../Main_Page/1234?test=mwAQ'); }); }); it('should preserve parameters while redirecting to a normalized version of a title, #2', function() { return preq.get({ uri: server.config.bucketURL + '/html/Main%20Page/', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 301); assert.deepEqual(res.headers['location'], '../Main_Page/'); }); }); it('should not redirect to a normalized version of a title, no-cache', function() { return preq.get({ uri: server.config.bucketURL + '/html/Main%20Page?test=mwAQ', headers: { 'cache-control': 'no-cache' }, followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 200); }); }); it('should redirect to commons for missing file pages', function() { return preq.get({ uri: server.config.bucketURL + '/html/File:ThinkingMan_Rodin.jpg', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers['location'], 'https://commons.wikimedia.org/api/rest_v1/page/html/File%3AThinkingMan_Rodin.jpg'); }); }); it('should redirect to commons for missing file pages, dewiki', function() { return preq.get({ uri: server.config.hostPort + '/de.wikipedia.org/v1/page/html/Datei:Name.jpg', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers['location'], 'https://commons.wikimedia.org/api/rest_v1/page/html/File%3AName.jpg'); }); }); it('should not redirect to commons for missing file pages, redirect=false', function() { return preq.get({ uri: server.config.bucketURL + '/html/File:ThinkingMan_Rodin.jpg?redirect=false' }) .then(function() { throw new Error('Error should be thrown'); }, function(e) { assert.deepEqual(e.status, 404); }); }); it('should not redirect to commons for missing file pages, no-cache', function() { return preq.get({ uri: server.config.bucketURL + '/html/File:ThinkingMan_Rodin.jpg', headers: { 'cache-control': 'no-cache' } }) .then(function() { throw new Error('Error should be thrown'); }, function(e) { assert.deepEqual(e.status, 404); }); }); it('should append ?redirect=false to self-redirecting pages', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2FSelf_Redirect', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers.location, 'User%3APchelolo%2FSelf_Redirect?redirect=false'); }); }); it('should not redirect if file is missing on commons', function() { return preq.get({ uri: server.config.hostPort + '/commons.wikimedia.org/v1/html/File:Some_File_That_Does_Not_Exist.jpg' }) .then(function() { throw new Error('Error should be thrown'); }, function(e) { assert.deepEqual(e.status, 404); }); }); it('should result in 404 if + is normalized by MW API', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2FOnDemand+Test' }) .then(function() { throw new Error('Error should be thrown'); }, function(e) { assert.deepEqual(e.status, 404); }); }); it('should not redirect if redirect=false and page is not in storage', function() { return preq.get({ uri: server.config.bucketURL + '/html/User:Pchelolo%2fRedirect_Test2?redirect=false', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 200); assert.deepEqual(res.headers.location, undefined); assert.deepEqual(res.headers['content-location'], 'https://en.wikipedia.org/api/rest_v1/page/html/User%3APchelolo%2FRedirect_Test2?redirect=false') assert.deepEqual(res.body.length > 0, true); }); }); it('should return 302 for redirect pages html and data-parsoid', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2fRedirect_Test', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers.location, 'User%3APchelolo%2FRedirect_Target_%25'); assert.deepEqual(res.headers['cache-control'], 'test_purged_cache_control'); assert.deepEqual(res.body.length > 0, true); assert.deepEqual(/Redirect Target/.test(res.body.toString()), false); var renderInfo = mwUtil.parseETag(res.headers.etag); return preq.get({ uri: server.config.labsBucketURL + '/data-parsoid/User:Pchelolo%2fRedirect_Test/' + renderInfo.rev + '/' + renderInfo.tid, followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers.location, '../../User%3APchelolo%2FRedirect_Target_%25'); assert.deepEqual(res.headers['cache-control'], 'test_purged_cache_control'); assert.deepEqual(res.headers['content-type'], server.config.conf.test.content_types['data-parsoid']); assert.deepEqual(Object.keys(res.body).length > 0, true); }); }); }); it('should return 302 for redirect pages html, entities', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2fRedirect_Test_Amp', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers.location, 'User%3APchelolo%2FRedirect_Target_%26'); assert.deepEqual(res.headers['cache-control'], 'test_purged_cache_control'); assert.deepEqual(res.body.length > 0, true); assert.deepEqual(/Redirect Target/.test(res.body.toString()), false); }); }); it('should return 302 for redirect pages html, hash', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2fRedirect_Test_Hash', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers.location, 'Main_Page'); assert.deepEqual(res.body.length > 0, true); assert.deepEqual(res.headers['cache-control'], 'test_purged_cache_control'); }); }); it('should return 200 for redirect pages html with redirect=no', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2fRedirect_Test?redirect=no', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 200); assert.deepEqual(res.headers.location, undefined); assert.deepEqual(res.body.length > 0, true); assert.deepEqual(/Redirect Target/.test(res.body.toString()), false); }); }); it('should return 200 for redirect pages html with no-cache', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2fRedirect_Test', headers: { 'cache-control': 'no-cache' }, followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 200); assert.deepEqual(res.headers.location, undefined); assert.deepEqual(res.body.length > 0, true); assert.deepEqual(/Redirect Target/.test(res.body.toString()), false); }); }); it('should return 302 for redirect pages html with revision', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2fRedirect_Test/331630', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers.location, '../User%3APchelolo%2FRedirect_Target_%25'); assert.deepEqual(res.headers['cache-control'], 'test_purged_cache_control'); assert.deepEqual(res.body.length > 0, true); assert.deepEqual(/Redirect Target/.test(res.body.toString()), false); }); }); it('should return 200 for redirect pages html with revision, redirect=no', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2fRedirect_Test/331630?redirect=no', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 200); assert.deepEqual(res.headers.location, undefined); assert.deepEqual(res.body.length > 0, true); assert.deepEqual(/Redirect Target/.test(res.body.toString()), false); }); }); it('should return 302 for redirect pages summary', function() { return preq.get({ uri: server.config.labsBucketURL + '/summary/User:Pchelolo%2fRedirect_Test', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers.location, 'User%3APchelolo%2FRedirect_Target_%25'); assert.deepEqual(res.headers['cache-control'], 'test_purged_cache_control_with_client_caching'); assert.deepEqual(res.body.length, 0); }); }); it('should return 302 for redirect pages mobile-sections', function() { return preq.get({ uri: server.config.labsBucketURL + '/mobile-sections/User:Pchelolo%2fRedirect_Test', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers.location, 'User%3APchelolo%2FRedirect_Target_%25'); assert.deepEqual(res.body.length, 0); }); }); it('should return 302 for redirect pages mobile-sections-lead', function() { return preq.get({ uri: server.config.labsBucketURL + '/mobile-sections-lead/User:Pchelolo%2fRedirect_Test', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers.location, 'User%3APchelolo%2FRedirect_Target_%25'); assert.deepEqual(res.body.length, 0); }); }); it('should return 302 for redirect pages mobile-sections-remaining', function() { return preq.get({ uri: server.config.labsBucketURL + '/mobile-sections-remaining/User:Pchelolo%2fRedirect_Test', followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 302); assert.deepEqual(res.headers.location, 'User%3APchelolo%2FRedirect_Target_%25'); assert.deepEqual(res.body.length, 0); }); }); it('should attach correct content-location', () => { return preq.get({ uri: server.config.bucketURL + '/html/Main_Page' }) .then((res) => { assert.deepEqual(res.status, 200); assert.deepEqual(res.headers['content-location'], 'https://en.wikipedia.org/api/rest_v1/page/html/Main_Page'); }) }); it('should return 200 for redirect pages html, cross-origin', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2fRedirect_Test', headers: { origin: 'test.com' }, followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 200); assert.deepEqual(res.headers['content-location'], 'https://en.wikipedia.beta.wmflabs.org/api/rest_v1/page/html/User%3APchelolo%2FRedirect_Target_%25'); assert.deepEqual(res.headers['cache-control'], 'no-cache'); assert.deepEqual(res.body.length > 0, true); assert.deepEqual(/Redirect Target/.test(res.body.toString()), true); }); }); it('should return 200 for redirect pages html, cross-origin, with title normalization', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2fRedirect%20Test', headers: { origin: 'test.com' }, followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 200); assert.deepEqual(res.headers['content-location'], 'https://en.wikipedia.beta.wmflabs.org/api/rest_v1/page/html/User%3APchelolo%2FRedirect_Target_%25'); assert.deepEqual(res.headers['cache-control'], 'no-cache'); assert.deepEqual(res.body.length > 0, true); assert.deepEqual(/Redirect Target/.test(res.body.toString()), true); }); }); it('should redirect to commons for missing file pages, cross-origin', function() { return preq.get({ uri: server.config.bucketURL + '/html/File:ThinkingMan_Rodin.jpg', headers: { origin: 'test.com' }, followRedirect: false }) .then(function(res) { assert.deepEqual(res.status, 200); assert.deepEqual(res.headers['content-location'], 'https://commons.wikimedia.org/api/rest_v1/page/html/File%3AThinkingMan_Rodin.jpg'); assert.deepEqual(res.headers['cache-control'], 'no-cache'); }); }); it('should stop redirect cycles, cross-origin', function() { return preq.get({ uri: server.config.labsBucketURL + '/html/User:Pchelolo%2fRedirect_Test_One', headers: { origin: 'test.com' }, followRedirect: false }) .then(() => { throw new Error('Error must be thrown'); }, (e) => { assert.deepEqual(e.status, 504); assert.deepEqual(/Exceeded maxRedirects/.test(e.body.detail), true); }); }); }); });
parallel('transform api', function() { this.timeout(20000); let contentTypes; const server = new Server(); before(() => { return server.start() .then(() => { contentTypes = server.config.conf.test.content_types; return preq.get({ uri: `${server.config.bucketURL('en.wikipedia.beta.wmflabs.org')}/html/${testPage.title}/${testPage.revision}` }); }) .then((res) => { testPage.html = res.body; }); }); after(() => server.stop()); it('wt2html', () => { return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/wikitext/to/html/User:GWicke%2F_restbase_test`, body: { wikitext: '== Heading ==' } }) .then((res) => { assert.deepEqual(res.status, 200); assert.contentType(res, contentTypes.html); const pattern = /<h2.*>Heading<\/h2>/; if (!pattern.test(res.body)) { throw new Error(`Expected pattern in response: ${pattern }\nSaw: ${res.body}`); } }); }); it('wt2html with body_only', () => { return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/wikitext/to/html/User:GWicke%2F_restbase_test`, body: { wikitext: '== Heading ==', body_only: true } }) .then((res) => { assert.deepEqual(res.status, 200); assert.contentType(res, contentTypes.html); const pattern = /^<h2.*>Heading<\/h2>$/; if (!pattern.test(res.body)) { throw new Error(`Expected pattern in response: ${pattern }\nSaw: ${res.body}`); } }); }); it('wt2lint', () => { return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/wikitext/to/lint`, body: { wikitext: '== Heading ==' } }).then((res) => { assert.deepEqual(res.status, 200); assert.deepEqual(res.body, []); }); }); it('wt2lint with errors', () => { return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/wikitext/to/lint`, body: { wikitext: '<div>No div ending' } }).then((res) => { assert.deepEqual(res.status, 200); assert.deepEqual(res.body.length, 1); }); }); it('html2wt, no-selser', () => { return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/html/to/wikitext/User:GWicke%2F_restbase_test`, body: { html: '<body>The modified HTML</body>' } }) .then((res) => { assert.deepEqual(res.status, 200); assert.deepEqual(res.body, 'The modified HTML'); assert.contentType(res, contentTypes.wikitext); }); }); it('html2wt, selser', () => { return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/html/to/wikitext/${testPage.title}/${testPage.revision}`, body: { html: testPage.html } }) .then((res) => { assert.deepEqual(res.status, 200); assert.deepEqual(res.body, testPage.wikitext); assert.contentType(res, contentTypes.wikitext); }); }); it('html2wt with scrub_wikitext', () => { return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/html/to/wikitext`, body: { html: '<h2></h2>', scrub_wikitext: 1 } }) .then((res) => { assert.deepEqual(res.status, 200); assert.deepEqual(res.body, ''); }); }); it('sections2wt, replace', () => { const pageWithSectionsTitle = 'User:Pchelolo%2Fsections_test'; const pageWithSectionsRev = 275834; return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/section-changes/to/wikitext/${pageWithSectionsTitle}/${pageWithSectionsRev}`, headers: { 'content-type': 'application/json' }, body: { changes: { mwAQ: [], mwAw: [{ html: "<h2>First Section replaced</h2>" }], mwBA: [{ html: "<h2>Second Section replaced</h2>" }] } } }) .then((res) => { assert.deepEqual(res.status, 200); assert.contentType(res, contentTypes.wikitext); assert.deepEqual(res.body, '== First Section replaced ==\n\n' + '== Second Section replaced ==\n'); }); }); it('sections2wt, replace, form-data', () => { const pageWithSectionsTitle = 'User:Pchelolo%2Fsections_test'; const pageWithSectionsRev = 275834; return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/section-changes/to/wikitext/${pageWithSectionsTitle}/${pageWithSectionsRev}`, body: { changes: JSON.stringify({ mwAQ: [], mwAw: [{ html: "<h2>First Section replaced</h2>" }], mwBA: [{ html: "<h2>Second Section replaced</h2>" }] }), scrub_wikitext: 'true' } }) .then((res) => { assert.deepEqual(res.status, 200); assert.contentType(res, contentTypes.wikitext); assert.deepEqual(res.body, '== First Section replaced ==\n\n' + '== Second Section replaced ==\n'); }); }); it('sections2wt, replace, scrub_wikitext', () => { const pageWithSectionsTitle = 'User:Pchelolo%2Fsections_test'; const pageWithSectionsRev = 275834; return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/section-changes/to/wikitext/${pageWithSectionsTitle}/${pageWithSectionsRev}`, headers: { 'content-type': 'application/json' }, body: { changes: { mwAQ: [], mwAw: [{ html: "<h2></h2>" }], mwBA: [{ html: "<h2>Second Section replaced</h2>" }] }, scrub_wikitext: true } }) .then((res) => { assert.deepEqual(res.status, 200); assert.contentType(res, contentTypes.wikitext); assert.deepEqual(res.body, '== Second Section replaced ==\n'); }); }); it('sections2wt, append', () => { const pageWithSectionsTitle = 'User:Pchelolo%2Fsections_test'; const pageWithSectionsRev = 275834; return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/section-changes/to/wikitext/${pageWithSectionsTitle}/${pageWithSectionsRev}`, headers: { 'content-type': 'application/json' }, body: { changes: { mwAQ: [], mwAw: [{ id: 'mwAw' }, { html: '<h2>Appended Section</h2>' }], mwBA: [{ html: '<h2>Prepended section</h2>' }, { id: 'mwBA' }] } } }) .then((res) => { assert.deepEqual(res.status, 200); assert.contentType(res, contentTypes.wikitext); assert.deepEqual(res.body, '== First Section ==\n\n' + '== Appended Section ==\n\n' + '== Prepended section ==\n\n' + '== Second Section ==\n'); }); }); it('sections2wt, move', () => { const pageWithSectionsTitle = 'User:Pchelolo%2Fsections_test'; const pageWithSectionsRev = 275834; return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/section-changes/to/wikitext/${pageWithSectionsTitle}/${pageWithSectionsRev}`, body: { changes: { mwAQ: [], mwAw: [{ id: 'mwBA' }, { id: 'mwAw' }], mwBA: [] } }, headers: { 'content-type': 'application/json' } }) .then((res) => { assert.deepEqual(res.status, 200); assert.contentType(res, contentTypes.wikitext); assert.deepEqual(res.body, '== Second Section ==\n' + '== First Section ==\n'); }); }); it('sections2wt, throws on invalid id', () => { const pageWithSectionsTitle = 'User:Pchelolo%2Fsections_test'; const pageWithSectionsRev = 275834; return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/section-changes/to/wikitext/${pageWithSectionsTitle}/${pageWithSectionsRev}`, body: { changes: { mwAASDC: [] } }, headers: { 'content-type': 'application/json' } }) .then(() => { throw new Error('Error must be thrown'); }) .catch((e) => { assert.deepEqual(e.status, 400); }); }); it('sections2wt, throws on invalid replacement id', () => { const pageWithSectionsTitle = 'User:Pchelolo%2Fsections_test'; const pageWithSectionsRev = 275834; return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/section-changes/to/wikitext/${pageWithSectionsTitle}/${pageWithSectionsRev}`, body: { changes: { mwAw:[ { id: 'mwAASDC' }, { id: 'mwAw' } ] } }, headers: { 'content-type': 'application/json' } }) .then(() => { throw new Error('Error must be thrown'); }) .catch((e) => { assert.deepEqual(e.status, 400); }); }); it('supports reversed order of properties in TimeUuid meta', () => { const newHtml = testPage.html.replace(/<meta property="mw:TimeUuid" content="([^"]+)"\/?>/, '<meta content="$1" property="mw:TimeUuid" />'); return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/html/to/wikitext/${testPage.title}/${testPage.revision}`, body: { html: newHtml } }) .then((res) => { assert.deepEqual(res.status, 200); const pattern = /Selser test/; if (!pattern.test(res.body)) { throw new Error(`Expected pattern in response: ${pattern }\nSaw: ${JSON.stringify(res, null, 2)}`); } assert.contentType(res, contentTypes.wikitext); }); }); it('supports stashing content', () => { return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/wikitext/to/html/${testPage.title}/${testPage.revision}`, body: { wikitext: '== ABCDEF ==', stash: true } }) .then((res) => { assert.deepEqual(res.status, 200); const etag = res.headers.etag; assert.deepEqual(/\/stash"$/.test(etag), true); return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/html/to/wikitext/${testPage.title}/${testPage.revision}`, headers: { 'if-match': etag }, body: { html: res.body.replace('>ABCDEF<', '>FECDBA<') } }); }) .then((res) => { assert.deepEqual(res.status, 200); assert.deepEqual(res.body, '== FECDBA =='); }); }); it('substitutes 0 as revision if not provided for stashing', () => { return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/wikitext/to/html/${testPage.title}`, body: { wikitext: '== ABCDEF ==', stash: true } }) .then((res) => { assert.deepEqual(res.status, 200); const etag = res.headers.etag; assert.deepEqual(/^"0\/[^\/]+\/stash"$/.test(etag), true); }); }); it('does not allow stashing without title', () => { return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/wikitext/to/html`, body: { wikitext: '== ABCDEF ==', stash: true } }) .then(() => { throw new Error('Error should be thrown'); }, (e) => { assert.deepEqual(e.status, 400); }); }); it('does not allow to transform html with no tid', () => { return preq.post({ uri: `${server.config.baseURL('en.wikipedia.beta.wmflabs.org')}/transform/html/to/wikitext/${testPage.title}/${testPage.revision}`, body: { html: '<h1>A</h1>' } }) .then(() => { throw new Error('Error should be thrown'); }, (e) => { assert.deepEqual(e.status, 400); }); }); });
parallel('#iterator', function() { it('should execute iterators', function(done) { var order = []; var iterator = async.iterator([ function() { order.push(1); }, function(arg1) { assert.strictEqual(arg1, 'arg1'); order.push(2); }, function(arg1, arg2) { assert.strictEqual(arg1, 'arg1'); assert.strictEqual(arg2, 'arg2'); order.push(3); } ]); iterator(); assert.deepStrictEqual(order, [1]); var iterator2 = iterator(); assert.deepStrictEqual(order, [1, 1]); var iterator3 = iterator2('arg1'); assert.deepStrictEqual(order, [1, 1, 2]); var iterator4 = iterator3('arg1', 'arg2'); assert.deepStrictEqual(order, [1, 1, 2, 3]); assert.strictEqual(iterator4, null); done(); }); it('should execute object iterators', function(done) { var order = []; var iterator = async.iterator({ a: function() { order.push(1); }, b: function(arg1) { assert.strictEqual(arg1, 'arg1'); order.push(2); }, c: function(arg1, arg2) { assert.strictEqual(arg1, 'arg1'); assert.strictEqual(arg2, 'arg2'); order.push(3); } }); iterator(); assert.deepStrictEqual(order, [1]); var iterator2 = iterator(); assert.deepStrictEqual(order, [1, 1]); var iterator3 = iterator2('arg1'); assert.deepStrictEqual(order, [1, 1, 2]); var iterator4 = iterator3('arg1', 'arg2'); assert.deepStrictEqual(order, [1, 1, 2, 3]); assert.strictEqual(iterator4, null); done(); }); it('should get undefined if array is empty', function(done) { var iterator = async.iterator([]); assert.deepStrictEqual(iterator(), null); assert.deepStrictEqual(iterator.next(), null); done(); }); it('should get next iterator', function(done) { var order = []; var iterator = async.iterator([ function() { order.push(1); }, function(arg1) { assert.strictEqual(arg1, 'arg1'); order.push(2); }, function(arg1, arg2) { assert.strictEqual(arg1, 'arg1'); assert.strictEqual(arg2, 'arg2'); order.push(3); } ]); var fn = iterator.next(); var iterator2 = fn('arg1'); assert.deepStrictEqual(order, [2]); iterator2('arg1', 'arg2'); assert.deepStrictEqual(order, [2, 3]); assert.deepStrictEqual(iterator2.next(), null); done(); }); });
describe('<Unit Test - Netsuite Search API>', function () { this.timeout(5000); before(done => { let metadata = [ base + '/meta/customrecord_codeg.json', base + '/meta/customrecord_codeg_ids.json' ], records = { 'customrecord_codeg': base + '/data/customrecord_codeg.json', 'customrecord_codeg_ids': base + '/data/customrecord_codeg_ids.json' }; nsmockup.init({records, metadata}, done); }); parallel('SuiteScript API - nlapiSearchRecord:', () => { let recType = 'customrecord_codeg'; it('search all', done => { var columns = [ 'custrecord_type_id', 'custrecord_code_id' ].map(c => new nlobjSearchColumn(c)); let codes = nlapiSearchRecord(recType, null, null, columns); should(codes).have.length(1244); for (let i = 0; i < codes.length; i++) { let code = codes[i]; should(code).have.instanceOf(nlobjSearchResult); should(code).have.property('id'); should(code).have.property('type', 'customrecord_codeg'); //should(code).have.property('rawColumns').have.length(3); let cols = code.getAllColumns(); should(cols).have.length(2); for (let j = 0; j < cols.length; j++) { let col = cols[j]; should(col).have.instanceOf(nlobjSearchColumn); should(col).have.property('name').have.equalOneOf(['custrecord_type_id', 'custrecord_code_id']); } } return done(); }); it('search by internalid', done => { let columns = [ 'custrecord_type_id', 'custrecord_code_id' ].map(c => new nlobjSearchColumn(c)); var codes = nlapiSearchRecord(recType, 5, null, columns); should(codes).have.length(1); return done(); }); it('search one field (using nlobjSearchFilter)', done => { let columns = [ 'custrecord_type_id', 'custrecord_code_id' ].map(c => new nlobjSearchColumn(c)), filters = [ ['custrecord_type_id', null, 'anyof', 237] ].map(f => new nlobjSearchFilter(f[0], f[1], f[2], f[3])); var codes = nlapiSearchRecord(recType, null, filters, columns); should(codes).have.length(224); return done(); }); it('search one field (using array filter)', done => { let columns = [ 'custrecord_type_id', 'custrecord_code_id' ].map(c => new nlobjSearchColumn(c)), filters = [ ['custrecord_type_id', null, 'anyof', 237] ]; var codes = nlapiSearchRecord(recType, null, filters, columns); should(codes).have.length(224); return done(); }); it('search one field + join', done => { let columns = [ 'custrecord_type_id', 'custrecord_code_id' ].map(c => new nlobjSearchColumn(c)), filters = [ ['custrecord_id_title_id', 'custrecord_type_id', 'is', 'japo 266'] ].map(f => new nlobjSearchFilter(f[0], f[1], f[2], f[3])); var codes = nlapiSearchRecord(recType, null, filters, columns); should(codes).have.length(15); return done(); }); it('search one field + join and column join (raw params)', done => { let columns = [ ['custrecord_id_title_id', 'custrecord_type_id'], ['custrecord_code_id'] ].map(c => new nlobjSearchColumn(c[0], c[1])), filters = [ ['internalid', 'custrecord_type_id', 'is', '266'], ['custrecord_id_title_id', 'custrecord_type_id', 'is', 'japo 266'] ].map(f => new nlobjSearchFilter(f[0], f[1], f[2], f[3])); let codes = nlapiSearchRecord(recType, null, filters, columns); should(codes).have.length(15); let code = codes[0]; should(code).have.property('id', 11); should(code).have.property('type', 'customrecord_codeg'); let code_id = code.getValue('custrecord_id_title_id', 'custrecord_type_id'); should(code_id).have.equal('japo 266'); return done(); }); it('search one field + join and column join (using nlobjSearchColumn)', done => { let columns = [ ['custrecord_id_title_id', 'custrecord_type_id'], ['custrecord_code_id'] ].map(c => new nlobjSearchColumn(c[0], c[1])), filters = [ ['custrecord_id_title_id', 'custrecord_type_id', 'is', 'japo 266'] ].map(f => new nlobjSearchFilter(f[0], f[1], f[2], f[3])); let codes = nlapiSearchRecord(recType, null, filters, columns); should(codes).have.length(15); let code = codes[0]; should(code).have.property('id', 11); should(code).have.property('type', 'customrecord_codeg'); let code_id = code.getValue(new nlobjSearchColumn('custrecord_id_title_id', 'custrecord_type_id')); should(code_id).have.equal('japo 266'); return done(); }); it('search formula text', done => { let columns = [ ['custrecord_id_title_id', 'custrecord_type_id'], ['custrecord_code_id'], ['formulatext'] ].map(c => new nlobjSearchColumn(c[0], c[1])), filters = [ ['custrecord_id_title_id', 'custrecord_type_id', 'is', 'japo 266'] ].map(f => new nlobjSearchFilter(f[0], f[1], f[2], f[3])); columns[2].setFormula('{custrecord_code_id}||" - "||case {custrecord_type_id.custrecord_id_title_id} when "japo 266" then "legal" else "humm" end'); let codes = nlapiSearchRecord(recType, null, filters, columns); should(codes).have.length(15); let code = codes[0]; should(code).have.property('id', 11); should(code).have.property('type', 'customrecord_codeg'); let code_id = code.getValue(columns[0]); should(code_id).have.equal('japo 266'); let formula = code.getValue(columns[2]); should(formula).have.equal('12 - legal'); return done(); }); it('search missing "type"', done => { try { nlapiSearchRecord(); return done('missing type'); } catch (e) { should(e).have.property('code', 'SSS_TYPE_ARG_REQD'); return done(); } }); it('search ivalid "id"', done => { try { nlapiSearchRecord(recType, 'opa'); return done('invalid id'); } catch (e) { should(e).have.property('code', 'SSS_INVALID_INTERNAL_ID'); return done(); } }); }); after(done => { nsmockup.destroy(done); }); });
parallel('#auto', function() { it('should execute in accordance with best order', function(done) { var order = []; var tasks = { task1: ['task2', function(results, callback) { setTimeout(function() { order.push('task1'); callback(); }, 25); }], task2: function(callback) { setTimeout(function() { order.push('task2'); callback(); }, 50); }, task3: ['task2', function(results, callback) { order.push('task3'); callback(); }], task4: ['task1', 'task2', function(results, callback) { order.push('task4'); callback(); }], task5: ['task2', function(results, callback) { setTimeout(function() { order.push('task5'); callback(); }, 0); }], task6: ['task2', function(results, callback) { order.push('task6'); callback(); }] }; async.auto(tasks, function(err) { if (err) { return done(err); } assert.deepStrictEqual(order, [ 'task2', 'task3', 'task6', 'task5', 'task1', 'task4' ]); done(); }); }); it('should execute in accordance with best order and get results', function(done) { var order = []; async.auto({ task1: ['task2', function(results, callback) { assert.strictEqual(results.task2, 'task2'); setTimeout(function() { order.push('task1'); callback(null, 'task1a', 'task1b'); }, 25); }], task2: function(callback) { setTimeout(function() { order.push('task2'); callback(null, 'task2'); }); }, task3: ['task2', function(results, callback) { assert.strictEqual(results.task2, 'task2'); order.push('task3'); callback(); }], task4: ['task1', 'task2', function(results, callback) { assert.deepStrictEqual(results.task1, ['task1a', 'task1b']); assert.strictEqual(results.task2, 'task2'); order.push('task4'); callback(null, 'task4'); }] }, function(err, results) { if (err) { return done(err); } assert.deepStrictEqual(order, ['task2', 'task3', 'task1', 'task4']); assert.deepStrictEqual(results, { task1: ['task1a', 'task1b'], task2: 'task2', task3: undefined, task4: 'task4' }); done(); }); }); it('should execute even if array task dosen\'t have nay dependencies', function(done) { var order = []; async.auto({ task1: function(callback) { order.push('task1'); callback(null, 'task1'); }, task2: ['task3', function(task3, callback) { order.push('task2'); callback(null, 'task2'); }], task3: [function(callback) { order.push('task3'); callback(null, 'task3'); }] }, function(err, results) { if (err) { return done(err); } assert.deepStrictEqual(order, [ 'task1', 'task3', 'task2' ]); assert.deepStrictEqual(results, { task1: 'task1', task2: 'task2', task3: 'task3' }); done(); }); }); it('should execute even if object is empty', function(done) { async.auto({}, done); }); it('should execute without callback', function(done) { var tasks = { task1: function(callback) { callback(); }, task2: ['task1', function(results, callback) { callback(); }] }; async.auto(tasks); setTimeout(done, delay); }); it('should execute without callback', function(done) { var tasks = { task1: function(callback) { callback(); }, task2: ['task1', function(results, callback) { callback(); }] }; async.auto(tasks, 1); setTimeout(done, delay); }); it('should throw error and get safe results', function(done) { var order = []; async.auto({ task1: ['task2', function(results, callback) { assert.strictEqual(results.task2, 'task2'); setTimeout(function() { order.push('task1'); callback(null, 'task1a', 'task1b'); }, 25); }], task2: function(callback) { setTimeout(function() { order.push('task2'); callback(null, 'task2'); }); }, task3: ['task2', function(results, callback) { assert.strictEqual(results.task2, 'task2'); order.push('task3'); callback('error', 'task3'); }], task4: ['task1', 'task2', function(results, callback) { assert.deepStrictEqual(results.task1, ['task1a', 'task1b']); assert.strictEqual(results.task2, 'task2'); order.push('task4'); callback(null, 'task4'); }] }, function(err, results) { assert.ok(err); assert.deepStrictEqual(order, ['task2', 'task3']); assert.deepStrictEqual(results, { task2: 'task2', task3: 'task3' }); done(); }); }); it('should avoid double callback', function(done) { var called = false; var tasks = { task1: function(callback) { try { callback('error'); } catch(exception) { try { callback(exception); } catch(e) { assert.ok(e); util.errorChecker(e); } done(); } } }; async.auto(tasks, function(err) { assert.ok(err); assert.strictEqual(called, false); called = true; async.nothing(); }); }); it('should execute in limited by concurrency', function(done) { var order = []; var tasks = { task1: function(callback) { order.push('task1'); callback(); }, task2: ['task1', function(results, callback) { setTimeout(function() { order.push('task2'); callback(); }, delay * 2); }], task3: ['task1', function(results, callback) { setTimeout(function() { order.push('task3'); callback(); }, delay * 2); }], task4: ['task1', function(results, callback) { setTimeout(function() { order.push('task4'); callback(); }, delay * 1); }], task5: ['task1', function(results, callback) { setTimeout(function() { order.push('task5'); callback(); }, delay * 1); }], task6: ['task1', function(results, callback) { setTimeout(function() { order.push('task6'); callback(); }, delay * 1); }] }; async.auto(tasks, 2, function(err) { if (err) { return done(err); } assert.deepStrictEqual(order, [ 'task1', 'task2', 'task3', 'task4', 'task5', 'task6' ]); done(); }); }); it('should throw error if double callback', function(done) { domain.create() .on('error', util.errorChecker) .on('error', function() { done(); }) .run(function() { async.auto({ task1: function(callback) { setImmediate(function() { callback(); callback(); }); }, task2: function(callback) { callback(); } }); }); }); it('should stop execution if a synchronous error occur', function(done) { async.auto({ task1: function(callback) { callback('error'); }, task2: function(callback) { assert.ok(false); callback(); } }, 1, function(err) { assert.strictEqual(err, 'error'); setTimeout(done, delay); }); }); it('should avoid unnecessary deferrals', function(done) { var sync = true; async.auto({ task1: function(callback) { callback(null, 1); }, task2: ['task1', function(results, callback) { callback(); }] }, function(err) { if (err) { return done(err); } assert.ok(sync); done(); }); sync = false; }); it('auto prevent dead-locks due to inexistant dependencies', function() { var err; try { async.auto({ task1: ['noexist', function(results, callback) { callback(null, 'task1'); }] }); } catch(e) { err = e; assert.ok(e); assert(/^async.auto task `task1` has non-existent dependency/.test(e.message)); } assert.ok(err); }); it('auto prevent dead-locks due to all cyclic dependencies', function() { var err; try { async.auto({ task1: ['task2', function(results, callback) { callback(null, 'task1'); }], task2: ['task1', function(results, callback) { callback(null, 'task2'); }] }); } catch(e) { err = e; assert.ok(e); assert.strictEqual(e.message, 'async.auto task has cyclic dependencies'); } assert.ok(err); }); it('auto prevent dead-locks due to some cyclic dependencies', function() { var err; try { async.auto({ task1: ['task2', function(results, callback) { callback(null, 'task1'); }], task2: ['task1', function(results, callback) { callback(null, 'task2'); }], task3: function(callback) { callback(null, 'task3'); }, task4: ['task5', function(results, callback) { callback(null, 'task4'); }], task5: ['task4', function(results, callback) { callback(null, 'task5'); }] }); } catch(e) { err = e; assert.ok(e); assert.strictEqual(e.message, 'async.auto task has cyclic dependencies'); } assert.ok(err); }); it('should throw an error if tasks have cyclic dependencies', function() { var err; var task = function(name) { return function(results, callback) { callback(null, 'task ' + name); }; }; try { async.auto({ a: ['c', task('a')], b: ['a', task('b')], c: ['b', task('c')] }); } catch(e) { err = e; assert.ok(e); assert.strictEqual(e.message, 'async.auto task has cyclic dependencies'); } assert.ok(err); }); it('should work even if reserved name is included', function(done) { // var async = require('async'); var tasks = { one: function(next) { next(null, 1); }, hasOwnProperty: function(next) { next(null, 2); } }; async.auto(tasks, function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, { one: 1, hasOwnProperty: 2 }); done(); }); }); /** * @see https://github.com/suguru03/neo-async/issues/57 */ it('should work without cyclic dependencies error', function(done) { var error = new Error('error'); async.auto({ task1: function(callback) { setTimeout(callback, delay, error); }, task2: function(callback) { setTimeout(callback, delay * 2) }, task3: ['task1', 'task2', function(callback) { setTimeout(callback, delay * 2) }] }, function(err) { assert.strictEqual(err, error); setTimeout(done, delay * 3); }); }); });
parallel('#times', function() { it('should execute iterator', function(done) { var n = 3; var order = []; async.times(n, timeItrator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, [0, 1, 2]); assert.deepStrictEqual(order, [0, 2, 1]); done(); }); }); it('should execute iterator even if num is string', function(done) { var n = '3'; var order = []; async.times(n, timeItrator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, [0, 1, 2]); assert.deepStrictEqual(order, [0, 2, 1]); done(); }); }); it('should execute iterator without binding', function(done) { var n = 3; var order = []; async.times(n, timeItrator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, [0, 1, 2]); assert.deepStrictEqual(order, [0, 2, 1]); done(); }, Math); }); it('should return response immediately', function(done) { var n = 0; var order = []; async.times(n, timeItrator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, []); assert.deepStrictEqual(order, []); done(); }); }); it('should throw error', function(done) { var n = 4; var iterator = function(n, next) { next(n === 2); }; async.times(n, iterator, function(err) { assert.ok(err); setTimeout(done, delay); }); }); it('should throw error if double callback', function(done) { var errorCallCount = 0; setTimeout(function() { assert.strictEqual(errorCallCount, 4); done(); }, delay); domain.create() .on('error', util.errorChecker) .on('error', function() { errorCallCount++; }) .run(function() { var iterator = function(num, callback) { process.nextTick(callback); process.nextTick(callback); }; async.times(4, iterator); }); }); });
describe('<Unit Test - Netsuite Encryption API>', function () { before(done => { nsmockup.init(done); }); parallel('Encription API - nlapiDecrypt:', () => { let strFinal = 'nsmockup - Test your Suitescripts before deploying to NetSuite.'; it('decrypt base64 to str', done => { let code = 'bnNtb2NrdXAgLSBUZXN0IHlvdXIgU3VpdGVzY3JpcHRzIGJlZm9yZSBkZXBsb3lpbmcgdG8gTmV0U3VpdGUu', algorithm = 'base64', str = nlapiDecrypt(code, algorithm); should(str).be.equal(strFinal); return done(); }); it('decrypt xor to str', done => { let code = 'BRYUBAYSHhVZRkUtDhYNSxwWHhdZOBAQHwAKCBcQGxEKSwccDQoLDkUdDhUVBBwQBQJZHwpZJQANOBAQHwBX', algorithm = 'xor', str = nlapiDecrypt(code, algorithm); should(str).be.equal(strFinal); return done(); }); it('decrypt aes to str', done => { let algorithm = 'aes', key = '128-bit', //code = nlapiEncrypt(strFinal, algorithm, key), //str = nlapiDecrypt(code, algorithm); str = nlapiDecrypt('opa', algorithm, key); //should(str).be.equal(strFinal); should(str).be.equal(null); return done(); }); it('decrypt missing str', done => { try { nlapiDecrypt(); return done('missing str'); } catch (e) { should(e).have.property('code', 'SSS_TYPE_STR_REQD'); return done(); } }); it('decrypt missing algorithm', done => { try { nlapiDecrypt('opa'); return done('missing algorithm'); } catch (e) { should(e).have.property('code', 'SSS_TYPE_ALGORITHM_REQD'); return done(); } }); it('decrypt invalid algorithm', done => { try { nlapiDecrypt('opa', 'des'); return done('missing algorithm'); } catch (e) { should(e).have.property('code', 'SSS_INVALID_ALGORITHM'); return done(); } }); }); after(done => { nsmockup.destroy(done); }); });
parallel('#applyEach', function() { it('should execute in parallel', function(done) { var order = []; var one = function(val, cb) { assert.equal(val, 5); setTimeout(function() { order.push(1); cb(null, 1); }, 100); }; var two = function(val, cb) { assert.equal(val, 5); setTimeout(function() { order.push(2); cb(null, 2); }, 50); }; var three = function(val, cb) { assert.equal(val, 5); setTimeout(function() { order.push(3); cb(null, 3); }, 150); }; async.applyEach([one, two, three], 5, function(err, res) { if (err) { return done(err); } assert.deepEqual(order, [2, 1, 3]); assert.deepEqual(res, [1, 2, 3]); done(); }); }); it('should execute as a partial apprication', function(done) { var order = []; var one = function(val, cb) { assert.equal(val, 5); setTimeout(function() { order.push(1); cb(null, 1); }, 100); }; var two = function(val, cb) { assert.equal(val, 5); setTimeout(function() { order.push(2); cb(null, 2); }, 50); }; var three = function(val, cb) { assert.equal(val, 5); setTimeout(function() { order.push(3); cb(null, 3); }, 150); }; async.applyEach([one, two, three])(5, function(err, res) { if (err) { return done(err); } assert.deepEqual(order, [2, 1, 3]); assert.deepEqual(res, [1, 2, 3]); done(); }); }); });
parallel('#whilst', function() { it('should execute until test is false', function(done) { var count = 0; var limit = 5; var order = { test: [], iterator: [] }; var test = function() { order.test.push(count); return count < limit; }; var iterator = function(callback) { order.iterator.push(count++); callback(null, count); }; async.whilst(test, iterator, function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(order.iterator, [0, 1, 2, 3, 4]); assert.deepStrictEqual(order.test, [0, 1, 2, 3, 4, 5]); assert.strictEqual(res, 5); done(); }); }); it('should execute without binding until test is false', function(done) { var count = 0; var limit = 5; var order = { test: [], iterator: [] }; var result = []; var test = function() { order.test.push(count); return count < limit; }; var iterator = function(callback) { assert.strictEqual(this, undefined); result.push(count * count); order.iterator.push(count++); callback(null, count); }; async.whilst(test, iterator, function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(order.iterator, [0, 1, 2, 3, 4]); assert.deepStrictEqual(order.test, [0, 1, 2, 3, 4, 5]); assert.deepStrictEqual(result, [0, 1, 4, 9, 16]); assert.strictEqual(res, 5); done(); }, Math); }); it('should execute on asynchronous', function(done) { var sync = true; var count = 0; var limit = 5; var test = function() { return count < limit; }; var iterator = function(callback) { count++; callback(null, count); }; async.whilst(test, iterator, function(err, res) { if (err) { return done(err); } assert.strictEqual(sync, false); assert.strictEqual(res, 5); done(); }); sync = false; }); it('should execute callback immediately if first test is falsy', function(done) { var test = function() { return false; }; var iterator = function(callback) { callback(); }; async.whilst(test, iterator, done); }); it('should get multiple result', function(done) { var count = 0; var limit = 5; var test = function() { assert.strictEqual(arguments.length, count); return count < limit; }; var iterator = function(callback) { callback.apply(null, [null].concat(_.range(++count))); }; async.whilst(test, iterator, function(err, res1, res2, res3, res4) { if (err) { return done(err); } assert.strictEqual(count, 5); assert.strictEqual(arguments.length, 6); assert.strictEqual(res1, 0); assert.strictEqual(res2, 1); assert.strictEqual(res3, 2); assert.strictEqual(res4, 3); done(); }); }); it('should execute without callback', function(done) { var count = 0; var limit = 5; var test = function() { return count < limit; }; var iterator = function(callback) { count++; callback(); }; async.whilst(test, iterator); setTimeout(function() { assert.strictEqual(count, 5); done(); }, delay); }); it('should throw error', function(done) { var count = 0; var limit = 5; var order = { test: [], iterator: [] }; var result = []; var test = function() { order.test.push(count); return count < limit; }; var iterator = function(callback) { assert.strictEqual(this, undefined); result.push(count * count); order.iterator.push(count++); callback(count === 3); }; async.whilst(test, iterator, function(err) { assert.ok(err); assert.deepStrictEqual(order.iterator, [0, 1, 2]); assert.deepStrictEqual(order.test, [0, 1, 2]); assert.deepStrictEqual(result, [0, 1, 4]); done(); }, Math); }); });
parallel('swagger spec', function () { before(function () { return server.start(); }); var swaggerSpec = specs.get(); swaggerSpec.host = server.config.hostPort; var xamples = swaggerTest.parse(swaggerSpec); it('should run ' + prereqs.length + ' idempotent prerequisites', function() { var count = 0; var reqChain = prereqs.map(function (req) { return function () { return preq[req.method](req) .then(function (res) { count = count + 1; return res; }); }; }) .reduce(function (f1, f2) { return function () { return f1().then(f2); }; }); return reqChain() .then(function () { assert.deepEqual(count, prereqs.length, 'only ran ' + count); }); }); xamples.forEach(function (xample) { it(xample.description, function() { return preq[xample.request.method](xample.request) .then(function (res) { assert.isSuperset(res, xample.response); return res; }); }); }); });
parallel('Responses should conform to the provided JSON schema of the response', function() { var ajv = new Ajv({}); function getToday() { function zeroPad(num) { if (num < 10) { return `0${num}`; } return `${num}`; } const now = new Date(); return `${now.getUTCFullYear()}/${zeroPad(now.getUTCMonth() + 1)}/${zeroPad(now.getUTCDate())}`; } before(function() { return server.start() .then(function() { return preq.get({ uri: server.config.baseURL + '/?spec' }); }) .then(function(res) { Object.keys(res.body.definitions).forEach(function(defName) { ajv.addSchema(res.body.definitions[defName], '#/definitions/' + defName); }); }); }); it('/feed/featured should conform schema', function() { return preq.get({ uri: `${server.config.baseURL}/feed/featured/${getToday()}` }) .then(function(res) { if (!ajv.validate('#/definitions/feed', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); it('/feed/featured should conform schema, ruwiki', function() { return preq.get({ uri: `${server.config.hostPort}/ru.wikipedia.org/v1/feed/featured/${getToday()}` }) .then(function(res) { if (!ajv.validate('#/definitions/feed', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); it('/page/summary/{title} should conform schema', function() { return preq.get({ uri: server.config.baseURL + '/page/summary/Tank' }) .then(function(res) { if (!ajv.validate('#/definitions/summary', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); it('/feed/announcements should conform schema', function() { return preq.get({ uri: server.config.baseURL + '/feed/announcements' }) .then(function(res) { if (!ajv.validate('#/definitions/announcementsResponse', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); it('/feed/onthisday should conform schema', function() { return preq.get({ uri: server.config.baseURL + '/feed/onthisday/all/01/03' }) .then(function(res) { if (!ajv.validate('#/definitions/onthisdayResponse', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); it('/page/related should conform schema', function() { return preq.get({ uri: server.config.bucketURL + '/related/Tank' }) .then(function(res) { if (!ajv.validate('#/definitions/related', res.body)) { throw new assert.AssertionError({ message: ajv.errorsText() }); } }); }); });
var async = require('../../'); parallel('#unmemoize', function() { it('should execute without memo', function(done) { var order = []; var fn = function(arg, callback) { order.push(arg); callback(); }; var fn2 = async.memoize(fn); fn2 = async.unmemoize(fn2); fn2(1, function() { fn2(2, function() { fn2(1, function() { assert.deepEqual(order, [1, 2, 1]); done(); }); }); }); }); });
describe('<Unit Test - Netsuite Search API>', function () { this.timeout(5000); before(done => { let metadata = [ ':customer', ':subsidiary' ], records = { 'customer': `${base}/data/customer.json`, 'subsidiary': `${base}/data/subsidiary.json` }, opts = { general: { dateFormat: 'DD-MM-YYYY', timeFormat: 'HH:mm:ss' }, metadata, records }; nsmockup.init(opts, done); }); let recType = 'customer', columns = [ ['email'], ['companynameforsupportmessages', 'subsidiary'] ].map(c => new nlobjSearchColumn(c[0], c[1])); parallel('SuiteScript API - Search Utils - "operators" - DATE:', () => { it('operator "after": customer by datecreated', done => { let filters = [ ['datecreated', null, 'after', '12-07-2015 12:34:23'] ]; let customers = nlapiSearchRecord(recType, null, filters, columns); validateCustomer(customers); let oFilters = [ ['datecreated', null, 'after', '14-07-2015 12:34:23'] ], empty = nlapiSearchRecord(recType, null, oFilters, columns); should(empty).not.ok(); return done(); }); it('operator "before": customer by datecreated', done => { let filters = [ ['datecreated', null, 'before', '14-07-2015 12:34:23'] ]; let customers = nlapiSearchRecord(recType, null, filters, columns); validateCustomer(customers); let oFilters = [ ['datecreated', null, 'before', '12-07-2015 12:34:23'] ], empty = nlapiSearchRecord(recType, null, oFilters, columns); should(empty).not.ok(); return done(); }); it('operator "notwithin": customer by datecreated', done => { let filters = [ ['datecreated', null, 'notwithin', '16-07-2015 18:36:23'] ]; let customers = nlapiSearchRecord(recType, null, filters, columns); validateCustomer(customers); let oFilters = [ ['datecreated', null, 'notwithin', '13-07-2015 14:39:00'] ], empty = nlapiSearchRecord(recType, null, oFilters, columns); should(empty).not.ok(); return done(); }); it('operator "notafter": customer by datecreated', done => { let filters = [ ['datecreated', null, 'notafter', '14-07-2015'] ]; let customers = nlapiSearchRecord(recType, null, filters, columns); validateCustomer(customers); let oFilters = [ ['datecreated', null, 'notafter', '12-07-2015 12:34:23'] ], empty = nlapiSearchRecord(recType, null, oFilters, columns); should(empty).not.ok(); return done(); }); it('operator "notbefore": customer by datecreated', done => { let filters = [ ['datecreated', null, 'notbefore', '12-07-2015'] ]; let customers = nlapiSearchRecord(recType, null, filters, columns); validateCustomer(customers); let oFilters = [ ['datecreated', null, 'notbefore', '14-07-2015 12:34:23'] ], empty = nlapiSearchRecord(recType, null, oFilters, columns); should(empty).not.ok(); return done(); }); it('operator "noton": customer by datecreated', done => { ['12-07-2015 18:36:23', '14-07-2015 06:36:23', '10-07-2016', '02-01-2014'].forEach(function(date) { let filters = [ ['datecreated', null, 'noton', date] ]; let customers = nlapiSearchRecord(recType, null, filters, columns); validateCustomer(customers, `invalid filter "${date}"`); }); let oFilters = [ ['datecreated', null, 'noton', '13-07-2015 14:39:00'] ], empty = nlapiSearchRecord(recType, null, oFilters, columns); should(empty).not.ok(); return done(); }); it('operator "notonorafter": customer by datecreated', done => { ['12-07-2015 18:36:23', '10-07-2015', '02-01-2014'].forEach(function(date) { let filters = [ ['datecreated', null, 'notonorafter', date] ]; let customers = nlapiSearchRecord(recType, null, filters, columns); validateCustomer(customers, `invalid filter "${date}"`); }); ['13-07-2015 14:39:00'].forEach(function(date) { let oFilters = [ ['datecreated', null, 'notonorafter', date] ], empty = nlapiSearchRecord(recType, null, oFilters, columns); should(empty).not.ok(); }); return done(); }); it('operator "notonorbefore": customer by datecreated', done => { ['14-07-2015 18:36:23', '17-07-2015', '02-01-2016'].forEach(function(date) { let filters = [ ['datecreated', null, 'notonorbefore', date] ]; let customers = nlapiSearchRecord(recType, null, filters, columns); validateCustomer(customers, `invalid filter "${date}"`); }); ['13-07-2015 14:39:00'].forEach(function(date) { let oFilters = [ ['datecreated', null, 'notonorbefore', date] ], empty = nlapiSearchRecord(recType, null, oFilters, columns); should(empty).not.ok(); }); return done(); }); it('operator "on": customer by datecreated', done => { let filters = [ ['datecreated', null, 'on', '13-07-2015 14:39:00'] ]; let customers = nlapiSearchRecord(recType, null, filters, columns); validateCustomer(customers); ['13-07-2015 13:39:00', '16-03-2015', '12-07-2015'].forEach(function(date) { let oFilters = [ ['datecreated', null, 'on', date] ], empty = nlapiSearchRecord(recType, null, oFilters, columns); should(empty).not.ok(); }); return done(); }); it('operator "onorafter": customer by datecreated', done => { ['13-07-2015 14:39:00', '16-03-2015', '11-01-2012'].forEach(function(date) { let filters = [ ['datecreated', null, 'onorafter', date] ]; let customers = nlapiSearchRecord(recType, null, filters, columns); validateCustomer(customers, `invalid filter "${date}"`); }); let oFilters = [ ['datecreated', null, 'onorafter', '12-08-2015 12:34:23'] ], empty = nlapiSearchRecord(recType, null, oFilters, columns); should(empty).not.ok(); return done(); }); it('operator "onorbefore": customer by datecreated', done => { ['14-07-2015 18:36:23', '13-07-2015 14:39:00', '16-08-2016'].forEach(function(date) { let filters = [ ['datecreated', null, 'onorbefore', date] ]; let customers = nlapiSearchRecord(recType, null, filters, columns); validateCustomer(customers, `invalid filter "${date}"`); }); let oFilters = [ ['datecreated', null, 'onorbefore', '12-07-2015 12:34:23'] ], empty = nlapiSearchRecord(recType, null, oFilters, columns); should(empty).not.ok(); return done(); }); }); after(done => { nsmockup.destroy(done); }); });
parallel('#transform', function() { it('should execute iterator by collection of array', function(done) { var order = []; var collection = [1, 5, 3, 2, 4]; async.transform(collection, transformIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, [1, 3, 5]); assert.deepStrictEqual(order, [1, 2, 3, 4, 5]); done(); }); }); it('should execute iterator by collection of array with passing index', function(done) { var order = []; var collection = [1, 5, 3, 2, 4]; async.transform(collection, transformIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, [1, 3, 5]); assert.deepStrictEqual(order, [ [1, 0], [2, 3], [3, 2], [4, 4], [5, 1] ]); done(); }); }); it('should execute iterator by collection of object', function(done) { var order = []; var collection = { a: 5, b: 3, c: 2 }; async.transform(collection, [], transformIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, [3, 5]); assert.deepStrictEqual(order, [2, 3, 5]); done(); }); }); it('should execute iterator by collection of object with passing key', function(done) { var order = []; var collection = { a: 5, b: 3, c: 2 }; async.transform(collection, transformIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { b: 3, a: 5 }); assert.deepStrictEqual(order, [ [2, 'c'], [3, 'b'], [5, 'a'] ]); done(); }); }); it('should execute iterator in limited by collection of Set', function(done) { var order = []; var set = new util.Set(); set.add(5); set.add(3); set.add(2); async.transform(set, [], transformIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, [3, 5]); assert.deepStrictEqual(order, [2, 3, 5]); done(); }); }); it('should execute iterator in limited by collection of Set with passing index', function(done) { var order = []; var set = new util.Set(); set.add(5); set.add(3); set.add(2); async.transform(set, transformIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { 0: 5, 1: 3 }); assert.deepStrictEqual(order, [ [2, 2], [3, 1], [5, 0] ]); done(); }); }); it('should work properly even if elements are added in callback', function(done) { var order = []; var arr = [1, 3, 2]; var set = new util.Set(arr); var iterator = function(acc, value, next) { order.push(value); acc.push(value); next(); }; async.transform(set, [], iterator, function(err, res) { if (err) { return done(err); } setTimeout(function() { assert.deepStrictEqual(order, arr); assert.deepStrictEqual(res, arr); done(); }, delay); set.add(4); }); }); it('should work even if the size is changed', function(done) { var order = []; var set = new util.Set([1, 2, 3, 4]); var iterator = function(acc, value, next) { order.push(value); set.delete(value + 1); acc.push(value); next(); }; async.transform(set, [], iterator, function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(order, [1, 3]); assert.deepStrictEqual(res, [1, 3]); done(); }); }); it('should execute iterator in limited by collection of Map', function(done) { var order = []; var map = new util.Map(); map.set('a', 5); map.set('b', 3); map.set('c', 2); async.transform(map, [], transformIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, [ ['b', 3], ['a', 5] ]); assert.deepStrictEqual(order, [ ['c', 2], ['b', 3], ['a', 5] ]); done(); }); }); it('should execute iterator in limited by collection of Map with passing key', function(done) { var order = []; var map = new util.Map(); map.set('a', 5); map.set('b', 3); map.set('c', 2); async.transform(map, transformIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { 0: ['a', 5], 1: ['b', 3] }); assert.deepStrictEqual(order, [ [['c', 2], 2], [['b', 3], 1], [['a', 5], 0] ]); done(); }); }); it('should execute iterator and break when callback is called "false"', function(done) { var order = []; var collection = [4, 3, 2]; var iterator = function(memo, num, callback) { setTimeout(function() { order.push(num); memo.push(num); callback(null, num !== 3); }, num * delay); }; async.transform(collection, iterator, function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, [2, 3]); assert.deepStrictEqual(order, [2, 3]); done(); }); }); it('should execute iterator and break when callback is called "false"', function(done) { var order = []; var collection = { a: 5, b: 3, c: 2, 'break': 3.5 }; async.transform(collection, [], transformIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, [3]); assert.deepStrictEqual(order, [ [2, 'c'], [3, 'b'], [3.5, 'break'] ]); done(); }); }); it('should execute iterator without binding', function(done) { var order = []; var collection = { a: 1.1, b: 3.5, c: 2.6 }; async.transform(collection, {}, transformIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); assert.deepStrictEqual(order, [ [1.1, 'a'], [2.6, 'c'], [3.5, 'b'] ]); done(); }, Math); }); it('should throw error', function(done) { var order = []; var collection = [1, 5, 3, 2, 4]; var iterator = function(memo, value, key, callback) { setTimeout(function() { memo.push(value); order.push(value); callback(value === 4); }, value * delay); }; async.transform(collection, iterator, function(err, res) { assert.ok(err); assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, [1, 2, 3, 4]); assert.deepStrictEqual(order, [1, 2, 3, 4]); done(); }); }); it('should avoid double callback', function(done) { var called = false; async.transform([1, 2, 3], function(memo, item, callback) { try { callback(item); } catch (exception) { try { callback(exception); } catch(e) { assert.ok(e); util.errorChecker(e); done(); } } }, function(err) { assert.ok(err); assert.strictEqual(called, false); called = true; async.nothing(); }); }); it('should return response immediately if array is empty', function(done) { var iterator = function(memo, value, key, callback) { callback(); }; async.transform([], iterator, function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, []); done(); }); }); it('should return response immediately if object is empty', function(done) { var iterator = function(memo, value, key, callback) { callback(); }; async.transform({}, iterator, function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); done(); }); }); it('should return response immediately if collection is function', function(done) { var order = []; async.transform(function() {}, transformIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is undefined', function(done) { var order = []; async.transform(undefined, transformIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is null', function(done) { var order = []; async.transform(null, transformIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); assert.deepStrictEqual(order, []); done(); }); }); it('should return accumulator immediately if array is empty', function(done) { var iterator = function(memo, value, key, callback) { callback(); }; async.transform([], {}, iterator, function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); done(); }); }); it('should return accumulator immediately if object is empty', function(done) { var iterator = function(memo, value, key, callback) { callback(); }; async.transform({}, [], iterator, function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.deepStrictEqual(res, []); done(); }); }); });
parallel('#omit', function() { it('should execute iterator by collection of array', function(done) { var order = []; var collection = [1, 3, 2, 4]; async.omit(collection, omitIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { '2': 2, '3': 4 }); assert.deepStrictEqual(order, [1, 2, 3, 4]); done(); }); }); it('should execute iterator by collection of array with passing index', function(done) { var order = []; var collection = [1, 3, 2, 4]; async.omit(collection, omitIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { '2': 2, '3': 4 }); assert.deepStrictEqual(order, [ [1, 0], [2, 2], [3, 1], [4, 3] ]); done(); }); }); it('should execute iterator by collection of object', function(done) { var order = []; var collection = { a: 4, b: 3, c: 2 }; async.omit(collection, omitIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { a: 4, c: 2 }); assert.deepStrictEqual(order, [2, 3, 4]); done(); }); }); it('should execute iterator by collection of object with passing key', function(done) { var order = []; var collection = { a: 4, b: 3, c: 2 }; async.omit(collection, omitIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { a: 4, c: 2 }); assert.deepStrictEqual(order, [ [2, 'c'], [3, 'b'], [4, 'a'] ]); done(); }); }); it('should execute iterator by collection of Set', function(done) { var order = []; var set = new util.Set(); set.add(4); set.add(3); set.add(2); async.omit(set, omitIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { '0': 4, '2': 2 }); assert.deepStrictEqual(order, [2, 3, 4]); done(); }); }); it('should execute iterator by collection of Set with passing key', function(done) { var order = []; var set = new util.Set(); set.add(4); set.add(3); set.add(2); async.omit(set, omitIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { '0': 4, '2': 2 }); assert.deepStrictEqual(order, [ [2, 2], [3, 1], [4, 0] ]); done(); }); }); it('should execute iterator by collection of Map', function(done) { var order = []; var map = new util.Map(); map.set('a', 4); map.set('b', 3); map.set('c', 2); async.omit(map, omitIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { '0': ['a', 4], '2': ['c', 2] }); assert.deepStrictEqual(order, [ ['c', 2], ['b', 3], ['a', 4] ]); done(); }); }); it('should execute iterator by collection of Map with passing key', function(done) { var order = []; var map = new util.Map(); map.set('a', 4); map.set('b', 3); map.set('c', 2); async.omit(map, omitIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { '0': ['a', 4], '2': ['c', 2] }); assert.deepStrictEqual(order, [ [['c', 2], 2], [['b', 3], 1], [['a', 4], 0] ]); done(); }); }); it('should execute iterator without binding', function(done) { var order = []; var collection = { a: 1.1, b: 3.5, c: 2.6 }; async.omit(collection, omitIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); assert.deepStrictEqual(order, [1.1, 2.6, 3.5]); done(); }, Math); }); it('should throw error', function(done) { var order = []; var collection = [1, 3, 2, 4]; var iterator = function(num, callback) { setTimeout(function() { order.push(num); callback(num === 3, num % 2); }, num * delay); }; async.omit(collection, iterator, function(err, res) { assert.ok(err); assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { '2': 2 }); assert.deepStrictEqual(order, [1, 2, 3]); done(); }); }); it('should throw error', function(done) { var order = []; var collection = { a: 1, b: 3, c: 2, d: 4 }; var iterator = function(num, callback) { setTimeout(function() { order.push(num); callback(num === 3, num % 2); }, num * delay); }; async.omit(collection, iterator, function(err, res) { assert.ok(err); assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { c: 2 }); assert.deepStrictEqual(order, [1, 2, 3]); done(); }); }); it('should throw error if double callback', function(done) { var errorCallCount = 0; setTimeout(function() { assert.strictEqual(errorCallCount, 3); done(); }, delay); domain.create() .on('error', util.errorChecker) .on('error', function() { errorCallCount++; }) .run(function() { var collection = [2, 1, 3]; var iterator = function(item, callback) { process.nextTick(callback); process.nextTick(callback); }; async.omit(collection, iterator); }); }); it('should throw error if double callback', function(done) { var errorCallCount = 0; setTimeout(function() { assert.strictEqual(errorCallCount, 3); done(); }, delay); domain.create() .on('error', util.errorChecker) .on('error', function() { errorCallCount++; }) .run(function() { var collection = [2, 1, 3]; var iterator = function(item, callback) { process.nextTick(callback); process.nextTick(callback); }; async.omit(collection, iterator, function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { '0': 2, '1': 1, '2': 3 }); }); }); }); it('should throw error if double callback', function(done) { var errorCallCount = 0; setTimeout(function() { assert.strictEqual(errorCallCount, 3); done(); }, delay); domain.create() .on('error', util.errorChecker) .on('error', function() { errorCallCount++; }) .run(function() { var collection = { a: 4, b: 3, c: 2 }; var iterator = function(item, callback) { process.nextTick(callback); process.nextTick(callback); }; async.omit(collection, iterator); }); }); it('should throw error if double callback', function(done) { var errorCallCount = 0; setTimeout(function() { assert.strictEqual(errorCallCount, 3); done(); }, delay); domain.create() .on('error', util.errorChecker) .on('error', function() { errorCallCount++; }) .run(function() { var collection = { a: 4, b: 3, c: 2 }; var iterator = function(item, callback) { process.nextTick(callback); process.nextTick(callback); }; async.omit(collection, iterator, function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, { a: 4, b: 3, c: 2 }); }); }); }); it('should avoid double callback', function(done) { var called = false; async.omit([1, 2, 3], function(item, callback) { try { callback(item); } catch (exception) { try { callback(exception); } catch(e) { assert.ok(e); util.errorChecker(e); done(); } } }, function(err) { assert.ok(err); assert.strictEqual(called, false); called = true; async.nothing(); }); }); it('should return response immediately if array is empty', function(done) { var order = []; var array = []; async.omit(array, omitIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if object is empty', function(done) { var order = []; var object = {}; async.omit(object, omitIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is function', function(done) { var order = []; async.omit(function() {}, omitIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is undefined', function(done) { var order = []; async.omit(undefined, omitIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is null', function(done) { var order = []; async.omit(null, omitIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Object]'); assert.deepStrictEqual(res, {}); assert.deepStrictEqual(order, []); done(); }); }); });
parallel('#auto', function() { it('should execute in accordance with best order', function(done) { var order = []; var tasks = { task1: ['task2', function(results, callback) { setTimeout(function() { order.push('task1'); callback(); }, 25); }], task2: function(callback) { setTimeout(function() { order.push('task2'); callback(); }, 50); }, task3: ['task2', function(results, callback) { order.push('task3'); callback(); }], task4: ['task1', 'task2', function(results, callback) { order.push('task4'); callback(); }], task5: ['task2', function(results, callback) { setTimeout(function() { order.push('task5'); callback(); }, 0); }], task6: ['task2', function(results, callback) { order.push('task6'); callback(); }] }; async.auto(tasks, function(err) { if (err) { return done(err); } assert.deepEqual(order, [ 'task2', 'task3', 'task6', 'task5', 'task1', 'task4' ]); done(); }); }); it('should execute in accordance with best order and get results', function(done) { var order = []; async.auto({ task1: ['task2', function(results, callback) { assert.strictEqual(results.task2, 'task2'); setTimeout(function() { order.push('task1'); callback(null, 'task1a', 'task1b'); }, 25); }], task2: function(callback) { setTimeout(function() { order.push('task2'); callback(null, 'task2'); }); }, task3: ['task2', function(results, callback) { assert.strictEqual(results.task2, 'task2'); order.push('task3'); callback(); }], task4: ['task1', 'task2', function(results, callback) { assert.deepEqual(results.task1, ['task1a', 'task1b']); assert.strictEqual(results.task2, 'task2'); order.push('task4'); callback(null, 'task4'); }] }, function(err, results) { if (err) { return done(err); } assert.deepEqual(order, ['task2', 'task3', 'task1', 'task4']); assert.deepEqual(results, { task1: ['task1a', 'task1b'], task2: 'task2', task3: undefined, task4: 'task4' }); done(); }); }); it('should execute even if object is empty', function(done) { async.auto({}, done); }); it('should execute without callback', function(done) { var tasks = { task1: function(callback) { callback(); }, task2: ['task1', function(results, callback) { callback(); }] }; async.auto(tasks); setTimeout(done, delay); }); it('should execute without callback', function(done) { var tasks = { task1: function(callback) { callback(); }, task2: ['task1', function(results, callback) { callback(); }] }; async.auto(tasks, 1); setTimeout(done, delay); }); it('should throw error and get safe results', function(done) { var order = []; async.auto({ task1: ['task2', function(results, callback) { assert.strictEqual(results.task2, 'task2'); setTimeout(function() { order.push('task1'); callback(null, 'task1a', 'task1b'); }, 25); }], task2: function(callback) { setTimeout(function() { order.push('task2'); callback(null, 'task2'); }); }, task3: ['task2', function(results, callback) { assert.strictEqual(results.task2, 'task2'); order.push('task3'); callback('error', 'task3'); }], task4: ['task1', 'task2', function(results, callback) { assert.deepEqual(results.task1, ['task1a', 'task1b']); assert.strictEqual(results.task2, 'task2'); order.push('task4'); callback(null, 'task4'); }] }, function(err, results) { assert.ok(err); assert.deepEqual(order, ['task2', 'task3']); assert.deepEqual(results, { task2: 'task2', task3: 'task3' }); done(); }); }); it('should execute in limited by concurrency', function(done) { var order = []; var tasks = { task1: function(callback) { order.push('task1'); callback(); }, task2: ['task1', function(results, callback) { setTimeout(function() { order.push('task2'); callback(); }, delay * 2); }], task3: ['task1', function(results, callback) { setTimeout(function() { order.push('task3'); callback(); }, delay * 2); }], task4: ['task1', function(results, callback) { setTimeout(function() { order.push('task4'); callback(); }, delay * 1); }], task5: ['task1', function(results, callback) { setTimeout(function() { order.push('task5'); callback(); }, delay * 1); }], task6: ['task1', function(results, callback) { setTimeout(function() { order.push('task6'); callback(); }, delay * 1); }] }; async.auto(tasks, 2, function(err) { if (err) { return done(err); } assert.deepEqual(order, [ 'task1', 'task2', 'task3', 'task4', 'task5', 'task6' ]); done(); }); }); it('should throw error if double callback', function(done) { domain.create() .on('error', util.errorChecker) .on('error', function() { done(); }) .run(function() { async.auto({ task1: function(callback) { setImmediate(function() { callback(); callback(); }); }, task2: function(callback) { callback(); } }); }); }); it('should stop execution if a synchronous error occur', function(done) { async.auto({ task1: function(callback) { callback('error'); }, task2: function(callback) { assert.ok(false); callback(); } }, 1, function(err) { assert.strictEqual(err, 'error'); setTimeout(done, delay); }); }); it('should avoid unnecessary deferrals', function(done) { var sync = true; async.auto({ task1: function(callback) { callback(null, 1); }, task2: ['task1', function(results, callback) { callback(); }] }, function(err) { if (err) { return done(err); } assert.ok(sync); done(); }); sync = false; }); it('auto prevent dead-locks due to inexistant dependencies', function() { var err; try { async.auto({ task1: ['noexist', function(results, callback) { callback(null, 'task1'); }] }); } catch(e) { err = e; assert.ok(e); assert(/^async.auto task `noexist` has non-existent dependency/.test(e.message)); } assert.ok(err); }); it('auto prevent dead-locks due to all cyclic dependencies', function() { var err; try { async.auto({ task1: ['task2', function(results, callback) { callback(null, 'task1'); }], task2: ['task1', function(results, callback) { callback(null, 'task2'); }] }); } catch(e) { err = e; assert.ok(e); assert.strictEqual(e.message, 'async.auto task has cyclic dependencies'); } assert.ok(err); }); it('auto prevent dead-locks due to some cyclic dependencies', function() { var err; try { async.auto({ task1: ['task2', function(results, callback) { callback(null, 'task1'); }], task2: ['task1', function(results, callback) { callback(null, 'task2'); }], task3: function(callback) { callback(null, 'task3'); }, task4: ['task5', function(results, callback) { callback(null, 'task4'); }], task5: ['task4', function(results, callback) { callback(null, 'task5'); }] }); } catch(e) { err = e; assert.ok(e); assert.strictEqual(e.message, 'async.auto task has cyclic dependencies'); } assert.ok(err); }); });
parallel('#nextTick', function() { 'use strict'; it('should assign setImmediate when process does not exist', function(done) { var context = { require: require, console: console, exports: exports, setTimeout: setTimeout, setImmediate: setImmediate }; vm.runInNewContext(fs.readFileSync(asyncPath), context); assert.strictEqual(typeof context.async.nextTick, 'function'); assert.notStrictEqual(context.async.nextTick, process.nextTick); assert.strictEqual(context.async.nextTick, setImmediate); context.async.nextTick(done); }); it('should assign setImmediate when process does not exist for coverage', function(done) { var _nextTick = process.nextTick; process.nextTick = undefined; delete(require.cache[asyncPath]); var async = require(asyncPath); process.nextTick = _nextTick; assert.strictEqual(typeof async.nextTick, 'function'); assert.notStrictEqual(async.nextTick, process.nextTick); assert.strictEqual(async.nextTick, setImmediate); async.nextTick(done); }); it('should create original nextTick when process does not have nextTick and setImmediate', function(done) { var context = { require: require, console: console, exports: exports, setTimeout: setTimeout }; vm.runInNewContext(fs.readFileSync(asyncPath), context); assert.strictEqual(typeof context.async.nextTick, 'function'); assert.notStrictEqual(context.async.nextTick, process.nextTick); context.async.nextTick(done); }); it('should create original nextTick when process does not have nextTick and setImmediate for coverage', function(done) { var _nextTick = process.nextTick; var _setImmediate = setImmediate; process.nextTick = undefined; setImmediate = undefined; delete(require.cache[asyncPath]); var async = require(asyncPath); process.nextTick = _nextTick; setImmediate = _setImmediate; assert.strictEqual(typeof async.nextTick, 'function'); assert.notStrictEqual(async.nextTick, process.nextTick); async.nextTick(done); }); it('should avoid node warning [v0.10.x only]', function(done) { var array = _.times(10000); var iterator = function(n, done) { done(); }; async.eachSeries(array, iterator, done); }); it('should pass extra arguments', function(done) { async.nextTick(function(a, b, c, d) { assert.strictEqual(a, 1); assert.strictEqual(b, 2); assert.strictEqual(c, 3); assert.strictEqual(d, undefined); done(); }, 1, 2, 3); }); });
parallel('#detect', function() { it('should execute iterator by collection of array', function(done) { var order = []; var collection = [1, 3, 2, 4]; async.detect(collection, detectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 1); assert.deepStrictEqual(order, [1]); done(); }); }); it('should execute iterator by collection of array with passing index', function(done) { var order = []; var collection = [1, 3, 2, 4]; async.detect(collection, detectIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 1); assert.deepStrictEqual(order, [ [1, 0] ]); done(); }); }); it('should execute iterator by collection of object', function(done) { var order = []; var collection = { a: 5, b: 3, c: 2 }; async.detect(collection, detectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 3); assert.deepStrictEqual(order, [2, 3]); done(); }); }); it('should execute iterator by collection of object with passing key', function(done) { var order = []; var collection = { a: 5, b: 3, c: 2 }; async.detect(collection, detectIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 3); assert.deepStrictEqual(order, [ [2, 'c'], [3, 'b'] ]); done(); }); }); it('should execute iterator by collection of Set', function(done) { var order = []; var set = new util.Set(); set.add(5); set.add(3); set.add(2); async.detect(set, detectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 3); assert.deepStrictEqual(order, [2, 3]); done(); }); }); it('should execute iterator by collection of Set with passing key', function(done) { var order = []; var set = new util.Set(); set.add(5); set.add(3); set.add(2); async.detect(set, detectIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 3); assert.deepStrictEqual(order, [ [2, 2], [3, 1] ]); done(); }); }); it('should work even if the size is decreased', function(done) { var order = []; var set = new util.Set([1, 2, 3, 4]); var iterator = function(value, next) { order.push(value); set.delete(value + 1); next(); }; async.detect(set, iterator, function(err) { if (err) { return done(err); } assert.deepStrictEqual(order, [1, 3]); done(); }); }); it('should work even if the size is increased', function(done) { var order = []; var size = 4; var set = new util.Set([1, 2, 3, 4]); var iterator = function(value, next) { order.push(value); value % 2 === 0 && set.add(++size); next(); }; async.detect(set, iterator, function(err) { if (err) { return done(err); } assert.deepStrictEqual(order, [1, 2, 3, 4, 5, 6, 7]); done(); }); }); it('should execute iterator by collection of Map', function(done) { var order = []; var map = new util.Map(); map.set('a', 5); map.set('b', 3); map.set('c', 2); async.detect(map, detectIterator(order), function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, ['b', 3]); assert.deepStrictEqual(order, [ ['c', 2], ['b', 3] ]); done(); }); }); it('should execute iterator by collection of Map with passing key', function(done) { var order = []; var map = new util.Map(); map.set('a', 5); map.set('b', 3); map.set('c', 2); async.detect(map, detectIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.deepStrictEqual(res, ['b', 3]); assert.deepStrictEqual(order, [ [ ['c', 2], 2], [ ['b', 3], 1] ]); done(); }); }); it('should execute iterator without binding', function(done) { var order = []; var collection = { a: 1.1, b: 3.5, c: 2.6 }; async.detect(collection, detectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 1.1); assert.deepStrictEqual(order, [1.1]); done(); }, Math); }); it('should not get item', function(done) { var order = []; var collection = [2, 6, 4]; async.detect(collection, detectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, undefined); assert.deepStrictEqual(order, [2, 4, 6]); done(); }); }); it('should throw error', function(done) { var order = []; var collection = [1, 3, 2, 4]; var iterator = function(num, callback) { setTimeout(function() { order.push(num); callback(num === 3, false); }, num * delay); }; async.detect(collection, iterator, function(err, res) { assert.ok(err); assert.strictEqual(res, undefined); done(); }); }); it('should throw error if double callback', function(done) { var errorCallCount = 0; setTimeout(function() { assert.strictEqual(errorCallCount, 4); done(); }, delay); domain.create() .on('error', util.errorChecker) .on('error', function() { errorCallCount++; }) .run(function() { var collection = [1, 3, 2, 4]; var iterator = function(num, callback) { process.nextTick(callback); process.nextTick(callback); }; async.detect(collection, iterator); }); }); it('should throw error if double callback', function(done) { var errorCallCount = 0; setTimeout(function() { assert.strictEqual(errorCallCount, 4); done(); }, delay); domain.create() .on('error', util.errorChecker) .on('error', function() { errorCallCount++; }) .run(function() { var collection = [1, 3, 2, 4]; var iterator = function(num, callback) { process.nextTick(callback); process.nextTick(callback); }; async.detect(collection, iterator, function(err, res) { if (err) { return done(err); } assert.strictEqual(res, undefined); }); }); }); it('should avoid double callback', function(done) { var called = false; async.detect([1, 2], function(item, callback) { try { callback(item); } catch (exception) { try { callback(exception); } catch(e) { assert.ok(e); util.errorChecker(e); } done(); } }, function(err) { assert.ok(err); assert.strictEqual(called, false); called = true; async.nothing(); }); }); it('should return response immediately if array is empty', function(done) { var order = []; var array = []; async.detect(array, detectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, undefined); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if object is empty', function(done) { var order = []; var object = {}; async.detect(object, detectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, undefined); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is function', function(done) { var order = []; async.detect(function() {}, detectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, undefined); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is undefined', function(done) { var order = []; async.detect(undefined, detectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, undefined); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is null', function(done) { var order = []; async.detect(null, detectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(res, undefined); assert.deepStrictEqual(order, []); done(); }); }); });
parallel('#reject', function() { it('should execute iterator by collection of array', function(done) { var order = []; var collection = [1, 3, 2, 4]; async.reject(collection, rejectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 2); assert.deepStrictEqual(res, [2, 4]); assert.deepStrictEqual(order, [1, 2, 3, 4]); done(); }); }); it('should execute iterator by collection of array with passing index', function(done) { var order = []; var collection = [1, 3, 2, 4]; async.reject(collection, rejectIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 2); assert.deepStrictEqual(res, [2, 4]); assert.deepStrictEqual(order, [ [1, 0], [2, 2], [3, 1], [4, 3] ]); done(); }); }); it('should execute iterator by collection of object', function(done) { var order = []; var collection = { a: 4, b: 3, c: 2 }; async.reject(collection, rejectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 2); assert.deepStrictEqual(res, [4, 2]); assert.deepStrictEqual(order, [2, 3, 4]); done(); }); }); it('should execute iterator by collection of object with passing key', function(done) { var order = []; var collection = { a: 4, b: 3, c: 2 }; async.reject(collection, rejectIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 2); assert.deepStrictEqual(res, [4, 2]); assert.deepStrictEqual(order, [ [2, 'c'], [3, 'b'], [4, 'a'] ]); done(); }); }); it('should execute iterator by collection of Set', function(done) { var order = []; var set = new util.Set(); set.add(4); set.add(3); set.add(2); async.reject(set, rejectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 2); assert.deepStrictEqual(res, [4, 2]); assert.deepStrictEqual(order, [2, 3, 4]); done(); }); }); it('should execute iterator by collection of Set with passing key', function(done) { var order = []; var set = new util.Set(); set.add(4); set.add(3); set.add(2); async.reject(set, rejectIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 2); assert.deepStrictEqual(res, [4, 2]); assert.deepStrictEqual(order, [ [2, 2], [3, 1], [4, 0] ]); done(); }); }); it('should work even if the size is decreased', function(done) { var order = []; var set = new util.Set([1, 2, 3, 4]); var iterator = function(value, next) { order.push(value); set.delete(value + 1); next(); }; async.reject(set, iterator, function(err) { if (err) { return done(err); } assert.deepStrictEqual(order, [1, 3]); done(); }); }); it('should work even if the size is increased', function(done) { var order = []; var size = 4; var set = new util.Set([1, 2, 3, 4]); var iterator = function(value, next) { order.push(value); value % 2 === 0 && set.add(++size); next(); }; async.reject(set, iterator, function(err) { if (err) { return done(err); } assert.deepStrictEqual(order, [1, 2, 3, 4, 5, 6, 7]); done(); }); }); it('should execute iterator by collection of Map', function(done) { var order = []; var map = new util.Map(); map.set('a', 4); map.set('b', 3); map.set('c', 2); async.reject(map, rejectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 2); assert.deepStrictEqual(res, [ ['a', 4], ['c', 2] ]); assert.deepStrictEqual(order, [ ['c', 2], ['b', 3], ['a', 4] ]); done(); }); }); it('should execute iterator by collection of Map with passing key', function(done) { var order = []; var map = new util.Map(); map.set('a', 4); map.set('b', 3); map.set('c', 2); async.reject(map, rejectIteratorWithKey(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 2); assert.deepStrictEqual(res, [ ['a', 4], ['c', 2] ]); assert.deepStrictEqual(order, [ [['c', 2], 2], [['b', 3], 1], [['a', 4], 0] ]); done(); }); }); it('should execute iterator without binding', function(done) { var order = []; var collection = { a: 1.1, b: 3.5, c: 2.6 }; async.reject(collection, rejectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 0); assert.deepStrictEqual(res, []); assert.deepStrictEqual(order, [1.1, 2.6, 3.5]); done(); }, Math); }); it('should throw error', function(done) { var order = []; var collection = [1, 3, 2, 4]; var iterator = function(num, callback) { setTimeout(function() { order.push(num); callback(num === 3, true); }, num * delay); }; async.reject(collection, iterator, function(err, res) { assert.ok(err); assert.strictEqual(res, undefined); done(); }); }); it('should throw error if double callback', function(done) { var errorCallCount = 0; setTimeout(function() { assert.strictEqual(errorCallCount, 3); done(); }, delay); domain.create() .on('error', util.errorChecker) .on('error', function() { errorCallCount++; }) .run(function() { var collection = [1, 2, 3]; var iterator = function(num, callback) { process.nextTick(callback); process.nextTick(callback); }; async.reject(collection, iterator); }); }); it('should not throw error of double callback', function(done) { var collection = [ 'dir1', 'dir2', 'file1', 'file2' ]; var iterator = function(name, callback) { var result = name.charAt(0) === 'd'; callback(null, result); }; var called = false; async.reject(collection, iterator, function(err, res) { if (err) { return done(err); } assert.strictEqual(called, false); called = true; assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 2); assert.deepStrictEqual(res, ['file1', 'file2']); setImmediate(done); }); }); it('should return response immediately if array is empty', function(done) { var order = []; var array = []; async.reject(array, rejectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 0); assert.deepStrictEqual(res, []); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if object is empty', function(done) { var order = []; var object = {}; async.reject(object, rejectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 0); assert.deepStrictEqual(res, []); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is function', function(done) { var order = []; async.reject(function() {}, rejectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 0); assert.deepStrictEqual(res, []); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is undefined', function(done) { var order = []; async.reject(undefined, rejectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 0); assert.deepStrictEqual(res, []); assert.deepStrictEqual(order, []); done(); }); }); it('should return response immediately if collection is null', function(done) { var order = []; async.reject(null, rejectIterator(order), function(err, res) { if (err) { return done(err); } assert.strictEqual(Object.prototype.toString.call(res), '[object Array]'); assert.strictEqual(res.length, 0); assert.deepStrictEqual(res, []); assert.deepStrictEqual(order, []); done(); }); }); });
parallel('#race', function() { it('should call each funciton in parallel and callback with first result', function(done) { var called = 0; var tasks = _.times(10, function(index) { return function(next) { called++; next(null, index); }; }); async.race(tasks, function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 0); assert.strictEqual(called, 1); setImmediate(function() { assert.strictEqual(called, 10); done(); }); }); }); it('should callback funciton in parallel with object tasks', function(done) { var called = 0; var tasks = _.mapValues(_.times(5, function(index) { return function(next) { setTimeout(function() { called++; next(null, index); }, 50 - index * 5); }; })); async.race(tasks, function(err, res) { if (err) { return done(err); } assert.strictEqual(res, 4); }); setTimeout(function() { assert.strictEqual(called, 5); done(); }, 100); }); it('should callback with the first error', function(done) { var tasks = _.times(6, function(index) { return function(next) { setTimeout(function() { next(new Error('error:' + index), index); }, 50 - index * 5); }; }); async.race(tasks, function(err, res) { assert.ok(err); assert.strictEqual(res, 5); assert.strictEqual(err.message, 'error:5'); done(); }); }); it('should callback when task is empty', function(done) { async.race([], function(err, res) { if (err) { return done(err); } assert.strictEqual(res, undefined); done(); }); }); });