Haraka 3.2.0 → 3.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/.githooks/pre-commit +41 -0
  2. package/.prettierignore +1 -0
  3. package/.qlty/.gitignore +7 -0
  4. package/.qlty/configs/.shellcheckrc +1 -0
  5. package/.qlty/qlty.toml +15 -0
  6. package/CHANGELOG.md +29 -2
  7. package/CONTRIBUTORS.md +5 -5
  8. package/README.md +6 -3
  9. package/bin/haraka +12 -4
  10. package/config/connection.ini +6 -0
  11. package/connection.js +67 -68
  12. package/contrib/bsd-rc.d/haraka +2 -0
  13. package/docs/CoreConfig.md +2 -0
  14. package/docs/HAProxy.md +4 -1
  15. package/eslint.config.mjs +2 -30
  16. package/haraka.js +2 -2
  17. package/line_socket.js +6 -33
  18. package/outbound/hmail.js +18 -29
  19. package/outbound/index.js +3 -3
  20. package/outbound/queue.js +8 -5
  21. package/package.json +51 -48
  22. package/plugins/auth/auth_proxy.js +7 -4
  23. package/plugins/block_me.js +1 -1
  24. package/plugins/delay_deny.js +1 -1
  25. package/plugins/queue/qmail-queue.js +1 -1
  26. package/plugins/queue/quarantine.js +5 -5
  27. package/plugins/queue/smtp_bridge.js +1 -1
  28. package/plugins/queue/smtp_proxy.js +2 -2
  29. package/plugins/status.js +2 -2
  30. package/plugins/toobusy.js +1 -1
  31. package/plugins.js +4 -3
  32. package/server.js +172 -28
  33. package/smtp_client.js +2 -1
  34. package/test/connection.js +119 -2
  35. package/test/fixtures/haproxy_allowed/config/connection.ini +3 -0
  36. package/test/fixtures/haproxy_disabled/config/connection.ini +3 -0
  37. package/test/fixtures/haproxy_untrusted/config/connection.ini +3 -0
  38. package/test/fixtures/line_socket.js +1 -1
  39. package/test/fixtures/util_hmailitem.js +2 -3
  40. package/test/outbound/index.js +6 -7
  41. package/test/outbound/qfile.js +1 -1
  42. package/test/outbound/queue.js +2 -2
  43. package/test/plugins/auth/auth_base.js +17 -17
  44. package/test/plugins/auth/auth_bridge.js +3 -3
  45. package/test/plugins/auth/auth_vpopmaild.js +3 -3
  46. package/test/plugins/auth/flat_file.js +16 -21
  47. package/test/plugins/block_me.js +7 -23
  48. package/test/plugins/data.signatures.js +17 -20
  49. package/test/plugins/delay_deny.js +3 -4
  50. package/test/plugins/prevent_credential_leaks.js +17 -21
  51. package/test/plugins/process_title.js +12 -6
  52. package/test/plugins/queue/deliver.js +7 -8
  53. package/test/plugins/queue/discard.js +3 -4
  54. package/test/plugins/queue/lmtp.js +5 -6
  55. package/test/plugins/queue/qmail-queue.js +7 -8
  56. package/test/plugins/queue/quarantine.js +3 -4
  57. package/test/plugins/queue/smtp_bridge.js +5 -7
  58. package/test/plugins/queue/smtp_forward.js +49 -60
  59. package/test/plugins/queue/smtp_proxy.js +6 -7
  60. package/test/plugins/rcpt_to.host_list_base.js +6 -9
  61. package/test/plugins/rcpt_to.in_host_list.js +6 -11
  62. package/test/plugins/record_envelope_addresses.js +33 -60
  63. package/test/plugins/reseed_rng.js +3 -3
  64. package/test/plugins/status.js +4 -5
  65. package/test/plugins/tarpit.js +3 -4
  66. package/test/plugins/tls.js +3 -5
  67. package/test/plugins/toobusy.js +186 -9
  68. package/test/plugins/xclient.js +7 -4
  69. package/test/server.js +425 -1
  70. package/test/smtp_client.js +11 -18
  71. package/test/tls_socket.js +3 -6
  72. package/tls_socket.js +3 -3
  73. package/transaction.js +3 -3
  74. package/address.js +0 -53
  75. package/endpoint.js +0 -96
  76. package/host_pool.js +0 -169
  77. package/outbound/fsync_writestream.js +0 -44
  78. package/outbound/timer_queue.js +0 -86
  79. package/rfc1869.js +0 -93
  80. package/test/endpoint.js +0 -128
  81. package/test/host_pool.js +0 -188
  82. package/test/rfc1869.js +0 -89
