935 lines
31 KiB
PHP
935 lines
31 KiB
PHP
|
<?php
|
||
|
declare(strict_types=1);
|
||
|
use PHPUnit\Framework\TestCase;
|
||
|
use EesyLDAP\Filter;
|
||
|
use EesyLDAP\Filter\FilterException;
|
||
|
use EesyLDAP\Filter\CombineException;
|
||
|
use EesyLDAP\Filter\ParserException;
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter
|
||
|
*/
|
||
|
final class FilterTest extends TestCase {
|
||
|
|
||
|
/**
|
||
|
* Constructor
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithAttrAndOpAndValue() {
|
||
|
$a = new Filter('attr', '=', 'value');
|
||
|
$this->assertEquals('attr', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('value', $a->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithAttrAndOpAliasAndValue() {
|
||
|
foreach(Filter :: operator_aliases() as $alias => $op) {
|
||
|
$a = new Filter('attr', $alias, 'value');
|
||
|
$this->assertEquals($op, $a->op);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithAttrAndSpecialOpAndValue() {
|
||
|
$a = new Filter('attr', 'begins', 'value');
|
||
|
$this->assertEquals('attr', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('value*', $a->pattern);
|
||
|
|
||
|
$a = new Filter('attr', 'contains', 'value');
|
||
|
$this->assertEquals('attr', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('*value*', $a->pattern);
|
||
|
|
||
|
$a = new Filter('attr', 'ends', 'value');
|
||
|
$this->assertEquals('attr', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('*value', $a->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithLogOpAndFilters() {
|
||
|
$ab = new Filter('a', '=', 'b');
|
||
|
$c2 = new Filter('c', '>=', '2');
|
||
|
$a = new Filter('&', $ab, $c2);
|
||
|
$this->assertEquals('&', $a->log_op);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertCount(2, $a->sub_filters);
|
||
|
$this->assertContains($ab, $a->sub_filters);
|
||
|
$this->assertContains($c2, $a->sub_filters);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithLogOpAliasAndFilters() {
|
||
|
foreach(Filter :: logical_operator_aliases() as $alias => $op) {
|
||
|
$a = new Filter($alias, new Filter('a', '=', 'b'));
|
||
|
$this->assertEquals($op, $a->log_op);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithLogOpAndArrayOfFilters() {
|
||
|
$ab = new Filter('a', '=', 'b');
|
||
|
$c2 = new Filter('c', '>=', '2');
|
||
|
$bd = new Filter('b', '=', 'd');
|
||
|
$a = new Filter('&', array($ab, $c2), $bd);
|
||
|
$this->assertEquals('&', $a->log_op);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertCount(3, $a->sub_filters);
|
||
|
$this->assertContains($ab, $a->sub_filters);
|
||
|
$this->assertContains($c2, $a->sub_filters);
|
||
|
$this->assertContains($bd, $a->sub_filters);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithLogOpAndArrayOfFilterStrings() {
|
||
|
$a = new Filter('&', array('a=b', '(c>=2)'), 'b~=test');
|
||
|
$this->assertEquals($a->as_string(), '(&(a=b)(c>=2)(b~=test))');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithLogOpAndMixedFilterTypes() {
|
||
|
$a = new Filter(
|
||
|
'|',
|
||
|
array(new Filter('a', '=', 'b'), 'c>=2'),
|
||
|
new Filter('b', '~=', 'test'),
|
||
|
'd=z'
|
||
|
);
|
||
|
$this->assertEquals($a->as_string(), '(|(a=b)(c>=2)(b~=test)(d=z))');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithNotOpAndFilter() {
|
||
|
$ab = new Filter('a', '=', 'b');
|
||
|
$a = new Filter('!', $ab);
|
||
|
$this->assertEquals('!', $a->log_op);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertCount(1, $a->sub_filters);
|
||
|
$this->assertContains($ab, $a->sub_filters);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithNotOpAndMoreThanOneFilter() {
|
||
|
$this->expectException(FilterException::class);
|
||
|
$a = new Filter('!', new Filter('a', '=', 'b'), new Filter('c', '>=', '2'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithPresentAnyOp() {
|
||
|
$a = new Filter('a', 'present');
|
||
|
$this->assertEquals('a', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('*', $a->pattern);
|
||
|
|
||
|
$a = new Filter('a', 'any');
|
||
|
$this->assertEquals('a', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('*', $a->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithEscapeArg() {
|
||
|
$a = new Filter('attr', '=', 'value*', true);
|
||
|
$this->assertEquals('attr', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('value\2a', $a->pattern);
|
||
|
|
||
|
$a = new Filter('attr', '=', 'value*', False);
|
||
|
$this->assertEquals('attr', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('value*', $a->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithoutArg() {
|
||
|
$this->expectException(FilterException::class);
|
||
|
$a = new Filter();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructCombineWithInvalidFilter() {
|
||
|
$this->expectException(FilterException::class);
|
||
|
// @phpstan-ignore-next-line
|
||
|
$a = new Filter('&', 'a=b', new FilterException('test'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithInvalidThreeArgs() {
|
||
|
$this->expectException(FilterException::class);
|
||
|
$a = new Filter('a', 'b', 'c');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__construct
|
||
|
*/
|
||
|
public function testConstructWithInvalidTwoArgs() {
|
||
|
$this->expectException(FilterException::class);
|
||
|
$a = new Filter('a', '&');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__get()
|
||
|
*/
|
||
|
public function testGetOnLeafFilter() {
|
||
|
$a = new Filter('attr', '=', 'value');
|
||
|
$this->assertEquals('attr', $a->attr_name);
|
||
|
$this->assertEquals('attr', $a->attribute);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('=', $a->operator);
|
||
|
$this->assertEquals('value', $a->pattern);
|
||
|
$this->assertNull($a->log_op);
|
||
|
$this->assertNull($a->logical_operator);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertEmpty($a->sub_filters);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__get
|
||
|
*/
|
||
|
public function testGetOnCombineFilter() {
|
||
|
$a = new Filter('&', 'attr=value');
|
||
|
$this->assertNull($a->attr_name);
|
||
|
$this->assertNull($a->attribute);
|
||
|
$this->assertNull($a->op);
|
||
|
$this->assertNull($a->operator);
|
||
|
$this->assertNull($a->pattern);
|
||
|
$this->assertEquals('&', $a->log_op);
|
||
|
$this->assertEquals('&', $a->logical_operator);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertCount(1, $a->sub_filters);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::__get
|
||
|
*/
|
||
|
public function testGetOnUndefinedProperty() {
|
||
|
$a = new Filter('&', 'attr=value');
|
||
|
$this->expectException(FilterException::class);
|
||
|
// @phpstan-ignore-next-line
|
||
|
$a->undefined;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::operators
|
||
|
*/
|
||
|
public function testOperators() {
|
||
|
$ops = Filter::operators();
|
||
|
$this->assertIsArray($ops);
|
||
|
$this->assertNotEmpty($ops);
|
||
|
foreach($ops as $op) {
|
||
|
$this->assertIsString($op);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::operator_aliases
|
||
|
*/
|
||
|
public function testOperatorAliases() {
|
||
|
$op_aliases = Filter::operator_aliases();
|
||
|
$this->assertIsArray($op_aliases);
|
||
|
$this->assertNotEmpty($op_aliases);
|
||
|
foreach($op_aliases as $alias => $op) {
|
||
|
$this->assertIsString($alias);
|
||
|
$this->assertIsString($op);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::logical_operators
|
||
|
*/
|
||
|
public function testLogicalOperators() {
|
||
|
$log_ops = Filter::logical_operators();
|
||
|
$this->assertIsArray($log_ops);
|
||
|
$this->assertNotEmpty($log_ops);
|
||
|
foreach($log_ops as $op) {
|
||
|
$this->assertIsString($op);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::logical_operator_aliases
|
||
|
*/
|
||
|
public function testLogicalOperatorAliases() {
|
||
|
$log_op_aliases = Filter::logical_operator_aliases();
|
||
|
$this->assertIsArray($log_op_aliases);
|
||
|
$this->assertNotEmpty($log_op_aliases);
|
||
|
foreach($log_op_aliases as $alias => $op) {
|
||
|
$this->assertIsString($alias);
|
||
|
$this->assertIsString($op);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::is_leaf
|
||
|
*/
|
||
|
public function testIsLeaf() {
|
||
|
$a = new Filter('attr', '=', 'value');
|
||
|
$this->assertTrue($a->is_leaf());
|
||
|
$a = new Filter('!', 'a=b');
|
||
|
$this->assertFalse($a->is_leaf());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::is_combine
|
||
|
*/
|
||
|
public function testIsCombine() {
|
||
|
$a = new Filter('attr', '=', 'value');
|
||
|
$this->assertFalse($a->is_combine());
|
||
|
$a = new Filter('!', 'a=b');
|
||
|
$this->assertTrue($a->is_combine());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::as_string
|
||
|
*/
|
||
|
public function testLeafFilterAsString() {
|
||
|
$a = new Filter('attr', '=', 'value');
|
||
|
$this->assertEquals('(attr=value)', $a->as_string(true));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::as_string
|
||
|
*/
|
||
|
public function testLeafFilterAsPrettyString() {
|
||
|
$a = new Filter('attr', '=', 'value');
|
||
|
$this->assertEquals('(attr=value)', $a->as_string());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineFilterAsString() {
|
||
|
$a = new Filter('&', 'a=b', 'c=d');
|
||
|
$this->assertEquals('(&(a=b)(c=d))', $a->as_string());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineFilterAsPrettyString() {
|
||
|
$a = new Filter('&', 'a=b', 'c=d');
|
||
|
$this->assertEquals("(&\n\t(a=b)\n\t(c=d)\n)", $a->as_string(true));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineStringFilters() {
|
||
|
$a = Filter :: combine('&', 'a=b', 'c=d');
|
||
|
$this->assertEquals('(&(a=b)(c=d))', $a->as_string());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineFilters() {
|
||
|
$ab = new Filter('a', '=', 'b');
|
||
|
$bd = new Filter('b', '=', 'd');
|
||
|
$a = Filter :: combine('&', $ab, $bd);
|
||
|
$this->assertEquals('&', $a->log_op);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertCount(2, $a->sub_filters);
|
||
|
$this->assertContains($ab, $a->sub_filters);
|
||
|
$this->assertContains($bd, $a->sub_filters);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineWithLogOpAlias() {
|
||
|
$ab = new Filter('a', '=', 'b');
|
||
|
foreach(Filter :: logical_operator_aliases() as $alias => $op) {
|
||
|
$a = Filter::combine($alias, $ab);
|
||
|
$this->assertEquals($op, $a->log_op);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineArrayOfFilters() {
|
||
|
$ab = new Filter('a', '=', 'b');
|
||
|
$c2 = new Filter('c', '>=', '2');
|
||
|
$bd = new Filter('b', '=', 'd');
|
||
|
$a = Filter::combine('&', array($ab, $c2), $bd);
|
||
|
$this->assertEquals('&', $a->log_op);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertCount(3, $a->sub_filters);
|
||
|
$this->assertContains($ab, $a->sub_filters);
|
||
|
$this->assertContains($c2, $a->sub_filters);
|
||
|
$this->assertContains($bd, $a->sub_filters);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineArrayOfFilterStrings() {
|
||
|
$a = Filter::combine('&', array('a=b', '(c>=2)'), 'b~=test');
|
||
|
$this->assertEquals($a->as_string(), '(&(a=b)(c>=2)(b~=test))');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineMixedFilterTypes() {
|
||
|
$a = Filter::combine(
|
||
|
'|',
|
||
|
array(new Filter('a', '=', 'b'), 'c>=2'),
|
||
|
new Filter('b', '~=', 'test'),
|
||
|
'd=z'
|
||
|
);
|
||
|
$this->assertEquals($a->as_string(), '(|(a=b)(c>=2)(b~=test)(d=z))');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineNotOpAndFilter() {
|
||
|
$ab = new Filter('a', '=', 'b');
|
||
|
$a = Filter::combine('!', $ab);
|
||
|
$this->assertEquals('!', $a->log_op);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertCount(1, $a->sub_filters);
|
||
|
$this->assertContains($ab, $a->sub_filters);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineNotOpAndMoreThanOneFilter() {
|
||
|
$this->expectException(CombineException::class);
|
||
|
$a = Filter::combine('!', new Filter('a', '=', 'b'), new Filter('c', '>=', '2'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineInvalidLogOp() {
|
||
|
$this->expectException(CombineException::class);
|
||
|
$a = Filter::combine('X', new Filter('a', '=', 'b'), new Filter('c', '>=', '2'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::combine
|
||
|
*/
|
||
|
public function testCombineInvalidFilter() {
|
||
|
$this->expectException(CombineException::class);
|
||
|
// @phpstan-ignore-next-line
|
||
|
$a = Filter::combine('&', new Filter('a', '=', 'b'), new FilterException('test'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::split_attr_string
|
||
|
*/
|
||
|
public function testSplitAttrString() {
|
||
|
$this-> assertEquals(array('a', '=', 'b'), Filter::split_attr_string('a=b'));
|
||
|
$this-> assertEquals(array('owner', '=', 'cn=admin,o=example'), Filter::split_attr_string('owner=cn=admin,o=example'));
|
||
|
$this-> assertFalse(Filter::split_attr_string('owner'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::is_op
|
||
|
*/
|
||
|
public function test_is_op() {
|
||
|
foreach(Filter::operators() as $op)
|
||
|
$this -> assertTrue(Filter::is_op($op));
|
||
|
foreach(Filter::operator_aliases() as $alias => $op) {
|
||
|
$this -> assertTrue(Filter::is_op($alias));
|
||
|
$this -> assertTrue(Filter::is_op($op));
|
||
|
}
|
||
|
$this -> assertFalse(Filter::is_op('fake_op', false));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::is_op
|
||
|
*/
|
||
|
public function test_is_op_without_alias() {
|
||
|
foreach(Filter::operators() as $op)
|
||
|
$this -> assertTrue(Filter::is_op($op, false));
|
||
|
foreach(Filter::operator_aliases() as $alias => $op) {
|
||
|
$this -> assertFalse(Filter::is_op($alias, false));
|
||
|
$this -> assertTrue(Filter::is_op($op, false));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::is_log_op
|
||
|
*/
|
||
|
public function test_is_log_op() {
|
||
|
foreach(Filter::logical_operators() as $op)
|
||
|
$this -> assertTrue(Filter::is_log_op($op));
|
||
|
foreach(Filter::logical_operator_aliases() as $alias => $op) {
|
||
|
$this -> assertTrue(Filter::is_log_op($alias));
|
||
|
$this -> assertTrue(Filter::is_log_op($op));
|
||
|
}
|
||
|
$this -> assertFalse(Filter::is_log_op('fake_op', false));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::is_log_op
|
||
|
*/
|
||
|
public function test_is_log_op_without_alias() {
|
||
|
foreach(Filter::logical_operators() as $op)
|
||
|
$this -> assertTrue(Filter::is_log_op($op, false));
|
||
|
foreach(Filter::logical_operator_aliases() as $alias => $op) {
|
||
|
$this -> assertFalse(Filter::is_log_op($alias, false));
|
||
|
$this -> assertTrue(Filter::is_log_op($op, false));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::unalias_op
|
||
|
*/
|
||
|
public function test_unalias_op() {
|
||
|
foreach(Filter::operators() as $op)
|
||
|
$this -> assertEquals($op, Filter::unalias_op($op));
|
||
|
foreach(Filter::operator_aliases() as $alias => $op) {
|
||
|
$this -> assertEquals($op, Filter::unalias_op($alias));
|
||
|
$this -> assertEquals($op, Filter::unalias_op($op));
|
||
|
}
|
||
|
$this -> assertFalse(Filter::unalias_op('fake_op'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::unalias_log_op
|
||
|
*/
|
||
|
public function test_unalias_log_op() {
|
||
|
foreach(Filter::logical_operators() as $op)
|
||
|
$this -> assertEquals($op, Filter::unalias_log_op($op));
|
||
|
foreach(Filter::logical_operator_aliases() as $alias => $op) {
|
||
|
$this -> assertEquals($op, Filter::unalias_log_op($alias));
|
||
|
$this -> assertEquals($op, Filter::unalias_log_op($op));
|
||
|
}
|
||
|
$this -> assertFalse(Filter::unalias_log_op('fake_op'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::is_not_op
|
||
|
*/
|
||
|
public function test_is_not_op() {
|
||
|
$this -> assertTrue(Filter :: is_not_op('!'));
|
||
|
$this -> assertFalse(Filter :: is_not_op('&'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::is_attr_name
|
||
|
*/
|
||
|
public function test_is_attr_name() {
|
||
|
$this -> assertTrue(Filter :: is_attr_name('o'));
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn'));
|
||
|
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn;x-test'));
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn;x-test;x-test2'));
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn;x-test;x-test2;x-test3'));
|
||
|
|
||
|
$this -> assertTrue(Filter :: is_attr_name('1.12.34'));
|
||
|
$this -> assertFalse(Filter :: is_attr_name('1.12.34.'));
|
||
|
$this -> assertFalse(Filter :: is_attr_name('1'));
|
||
|
$this -> assertFalse(Filter :: is_attr_name('1.'));
|
||
|
|
||
|
$this -> assertFalse(Filter :: is_attr_name('bad name'));
|
||
|
$this -> assertFalse(Filter :: is_attr_name('1word'));
|
||
|
|
||
|
$this -> assertFalse(Filter :: is_attr_name('cn:', false));
|
||
|
// @phpstan-ignore-next-line
|
||
|
$this -> assertFalse(Filter :: is_attr_name(false));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::is_attr_name
|
||
|
*/
|
||
|
public function test_is_attr_name_allow_extended_by_default() {
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn:dn:'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::is_attr_name
|
||
|
*/
|
||
|
public function test_is_attr_name_extended() {
|
||
|
$this -> assertTrue(Filter :: is_attr_name('o', true));
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn', true));
|
||
|
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn;x-test', true));
|
||
|
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn:', true));
|
||
|
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn:dn:', true));
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn:DN:', true));
|
||
|
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn:dn:caseExactMatch:', true));
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn:DN:caseExactMatch:', true));
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn:dn:2.4.6.8.10:', true));
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn:DN:2.4.6.8.10:', true));
|
||
|
|
||
|
$this -> assertTrue(Filter :: is_attr_name(':DN:caseExactMatch:', true));
|
||
|
$this -> assertTrue(Filter :: is_attr_name(':DN:2.4.6.8.10:', true));
|
||
|
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn:caseExactMatch:', true));
|
||
|
$this -> assertTrue(Filter :: is_attr_name('cn:2.4.6.8.10:', true));
|
||
|
|
||
|
$this -> assertFalse(Filter :: is_attr_name('bad name', true));
|
||
|
$this -> assertFalse(Filter :: is_attr_name('cn:dn', true));
|
||
|
$this -> assertFalse(Filter :: is_attr_name('cn:DN', true));
|
||
|
$this -> assertFalse(Filter :: is_attr_name('cn:case10', true));
|
||
|
$this -> assertFalse(Filter :: is_attr_name('cn:case10:', true));
|
||
|
$this -> assertFalse(Filter :: is_attr_name('cn:test1:test2:', true));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::escape
|
||
|
*/
|
||
|
public function testEscape(){
|
||
|
$this->assertEquals('test\2a', Filter::escape('test*'));
|
||
|
$this->assertEquals('\28test\29', Filter::escape('(test)'));
|
||
|
$this->assertEquals('\5ctest', Filter::escape('\\test'));
|
||
|
$this->assertEquals('\00', Filter::escape("\u{0000}"));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::unescape
|
||
|
*/
|
||
|
public function testUnescape(){
|
||
|
$this->assertEquals('test*test', Filter::unescape('test\2atest'));
|
||
|
$this->assertEquals('(test)', Filter::unescape('\28test\29'));
|
||
|
$this->assertEquals('\test', Filter::unescape('\\5ctest'));
|
||
|
$this->assertEquals("\u{0000}", Filter::unescape('\00'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Note: Freely inspired by test cases provided with butonic's php-ldap-filter-parser.
|
||
|
* @see: https://github.com/butonic/php-ldap-filter-parser
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_leaf_filter() {
|
||
|
$a = Filter::parse('(cn=Babs Jensen)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('cn', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('Babs Jensen', $a->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_leaf_filter_without_brackets() {
|
||
|
$a = Filter::parse('cn=Babs Jensen');
|
||
|
$b = Filter::parse('(cn=Babs Jensen)');
|
||
|
$this->assertEquals($a, $b);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_leaf_filter_with_one_asterisk() {
|
||
|
$a = Filter::parse('(cn=Babs *)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('cn', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('Babs *', $a->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_leaf_filter_with_multiple_asterisk() {
|
||
|
$a = Filter::parse('(o=univ*of*mich*)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('o', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('univ*of*mich*', $a->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_leaf_filter_with_empty_value() {
|
||
|
$a = Filter::parse('(seeAlso=)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('seeAlso', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('', $a->pattern);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Extended attribute name filters
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_leaf_filter_with_extended_attr_name() {
|
||
|
$a = Filter::parse('(cn:caseExactMatch:=Fred Flintstone)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('cn:caseExactMatch:', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('Fred Flintstone', $a->pattern);
|
||
|
|
||
|
$a = Filter::parse('(cn:=Betty Rubble)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('cn:', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('Betty Rubble', $a->pattern);
|
||
|
|
||
|
$a = Filter::parse('(sn:dn:2.4.6.8.10:=Betty Rubble)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('sn:dn:2.4.6.8.10:', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('Betty Rubble', $a->pattern);
|
||
|
|
||
|
$a = Filter::parse('(o:dn:=Ace Industry:)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('o:dn:', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('Ace Industry:', $a->pattern);
|
||
|
|
||
|
$a = Filter::parse('(:1.2.3:=Wilma Flintstone)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals(':1.2.3:', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('Wilma Flintstone', $a->pattern);
|
||
|
|
||
|
$a = Filter::parse('(:DN:2.4.6.8.10:=Dino)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals(':DN:2.4.6.8.10:', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('Dino', $a->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Escaped characters
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_leaf_filter_with_escaped_characters() {
|
||
|
$a = Filter::parse('(o=Parens R Us \\28for all your parenthetical needs\\29)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('o', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('Parens R Us \\28for all your parenthetical needs\\29', $a->pattern);
|
||
|
|
||
|
$a = Filter::parse('(cn=*\\2A*)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('cn', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('*\\2A*', $a->pattern);
|
||
|
|
||
|
$a = Filter::parse('(filename=C:\\5cMyFile)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('filename', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('C:\\5cMyFile', $a->pattern);
|
||
|
|
||
|
$a = Filter::parse('(bin=\\00\\00\\00\\04)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('bin', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('\\00\\00\\00\\04', $a->pattern);
|
||
|
|
||
|
$a = Filter::parse('(sn=Lu\\c4\\8di\\c4\\87)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('sn', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('Lu\\c4\\8di\\c4\\87', $a->pattern);
|
||
|
|
||
|
$a = Filter::parse('(1.3.6.1.4.1.1466.0=\\04\\02\\48\\69)');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertEquals('1.3.6.1.4.1.1466.0', $a->attr_name);
|
||
|
$this->assertEquals('=', $a->op);
|
||
|
$this->assertEquals('\\04\\02\\48\\69', $a->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parse combined filters
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_combined_filter() {
|
||
|
$a = Filter::parse('(&(objectClass=inetOrgPerson)(memberOf=cn=owncloudusers,ou=groups,dc=example,dc=com))');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertTrue($a->is_combine());
|
||
|
$this->assertEquals('&', $a->log_op);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertCount(2, $a->sub_filters);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[0]);
|
||
|
$this->assertTrue($a->sub_filters[0]->is_leaf());
|
||
|
$this->assertEquals('objectClass', $a->sub_filters[0]->attr_name);
|
||
|
$this->assertEquals('=', $a->sub_filters[0]->op);
|
||
|
$this->assertEquals('inetOrgPerson', $a->sub_filters[0]->pattern);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[1]);
|
||
|
$this->assertTrue($a->sub_filters[1]->is_leaf());
|
||
|
$this->assertEquals('memberOf', $a->sub_filters[1]->attr_name);
|
||
|
$this->assertEquals('=', $a->sub_filters[1]->op);
|
||
|
$this->assertEquals('cn=owncloudusers,ou=groups,dc=example,dc=com', $a->sub_filters[1]->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parse multiple combined filters
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_multiple_combined_filters() {
|
||
|
$a = Filter::parse('(&(|(uid=a*)(userid=a*))(|(telephoneNumber=1234)(mobile=1234)))');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertTrue($a->is_combine());
|
||
|
$this->assertEquals('&', $a->log_op);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertCount(2, $a->sub_filters);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[0]);
|
||
|
$this->assertTrue($a->sub_filters[0]->is_combine());
|
||
|
$this->assertEquals('|', $a->sub_filters[0]->log_op);
|
||
|
$this->assertIsArray($a->sub_filters[0]->sub_filters);
|
||
|
$this->assertCount(2, $a->sub_filters[0]->sub_filters);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[0]->sub_filters[0]);
|
||
|
$this->assertTrue($a->sub_filters[0]->sub_filters[0]->is_leaf());
|
||
|
$this->assertEquals('uid', $a->sub_filters[0]->sub_filters[0]->attr_name);
|
||
|
$this->assertEquals('=', $a->sub_filters[0]->sub_filters[0]->op);
|
||
|
$this->assertEquals('a*', $a->sub_filters[0]->sub_filters[0]->pattern);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[0]->sub_filters[1]);
|
||
|
$this->assertTrue($a->sub_filters[0]->sub_filters[1]->is_leaf());
|
||
|
$this->assertEquals('userid', $a->sub_filters[0]->sub_filters[1]->attr_name);
|
||
|
$this->assertEquals('=', $a->sub_filters[0]->sub_filters[1]->op);
|
||
|
$this->assertEquals('a*', $a->sub_filters[0]->sub_filters[1]->pattern);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[1]);
|
||
|
$this->assertTrue($a->sub_filters[1]->is_combine());
|
||
|
$this->assertEquals('|', $a->sub_filters[1]->log_op);
|
||
|
$this->assertIsArray($a->sub_filters[1]->sub_filters);
|
||
|
$this->assertCount(2, $a->sub_filters[1]->sub_filters);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[1]->sub_filters[0]);
|
||
|
$this->assertTrue($a->sub_filters[1]->sub_filters[0]->is_leaf());
|
||
|
$this->assertEquals('telephoneNumber', $a->sub_filters[1]->sub_filters[0]->attr_name);
|
||
|
$this->assertEquals('=', $a->sub_filters[1]->sub_filters[0]->op);
|
||
|
$this->assertEquals('1234', $a->sub_filters[1]->sub_filters[0]->pattern);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[1]->sub_filters[1]);
|
||
|
$this->assertTrue($a->sub_filters[1]->sub_filters[1]->is_leaf());
|
||
|
$this->assertEquals('mobile', $a->sub_filters[1]->sub_filters[1]->attr_name);
|
||
|
$this->assertEquals('=', $a->sub_filters[1]->sub_filters[1]->op);
|
||
|
$this->assertEquals('1234', $a->sub_filters[1]->sub_filters[1]->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parse multiple combined and nested filters
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_multiple_combined_and_nested_filters() {
|
||
|
$a = Filter::parse('(&(objectClass=Person)(|(sn=Jensen)(cn=Babs J*)))');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertTrue($a->is_combine());
|
||
|
$this->assertEquals('&', $a->log_op);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertCount(2, $a->sub_filters);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[0]);
|
||
|
$this->assertTrue($a->sub_filters[0]->is_leaf());
|
||
|
$this->assertEquals('objectClass', $a->sub_filters[0]->attr_name);
|
||
|
$this->assertEquals('=', $a->sub_filters[0]->op);
|
||
|
$this->assertEquals('Person', $a->sub_filters[0]->pattern);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[1]);
|
||
|
$this->assertTrue($a->sub_filters[1]->is_combine());
|
||
|
$this->assertEquals('|', $a->sub_filters[1]->log_op);
|
||
|
$this->assertIsArray($a->sub_filters[1]->sub_filters);
|
||
|
$this->assertCount(2, $a->sub_filters[1]->sub_filters);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[1]->sub_filters[0]);
|
||
|
$this->assertTrue($a->sub_filters[1]->sub_filters[0]->is_leaf());
|
||
|
$this->assertEquals('sn', $a->sub_filters[1]->sub_filters[0]->attr_name);
|
||
|
$this->assertEquals('=', $a->sub_filters[1]->sub_filters[0]->op);
|
||
|
$this->assertEquals('Jensen', $a->sub_filters[1]->sub_filters[0]->pattern);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[1]->sub_filters[1]);
|
||
|
$this->assertTrue($a->sub_filters[1]->sub_filters[1]->is_leaf());
|
||
|
$this->assertEquals('cn', $a->sub_filters[1]->sub_filters[1]->attr_name);
|
||
|
$this->assertEquals('=', $a->sub_filters[1]->sub_filters[1]->op);
|
||
|
$this->assertEquals('Babs J*', $a->sub_filters[1]->sub_filters[1]->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parse a not filter
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_not_filter() {
|
||
|
$a = Filter::parse('(!(objectClass=Person))');
|
||
|
$this->assertInstanceOf(Filter::class, $a);
|
||
|
$this->assertTrue($a->is_combine());
|
||
|
$this->assertEquals('!', $a->log_op);
|
||
|
$this->assertIsArray($a->sub_filters);
|
||
|
$this->assertCount(1, $a->sub_filters);
|
||
|
|
||
|
$this->assertInstanceOf(Filter::class, $a->sub_filters[0]);
|
||
|
$this->assertTrue($a->sub_filters[0]->is_leaf());
|
||
|
$this->assertEquals('objectClass', $a->sub_filters[0]->attr_name);
|
||
|
$this->assertEquals('=', $a->sub_filters[0]->op);
|
||
|
$this->assertEquals('Person', $a->sub_filters[0]->pattern);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parse filter with unclosed bracket
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_filter_with_unclosed_bracket() {
|
||
|
$this->expectException(ParserException::class);
|
||
|
Filter::parse('(objectClass=Person');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parse NOT filter with multiple sub filters
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_not_filter_with_multiple_filter() {
|
||
|
$this->expectException(ParserException::class);
|
||
|
Filter::parse('(!(objectClass=Person)(cn=test))');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parse filter with unescaped brackets
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_with_unescaped_brackets() {
|
||
|
$this->expectException(ParserException::class);
|
||
|
var_dump(Filter::parse('(cn=test(test))'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parse filter with invalid sub filter
|
||
|
* @covers \EesyLDAP\Filter::parse
|
||
|
*/
|
||
|
public function test_parse_with_invalid_sub_filter() {
|
||
|
$this->expectException(ParserException::class);
|
||
|
var_dump(Filter::parse('(&(cn=test)(test))'));
|
||
|
}
|
||
|
|
||
|
}
|