123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- 'use strict'
- const tap = require('tap')
- const warning = require('./deprecations')
- const RDN = require('./rdn')
- const DN = require('./dn')
- // Silence the standard warning logs. We will test the messages explicitly.
- process.removeAllListeners('warning')
- tap.test('constructor', t => {
- t.test('throws for non-array', async t => {
- t.throws(
- () => new DN({ rdns: 42 }),
- Error('rdns must be an array')
- )
- })
- t.test('throws for non-rdn in array', async t => {
- const rdns = [
- new RDN(),
- { 'non-string-value': 42 },
- new RDN()
- ]
- t.throws(
- () => new DN({ rdns })
- )
- })
- t.test('handles mixed array', async t => {
- const rdns = [
- { cn: 'foo' },
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- const dn = new DN({ rdns })
- t.equal(dn.length, 3)
- t.equal(dn.toString(), 'cn=foo,dc=example,dc=com')
- })
- t.end()
- })
- tap.test('childOf', t => {
- t.test('false if we are shallower', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const target = new DN({
- rdns: [
- new RDN({ cn: 'foo' }),
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.childOf(target), false)
- })
- t.test('false if differing path', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const target = new DN({
- rdns: [
- new RDN({ dc: 'ldapjs' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.childOf(target), false)
- })
- t.test('true if we are a child', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const target = new DN({
- rdns: [
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.childOf(target), true)
- })
- t.test('handles string input', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const target = 'dc=example,dc=com'
- t.equal(dn.childOf(target), true)
- })
- t.end()
- })
- tap.test('clone', t => {
- t.test('returns a copy', async t => {
- const rdns = [new RDN({ cn: 'foo' })]
- const src = new DN({ rdns })
- const clone = src.clone()
- t.equal(src.length, clone.length)
- t.equal(src.toString(), clone.toString())
- })
- t.end()
- })
- tap.test('equals', t => {
- t.test('false for non-equal length', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const target = new DN({
- rdns: [
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.equals(target), false)
- })
- t.test('false for non-equal paths', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const target = new DN({
- rdns: [
- new RDN({ ou: 'computers' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.equals(target), false)
- })
- t.test('true for equal paths', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const target = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.equals(target), true)
- })
- t.test('handles string input', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const target = 'ou=people,dc=example,dc=com'
- t.equal(dn.equals(target), true)
- })
- t.end()
- })
- tap.test('format', t => {
- t.test('emits warning', t => {
- process.on('warning', handler)
- t.teardown(async () => {
- process.removeListener('warning', handler)
- warning.emitted.set('LDAP_DN_DEP_002', false)
- })
- const rdns = [{ cn: 'foo' }]
- const dnString = (new DN({ rdns })).format()
- t.equal(dnString, 'cn=foo')
- function handler (error) {
- t.equal(error.message, '.format() is deprecated. Use .toString() instead')
- t.end()
- }
- })
- t.end()
- })
- tap.test('isEmpty', t => {
- t.test('returns correct result', async t => {
- let dn = new DN()
- t.equal(dn.isEmpty(), true)
- dn = new DN({
- rdns: [new RDN({ cn: 'foo' })]
- })
- t.equal(dn.isEmpty(), false)
- })
- t.end()
- })
- tap.test('parent', t => {
- t.test('undefined for an empty DN', async t => {
- const dn = new DN()
- const parent = dn.parent()
- t.equal(parent, undefined)
- })
- t.test('returns correct DN', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ cn: 'jdoe', givenName: 'John' }),
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const parent = dn.parent()
- t.equal(parent.toString(), 'ou=people,dc=example,dc=com')
- })
- t.end()
- })
- tap.test('parentOf', t => {
- t.test('false if we are deeper', async t => {
- const target = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const dn = new DN({
- rdns: [
- new RDN({ cn: 'foo' }),
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.parentOf(target), false)
- })
- t.test('false if differing path', async t => {
- const target = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const dn = new DN({
- rdns: [
- new RDN({ dc: 'ldapjs' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.parentOf(target), false)
- })
- t.test('true if we are a parent', async t => {
- const target = new DN({
- rdns: [
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const dn = new DN({
- rdns: [
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.parentOf(target), true)
- })
- t.test('handles string input', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const target = 'ou=people,dc=example,dc=com'
- t.equal(dn.parentOf(target), true)
- })
- t.end()
- })
- tap.test('pop', t => {
- t.test('returns the last element and shortens the list', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ cn: 'foo' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.toString(), 'cn=foo,dc=example,dc=com')
- const rdn = dn.pop()
- t.equal(rdn.toString(), 'dc=com')
- t.equal(dn.toString(), 'cn=foo,dc=example')
- })
- t.end()
- })
- tap.test('push', t => {
- t.test('throws for bad input', async t => {
- const dn = new DN()
- t.throws(
- () => dn.push({ cn: 'foo' }),
- Error('rdn must be a RDN instance')
- )
- })
- t.test('adds to the front of the list', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ cn: 'foo' }),
- new RDN({ dc: 'example' })
- ]
- })
- t.equal(dn.toString(), 'cn=foo,dc=example')
- const newLength = dn.push(new RDN({ dc: 'com' }))
- t.equal(newLength, 3)
- t.equal(dn.toString(), 'cn=foo,dc=example,dc=com')
- })
- t.end()
- })
- tap.test('rdnAt', t => {
- t.test('returns correct RDN', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ cn: 'jdoe', givenName: 'John' }),
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- const rdn = dn.rdnAt(1)
- t.equal(rdn.toString(), 'ou=people')
- })
- t.end()
- })
- tap.test('reverse', t => {
- t.test('reverses the list', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ dc: 'com' }),
- new RDN({ dc: 'example' }),
- new RDN({ cn: 'foo' })
- ]
- })
- t.equal(dn.toString(), 'dc=com,dc=example,cn=foo')
- const result = dn.reverse()
- t.equal(dn, result)
- t.equal(dn.toString(), 'cn=foo,dc=example,dc=com')
- })
- t.end()
- })
- tap.test('setFormat', t => {
- t.test('emits warning', t => {
- process.on('warning', handler)
- t.teardown(async () => {
- process.removeListener('warning', handler)
- warning.emitted.set('LDAP_DN_DEP_004', false)
- })
- const rdns = [{ cn: 'foo' }]
- new DN({ rdns }).setFormat()
- function handler (error) {
- t.equal(error.message, '.setFormat() is deprecated. Options will be ignored')
- t.end()
- }
- })
- t.end()
- })
- tap.test('shift', t => {
- t.test('returns the first element and shortens the list', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ cn: 'foo' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.toString(), 'cn=foo,dc=example,dc=com')
- const rdn = dn.shift()
- t.equal(rdn.toString(), 'cn=foo')
- t.equal(dn.toString(), 'dc=example,dc=com')
- })
- t.end()
- })
- tap.test('toString', t => {
- t.test('renders correctly', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ cn: 'jdoe', givenName: 'John' }),
- new RDN({ ou: 'people' }),
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.toString(), 'cn=jdoe+givenName=John,ou=people,dc=example,dc=com')
- })
- t.test('empty string for empty DN', async t => {
- const dn = new DN()
- t.equal(dn.toString(), '')
- })
- t.end()
- })
- tap.test('unshift', t => {
- t.test('throws for bad input', async t => {
- const dn = new DN()
- t.throws(
- () => dn.unshift({ cn: 'foo' }),
- Error('rdn must be a RDN instance')
- )
- })
- t.test('adds to the front of the list', async t => {
- const dn = new DN({
- rdns: [
- new RDN({ dc: 'example' }),
- new RDN({ dc: 'com' })
- ]
- })
- t.equal(dn.toString(), 'dc=example,dc=com')
- const newLength = dn.unshift(new RDN({ cn: 'foo' }))
- t.equal(newLength, 3)
- t.equal(dn.toString(), 'cn=foo,dc=example,dc=com')
- })
- t.end()
- })
- tap.test('#isDn', t => {
- t.test('true for instance', async t => {
- const dn = new DN()
- t.equal(DN.isDn(dn), true)
- })
- t.test('false for non-object', async t => {
- t.equal(DN.isDn(42), false)
- })
- t.test('false for non-array rdns', async t => {
- const input = { rdns: 42 }
- t.equal(DN.isDn(input), false)
- })
- t.test('false for bad rdn', async t => {
- const input = { rdns: [{ bad: 'rdn', answer: 42 }] }
- t.equal(DN.isDn(input), false)
- })
- t.test('true for dn-like', async t => {
- const input = { rdns: [{ name: 'cn', value: 'foo' }] }
- t.equal(DN.isDn(input), true)
- })
- t.end()
- })
- tap.test('#fromString', t => {
- t.test('parses a basic string into an instance', async t => {
- const input = 'cn=foo+sn=bar,dc=example,dc=com'
- const dn = DN.fromString(input)
- t.equal(DN.isDn(dn), true)
- t.equal(dn.length, 3)
- t.equal(dn.rdnAt(0).toString(), 'cn=foo+sn=bar')
- })
- t.end()
- })
|