php-eesyldap/tests/FilterTest.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(FilterException::class);
$a = Filter::combine('X', new Filter('a', '=', 'b'), new Filter('c', '>=', '2'));
}
/**
* @covers \EesyLDAP\Filter::combine
*/
public function testCombineInvalidFilter() {
$this->expectException(FilterException::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))'));
}
}