2011-08-04 20:32:01 +00:00
|
|
|
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
|
|
|
|
|
|
|
var test = require('tap').test;
|
|
|
|
var uuid = require('node-uuid');
|
|
|
|
|
|
|
|
|
|
|
|
///--- Globals
|
|
|
|
|
|
|
|
var BIND_DN = 'cn=root';
|
|
|
|
var BIND_PW = 'secret';
|
|
|
|
var SOCKET = '/tmp/.' + uuid();
|
|
|
|
|
|
|
|
var SUFFIX = 'dc=test';
|
|
|
|
|
|
|
|
var ldap;
|
|
|
|
var Attribute;
|
|
|
|
var Change;
|
|
|
|
var client;
|
|
|
|
var server;
|
|
|
|
|
|
|
|
|
|
|
|
///--- Tests
|
|
|
|
|
|
|
|
test('setup', function(t) {
|
|
|
|
ldap = require('../lib/index');
|
|
|
|
t.ok(ldap);
|
|
|
|
t.ok(ldap.createClient);
|
|
|
|
t.ok(ldap.createServer);
|
|
|
|
t.ok(ldap.Attribute);
|
|
|
|
t.ok(ldap.Change);
|
|
|
|
|
|
|
|
Attribute = ldap.Attribute;
|
|
|
|
Change = ldap.Change;
|
|
|
|
|
|
|
|
server = ldap.createServer();
|
|
|
|
t.ok(server);
|
|
|
|
|
|
|
|
server.bind(BIND_DN, function(req, res, next) {
|
|
|
|
if (req.credentials !== BIND_PW)
|
|
|
|
return next(new ldap.InvalidCredentialsError('Invalid password'));
|
|
|
|
|
|
|
|
res.end();
|
|
|
|
return next();
|
|
|
|
});
|
|
|
|
|
|
|
|
server.add(SUFFIX, function(req, res, next) {
|
|
|
|
res.end();
|
|
|
|
return next();
|
|
|
|
});
|
|
|
|
|
|
|
|
server.compare(SUFFIX, function(req, res, next) {
|
2011-08-23 00:16:36 +00:00
|
|
|
res.end(req.value === 'test');
|
2011-08-04 20:32:01 +00:00
|
|
|
return next();
|
|
|
|
});
|
|
|
|
|
|
|
|
server.del(SUFFIX, function(req, res, next) {
|
|
|
|
res.end();
|
|
|
|
return next();
|
|
|
|
});
|
|
|
|
|
|
|
|
// LDAP whoami
|
|
|
|
server.exop('1.3.6.1.4.1.4203.1.11.3', function(req, res, next) {
|
|
|
|
res.value = 'u:xxyyz@EXAMPLE.NET';
|
|
|
|
res.end();
|
|
|
|
return next();
|
|
|
|
});
|
|
|
|
|
|
|
|
server.modify(SUFFIX, function(req, res, next) {
|
|
|
|
res.end();
|
|
|
|
return next();
|
|
|
|
});
|
|
|
|
|
|
|
|
server.modifyDN(SUFFIX, function(req, res, next) {
|
|
|
|
res.end();
|
|
|
|
return next();
|
|
|
|
});
|
|
|
|
|
|
|
|
server.search(SUFFIX, function(req, res, next) {
|
2011-09-27 18:49:33 +00:00
|
|
|
|
2011-10-11 18:39:56 +00:00
|
|
|
if (req.dn.equals('cn=ref,' + SUFFIX)) {
|
|
|
|
res.send(res.createSearchReference('ldap://localhost'));
|
|
|
|
} else if (req.dn.equals('cn=bin,' + SUFFIX)) {
|
|
|
|
res.send(res.createSearchEntry({
|
|
|
|
objectName: req.dn,
|
|
|
|
attributes: {
|
2011-10-11 20:56:16 +00:00
|
|
|
'foo;binary': 'wr0gKyDCvCA9IMK+',
|
2011-10-11 22:24:00 +00:00
|
|
|
'gb18030': new Buffer([0xB5, 0xE7, 0xCA, 0xD3, 0xBB, 0xFA]),
|
2011-10-11 20:56:16 +00:00
|
|
|
'objectclass': 'binary'
|
2011-10-11 18:39:56 +00:00
|
|
|
}
|
|
|
|
}));
|
|
|
|
} else {
|
2011-09-27 18:49:33 +00:00
|
|
|
var e = res.createSearchEntry({
|
|
|
|
objectName: req.dn,
|
|
|
|
attributes: {
|
|
|
|
cn: ['unit', 'test'],
|
2011-10-04 17:27:43 +00:00
|
|
|
SN: 'testy'
|
2011-09-27 18:49:33 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
res.send(e);
|
|
|
|
res.send(e);
|
|
|
|
}
|
|
|
|
|
2011-10-11 18:39:56 +00:00
|
|
|
|
2011-08-04 20:32:01 +00:00
|
|
|
res.end();
|
|
|
|
return next();
|
|
|
|
});
|
|
|
|
|
2011-09-30 17:48:56 +00:00
|
|
|
server.search('dc=empty', function(req, res, next) {
|
|
|
|
res.send({
|
|
|
|
dn: 'dc=empty',
|
|
|
|
attributes: {
|
|
|
|
member: [],
|
2011-10-17 23:37:09 +00:00
|
|
|
'member;range=0-1': ['cn=user1, dc=empty', 'cn=user2, dc=empty']
|
2011-09-30 17:48:56 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
res.end();
|
|
|
|
return next();
|
|
|
|
});
|
|
|
|
|
2011-08-04 20:32:01 +00:00
|
|
|
server.unbind(function(req, res, next) {
|
|
|
|
res.end();
|
|
|
|
return next();
|
|
|
|
});
|
|
|
|
|
|
|
|
server.listen(SOCKET, function() {
|
|
|
|
client = ldap.createClient({
|
2011-09-26 23:45:49 +00:00
|
|
|
socketPath: SOCKET,
|
|
|
|
reconnect: false // turn this off for unit testing
|
2011-08-04 20:32:01 +00:00
|
|
|
});
|
|
|
|
t.ok(client);
|
2011-09-26 23:45:49 +00:00
|
|
|
client.log4js.setLevel('Trace');
|
2011-08-04 20:32:01 +00:00
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('simple bind success', function(t) {
|
|
|
|
client.bind(BIND_DN, BIND_PW, function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('simple bind failure', function(t) {
|
|
|
|
client.bind(BIND_DN, uuid(), function(err, res) {
|
|
|
|
t.ok(err);
|
|
|
|
t.notOk(res);
|
|
|
|
|
|
|
|
t.ok(err instanceof ldap.InvalidCredentialsError);
|
|
|
|
t.ok(err instanceof Error);
|
|
|
|
t.ok(err.dn);
|
|
|
|
t.ok(err.message);
|
|
|
|
t.ok(err.stack);
|
|
|
|
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('add success', function(t) {
|
|
|
|
var attrs = [
|
|
|
|
new Attribute({
|
|
|
|
type: 'cn',
|
|
|
|
vals: ['test']
|
|
|
|
})
|
|
|
|
];
|
|
|
|
client.add('cn=add, ' + SUFFIX, attrs, function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-08-04 21:25:12 +00:00
|
|
|
test('add success with object', function(t) {
|
|
|
|
var entry = {
|
|
|
|
cn: ['unit', 'add'],
|
|
|
|
sn: 'test'
|
|
|
|
};
|
|
|
|
client.add('cn=add, ' + SUFFIX, entry, function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-08-04 20:32:01 +00:00
|
|
|
test('compare success', function(t) {
|
|
|
|
client.compare('cn=compare, ' + SUFFIX, 'cn', 'test', function(err,
|
|
|
|
matched,
|
|
|
|
res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(matched);
|
|
|
|
t.ok(res);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('compare false', function(t) {
|
|
|
|
client.compare('cn=compare, ' + SUFFIX, 'cn', 'foo', function(err,
|
|
|
|
matched,
|
|
|
|
res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.notOk(matched);
|
|
|
|
t.ok(res);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('compare bad suffix', function(t) {
|
|
|
|
client.compare('cn=' + uuid(), 'cn', 'foo', function(err,
|
|
|
|
matched,
|
|
|
|
res) {
|
|
|
|
t.ok(err);
|
|
|
|
t.ok(err instanceof ldap.NoSuchObjectError);
|
|
|
|
t.notOk(matched);
|
|
|
|
t.notOk(res);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('delete success', function(t) {
|
|
|
|
client.del('cn=delete, ' + SUFFIX, function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('exop success', function(t) {
|
|
|
|
client.exop('1.3.6.1.4.1.4203.1.11.3', function(err, value, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(value);
|
|
|
|
t.ok(res);
|
|
|
|
t.equal(value, 'u:xxyyz@EXAMPLE.NET');
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('exop invalid', function(t) {
|
|
|
|
client.exop('1.2.3.4', function(err, res) {
|
|
|
|
t.ok(err);
|
|
|
|
t.ok(err instanceof ldap.ProtocolError);
|
|
|
|
t.notOk(res);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-09-23 16:00:28 +00:00
|
|
|
test('bogus exop (GH-17)', function(t) {
|
|
|
|
client.exop('cn=root', function(err, value) {
|
|
|
|
t.ok(err);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-08-04 20:32:01 +00:00
|
|
|
test('modify success', function(t) {
|
|
|
|
var change = new Change({
|
|
|
|
type: 'Replace',
|
|
|
|
modification: new Attribute({
|
|
|
|
type: 'cn',
|
|
|
|
vals: ['test']
|
|
|
|
})
|
|
|
|
});
|
|
|
|
client.modify('cn=modify, ' + SUFFIX, change, function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-08-04 21:25:12 +00:00
|
|
|
test('modify change plain object success', function(t) {
|
|
|
|
var change = new Change({
|
|
|
|
type: 'Replace',
|
|
|
|
modification: {
|
|
|
|
cn: 'test'
|
|
|
|
}
|
|
|
|
});
|
|
|
|
client.modify('cn=modify, ' + SUFFIX, change, function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-08-04 20:32:01 +00:00
|
|
|
test('modify array success', function(t) {
|
|
|
|
var changes = [
|
|
|
|
new Change({
|
|
|
|
operation: 'Replace',
|
|
|
|
modification: new Attribute({
|
|
|
|
type: 'cn',
|
|
|
|
vals: ['test']
|
|
|
|
})
|
|
|
|
}),
|
|
|
|
new Change({
|
|
|
|
operation: 'Delete',
|
|
|
|
modification: new Attribute({
|
|
|
|
type: 'sn'
|
|
|
|
})
|
|
|
|
})
|
|
|
|
];
|
|
|
|
client.modify('cn=modify, ' + SUFFIX, changes, function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-11-08 21:31:00 +00:00
|
|
|
test('modify change plain object success (GH-31)', function(t) {
|
|
|
|
var change = {
|
|
|
|
type: 'replace',
|
|
|
|
modification: {
|
|
|
|
cn: 'test',
|
|
|
|
sn: 'bar'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
client.modify('cn=modify, ' + SUFFIX, change, function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-08-04 20:32:01 +00:00
|
|
|
test('modify DN new RDN only', function(t) {
|
|
|
|
client.modifyDN('cn=old, ' + SUFFIX, 'cn=new', function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('modify DN new superior', function(t) {
|
|
|
|
client.modifyDN('cn=old, ' + SUFFIX, 'cn=new, dc=foo', function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('search basic', function(t) {
|
|
|
|
client.search('cn=test, ' + SUFFIX, '(objectclass=*)', function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
var gotEntry = 0;
|
|
|
|
res.on('searchEntry', function(entry) {
|
|
|
|
t.ok(entry);
|
|
|
|
t.ok(entry instanceof ldap.SearchEntry);
|
|
|
|
t.equal(entry.dn.toString(), 'cn=test, ' + SUFFIX);
|
|
|
|
t.ok(entry.attributes);
|
|
|
|
t.ok(entry.attributes.length);
|
2011-10-04 17:27:43 +00:00
|
|
|
t.equal(entry.attributes[0].type, 'cn');
|
|
|
|
t.equal(entry.attributes[1].type, 'SN');
|
2011-08-04 21:25:12 +00:00
|
|
|
t.ok(entry.object);
|
2011-08-04 20:32:01 +00:00
|
|
|
gotEntry++;
|
|
|
|
});
|
|
|
|
res.on('error', function(err) {
|
|
|
|
t.fail(err);
|
|
|
|
});
|
|
|
|
res.on('end', function(res) {
|
|
|
|
t.ok(res);
|
|
|
|
t.ok(res instanceof ldap.SearchResponse);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.equal(gotEntry, 2);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-09-27 18:49:33 +00:00
|
|
|
test('search referral', function(t) {
|
|
|
|
client.search('cn=ref, ' + SUFFIX, '(objectclass=*)', function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
var gotEntry = 0;
|
|
|
|
var gotReferral = false;
|
|
|
|
res.on('searchEntry', function(entry) {
|
|
|
|
gotEntry++;
|
|
|
|
});
|
|
|
|
res.on('searchReference', function(referral) {
|
|
|
|
gotReferral = true;
|
|
|
|
t.ok(referral);
|
|
|
|
t.ok(referral instanceof ldap.SearchReference);
|
|
|
|
t.ok(referral.uris);
|
|
|
|
t.ok(referral.uris.length);
|
|
|
|
});
|
|
|
|
res.on('error', function(err) {
|
|
|
|
t.fail(err);
|
|
|
|
});
|
|
|
|
res.on('end', function(res) {
|
|
|
|
t.ok(res);
|
|
|
|
t.ok(res instanceof ldap.SearchResponse);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.equal(gotEntry, 0);
|
|
|
|
t.ok(gotReferral);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-09-30 17:48:56 +00:00
|
|
|
test('search empty attribute', function(t) {
|
|
|
|
client.search('dc=empty', '(objectclass=*)', function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
var gotEntry = 0;
|
|
|
|
res.on('searchEntry', function(entry) {
|
|
|
|
var obj = entry.toObject();
|
|
|
|
t.equal('dc=empty', obj.dn);
|
|
|
|
t.ok(obj.member);
|
|
|
|
t.equal(obj.member.length, 0);
|
|
|
|
t.ok(obj['member;range=0-1']);
|
|
|
|
t.ok(obj['member;range=0-1'].length);
|
|
|
|
gotEntry++;
|
|
|
|
});
|
|
|
|
res.on('error', function(err) {
|
|
|
|
t.fail(err);
|
|
|
|
});
|
|
|
|
res.on('end', function(res) {
|
2011-10-11 20:56:16 +00:00
|
|
|
t.ok(res);
|
|
|
|
t.ok(res instanceof ldap.SearchResponse);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.equal(gotEntry, 1);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('GH-21 binary attributes', function(t) {
|
|
|
|
client.search('cn=bin, ' + SUFFIX, '(objectclass=*)', function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
var gotEntry = 0;
|
|
|
|
var expect = new Buffer('\u00bd + \u00bc = \u00be', 'utf8');
|
2011-10-11 22:24:00 +00:00
|
|
|
var expect2 = new Buffer([0xB5, 0xE7, 0xCA, 0xD3, 0xBB, 0xFA]);
|
2011-10-11 20:56:16 +00:00
|
|
|
res.on('searchEntry', function(entry) {
|
|
|
|
t.ok(entry);
|
|
|
|
t.ok(entry instanceof ldap.SearchEntry);
|
|
|
|
t.equal(entry.dn.toString(), 'cn=bin, ' + SUFFIX);
|
|
|
|
t.ok(entry.attributes);
|
|
|
|
t.ok(entry.attributes.length);
|
|
|
|
t.equal(entry.attributes[0].type, 'foo;binary');
|
|
|
|
t.equal(entry.attributes[0].vals[0], expect.toString('base64'));
|
|
|
|
t.equal(entry.attributes[0].buffers[0].toString('base64'),
|
|
|
|
expect.toString('base64'));
|
2011-10-11 22:24:00 +00:00
|
|
|
|
|
|
|
t.ok(entry.attributes[1].type, 'gb18030');
|
|
|
|
t.equal(entry.attributes[1].buffers.length, 1);
|
|
|
|
t.equal(expect2.length, entry.attributes[1].buffers[0].length);
|
|
|
|
for (var i = 0; i < expect2.length; i++)
|
|
|
|
t.equal(expect2[i], entry.attributes[1].buffers[0][i]);
|
|
|
|
|
2011-10-11 20:56:16 +00:00
|
|
|
t.ok(entry.object);
|
|
|
|
gotEntry++;
|
|
|
|
});
|
|
|
|
res.on('error', function(err) {
|
|
|
|
t.fail(err);
|
|
|
|
});
|
|
|
|
res.on('end', function(res) {
|
2011-09-30 17:48:56 +00:00
|
|
|
t.ok(res);
|
|
|
|
t.ok(res instanceof ldap.SearchResponse);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.equal(gotEntry, 1);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-10-11 17:43:27 +00:00
|
|
|
test('GH-23 case insensitive attribute filtering', function(t) {
|
|
|
|
var opts = {
|
|
|
|
filter: '(objectclass=*)',
|
|
|
|
attributes: ['Cn']
|
|
|
|
};
|
|
|
|
client.search('cn=test, ' + SUFFIX, opts, function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
var gotEntry = 0;
|
|
|
|
res.on('searchEntry', function(entry) {
|
|
|
|
t.ok(entry);
|
|
|
|
t.ok(entry instanceof ldap.SearchEntry);
|
|
|
|
t.equal(entry.dn.toString(), 'cn=test, ' + SUFFIX);
|
|
|
|
t.ok(entry.attributes);
|
|
|
|
t.ok(entry.attributes.length);
|
|
|
|
t.equal(entry.attributes[0].type, 'cn');
|
|
|
|
t.ok(entry.object);
|
|
|
|
gotEntry++;
|
|
|
|
});
|
|
|
|
res.on('error', function(err) {
|
|
|
|
t.fail(err);
|
|
|
|
});
|
|
|
|
res.on('end', function(res) {
|
|
|
|
t.ok(res);
|
|
|
|
t.ok(res instanceof ldap.SearchResponse);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.equal(gotEntry, 2);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2011-10-11 18:39:56 +00:00
|
|
|
|
|
|
|
test('GH-24 attribute selection of *', function(t) {
|
|
|
|
var opts = {
|
|
|
|
filter: '(objectclass=*)',
|
|
|
|
attributes: ['*']
|
|
|
|
};
|
|
|
|
client.search('cn=test, ' + SUFFIX, opts, function(err, res) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.ok(res);
|
|
|
|
var gotEntry = 0;
|
|
|
|
res.on('searchEntry', function(entry) {
|
|
|
|
t.ok(entry);
|
|
|
|
t.ok(entry instanceof ldap.SearchEntry);
|
|
|
|
t.equal(entry.dn.toString(), 'cn=test, ' + SUFFIX);
|
|
|
|
t.ok(entry.attributes);
|
|
|
|
t.ok(entry.attributes.length);
|
|
|
|
t.equal(entry.attributes[0].type, 'cn');
|
|
|
|
t.equal(entry.attributes[1].type, 'SN');
|
|
|
|
t.ok(entry.object);
|
|
|
|
gotEntry++;
|
|
|
|
});
|
|
|
|
res.on('error', function(err) {
|
|
|
|
t.fail(err);
|
|
|
|
});
|
|
|
|
res.on('end', function(res) {
|
|
|
|
t.ok(res);
|
|
|
|
t.ok(res instanceof ldap.SearchResponse);
|
|
|
|
t.equal(res.status, 0);
|
|
|
|
t.equal(gotEntry, 2);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-11-07 22:13:53 +00:00
|
|
|
test('abandon (GH-27)', function(t) {
|
|
|
|
client.abandon(401876543, function(err) {
|
|
|
|
t.ifError(err);
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-11-09 22:55:13 +00:00
|
|
|
test('unbind (GH-30)', function(t) {
|
2011-11-08 21:10:39 +00:00
|
|
|
client.unbind(function(err) {
|
|
|
|
t.ifError(err);
|
2011-11-09 22:55:13 +00:00
|
|
|
t.end();
|
2011-11-08 21:10:39 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2011-11-09 22:55:13 +00:00
|
|
|
|
2011-08-04 20:32:01 +00:00
|
|
|
test('shutdown', function(t) {
|
2011-11-08 21:10:39 +00:00
|
|
|
client.unbind(function(err) {
|
2011-08-04 20:32:01 +00:00
|
|
|
server.on('close', function() {
|
|
|
|
t.end();
|
|
|
|
});
|
|
|
|
server.close();
|
|
|
|
});
|
|
|
|
});
|