issue-890.test.js 2.4 KB

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