php-eesyldap/tests/SchemaTest.php

638 lines
20 KiB
PHP
Raw Permalink Normal View History

2023-03-26 13:59:21 +02:00
<?php
declare(strict_types=1);
use \Mockery\Adapter\Phpunit\MockeryTestCase;
use EesyLDAP\Entry;
use EesyLDAP\LdapException;
use EesyLDAP\Schema;
use EesyLDAP\InvalidPropertyException;
/**
* @covers EesyLDAP\Schema::load
* @covers EesyLDAP\Schema::__construct
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
final class SchemaTest extends MockeryTestCase {
public function testLoad() {
$entry = Mockery::mock('overload:EesyLDAP\Entry');
$entry->shouldReceive('get_raw_values')
->andReturn(array());
$ldap = Mockery::mock('overload:EesyLDAP\Ldap');
$ldap->shouldReceive('get_entry')
->once()
->with(
'cn=SubSchema', '(objectclass=*)',
['attributeTypes', 'matchingRules', 'matchingRuleUse', 'objectClasses', 'ldapSyntaxes']
)
->andReturn($entry);
$obj = Schema::load($ldap);
$this -> assertInstanceOf(Schema::class, $obj);
}
/**
* @covers EesyLDAP\Schema::load
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
public function testLoadFail() {
$raise = true;
$ldap = Mockery::mock('overload:EesyLDAP\Ldap');
$ldap->shouldReceive('get_entry')
->once()
->with(
'cn=SubSchema', '(objectclass=*)',
['attributeTypes', 'matchingRules', 'matchingRuleUse', 'objectClasses', 'ldapSyntaxes']
)
->andReturn(false);
$ldap->shouldReceive('error')
->once()
->with('Fail to load cn=SubSchema entry', $raise)
->andThrow(LdapException::class);
$this->expectException(LdapException::class);
$obj = Schema::load($ldap, $raise);
}
/**
* @covers EesyLDAP\Schema::__get
*/
public function testGetLoaded() {
$schema = $this -> getSchema();
$this -> assertTrue($schema->__get('loaded'));
}
/**
* @covers EesyLDAP\Schema::__get
*/
public function testGetInvalidProperty() {
$schema = $this -> getSchema();
$this->expectException(InvalidPropertyException::class);
$this -> assertTrue($schema->__get('undefined'));
}
/**
* @return Schema
*/
public function getSchema() {
$ldap = Mockery::mock('EesyLDAP\Ldap');
$entry = Mockery::mock('EesyLDAP\Entry');
$entry->shouldReceive('get_raw_values')
->andReturn(array());
return new Schema($ldap, $entry);
}
/**
* @covers \EesyLDAP\Schema::parse
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
public function testParse() {
$data = array(
'attributeTypes' => array(
"type" => "Attribute",
"values" => array(
"( 2.5.4.0 NAME 'objectClass' DESC 'RFC4512: object classes of the entity' EQUALITY ".
"objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
),
"oid" => "2.5.4.0",
"name" => "objectClass",
"entry" => null,
),
'matchingRules' => array(
"type" => "MatchingRule",
"values" => array(
"( 2.5.13.20 NAME 'telephoneNumberMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
),
"oid" => "2.5.13.20",
"name" => "telephoneNumberMatch",
"entry" => null,
),
'matchingRuleUse' => array(
"type" => "MatchingRuleUse",
"values" => array(
"( 2.5.13.20 NAME 'telephoneNumberMatch' APPLIES ( telephoneNumber $ homePhone $ mobile".
" $ pager ) )",
),
"oid" => "2.5.13.20",
"name" => "telephoneNumberMatch",
"entry" => null,
),
'objectClasses' => array(
"type" => "ObjectClass",
"values" => array(
"( 2.5.6.14 NAME 'device' DESC 'RFC2256: a device' SUP top STRUCTURAL MUST cn MAY ( ".
"serialNumber $ seeAlso $ owner $ ou $ o $ l $ description ) )",
),
"oid" => "2.5.6.14",
"name" => "device",
"entry" => null,
),
'ldapSyntaxes' => array(
"type" => "Syntax",
"values" => array(
"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
),
"oid" => "1.3.6.1.4.1.1466.115.121.1.7",
"name" => "Boolean",
"entry" => null,
),
);
$entry = Mockery::mock('EesyLDAP\Entry');
foreach($data as $attr => $info) {
$entry->shouldReceive('get_raw_values')
->once()
->with($attr, array(), true)
->andReturn($info['values']);
$data[$attr]['entry'] = Mockery::mock('EesyLDAP\Schema\SchemaEntry');
// @phpstan-ignore-next-line
$data[$attr]['entry']->oid = $info['oid'];
// @phpstan-ignore-next-line
$data[$attr]['entry']->name = $info['name'];
$data[$attr]['mock'] = Mockery::mock("overload:EesyLDAP\\Schema\\".$info['type']);
// @phpstan-ignore-next-line
$data[$attr]['mock']->shouldReceive('parse')
->once()
->with($info['values'][0])
->andReturn($data[$attr]['entry']);
}
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$reflection = new ReflectionClass($schema);
$entry_property = $reflection->getProperty('entry');
$entry_property->setAccessible(true);
$entry_property->setValue($schema, $entry);
$schema->shouldReceive('parse')->passthru();
$parse_method = new ReflectionMethod('EesyLDAP\Schema', 'parse');
$parse_method->setAccessible(true);
$parse_method->invoke($schema);
$reflection = new ReflectionClass($schema);
$entries_property = $reflection->getProperty('entries');
$entries_property->setAccessible(true);
$entries = $entries_property->getValue($schema);
$oids_property = $reflection->getProperty('oids');
$oids_property->setAccessible(true);
$oids = $oids_property->getValue($schema);
foreach($data as $attr => $info) {
// @phpstan-ignore-next-line
$this->assertSame($info['entry'], $entries[strtolower($info['type'])][$info['name']]);
// @phpstan-ignore-next-line
$this->assertEquals($info['entry'], $oids[$info['oid']]);
}
}
/**
* @covers \EesyLDAP\Schema::parse
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
public function testParseBadSchemaValue() {
$attr = "attributeTypes";
$value = "bad value";
$ldap = Mockery::mock('EesyLDAP\Ldap');
$ldap->shouldReceive('error')
->once()
->with("Fail to parse %s schema value: %s", null, $attr, $value)
->andThrow(LdapException::class);
$entry = Mockery::mock('EesyLDAP\Entry');
$entry->shouldReceive('get_raw_values')
->once()
->with($attr, array(), true)
->andReturn(array($value));
$attribute = Mockery::mock("overload:EesyLDAP\Schema\Attribute");
$attribute->shouldReceive('parse')
->once()
->with($value)
->andReturn(false);
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$reflection = new ReflectionClass($schema);
$ldap_property = $reflection->getProperty('ldap');
$ldap_property->setAccessible(true);
$ldap_property->setValue($schema, $ldap);
$entry_property = $reflection->getProperty('entry');
$entry_property->setAccessible(true);
$entry_property->setValue($schema, $entry);
$schema->shouldReceive('parse')->passthru();
$this->expectException(LdapException::class);
$parse_method = new ReflectionMethod('EesyLDAP\Schema', 'parse');
$parse_method->setAccessible(true);
$parse_method->invoke($schema);
}
/**
* @covers \EesyLDAP\Schema::parse
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
public function testParseDuplicateOid() {
$attr = "attributeTypes";
$oid = "1.2.3";
$value1 = "test1";
$entry1 = Mockery::mock('EesyLDAP\Schema\SchemaEntry');
$entry1->oid = $oid;
$entry1->name = "test1";
$value2 = "test2";
$entry2 = Mockery::mock('EesyLDAP\Schema\SchemaEntry');
$entry2->oid = $oid;
$entry2->name = "test2";
$ldap = Mockery::mock('EesyLDAP\Ldap');
$ldap->shouldReceive('error')
->once()
->with("Duplicate OID %s found in schema: %s / %s", null, $oid, $entry1, $entry2)
->andThrow(LdapException::class);
$entry = Mockery::mock('EesyLDAP\Entry');
$entry->shouldReceive('get_raw_values')
->once()
->with($attr, array(), true)
->andReturn(array($value1, $value2));
$attribute = Mockery::mock("overload:EesyLDAP\Schema\Attribute");
$attribute->shouldReceive('parse')
->once()
->with($value1)
->andReturn($entry1)
->shouldReceive('parse')
->once()
->with($value2)
->andReturn($entry2);
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$reflection = new ReflectionClass($schema);
$ldap_property = $reflection->getProperty('ldap');
$ldap_property->setAccessible(true);
$ldap_property->setValue($schema, $ldap);
$entry_property = $reflection->getProperty('entry');
$entry_property->setAccessible(true);
$entry_property->setValue($schema, $entry);
$schema->shouldReceive('parse')->passthru();
$this->expectException(LdapException::class);
$parse_method = new ReflectionMethod('EesyLDAP\Schema', 'parse');
$parse_method->setAccessible(true);
$parse_method->invoke($schema);
}
/**
* @covers \EesyLDAP\Schema::parse
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
public function testParseDuplicateName() {
$attr = "attributeTypes";
$name = "test";
$value1 = "test1";
$entry1 = Mockery::mock('EesyLDAP\Schema\SchemaEntry');
$entry1->oid = "1.2.3";
$entry1->name = $name;
$value2 = "test2";
$entry2 = Mockery::mock('EesyLDAP\Schema\SchemaEntry');
$entry2->oid = "1.2.4";
$entry2->name = $name;
$ldap = Mockery::mock('EesyLDAP\Ldap');
$ldap->shouldReceive('error')
->once()
->with(
"Duplicate %s schema entry %s found: %s / %s",
null, "Attribute", $name, $entry1, $entry2)
->andThrow(LdapException::class);
$entry = Mockery::mock('EesyLDAP\Entry');
$entry->shouldReceive('get_raw_values')
->once()
->with($attr, array(), true)
->andReturn(array($value1, $value2));
$attribute = Mockery::mock("overload:EesyLDAP\Schema\Attribute");
$attribute->shouldReceive('parse')
->once()
->with($value1)
->andReturn($entry1)
->shouldReceive('parse')
->once()
->with($value2)
->andReturn($entry2);
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$reflection = new ReflectionClass($schema);
$ldap_property = $reflection->getProperty('ldap');
$ldap_property->setAccessible(true);
$ldap_property->setValue($schema, $ldap);
$entry_property = $reflection->getProperty('entry');
$entry_property->setAccessible(true);
$entry_property->setValue($schema, $entry);
$schema->shouldReceive('parse')->passthru();
$this->expectException(LdapException::class);
$parse_method = new ReflectionMethod('EesyLDAP\Schema', 'parse');
$parse_method->setAccessible(true);
$parse_method->invoke($schema);
}
/**
* @covers \EesyLDAP\Schema::_get_entry
*/
public function testGetEntryByOid() {
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$reflection = new ReflectionClass($schema);
$schema->shouldReceive('_get_entry')->passthru();
$oid = "1.2.3";
$attr = Mockery::mock('EesyLDAP\Schema\Attribute');
$reflection = new ReflectionClass($schema);
$oids_property = $reflection->getProperty('oids');
$oids_property->setAccessible(true);
$oids_property->setValue($schema, array($oid => $attr));
$get_entry_method = new ReflectionMethod('EesyLDAP\Schema', '_get_entry');
$get_entry_method->setAccessible(true);
$this->assertSame($attr, $get_entry_method->invoke($schema, "Attribute", $oid));
}
/**
* @covers \EesyLDAP\Schema::_get_entry
*/
public function testGetEntryByName() {
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$reflection = new ReflectionClass($schema);
$schema->shouldReceive('_get_entry')->passthru();
$name = "test";
$attr = Mockery::mock('EesyLDAP\Schema\Attribute');
$attr->shouldReceive('is_me')
->once()
->with($name)
->andReturn(true);
$reflection = new ReflectionClass($schema);
$entries_property = $reflection->getProperty('entries');
$entries_property->setAccessible(true);
$entries_property->setValue($schema, array("attribute" => array($name => $attr)));
$get_entry_method = new ReflectionMethod('EesyLDAP\Schema', '_get_entry');
$get_entry_method->setAccessible(true);
$this->assertSame($attr, $get_entry_method->invoke($schema, "Attribute", $name));
}
/**
* @covers \EesyLDAP\Schema::_get_entry
*/
public function testGetEntryUndefinedType() {
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$reflection = new ReflectionClass($schema);
$schema->shouldReceive('_get_entry')->passthru();
$reflection = new ReflectionClass($schema);
$get_entry_method = new ReflectionMethod('EesyLDAP\Schema', '_get_entry');
$get_entry_method->setAccessible(true);
$this->assertFalse($get_entry_method->invoke($schema, "Attribute", "undefined"));
}
/**
* @covers \EesyLDAP\Schema::_get_entry
*/
public function testGetEntryUndefinedEntry() {
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$reflection = new ReflectionClass($schema);
$schema->shouldReceive('_get_entry')->passthru();
$reflection = new ReflectionClass($schema);
$entries_property = $reflection->getProperty('entries');
$entries_property->setAccessible(true);
$entries_property->setValue($schema, array("attribute" => array()));
$get_entry_method = new ReflectionMethod('EesyLDAP\Schema', '_get_entry');
$get_entry_method->setAccessible(true);
$this->assertFalse($get_entry_method->invoke($schema, "Attribute", "undefined"));
}
/**
* @covers \EesyLDAP\Schema::attribute
*/
public function testAttribute() {
$name = 'test';
$entry = Mockery::mock("overload:EesyLDAP\Schema\Attribute");
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$schema->shouldReceive('_get_entry')
->once()
->with("Attribute", $name)
->andReturn($entry);
$schema->shouldReceive('attribute')->passthru();
$this->assertSame($entry, $schema->attribute($name));
}
/**
* @covers \EesyLDAP\Schema::objectclass
*/
public function testObjectclass() {
$name = 'test';
$entry = Mockery::mock("overload:EesyLDAP\Schema\ObjectClass");
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$schema->shouldReceive('_get_entry')
->once()
->with("ObjectClass", $name)
->andReturn($entry);
$schema->shouldReceive('objectclass')->passthru();
$this->assertSame($entry, $schema->objectclass($name));
}
/**
* @covers \EesyLDAP\Schema::matching_rule
*/
public function testMatchingRule() {
$name = 'test';
$entry = Mockery::mock("overload:EesyLDAP\Schema\MatchingRule");
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$schema->shouldReceive('_get_entry')
->once()
->with("MatchingRule", $name)
->andReturn($entry);
$schema->shouldReceive('matching_rule')->passthru();
$this->assertSame($entry, $schema->matching_rule($name));
}
/**
* @covers \EesyLDAP\Schema::matching_rule_use
*/
public function testMatchingRuleUse() {
$name = 'test';
$entry = Mockery::mock("overload:EesyLDAP\Schema\MatchingRuleUse");
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$schema->shouldReceive('_get_entry')
->once()
->with("MatchingRuleUse", $name)
->andReturn($entry);
$schema->shouldReceive('matching_rule_use')->passthru();
$this->assertSame($entry, $schema->matching_rule_use($name));
}
/**
* @covers \EesyLDAP\Schema::syntax
*/
public function testSyntax() {
$name = 'test';
$entry = Mockery::mock("overload:EesyLDAP\Schema\Syntax");
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$schema->shouldReceive('_get_entry')
->once()
->with("Syntax", $name)
->andReturn($entry);
$schema->shouldReceive('syntax')->passthru();
$this->assertSame($entry, $schema->syntax($name));
}
/**
* @covers \EesyLDAP\Schema::has_attribute
*/
public function testHasAttribute() {
$attr = 'test';
$oc1 = Mockery::mock("overload:EesyLDAP\Schema\ObjectClass");
$oc1_name = 'test1';
$oc1->shouldReceive('has_attribute')
->once()
->with($attr)
->andReturn(false);
$oc2 = Mockery::mock("overload:EesyLDAP\Schema\ObjectClass");
$oc2_name = 'test2';
$oc2->shouldReceive('has_attribute')
->once()
->with($attr)
->andReturn(true);
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$schema->shouldReceive('objectclass')
->once()
->with($oc1_name)
->andReturn($oc1)
->shouldReceive('objectclass')
->once()
->with($oc2_name)
->andReturn($oc2);
$schema->shouldReceive('has_attribute')->passthru();
$this->assertTrue($schema->has_attribute($attr, $oc1_name, $oc2_name));
}
/**
* @covers \EesyLDAP\Schema::has_attribute
*/
public function testHasAttributeWithArray() {
$attr = 'test';
$oc1 = Mockery::mock("overload:EesyLDAP\Schema\ObjectClass");
$oc1_name = 'test1';
$oc1->shouldReceive('has_attribute')
->once()
->with($attr)
->andReturn(false);
$oc2 = Mockery::mock("overload:EesyLDAP\Schema\ObjectClass");
$oc2_name = 'test2';
$oc2->shouldReceive('has_attribute')
->once()
->with($attr)
->andReturn(true);
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$schema->shouldReceive('objectclass')
->once()
->with($oc1_name)
->andReturn($oc1)
->shouldReceive('objectclass')
->once()
->with($oc2_name)
->andReturn($oc2);
$schema->shouldReceive('has_attribute')->passthru();
$this->assertTrue($schema->has_attribute($attr, [$oc1_name, $oc2_name]));
}
/**
* @covers \EesyLDAP\Schema::has_attribute
*/
public function testHasAttributeWithArrayAndContinue() {
$attr = 'test';
$oc1 = Mockery::mock("overload:EesyLDAP\Schema\ObjectClass");
$oc1_name = 'test1';
$oc1->shouldReceive('has_attribute')
->once()
->with($attr)
->andReturn(false);
$oc2 = Mockery::mock("overload:EesyLDAP\Schema\ObjectClass");
$oc2_name = 'test2';
$oc2->shouldReceive('has_attribute')
->once()
->with($attr)
->andReturn(true);
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$schema->shouldReceive('objectclass')
->once()
->with($oc1_name)
->andReturn($oc1)
->shouldReceive('objectclass')
->once()
->with($oc2_name)
->andReturn($oc2);
$schema->shouldReceive('has_attribute')->passthru();
$this->assertTrue($schema->has_attribute($attr, [$oc1_name], $oc2_name));
}
/**
* @covers \EesyLDAP\Schema::has_attribute
*/
public function testHasAttributeBadObjectClass() {
$attr = 'test';
$bad_oc_name = 'badOc';
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$schema->shouldReceive('objectclass')
->once()
->with($bad_oc_name)
->andReturn(false);
$schema->shouldReceive('has_attribute')->passthru();
$this->assertFalse($schema->has_attribute($attr, $bad_oc_name));
}
/**
* @covers \EesyLDAP\Schema::has_attribute
*/
public function testHasNotAttribute() {
$bad_oc_name = "badOc";
$schema = Mockery::mock('EesyLDAP\Schema')
->shouldAllowMockingProtectedMethods();
$schema->shouldReceive('objectclass')
->once()
->with($bad_oc_name)
->andReturn(false);
$schema->shouldReceive('has_attribute')->passthru();
$this->assertFalse($schema->has_attribute("test", $bad_oc_name));
}
}