php-eesyldap/tests/LdapTest.php

1294 lines
38 KiB
PHP

<?php
declare(strict_types=1);
use \Mockery\Adapter\Phpunit\MockeryTestCase;
use PHPUnit\Extension\FunctionMocker;
use EesyLDAP\Entry;
use EesyLDAP\Ldap;
use EesyLDAP\LdapException;
use EesyLDAP\Link;
use EesyLDAP\Filter;
/**
* @covers \EesyLDAP\Ldap
*/
final class LdapTest extends MockeryTestCase {
/**
* @var FunctionMocker
*/
protected $func;
public function setUp(): void {
$this->func = FunctionMocker::start($this, 'EesyLDAP')
->mockFunction('extension_loaded')
->getMock();
}
/**
* Set config with invalid config data
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigInvalid() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
// @phpstan-ignore-next-line
$ldap->set_config(false);
}
/**
* Set config with invalid parameter
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigInvalidParameter() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->set_config(array('fake' => 'value'));
}
/**
* Set config
* @covers \EesyLDAP\Ldap::set_config
* @covers \EesyLDAP\Filter
*/
public function testSetConfig() {
$ldap = new Ldap(null, false);
$config = array(
'hosts' => array('ldap.example.com'),
'port' => 666,
'version' => 2,
'starttls' => true,
'bind_dn' => 'cn=admin,o=example',
'bind_password' => 'secret',
'basedn' => 'o=example',
'options' => array('LDAP_OPT_NETWORK_TIMEOUT' => 30),
'filter' => Filter::parse('(objectClass=person)'),
'scope' => 'one',
'raise_on_error' => false,
'use_schema' => true,
);
$ldap->set_config($config);
foreach($config as $key => $expected_value)
$this->assertSame($expected_value, $ldap->get_config($key));
}
/**
* Set config using aliases
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigWithAlias() {
$ldap = new Ldap(null, false);
$config = array(
'host' => array('ldap.example.com'),
'binddn' => 'cn=admin,o=example',
'bindpw' => 'secret',
);
$ldap->set_config($config);
foreach($config as $key => $expected_value)
$this->assertSame($expected_value, $ldap->get_config($key));
}
/**
* Set config hosts as string
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigHostsString() {
$ldap = new Ldap(null, false);
$hosts = array('host1', 'host2');
$ldap->set_config(array('hosts' => implode(',', $hosts)));
$this->assertSame($hosts, $ldap->get_config('hosts'));
}
/**
* Set config hosts as array
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigHostsArray() {
$ldap = new Ldap(null, false);
$hosts = array('host1', 'host2');
$ldap->set_config(array('hosts' => $hosts));
$this->assertSame($hosts, $ldap->get_config('hosts'));
}
/**
* Set config empty host
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigEmptyHost() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->set_config(array('hosts' => 'host1,'));
}
/**
* Set config invalid hosts
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigInvalidHosts() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->set_config(array('hosts' => null));
}
/**
* Set config port
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigPort() {
$ldap = new Ldap(null, false);
$port = 666;
$ldap->set_config(array('port' => $port));
$this->assertSame($port, $ldap->get_config('port'));
}
/**
* Set config version
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigVersion() {
$ldap = new Ldap(null, false);
$version = 2;
$ldap->set_config(array('version' => $version));
$this->assertSame($version, $ldap->get_config('version'));
}
/**
* Set config starttls
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigStartTLS() {
$ldap = new Ldap(null, false);
$starttls = true;
$ldap->set_config(array('starttls' => $starttls));
$this->assertSame($starttls, $ldap->get_config('starttls'));
}
/**
* Set config options
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigOptions() {
$ldap = new Ldap(null, false);
$options = array('LDAP_OPT_NETWORK_TIMEOUT' => 30);
$ldap->set_config(array('options' => $options));
$this->assertSame($options, $ldap->get_config('options'));
}
/**
* Set config options with invalid value
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigOptionsInvalid() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->set_config(array('options' => null));
}
/**
* Set config required options
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigRequiredOptions() {
$ldap = new Ldap(null, false);
$required_options = array('LDAP_OPT_NETWORK_TIMEOUT');
$ldap->set_config(array('required_options' => $required_options));
$this->assertSame($required_options, $ldap->get_config('required_options'));
}
/**
* Set config required options as true
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigRequiredOptionsTrue() {
$ldap = new Ldap(null, false);
$options = array('LDAP_OPT_NETWORK_TIMEOUT' => 30);
$ldap->set_config(array('options' => $options));
$ldap->set_config(array('required_options' => true));
$this->assertSame(array_keys($options), $ldap->get_config('required_options'));
}
/**
* Set config required options as false
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigRequiredOptionsFalse() {
$ldap = new Ldap(null, false);
$options = array('LDAP_OPT_NETWORK_TIMEOUT' => 30);
$ldap->set_config(array('options' => $options));
$ldap->set_config(array('required_options' => false));
$this->assertSame(array(), $ldap->get_config('required_options'));
}
/**
* Set config required options with invalid value
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigRequiredOptionsInvalid() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->set_config(array('required_options' => null));
}
/**
* Set config filter as string
* @covers \EesyLDAP\Ldap::set_config
* @covers \EesyLDAP\Filter
*/
public function testSetConfigFilterString() {
$ldap = new Ldap(null, false);
$filter = '(uid=test)';
$ldap->set_config(array('filter' => $filter));
$this->assertEquals(Filter::parse($filter), $ldap->get_config('filter'));
}
/**
* Set config filter as object
* @covers \EesyLDAP\Ldap::set_config
* @covers \EesyLDAP\Filter
*/
public function testSetConfigFilterObject() {
$ldap = new Ldap(null, false);
$filter = Filter::parse('(uid=test)');
$ldap->set_config(array('filter' => $filter));
$this->assertSame($filter, $ldap->get_config('filter'));
}
/**
* Set config filter with invalid value
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigFilterInvalid() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->set_config(array('filter' => null));
}
/**
* Set config scope
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigScope() {
$ldap = new Ldap(null, false);
$scopes = array('one', 'base', 'sub');
foreach ($scopes as $scope) {
$ldap->set_config(array('scope' => $scope));
$this->assertSame($scope, $ldap->get_config('scope'));
}
}
/**
* Set config scope with invalid value
* @covers \EesyLDAP\Ldap::set_config
*/
public function testSetConfigScopeInvalid() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->set_config(array('scope' => 'fake'));
}
/**
* @covers \EesyLDAP\Ldap::connect
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testConnect() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'starttls' => true, 'version' => 2,
'bind_dn' => 'cn=admin', 'bind_password' => 'secret'
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(true);
$link->shouldReceive('bind')
->once()
->with($config['bind_dn'], $config['bind_password'])
->andReturn(true);
$link->shouldReceive('start_tls')
->once()
->with()
->andReturn(true);
$ldap = new Ldap($config);
}
/**
* @covers \EesyLDAP\Ldap::connect
*/
public function testConnectWhenAlreadyConnected() {
$ldap = new Ldap(null, false);
$reflection = new ReflectionClass($ldap);
$link_property = $reflection->getProperty('_link');
$link_property->setAccessible(true);
$link_property->setValue($ldap, true);
$this -> assertTrue($ldap->connect());
}
/**
* @covers \EesyLDAP\Ldap::connect
*/
public function testConnectNoLdapExtension() {
$ldap = $this->getMockBuilder(Ldap::class)
->disableOriginalConstructor()
->onlyMethods(['check_ldap_extension'])
->getMock();
$ldap->expects($this->once())
->method('check_ldap_extension')
->willReturn(false);
$this -> assertFalse($ldap->connect());
}
/**
* @covers \EesyLDAP\Ldap::connect
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testConnectFailure() {
$config = array(
'host' => 'ldap1', 'port' => 389,
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(false);
$this->expectException(LdapException::class);
$ldap = new Ldap($config);
Mockery::close();
}
/**
* @covers \EesyLDAP\Ldap::connect
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testConnectStartTLSFailure() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'starttls' => true,
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('start_tls')
->once()
->with()
->andReturn(false);
$link->shouldReceive('close')
->once()
->with();
$this->expectException(LdapException::class);
$ldap = new Ldap($config);
Mockery::close();
}
/**
* @covers \EesyLDAP\Ldap::connect
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testConnectSetVersionFailure() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'version' => 2,
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(false);
$link->shouldReceive('errno')
->once()
->with()
->andReturn(10);
$link->shouldReceive('err2str')
->once()
->with(10)
->andReturn('oups');
$link->shouldReceive('close')
->once()
->with();
$this->expectException(LdapException::class);
$ldap = new Ldap($config);
Mockery::close();
}
/**
* @covers \EesyLDAP\Ldap::connect
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testConnectBindFailure() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'version' => 2,
'bind_dn' => 'cn=admin', 'bind_password' => 'secret'
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(true);
$link->shouldReceive('bind')
->once()
->with($config['bind_dn'], $config['bind_password'])
->andReturn(false);
$link->shouldReceive('errno')
->once()
->with()
->andReturn(false);
$link->shouldReceive('close')
->with();
$this->expectException(LdapException::class);
$ldap = new Ldap($config);
Mockery::close();
}
/**
* @covers \EesyLDAP\Ldap::connect
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testConnectRequiredOptionFailure() {
$option_name = 'LDAP_OPT_NETWORK_TIMEOUT';
$option_value = 30;
$config = array(
'host' => 'ldap1', 'port' => 389, 'version' => 2,
'bind_dn' => 'cn=admin', 'bind_password' => 'secret',
'options' => array($option_name => $option_value),
'required_options' => array($option_name)
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(true);
$link->shouldReceive('bind')
->once()
->with($config['bind_dn'], $config['bind_password'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(constant($option_name), $option_value)
->andReturn(false);
$link->shouldReceive('errno')
->once()
->with()
->andReturn(false);
$link->shouldReceive('close')
->with();
$this->expectException(LdapException::class);
$ldap = new Ldap($config);
Mockery::close();
}
/**
* @covers \EesyLDAP\Ldap::set_option
*/
public function testSetOptionNoLink() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->set_option('LDAP_OPT_NETWORK_TIMEOUT', 30);
}
/**
* @covers \EesyLDAP\Ldap::set_option
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testSetOptionInvalid() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'version' => 2,
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(true);
$link->shouldReceive('bind')
->once()
->andReturn(true);
$ldap = new Ldap($config);
$this->expectException(LdapException::class);
$ldap->set_option('LDAP_FAKE_OPT', 30);
Mockery::close();
}
/**
* @covers \EesyLDAP\Ldap::__get
*/
public function testGetConfigAliases() {
$ldap = new Ldap(null, false);
$this->assertIsArray($ldap->config_aliases);
}
/**
* @covers \EesyLDAP\Ldap::__get
*/
public function testGetDefaultConfig() {
$ldap = new Ldap(null, false);
$this->assertIsArray($ldap->default_config);
}
/**
* @covers \EesyLDAP\Ldap::__get
*/
public function testGetSchemaWhenDisable() {
$ldap = new Ldap(array('use_schema' => false), false);
$this->assertFalse($ldap->schema);
}
/**
* @covers \EesyLDAP\Ldap::__get
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testGetSchema() {
$ldap = new Ldap(array('use_schema' => true), false);
$schema = Mockery::mock('overload:EesyLDAP\Schema');
$schema->shouldReceive('load')
->once()
->with($ldap)
->andSet('loaded', true)
->andReturn($schema);
$this->assertSame($schema, $ldap->__get('schema'));
Mockery::close();
}
/**
* @covers \EesyLDAP\Ldap::__get
*/
public function testGetInvalidProperty() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->__get('invalid');
}
/**
* @covers \EesyLDAP\Ldap::get_config
*/
public function testGetConfigInvalid() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->get_config('invalid');
}
/**
* @covers \EesyLDAP\Ldap::get_config
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testGetConfigFilterFromString() {
$ldap = new Ldap(null, false);
$filter = Mockery::mock('overload:EesyLDAP\Filter');
$filter->shouldReceive('parse')
->once()
->with($ldap->default_config['filter'])
->andReturn('success');
$this->assertEquals('success', $ldap->get_config('filter'));
}
/**
* @covers \EesyLDAP\Ldap::get_config
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testSearchWithoutParameter() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'version' => 2,
'bind_dn' => 'cn=admin', 'bind_password' => 'secret',
'basedn' => 'o=example', 'filter' => '(objectClass=*)'
);
$result_ref = 'success';
$raw_result = [
'count' => 1,
0 => [
'objectclass' => [
'count' => 2,
0 => 'top',
1 => 'inetOrgPerson',
],
0 => 'objectclass',
'cn' => [
'count' => 1,
0 => 'test',
],
1 => 'cn',
'count' => 2,
'dn' => 'cn=test',
],
];
$expected_result = array(
'cn=test' => array(
'objectclass' => array('top', 'inetOrgPerson'),
'cn' => array('test'),
),
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(true);
$link->shouldReceive('bind')
->once()
->with($config['bind_dn'], $config['bind_password'])
->andReturn(true);
$link->shouldReceive('search')
->once()
->with($config['basedn'], $config['filter'], null, 0, 0, 0)
->andReturn($result_ref);
$link->shouldReceive('get_entries')
->once()
->with($result_ref)
->andReturn($raw_result);
$ldap = new Ldap($config);
$result = $ldap->search();
$this->assertIsArray($result);
$this->assertCount(count($expected_result), $result);
$this->assertContainsOnlyInstancesOf(Entry::class, $result);
$dn = key($result);
$this->assertEquals(key($expected_result), $dn);
foreach($expected_result[$dn] as $attr => $values)
$this->assertEquals($values, $result[$dn]->get_raw_values($attr));
Mockery::close();
}
/**
* @covers \EesyLDAP\Ldap::get_config
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testSearchWithParameters() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'version' => 2,
'bind_dn' => 'cn=admin', 'bind_password' => 'secret'
);
$filter = '(cn=test)';
$base = 'o=example';
$scope = 'one';
$attributes = ['cn', 'objectclass'];
$params = [
'attrsonly' => 1,
'sizelimit' => 10,
'timelimit' => 60,
];
$result_ref = 'success';
$raw_result = [
'count' => 1,
0 => [
'objectclass' => [
'count' => 2,
0 => 'top',
1 => 'inetOrgPerson',
],
0 => 'objectclass',
'cn' => [
'count' => 1,
0 => 'test',
],
1 => 'cn',
'count' => 2,
'dn' => 'cn=test',
],
];
$expected_result = array(
'cn=test' => array(
'objectclass' => array('top', 'inetOrgPerson'),
'cn' => array('test'),
),
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(true);
$link->shouldReceive('bind')
->once()
->with($config['bind_dn'], $config['bind_password'])
->andReturn(true);
$link->shouldReceive('list')
->once()
->with(
$base, $filter, $attributes, $params['attrsonly'], $params['sizelimit'],
$params['timelimit'])
->andReturn($result_ref);
$link->shouldReceive('get_entries')
->once()
->with($result_ref)
->andReturn($raw_result);
$ldap = new Ldap($config);
$result = $ldap->search($filter, $base, $scope, $attributes, $params);
$this->assertIsArray($result);
$this->assertCount(count($expected_result), $result);
$this->assertContainsOnlyInstancesOf(Entry::class, $result);
$dn = key($result);
$this->assertEquals(key($expected_result), $dn);
foreach($expected_result[$dn] as $attr => $values)
$this->assertEquals($values, $result[$dn]->get_raw_values($attr));
Mockery::close();
}
/**
* @covers \EesyLDAP\Ldap::get_config
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testSearchWithEntryAsBaseDN() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'version' => 2,
'bind_dn' => 'cn=admin', 'bind_password' => 'secret'
);
$filter = '(cn=test)';
$dn = 'cn=test';
$base = new Entry($dn);
$scope = 'sub';
$result_ref = 'success';
$raw_result = [
'count' => 1,
0 => [
'objectclass' => [
'count' => 2,
0 => 'top',
1 => 'inetOrgPerson',
],
0 => 'objectclass',
'cn' => [
'count' => 1,
0 => 'test',
],
1 => 'cn',
'count' => 2,
'dn' => 'cn=test',
],
];
$expected_result = array(
'cn=test' => array(
'objectclass' => array('top', 'inetOrgPerson'),
'cn' => array('test'),
),
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(true);
$link->shouldReceive('bind')
->once()
->with($config['bind_dn'], $config['bind_password'])
->andReturn(true);
$link->shouldReceive('search')
->once()
->with($dn, $filter, array(), 0, 0, 0)
->andReturn($result_ref);
$link->shouldReceive('get_entries')
->once()
->with($result_ref)
->andReturn($raw_result);
$ldap = new Ldap($config);
$result = $ldap->search($filter, $base, $scope);
$this->assertIsArray($result);
$this->assertCount(count($expected_result), $result);
$this->assertContainsOnlyInstancesOf(Entry::class, $result);
Mockery::close();
}
/**
* @covers \EesyLDAP\Ldap::search
*/
public function testSearchNoLink() {
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->search();
}
/**
* @covers \EesyLDAP\Ldap::search
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testSearchInvalidScope() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'version' => 2,
'bind_dn' => 'cn=admin', 'bind_password' => 'secret'
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(true);
$link->shouldReceive('bind')
->once()
->with($config['bind_dn'], $config['bind_password'])
->andReturn(true);
$ldap = new Ldap($config);
$this->expectException(LdapException::class);
$ldap->search('cn=test', null, 'bad_scope');
}
/**
* @covers \EesyLDAP\Ldap::search
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testSearchInvalidAttributes() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'version' => 2,
'bind_dn' => 'cn=admin', 'bind_password' => 'secret'
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(true);
$link->shouldReceive('bind')
->once()
->with($config['bind_dn'], $config['bind_password'])
->andReturn(true);
$ldap = new Ldap($config);
$this->expectException(LdapException::class);
// @phpstan-ignore-next-line
$ldap->search('cn=test', null, null, true);
}
/**
* @covers \EesyLDAP\Ldap::search
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testSearchBadResult() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'version' => 2,
'bind_dn' => 'cn=admin', 'bind_password' => 'secret'
);
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(true);
$link->shouldReceive('bind')
->once()
->with($config['bind_dn'], $config['bind_password'])
->andReturn(true);
$link->shouldReceive('search')
->once()
->andReturn(false);
$link->shouldReceive('errno')
->once()
->with()
->andReturn(false);
$ldap = new Ldap($config);
$this->expectException(LdapException::class);
$ldap->search();
}
/**
* @covers \EesyLDAP\Ldap::search
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testSearchBadEntries() {
$config = array(
'host' => 'ldap1', 'port' => 389, 'version' => 2,
'bind_dn' => 'cn=admin', 'bind_password' => 'secret'
);
$result = 'success';
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$link = Mockery::mock('overload:EesyLDAP\Link');
$link->shouldReceive('connect')
->once()
->with($config['host'], $config['port'])
->andReturn(true);
$link->shouldReceive('set_option')
->once()
->with(LDAP_OPT_PROTOCOL_VERSION, $config['version'])
->andReturn(true);
$link->shouldReceive('bind')
->once()
->with($config['bind_dn'], $config['bind_password'])
->andReturn(true);
$link->shouldReceive('search')
->once()
->andReturn($result);
$link->shouldReceive('get_entries')
->once()
->with($result)
->andReturn(false);
$link->shouldReceive('errno')
->once()
->with()
->andReturn(false);
$ldap = new Ldap($config);
$this->expectException(LdapException::class);
$ldap->search();
}
/**
* @covers \EesyLDAP\Ldap::get_entry
* @covers \EesyLDAP\Entry::__construct
*/
public function testGetEntry() {
$dn = 'cn=test';
$filter = '(cn=test)';
$attributes = array('cn');
$params = array('attrsonly' => 1);
$raise = true;
$expected_entry = new Entry();
$expected_result = array('cn=test' => $expected_entry);
$ldap = $this->getMockBuilder(Ldap::class)
->disableOriginalConstructor()
->onlyMethods(['search'])
->getMock();
$ldap->expects($this->once())
->method('search')
->with($filter, $dn, 'base', $attributes, $params, $raise)
->willReturn($expected_result);
$entry = $ldap->get_entry($dn, $filter, $attributes, $params, $raise);
$this->assertInstanceOf(Entry::class, $entry);
$this->assertSame($expected_entry, $entry);
}
/**
* @covers \EesyLDAP\Ldap::get_entry
*/
public function testGetEntryInvalid() {
$ldap = $this->getMockBuilder(Ldap::class)
->disableOriginalConstructor()
->onlyMethods(['search'])
->getMock();
$ldap->expects($this->once())
->method('search')
->willReturn(false);
$this->assertFalse($ldap->get_entry('o=example'));
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testGetParam() {
$params = ['test' => 'test'];
$ldap = new Ldap(null, false);
$this->assertEquals(
'test',
self :: callProtectedMethod($ldap, 'get_param', array($params, 'test'))
);
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testGetParamDefault() {
$params = [];
$ldap = new Ldap(null, false);
$this->assertEquals(
'default',
self :: callProtectedMethod($ldap, 'get_param', array($params, 'test', 'default'))
);
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testGetParamBool() {
$params = ['test' => 1];
$ldap = new Ldap(null, false);
$this->assertTrue(
self :: callProtectedMethod($ldap, 'get_param', array($params, 'test', null, 'bool'))
);
$this->assertTrue(
self :: callProtectedMethod($ldap, 'get_param', array($params, 'test', null, 'boolean'))
);
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testGetParamInt() {
$params = ['test' => '10'];
$ldap = new Ldap(null, false);
$value = self :: callProtectedMethod($ldap, 'get_param', array($params, 'test', null, 'int'));
$this->assertIsInt($value);
$this->assertEquals(10, $value);
$value = self :: callProtectedMethod($ldap, 'get_param', array($params, 'test', null, 'integer'));
$this->assertIsInt($value);
$this->assertEquals(10, $value);
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testGetParamFloat() {
$params = ['test' => '10.5'];
$ldap = new Ldap(null, false);
$value = self :: callProtectedMethod($ldap, 'get_param', array($params, 'test', null, 'float'));
$this->assertIsFloat($value);
$this->assertEquals(10.5, $value);
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testGetParamString() {
$params = ['test' => '10.5'];
$ldap = new Ldap(null, false);
$value = self :: callProtectedMethod($ldap, 'get_param', array($params, 'test', null, 'str'));
$this->assertIsString($value);
$this->assertEquals('10.5', $value);
$value = self :: callProtectedMethod($ldap, 'get_param', array($params, 'test', null, 'string'));
$this->assertIsString($value);
$this->assertEquals('10.5', $value);
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testGetParamArray() {
$params = ['test' => array('10.5')];
$ldap = new Ldap(null, false);
$value = self :: callProtectedMethod($ldap, 'get_param', array($params, 'test', null, 'array'));
$this->assertIsArray($value);
$this->assertEquals(array('10.5'), $value);
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testGetParamCastedArray() {
$params = ['test' => '10.5'];
$ldap = new Ldap(null, false);
$value = self :: callProtectedMethod($ldap, 'get_param', array($params, 'test', null, 'array'));
$this->assertIsArray($value);
$this->assertEquals(array('10.5'), $value);
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testGetParamEmptyArray() {
$params = ['test' => null];
$ldap = new Ldap(null, false);
$value = self :: callProtectedMethod($ldap, 'get_param', array($params, 'test', null, 'array'));
$this->assertIsArray($value);
$this->assertEquals(array(), $value);
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testLogError() {
$prefix = 'Error %s occured';
$prefix_var = 'test';
$ldap = $this->getMockBuilder(Ldap::class)
->disableOriginalConstructor()
->onlyMethods(['error'])
->getMock();
$ldap->expects($this->once())
->method('error')
->with("%s: unkown error", true, "Error test occured")
->willReturn(false);
self :: callProtectedMethod($ldap, 'log_error', array($prefix, true, $prefix_var));
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testLogErrorWithLink() {
$prefix = 'Error %s occured';
$prefix_var = 'test';
$link = $this->getMockBuilder(Link::class)
->disableOriginalConstructor()
->onlyMethods(['errno', 'err2str'])
->getMock();
$link->expects($this->once())
->method('errno')
->willReturn(10);
$link->expects($this->once())
->method('err2str')
->with(10)
->willReturn('error');
$ldap = $this->getMockBuilder(Ldap::class)
->disableOriginalConstructor()
->onlyMethods(['error'])
->getMock();
$reflection = new ReflectionClass($ldap);
$link_property = $reflection->getProperty('_link');
$link_property->setAccessible(true);
$link_property->setValue($ldap, $link);
$ldap->expects($this->once())
->method('error')
->with("%s: %s (#%s)", true, "Error test occured", 'error', 10)
->willReturn(false);
self :: callProtectedMethod($ldap, 'log_error', array($prefix, true, $prefix_var));
}
/**
* @covers \EesyLDAP\Ldap::get_param
*/
public function testLogErrorUnknown() {
$prefix = 'Error %s occured';
$prefix_var = 'test';
$link = $this->getMockBuilder(Link::class)
->disableOriginalConstructor()
->onlyMethods(['errno', 'err2str'])
->getMock();
$link->expects($this->once())
->method('errno')
->willReturn(10);
$link->expects($this->once())
->method('err2str')
->with(10)
->willReturn(false);
$ldap = $this->getMockBuilder(Ldap::class)
->disableOriginalConstructor()
->onlyMethods(['error'])
->getMock();
$reflection = new ReflectionClass($ldap);
$link_property = $reflection->getProperty('_link');
$link_property->setAccessible(true);
$link_property->setValue($ldap, $link);
$ldap->expects($this->once())
->method('error')
->with('%s: error #%s', true, 'Error test occured', 10)
->willReturn(false);
self :: callProtectedMethod($ldap, 'log_error', array($prefix, true, $prefix_var));
}
/**
* @covers \EesyLDAP\Ldap::check_ldap_extension
*/
public function testCheckLdapExtension() {
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(true));
$ldap = new Ldap(null, false);
$this->assertTrue($ldap->check_ldap_extension());
}
/**
* @covers \EesyLDAP\Ldap::check_ldap_extension
*/
public function testCheckLdapExtensionNotInstalled() {
$this->func->expects($this->once())
->method('extension_loaded')
->with('ldap')
->will($this->returnValue(False));
$ldap = new Ldap(null, false);
$this->expectException(LdapException::class);
$ldap->check_ldap_extension();
}
/**
* Helper to call protected method
* @param object $obj
* @param string $name
* @param array<mixed> $args
* @return mixed
*/
public static function callProtectedMethod($obj, $name, $args) {
$class = new \ReflectionClass($obj);
$method = $class->getMethod($name);
$method->setAccessible(true);
return $method->invokeArgs($obj, $args);
}
}