diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 3e360d0d..90b77b8c 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -20,10 +20,12 @@ jobs: services: openldap: - image: ghcr.io/ldapjs/docker-test-openldap/openldap:latest + image: ghcr.io/ldapjs/docker-test-openldap/openldap:2023-03-18 ports: - 389:389 - 636:636 + options: > + --health-cmd "ldapsearch -Y EXTERNAL -Q -H ldapi:// -b ou=people,dc=planetexpress,dc=com -LLL '(cn=Turanga Leela)' cn" steps: - uses: actions/checkout@v3 diff --git a/docker-compose.yml b/docker-compose.yml index f11187d2..056d3388 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,10 @@ -version: '3' - services: openldap: - image: ghcr.io/ldapjs/docker-test-openldap/openldap:latest + image: ghcr.io/ldapjs/docker-test-openldap/openldap:2023-03-18 ports: - 389:389 - 636:636 + healthcheck: + start_period: 3s + test: > + /usr/bin/ldapsearch -Y EXTERNAL -Q -H ldapi:// -b ou=people,dc=planetexpress,dc=com -LLL '(cn=Turanga Leela)' cn 1>/dev/null diff --git a/package.json b/package.json index 7309b876..60c8cc98 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "test:cov:html": "tap --coverage-report=html -R terse", "test:watch": "tap -n -w --no-coverage-report -R terse", "test:integration": "tap --no-cov -R terse 'test-integration/**/*.test.js'", - "test:integration:local": "docker-compose up -d && npm run test:integration && docker-compose down", + "test:integration:local": "docker-compose up -d --wait && npm run test:integration ; docker-compose down", "lint": "eslint . --fix", "lint:ci": "eslint .", "docs": "node scripts/build-docs.js" diff --git a/test-integration/client/issue-923.test.js b/test-integration/client/issue-923.test.js new file mode 100644 index 00000000..7dde9ece --- /dev/null +++ b/test-integration/client/issue-923.test.js @@ -0,0 +1,91 @@ +'use strict' + +const tap = require('tap') +const ldapjs = require('../../lib') +const { DN } = require('@ldapjs/dn') +const Change = require('@ldapjs/change') + +const SCHEME = process.env.SCHEME || 'ldap' +const HOST = process.env.HOST || '127.0.0.1' +const PORT = process.env.PORT || 389 +const baseURL = `${SCHEME}://${HOST}:${PORT}` + +const client = ldapjs.createClient({ url: baseURL }) + +tap.teardown(() => { + client.unbind() +}) + +tap.test('modifies entry specified by dn string', t => { + t.plan(4) + + client.bind('cn=admin,dc=planetexpress,dc=com', 'GoodNewsEveryone', (err) => { + t.error(err, 'bind error') + }) + + const dn = 'cn=large10,ou=large_ou,dc=planetexpress,dc=com' + const change = new Change({ + operation: 'replace', + modification: { + type: 'givenName', + values: ['test'] + } + }) + + client.modify(dn, change, (err) => { + t.error(err, 'modify error') + validateChange({ t, expected: 'test', client }) + }) +}) + +tap.test('modifies entry specified by dn object', t => { + t.plan(4) + + client.bind('cn=admin,dc=planetexpress,dc=com', 'GoodNewsEveryone', (err) => { + t.error(err, 'bind error') + }) + + const dn = DN.fromString('cn=large10,ou=large_ou,dc=planetexpress,dc=com') + const change = new Change({ + operation: 'replace', + modification: { + type: 'givenName', + values: ['test2'] + } + }) + + client.modify(dn, change, (err) => { + t.error(err, 'modify error') + validateChange({ t, expected: 'test2', client }) + }) +}) + +function validateChange ({ t, expected, client }) { + const searchBase = 'ou=large_ou,dc=planetexpress,dc=com' + const searchOpts = { + filter: '(cn=large10)', + scope: 'subtree', + attributes: ['givenName'], + sizeLimit: 10, + timeLimit: 0 + } + + client.search(searchBase, searchOpts, (err, res) => { + t.error(err, 'search error') + + res.on('searchEntry', entry => { + t.equal( + entry.attributes.filter(a => a.type === 'givenName').pop().values.pop(), + expected + ) + }) + + res.on('error', err => { + t.error(err, 'search entry error') + }) + + res.on('end', () => { + t.end() + }) + }) +}