Skip to content

Commit 2347313

Browse files
committed
Attribute.isAttribute improvements
1 parent 031bc97 commit 2347313

File tree

3 files changed

+75
-14
lines changed

3 files changed

+75
-14
lines changed

index.js

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,36 @@ class Attribute {
254254
/**
255255
* Determine if an object represents an {@link Attribute}.
256256
*
257-
* @param {object} item
257+
* @param {object} attr The object to check. It can be an instance of
258+
* {@link Attribute} or a plain JavaScript object that looks like an
259+
* {@link Attribute} and can be passed to the constructor to create one.
258260
*
259261
* @returns {boolean}
260262
*/
261-
static isAttribute (item) {
262-
// TODO: we might need to support a plain object that looks like
263-
// an attribute object. The original code does.
264-
return Object.prototype.toString.call(item) === '[object LdapAttribute]'
263+
static isAttribute (attr) {
264+
if (typeof attr !== 'object') {
265+
return false
266+
}
267+
268+
if (Object.prototype.toString.call(attr) === '[object LdapAttribute]') {
269+
return true
270+
}
271+
272+
const typeOk = typeof attr.type === 'string'
273+
let valuesOk = Array.isArray(attr.values)
274+
if (valuesOk === true) {
275+
for (const val of attr.values) {
276+
if (typeof val !== 'string' && Buffer.isBuffer(val) === false) {
277+
valuesOk = false
278+
break
279+
}
280+
}
281+
}
282+
if (typeOk === true && valuesOk === true) {
283+
return true
284+
}
285+
286+
return false
265287
}
266288
}
267289

index.test.js

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -290,14 +290,53 @@ tap.test('#fromBer', t => {
290290
t.end()
291291
})
292292

293-
tap.test('#isAttribute', async t => {
294-
const isA = Attribute.isAttribute
295-
t.notOk(isA(null))
296-
t.notOk(isA('asdf'))
297-
t.ok(isA(new Attribute({
298-
type: 'foobar',
299-
values: ['asdf']
300-
})))
293+
tap.test('#isAttribute', t => {
294+
t.test('rejects non-object', async t => {
295+
t.equal(Attribute.isAttribute(42), false)
296+
})
297+
298+
t.test('accepts Attribute instances', async t => {
299+
const input = new Attribute({
300+
type: 'cn',
301+
values: ['foo']
302+
})
303+
t.equal(Attribute.isAttribute(input), true)
304+
})
305+
306+
t.test('accepts attribute-like objects', async t => {
307+
const input = {
308+
type: 'cn',
309+
values: [
310+
'foo',
311+
Buffer.from('bar')
312+
]
313+
}
314+
t.equal(Attribute.isAttribute(input), true)
315+
})
316+
317+
t.test('rejects non-attribute-like objects', async t => {
318+
let input = {
319+
foo: 'foo',
320+
values: 'bar'
321+
}
322+
t.equal(Attribute.isAttribute(input), false)
323+
324+
input = {
325+
type: 'cn',
326+
values: [42]
327+
}
328+
t.equal(Attribute.isAttribute(input), false)
329+
})
330+
331+
// const isA = Attribute.isAttribute
332+
// t.notOk(isA(null))
333+
// t.notOk(isA('asdf'))
334+
// t.ok(isA(new Attribute({
335+
// type: 'foobar',
336+
// values: ['asdf']
337+
// })))
338+
339+
t.end()
301340
})
302341

303342
tap.test('compare', async t => {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"name": "@ldapjs/attribute",
88
"homepage": "https://github.com/ldapjs/attribute",
99
"description": "API for handling LDAP entry attributes",
10-
"version": "1.0.0-rc.1",
10+
"version": "1.0.0-rc.2",
1111
"license": "MIT",
1212
"repository": {
1313
"type": "git",

0 commit comments

Comments
 (0)