@@ -2,16 +2,15 @@
2
2
  const assert = require('node:assert/strict')
3
3
  const { describe, it, beforeEach } = require('node:test')
4
4
 
5
- const { Address } = require('../../address')
6
- const fixtures = require('haraka-test-fixtures')
5
+ const { Address } = require('@haraka/email-address')
6
+ const { assertResult, makeConnection, makePlugin } = require('haraka-test-fixtures')
7
7
 
8
8
  const _set_up = () => {
9
- this.plugin = new fixtures.plugin('rcpt_to.host_list_base')
9
+ this.plugin = makePlugin('rcpt_to.host_list_base', { register: false })
10
10
  this.plugin.cfg = {}
11
11
  this.plugin.host_list = {}
12
12
 
13
- this.connection = fixtures.connection.createConnection()
14
- this.connection.init_transaction()
13
+ this.connection = makeConnection({ withTxn: true })
15
14
  }
16
15
 
17
16
  describe('rcpt_to.host_list_base', () => {
@@ -78,8 +77,7 @@ describe('rcpt_to.host_list_base', () => {
78
77
  const { rc, msg } = await callMailHook('<user@example.com>')
79
78
  assert.equal(rc, undefined)
80
79
  assert.equal(msg, undefined)
81
- const res = this.connection.transaction.results.get('rcpt_to.host_list_base')
82
- assert.ok(res.msg.includes('mail_from!local'))
80
+ assertResult(this.connection.transaction, 'rcpt_to.host_list_base', 'msg', /^mail_from!local$/)
83
81
  })
84
82
 
85
83
  for (const [desc, setup] of [
@@ -97,8 +95,7 @@ describe('rcpt_to.host_list_base', () => {
97
95
  const { rc, msg } = await callMailHook('<user@example.com>')
98
96
  assert.equal(rc, undefined)
99
97
  assert.equal(msg, undefined)
100
- const res = this.connection.transaction.results.get('rcpt_to.host_list_base')
101
- assert.ok(res.pass.includes('mail_from'))
98
+ assertResult(this.connection.transaction, 'rcpt_to.host_list_base', 'pass', /^mail_from$/)
102
99
  })
103
100
  }
104
101
  })
@@ -2,21 +2,18 @@
2
2
  const assert = require('node:assert/strict')
3
3
  const { describe, it, beforeEach } = require('node:test')
4
4
 
5
- const { Address } = require('../../address')
5
+ const { Address } = require('@haraka/email-address')
6
6
  const fixtures = require('haraka-test-fixtures')
7
+ const { assertResult, makeConnection, makePlugin } = fixtures
7
8
  require('haraka-constants').import(global)
8
9
 
9
10
  const _set_up = () => {
10
- this.plugin = new fixtures.plugin('rcpt_to.in_host_list')
11
+ this.plugin = makePlugin('rcpt_to.in_host_list', { register: false })
11
12
  this.plugin.inherits('rcpt_to.host_list_base')
12
13
  this.plugin.cfg = {}
13
14
  this.plugin.host_list = {}
14
15
 
15
- this.connection = fixtures.connection.createConnection()
16
- this.connection.transaction = {
17
- results: new fixtures.results(this.connection),
18
- notes: {},
19
- }
16
+ this.connection = makeConnection({ withTxn: true })
20
17
  }
21
18
 
22
19
  describe('in_host_list', () => {
@@ -81,8 +78,7 @@ describe('in_host_list', () => {
81
78
  const { rc, msg } = await callMailHook('<user@example.com>')
82
79
  assert.equal(rc, undefined)
83
80
  assert.equal(msg, undefined)
84
- const res = this.connection.transaction.results.get('rcpt_to.in_host_list')
85
- assert.ok(res.msg.includes('mail_from!local'))
81
+ assertResult(this.connection.transaction, 'rcpt_to.in_host_list', 'msg', /^mail_from!local$/)
86
82
  })
87
83
 
88
84
  for (const [desc, setup] of [
@@ -100,8 +96,7 @@ describe('in_host_list', () => {
100
96
  const { rc, msg } = await callMailHook('<user@example.com>')
101
97
  assert.equal(rc, undefined)
102
98
  assert.equal(msg, undefined)
103
- const res = this.connection.transaction.results.get('rcpt_to.in_host_list')
104
- assert.ok(res.pass.includes('mail_from'))
99
+ assertResult(this.connection.transaction, 'rcpt_to.in_host_list', 'pass', /^mail_from$/)
105
100
  })
106
101
  }
107
102
  })
@@ -3,13 +3,11 @@
3
3
  const assert = require('node:assert')
4
4
  const { describe, it, beforeEach } = require('node:test')
5
5
 
6
- const { Address } = require('../../address')
7
- const fixtures = require('haraka-test-fixtures')
6
+ const { callMail, callRcpt, makeConnection, makePlugin } = require('haraka-test-fixtures')
8
7
 
9
8
  const _set_up = () => {
10
- this.plugin = new fixtures.plugin('record_envelope_addresses')
11
- this.connection = fixtures.connection.createConnection()
12
- this.connection.init_transaction()
9
+ this.plugin = makePlugin('record_envelope_addresses')
10
+ this.connection = makeConnection({ withTxn: true })
13
11
  }
14
12
 
15
13
  describe('record_envelope_addresses', () => {
@@ -17,77 +15,52 @@ describe('record_envelope_addresses', () => {
17
15
 
18
16
  describe('hook_mail', () => {
19
17
  it('adds X-Envelope-From header from MAIL FROM address', (t, done) => {
20
- const addr = new Address('<sender@example.com>')
21
- this.plugin.hook_mail(
22
- () => {
23
- const vals = this.connection.transaction.header.get_all('X-Envelope-From')
24
- assert.equal(vals.length, 1, 'header was added')
25
- assert.equal(vals[0], 'sender@example.com')
26
- done()
27
- },
28
- this.connection,
29
- [addr],
30
- )
18
+ callMail(this.plugin, this.connection, 'sender@example.com').then(() => {
19
+ const vals = this.connection.transaction.header.get_all('X-Envelope-From')
20
+ assert.equal(vals.length, 1, 'header was added')
21
+ assert.equal(vals[0], 'sender@example.com')
22
+ done()
23
+ })
31
24
  })
32
25
 
33
26
  it('does not throw when connection has no transaction', (t, done) => {
34
27
  this.connection.transaction = null
35
- const addr = new Address('<sender@example.com>')
36
- this.plugin.hook_mail(
37
- () => {
38
- assert.ok(true, 'next was called without error')
39
- done()
40
- },
41
- this.connection,
42
- [addr],
43
- )
28
+ callMail(this.plugin, this.connection, 'sender@example.com').then(() => {
29
+ assert.ok(true, 'next was called without error')
30
+ done()
31
+ })
44
32
  })
45
33
  })
46
34
 
47
35
  describe('hook_rcpt', () => {
48
36
  it('adds X-Envelope-To header from RCPT TO address', (t, done) => {
49
- const addr = new Address('<rcpt@example.com>')
50
- this.plugin.hook_rcpt(
51
- () => {
52
- const vals = this.connection.transaction.header.get_all('X-Envelope-To')
53
- assert.equal(vals.length, 1, 'header was added')
54
- assert.equal(vals[0], 'rcpt@example.com')
55
- done()
56
- },
57
- this.connection,
58
- [addr],
59
- )
37
+ callRcpt(this.plugin, this.connection, 'rcpt@example.com').then(() => {
38
+ const vals = this.connection.transaction.header.get_all('X-Envelope-To')
39
+ assert.equal(vals.length, 1, 'header was added')
40
+ assert.equal(vals[0], 'rcpt@example.com')
41
+ done()
42
+ })
60
43
  })
61
44
 
62
45
  it('adds X-Envelope-To header for each recipient', (t, done) => {
63
- const addr1 = new Address('<one@example.com>')
64
- const addr2 = new Address('<two@example.com>')
65
- let calls = 0
66
- const next = () => {
67
- calls++
68
- if (calls === 2) {
69
- const vals = this.connection.transaction.header.get_all('X-Envelope-To')
70
- assert.equal(vals.length, 2, 'two headers added')
71
- assert.equal(vals[0], 'one@example.com')
72
- assert.equal(vals[1], 'two@example.com')
73
- done()
74
- }
75
- }
76
- this.plugin.hook_rcpt(next, this.connection, [addr1])
77
- this.plugin.hook_rcpt(next, this.connection, [addr2])
46
+ Promise.all([
47
+ callRcpt(this.plugin, this.connection, 'one@example.com'),
48
+ callRcpt(this.plugin, this.connection, 'two@example.com'),
49
+ ]).then(() => {
50
+ const vals = this.connection.transaction.header.get_all('X-Envelope-To')
51
+ assert.equal(vals.length, 2, 'two headers added')
52
+ assert.equal(vals[0], 'one@example.com')
53
+ assert.equal(vals[1], 'two@example.com')
54
+ done()
55
+ })
78
56
  })
79
57
 
80
58
  it('does not throw when connection has no transaction', (t, done) => {
81
59
  this.connection.transaction = null
82
- const addr = new Address('<rcpt@example.com>')
83
- this.plugin.hook_rcpt(
84
- () => {
85
- assert.ok(true, 'next was called without error')
86
- done()
87
- },
88
- this.connection,
89
- [addr],
90
- )
60
+ callRcpt(this.plugin, this.connection, 'rcpt@example.com').then(() => {
61
+ assert.ok(true, 'next was called without error')
62
+ done()
63
+ })
91
64
  })
92
65
  })
93
66
  })
@@ -3,12 +3,12 @@
3
3
  const assert = require('node:assert/strict')
4
4
  const { describe, it } = require('node:test')
5
5
 
6
- const fixtures = require('haraka-test-fixtures')
6
+ const { makePlugin } = require('haraka-test-fixtures')
7
7
 
8
8
  describe('reseed_rng', () => {
9
9
  describe('hook_init_child', () => {
10
10
  it('calls Math.seedrandom with a hex string and calls next', (t, done) => {
11
- const plugin = new fixtures.plugin('reseed_rng')
11
+ const plugin = makePlugin('reseed_rng', { register: false })
12
12
  let called = false
13
13
  let calledArg
14
14
  Math.seedrandom = (arg) => {
@@ -26,7 +26,7 @@ describe('reseed_rng', () => {
26
26
  })
27
27
 
28
28
  it('throws when Math.seedrandom is not defined', () => {
29
- const plugin = new fixtures.plugin('reseed_rng')
29
+ const plugin = makePlugin('reseed_rng', { register: false })
30
30
  delete Math.seedrandom
31
31
  assert.throws(() => plugin.hook_init_child(() => {}), /Math\.seedrandom is not a function/)
32
32
  })
@@ -4,16 +4,15 @@ const assert = require('node:assert/strict')
4
4
  const { describe, it, beforeEach } = require('node:test')
5
5
 
6
6
  const fixtures = require('haraka-test-fixtures')
7
+ const { makeConnection, makePlugin } = fixtures
7
8
  const outbound = require('../../outbound')
8
- const TimerQueue = require('../../outbound/timer_queue')
9
-
10
- const Connection = fixtures.connection
9
+ const { TimerQueue } = require('haraka-utils')
11
10
 
12
11
  const _set_up = () => {
13
- this.plugin = new fixtures.plugin('status')
12
+ this.plugin = makePlugin('status', { register: false })
14
13
  this.plugin.outbound = outbound
15
14
 
16
- this.connection = Connection.createConnection()
15
+ this.connection = makeConnection()
17
16
  this.connection.remote.is_local = true
18
17
  }
19
18
 
@@ -3,13 +3,13 @@
3
3
  const assert = require('node:assert/strict')
4
4
  const { describe, it, beforeEach } = require('node:test')
5
5
 
6
- const fixtures = require('haraka-test-fixtures')
6
+ const { makeConnection, makePlugin } = require('haraka-test-fixtures')
7
7
 
8
8
  describe('tarpit', () => {
9
9
  let plugin
10
10
 
11
11
  beforeEach(() => {
12
- plugin = new fixtures.plugin('tarpit')
12
+ plugin = makePlugin('tarpit', { register: false })
13
13
  plugin.config.get = () => ({ main: {} })
14
14
  })
15
15
 
@@ -40,8 +40,7 @@ describe('tarpit', () => {
40
40
  let conn
41
41
 
42
42
  beforeEach(() => {
43
- conn = fixtures.connection.createConnection()
44
- conn.init_transaction()
43
+ conn = makeConnection({ withTxn: true })
45
44
  })
46
45
 
47
46
  it('calls next immediately when no transaction', (t, done) => {
@@ -4,15 +4,13 @@ const assert = require('node:assert/strict')
4
4
  const path = require('node:path')
5
5
  const { describe, it, beforeEach } = require('node:test')
6
6
 
7
- const fixtures = require('haraka-test-fixtures')
8
- const Plugin = fixtures.plugin
7
+ const { makeConnection, makePlugin } = require('haraka-test-fixtures')
9
8
 
10
9
  const _set_up = () => {
11
- this.plugin = new Plugin('tls')
12
- this.connection = new fixtures.connection.createConnection()
10
+ this.plugin = makePlugin('tls', { register: false, configDir: 'test' })
11
+ this.connection = makeConnection()
13
12
 
14
13
  // use test/config instead of ./config
15
- this.plugin.config = this.plugin.config.module_config(path.resolve('test'))
16
14
  this.plugin.net_utils.config = this.plugin.net_utils.config.module_config(path.resolve('test'))
17
15
 
18
16
  this.plugin.tls_opts = {}
@@ -1,21 +1,198 @@
1
1
  'use strict'
2
2
 
3
3
  const assert = require('node:assert/strict')
4
- const { describe, it } = require('node:test')
4
+ const { beforeEach, describe, it } = require('node:test')
5
5
 
6
- const fixtures = require('haraka-test-fixtures')
6
+ const { makeConnection, makePlugin } = require('haraka-test-fixtures')
7
+ require('haraka-constants').import(global)
7
8
 
8
9
  describe('toobusy', () => {
10
+ let plugin
11
+
12
+ beforeEach(() => {
13
+ plugin = makePlugin('toobusy', { register: false })
14
+ })
15
+
9
16
  describe('register', () => {
10
- it('handles missing toobusy-js gracefully (does not throw)', () => {
11
- const plugin = new fixtures.plugin('toobusy')
12
- // toobusy-js is not installed; register should catch the error and return
13
- let registered = false
14
- plugin.register_hook = () => {
15
- registered = true
17
+ it('registers connect hook with correct priority', () => {
18
+ const hooks = []
19
+ plugin.register_hook = function (hook, name, priority) {
20
+ hooks.push({ hook, name, priority })
16
21
  }
22
+
23
+ plugin.register()
24
+
25
+ assert.equal(hooks.length, 1, 'should register one hook')
26
+ assert.equal(hooks[0].hook, 'connect')
27
+ assert.equal(hooks[0].name, 'check_busy')
28
+ assert.equal(hooks[0].priority, -100)
29
+ })
30
+
31
+ it('loads config on register', () => {
32
+ let loadConfigCalled = false
33
+ const originalLoadConfig = plugin.loadConfig
34
+ plugin.loadConfig = function () {
35
+ loadConfigCalled = true
36
+ return originalLoadConfig.call(this)
37
+ }
38
+
39
+ plugin.register()
40
+
41
+ assert.equal(loadConfigCalled, true, 'loadConfig should be called')
42
+ })
43
+
44
+ it('handles missing toobusy-js gracefully', () => {
17
45
  assert.doesNotThrow(() => plugin.register())
18
- assert.equal(registered, false, 'hook should not be registered without toobusy-js')
46
+ })
47
+ })
48
+
49
+ describe('loadConfig', () => {
50
+ beforeEach(() => {
51
+ plugin.register()
52
+ })
53
+
54
+ it('gets toobusy.maxlag config value', () => {
55
+ let configArgs = []
56
+
57
+ plugin.config.get = function (key, type, callback) {
58
+ configArgs = [key, type]
59
+ return '70'
60
+ }
61
+
62
+ plugin.loadConfig()
63
+
64
+ assert.equal(configArgs[0], 'toobusy.maxlag')
65
+ assert.equal(configArgs[1], 'value')
66
+ })
67
+
68
+ it('passes callback to config.get for hot reload', () => {
69
+ let callbackProvided = false
70
+
71
+ plugin.config.get = function (key, type, callback) {
72
+ callbackProvided = typeof callback === 'function'
73
+ return '70'
74
+ }
75
+
76
+ plugin.loadConfig()
77
+
78
+ assert.equal(callbackProvided, true, 'callback should be provided for hot reload')
79
+ })
80
+
81
+ it('handles zero maxLag value', () => {
82
+ plugin.config.get = () => '0'
83
+
84
+ assert.doesNotThrow(() => {
85
+ plugin.loadConfig()
86
+ })
87
+ })
88
+
89
+ it('handles non-numeric maxLag value', () => {
90
+ plugin.config.get = () => 'notanumber'
91
+
92
+ assert.doesNotThrow(() => {
93
+ plugin.loadConfig()
94
+ })
95
+ })
96
+
97
+ it('handles empty string maxLag value', () => {
98
+ plugin.config.get = () => ''
99
+
100
+ assert.doesNotThrow(() => {
101
+ plugin.loadConfig()
102
+ })
103
+ })
104
+
105
+ it('parses numeric maxLag as integer', () => {
106
+ plugin.config.get = () => '100'
107
+
108
+ assert.doesNotThrow(() => {
109
+ plugin.loadConfig()
110
+ })
111
+ })
112
+
113
+ it('supports reload via callback', () => {
114
+ let callbackFn = null
115
+
116
+ plugin.config.get = function (key, type, callback) {
117
+ callbackFn = callback
118
+ return '70'
119
+ }
120
+
121
+ plugin.loadConfig()
122
+
123
+ assert.equal(typeof callbackFn, 'function', 'callback should be provided')
124
+ assert.doesNotThrow(() => {
125
+ if (callbackFn) callbackFn()
126
+ })
127
+ })
128
+ })
129
+
130
+ describe('check_busy', () => {
131
+ beforeEach(() => {
132
+ plugin.register()
133
+ })
134
+
135
+ it('calls next without args when not busy', (t, done) => {
136
+ plugin.config.get = () => '70'
137
+ plugin.loadConfig()
138
+
139
+ plugin.check_busy(function (...args) {
140
+ assert.equal(args.length, 0, 'should call next with no arguments')
141
+ done()
142
+ })
143
+ })
144
+
145
+ it('initializes was_busy state', (t, done) => {
146
+ plugin.config.get = () => '70'
147
+ plugin.loadConfig()
148
+
149
+ plugin.check_busy(function () {
150
+ done()
151
+ })
152
+ })
153
+
154
+ it('is a callable function', () => {
155
+ assert.equal(typeof plugin.check_busy, 'function')
156
+ })
157
+
158
+ it('does not log when not busy', (t, done) => {
159
+ plugin.config.get = () => '70'
160
+ plugin.loadConfig()
161
+
162
+ let logCount = 0
163
+ plugin.logcrit = function () {
164
+ logCount++
165
+ }
166
+
167
+ plugin.check_busy(function () {
168
+ plugin.check_busy(function () {
169
+ assert.equal(logCount, 0, 'should not log when not busy')
170
+ done()
171
+ })
172
+ })
173
+ })
174
+
175
+ it('accepts next callback', (t, done) => {
176
+ plugin.config.get = () => '70'
177
+ plugin.loadConfig()
178
+
179
+ const nextFn = function () {
180
+ done()
181
+ }
182
+
183
+ assert.doesNotThrow(() => {
184
+ plugin.check_busy(nextFn)
185
+ })
186
+ })
187
+
188
+ it('works with connection context', (t, done) => {
189
+ plugin.config.get = () => '70'
190
+ plugin.loadConfig()
191
+
192
+ const conn = makeConnection()
193
+ plugin.check_busy.call(conn, function () {
194
+ done()
195
+ })
19
196
  })
20
197
  })
21
198
  })
@@ -3,11 +3,11 @@
3
3
  const assert = require('node:assert/strict')
4
4
  const { describe, it, beforeEach } = require('node:test')
5
5
 
6
- const fixtures = require('haraka-test-fixtures')
6
+ const { makeConnection, makePlugin } = require('haraka-test-fixtures')
7
7
 
8
8
  const _set_up = () => {
9
- this.plugin = new fixtures.plugin('xclient')
10
- this.connection = fixtures.connection.createConnection()
9
+ this.plugin = makePlugin('xclient', { register: false })
10
+ this.connection = makeConnection()
11
11
  this.connection.capabilities = []
12
12
  }
13
13
 
@@ -45,7 +45,10 @@ describe('xclient', () => {
45
45
  },
46
46
  {
47
47
  desc: 'denies XCLIENT when transaction is in progress',
48
- setup: () => this.connection.init_transaction(),
48
+ setup: () => {
49
+ this.connection = makeConnection({ withTxn: true })
50
+ this.connection.capabilities = []
51
+ },
49
52
  params: ['XCLIENT', 'ADDR=127.0.0.1'],
50
53
  check: (code) => assert.equal(code, DENY),
51
54
  },