wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
'use strict'
 
// This test is complicated. It must simulate a server sending an unsolicited,
// or a mismatched, message in order to force the client's internal message
// tracker to try and find a corresponding sent message that does not exist.
// In order to do that, we need to set a high test timeout and wait for the
// error message to be logged.
 
const tap = require('tap')
const ldapjs = require('../')
const { SearchResultEntry } = require('@ldapjs/messages')
const server = ldapjs.createServer()
const SUFFIX = ''
 
tap.timeout = 10000
 
server.bind(SUFFIX, (res, done) => {
  res.end()
  return done()
})
 
server.search(SUFFIX, (req, res, done) => {
  const result = new SearchResultEntry({
    objectName: `dc=${req.scopeName}`
  })
 
  // Respond to the search request with a matched response.
  res.send(result)
  res.end()
 
  // After a short delay, send ANOTHER response to the client that will not
  // be matched by the client's internal tracker.
  setTimeout(
    () => {
      res.send(result)
      res.end()
      done()
    },
    100
  )
})
 
tap.beforeEach(t => {
  return new Promise((resolve, reject) => {
    server.listen(0, '127.0.0.1', (err) => {
      if (err) return reject(err)
 
      t.context.logMessages = []
      t.context.logger = {
        child () { return this },
        debug () {},
        error (...args) {
          t.context.logMessages.push(args)
        },
        trace () {}
      }
 
      t.context.url = server.url
      t.context.client = ldapjs.createClient({
        url: [server.url],
        timeout: 5,
        log: t.context.logger
      })
 
      resolve()
    })
  })
})
 
tap.afterEach(t => {
  return new Promise((resolve, reject) => {
    t.context.client.destroy()
    server.close((err) => {
      if (err) return reject(err)
      resolve()
    })
  })
})
 
tap.test('handle null messages', t => {
  const { client, logMessages } = t.context
 
  // There's no way to get an error from the client when it has received an
  // unmatched response from the server. So we need to poll our logger instance
  // and detect when the corresponding error message has been logged.
  const timer = setInterval(
    () => {
      if (logMessages.length > 0) {
        t.equal(
          logMessages.some(msg => msg[1] === 'unmatched server message received'),
          true
        )
        clearInterval(timer)
        t.end()
      }
    },
    100
  )
 
  client.search('dc=test', (error) => {
    t.error(error)
  })
})