Skip to content

Commit

Permalink
Improve unit-test for indexed endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed May 22, 2023
1 parent 532795e commit b418b3e
Show file tree
Hide file tree
Showing 8 changed files with 334 additions and 101 deletions.
33 changes: 33 additions & 0 deletions src/SAML2/XML/idpdisc/DiscoveryResponse.php
Expand Up @@ -4,6 +4,7 @@

namespace SimpleSAML\SAML2\XML\idpdisc;

use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Constants as C;
use SimpleSAML\SAML2\XML\md\AbstractIndexedEndpointType;

Expand All @@ -21,4 +22,36 @@ final class DiscoveryResponse extends AbstractIndexedEndpointType

/** @var string */
public const NS_PREFIX = 'idpdisc';


/**
* DiscoveryResponse constructor.
*
* This is an endpoint with one restriction: it cannot contain a ResponseLocation.
*
* @param int $index
* @param string $binding
* @param string $location
* @param bool|null $isDefault
* @param string|null $unused
* @param list<\SimpleSAML\XML\Attribute> $attributes
* @param array $children
*
* @throws \SimpleSAML\Assert\AssertionFailedException
*/
public function __construct(
int $index,
string $binding,
string $location,
?bool $isDefault = null,
?string $unused = null,
array $attributes = [],
array $children = [],
) {
Assert::null(
$unused,
'The \'ResponseLocation\' attribute must be omitted for idpdisc:DiscoveryResponse.',
);
parent::__construct($index, $binding, $location, $isDefault, null, $attributes, $children);
}
}
2 changes: 1 addition & 1 deletion src/SAML2/XML/md/ArtifactResolutionService.php
Expand Up @@ -24,7 +24,7 @@ final class ArtifactResolutionService extends AbstractIndexedEndpointType
* @param bool|null $isDefault
* @param string|null $unused
* @param list<\SimpleSAML\XML\Attribute> $attributes
* @param array children
* @param array $children
*
* @throws \SimpleSAML\Assert\AssertionFailedException
*/
Expand Down
69 changes: 60 additions & 9 deletions tests/SAML2/XML/idpdisc/DiscoveryResponseTest.php
Expand Up @@ -9,9 +9,12 @@
use SimpleSAML\Assert\AssertionFailedException;
use SimpleSAML\SAML2\XML\idpdisc\DiscoveryResponse;
use SimpleSAML\Test\SAML2\Constants as C;
use SimpleSAML\XML\Attribute as XMLAttribute;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\MissingAttributeException;
use SimpleSAML\XML\TestUtils\ArrayizableElementTestTrait;
use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait;
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;

Expand All @@ -28,9 +31,16 @@
*/
final class DiscoveryResponseTest extends TestCase
{
use ArrayizableElementTestTrait;
use SchemaValidationTestTrait;
use SerializableElementTestTrait;

/** @var \SimpleSAML\XML\Chunk */
protected Chunk $ext;

/** @var \SimpleSAML\XML\Attribute */
protected XMLAttribute $attr;


/**
*/
Expand All @@ -40,6 +50,22 @@ protected function setUp(): void

$this->testedClass = DiscoveryResponse::class;

$this->attr = new XMLAttribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr1', 'testval1');

$this->ext = new Chunk(DOMDocumentFactory::fromString(
'<some:Ext xmlns:some="urn:mace:some:metadata:1.0">SomeExtension</some:Ext>'
)->documentElement);

$this->arrayRepresentation = [
'index' => 1,
'Binding' => C::BINDING_HTTP_POST,
'Location' => 'https://whatever/',
'isDefault' => true,
//'ResponseLocation' => null,
'Extensions' => [$this->ext],
'attributes' => [$this->attr->toArray()],
];

$this->xmlRepresentation = DOMDocumentFactory::fromFile(
dirname(__FILE__, 4) . '/resources/xml/idpdisc_DiscoveryResponse.xml',
);
Expand All @@ -54,7 +80,15 @@ protected function setUp(): void
*/
public function testMarshalling(): void
{
$discoResponse = new DiscoveryResponse(43, C::BINDING_HTTP_POST, C::LOCATION_A, false);
$discoResponse = new DiscoveryResponse(
43,
C::BINDING_HTTP_POST,
C::LOCATION_A,
false,
null,
[$this->attr],
[$this->ext],
);

$this->assertEquals(
$this->xmlRepresentation->saveXML($this->xmlRepresentation->documentElement),
Expand All @@ -64,17 +98,15 @@ public function testMarshalling(): void


/**
* Test that creating a DiscoveryResponse from scratch without specifying isDefault works.
* Test that creating a DiscoveryResponseService from scratch with a ResponseLocation fails.
*/
public function testMarshallingWithoutIsDefault(): void
public function testMarshallingWithResponseLocation(): void
{
$discoResponse = new DiscoveryResponse(43, C::BINDING_HTTP_POST, C::LOCATION_A);
$this->xmlRepresentation->documentElement->removeAttribute('isDefault');
$this->assertEquals(
$this->xmlRepresentation->saveXML($this->xmlRepresentation->documentElement),
strval($discoResponse),
$this->expectException(AssertionFailedException::class);
$this->expectExceptionMessage(
'The \'ResponseLocation\' attribute must be omitted for idpdisc:DiscoveryResponse.',
);
$this->assertNull($discoResponse->getIsDefault());
new DiscoveryResponse(42, C::BINDING_HTTP_ARTIFACT, C::LOCATION_A, false, 'https://response.location/');
}


Expand All @@ -93,4 +125,23 @@ public function testUnmarshalling(): void
strval($discoResponse),
);
}


/**
* Test that creating a DiscoveryResponse from XML fails when ResponseLocation is present.
*/
public function testUnmarshallingWithResponseLocation(): void
{
$this->expectException(AssertionFailedException::class);
$this->expectExceptionMessage(
'The \'ResponseLocation\' attribute must be omitted for idpdisc:DiscoveryResponse.',
);
$this->xmlRepresentation->documentElement->setAttribute('ResponseLocation', 'https://response.location/');

DiscoveryResponse::fromXML($this->xmlRepresentation->documentElement);
DiscoveryResponse::fromArray(array_merge(
$this->arrayRepresentation,
['ResponseLocation', 'https://response.location'],
));
}
}
41 changes: 31 additions & 10 deletions tests/SAML2/XML/md/ArtifactResolutionServiceTest.php
Expand Up @@ -12,43 +12,61 @@
use SimpleSAML\XML\Attribute as XMLAttribute;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\TestUtils\ArrayizableElementTestTrait;
use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait;
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;

use function array_merge;
use function dirname;
use function strval;

/**
* Tests for md:ArtifactResolutionService.
*
* @covers \SimpleSAML\SAML2\XML\md\AbstractMdElement
* @covers \SimpleSAML\SAML2\XML\md\AbstractIndexedEndpointType
* @covers \SimpleSAML\SAML2\XML\md\ArtifactResolutionService
* @package simplesamlphp/saml2
*/
final class ArtifactResolutionServiceTest extends TestCase
{
use ArrayizableElementTestTrait;
use SchemaValidationTestTrait;
use SerializableElementTestTrait;

/** @var \DOMDocument */
protected DOMDocument $ext;
/** @var \SimpleSAML\XML\Chunk */
protected Chunk $ext;

/** @var \SimpleSAML\XML\Attribute */
protected XMLAttribute $attr;


/**
*/
protected function setUp(): void
{
$this->ext = new Chunk(DOMDocumentFactory::fromString(
'<some:Ext xmlns:some="urn:mace:some:metadata:1.0">SomeExtension</some:Ext>'
)->documentElement);

$this->attr = new XMLAttribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr1', 'testval1');

$this->schema = dirname(__FILE__, 5) . '/resources/schemas/saml-schema-metadata-2.0.xsd';

$this->testedClass = ArtifactResolutionService::class;

$this->arrayRepresentation = [
'index' => 1,
'Binding' => C::BINDING_HTTP_ARTIFACT,
'Location' => 'https://whatever/',
'isDefault' => true,
'Extensions' => [$this->ext],
'attributes' => [$this->attr->toArray()],
];

$this->xmlRepresentation = DOMDocumentFactory::fromFile(
dirname(__FILE__, 4) . '/resources/xml/md_ArtifactResolutionService.xml',
);

$this->ext = DOMDocumentFactory::fromString(
'<some:Ext xmlns:some="urn:mace:some:metadata:1.0">SomeExtension</some:Ext>'
);
}


Expand All @@ -60,16 +78,14 @@ protected function setUp(): void
*/
public function testMarshalling(): void
{
$attr = new XMLAttribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr1', 'testval1');

$ars = new ArtifactResolutionService(
42,
C::BINDING_HTTP_ARTIFACT,
'https://simplesamlphp.org/some/endpoint',
false,
null,
[$attr],
[new Chunk($this->ext->documentElement)],
[$this->attr],
[$this->ext],
);

$this->assertEquals(
Expand Down Expand Up @@ -119,6 +135,11 @@ public function testUnmarshallingWithResponseLocation(): void
'The \'ResponseLocation\' attribute must be omitted for md:ArtifactResolutionService.',
);
$this->xmlRepresentation->documentElement->setAttribute('ResponseLocation', 'https://response.location/');

ArtifactResolutionService::fromXML($this->xmlRepresentation->documentElement);
ArtifactResolutionService::fromArray(array_merge(
$this->arrayRepresentation,
['ResponseLocation', 'https://response.location'],
));
}
}
114 changes: 114 additions & 0 deletions tests/SAML2/XML/md/AssertionConsumerServiceTest.php
@@ -0,0 +1,114 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\SAML2\XML\md;

use DOMDocument;
use PHPUnit\Framework\TestCase;
use SimpleSAML\SAML2\XML\md\AssertionConsumerService;
use SimpleSAML\Test\SAML2\Constants as C;
use SimpleSAML\XML\Attribute as XMLAttribute;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\MissingAttributeException;
use SimpleSAML\XML\TestUtils\ArrayizableElementTestTrait;
use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait;
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;

use function dirname;
use function strval;

/**
* Class \SimpleSAML\SAML2\XML\md\AssertionConsumerServiceTest
*
* @covers \SimpleSAML\SAML2\XML\md\AssertionConsumerService
* @covers \SimpleSAML\SAML2\XML\md\AbstractIndexedEndpointType
* @covers \SimpleSAML\SAML2\XML\md\AbstractMdElement
* @package simplesamlphp/saml2
*/
final class AssertionConsumerServiceTest extends TestCase
{
use ArrayizableElementTestTrait;
use SchemaValidationTestTrait;
use SerializableElementTestTrait;

/** @var \SimpleSAML\XML\Chunk */
protected Chunk $ext;

/** @var \SimpleSAML\XML\Attribute */
protected XMLAttribute $attr;


/**
*/
protected function setUp(): void
{
$this->ext = new Chunk(DOMDocumentFactory::fromString(
'<some:Ext xmlns:some="urn:mace:some:metadata:1.0">SomeExtension</some:Ext>',
)->documentElement);

$this->attr = new XMLAttribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr1', 'testval1');

$this->schema = dirname(__FILE__, 5) . '/resources/schemas/saml-schema-metadata-2.0.xsd';

$this->testedClass = AssertionConsumerService::class;

$this->arrayRepresentation = [
'index' => 1,
'Binding' => C::BINDING_HTTP_POST,
'Location' => 'https://whatever/',
'isDefault' => true,
'ResponseLocation' => 'https://foo.bar/',
'Extensions' => [$this->ext],
'attributes' => [$this->attr->toArray()],
];

$this->xmlRepresentation = DOMDocumentFactory::fromFile(
dirname(__FILE__, 4) . '/resources/xml/md_AssertionConsumerService.xml',
);
}


// test marshalling


/**
* Test creating an IndexedEndpointType from scratch.
*/
public function testMarshalling(): void
{
$idxep = new AssertionConsumerService(
42,
C::BINDING_HTTP_POST,
C::LOCATION_A,
false,
'https://foo.bar/',
[$this->attr],
[$this->ext],
);

$this->assertEquals(
$this->xmlRepresentation->saveXML($this->xmlRepresentation->documentElement),
strval($idxep),
);
}


// test unmarshalling


/**
* Test creating an IndexedEndpointType from XML.
*/
public function testUnmarshalling(): void
{
$idxep = AssertionConsumerService::fromXML($this->xmlRepresentation->documentElement);

$this->assertEquals(
$this->xmlRepresentation->saveXML($this->xmlRepresentation->documentElement),
strval($idxep),
);
}
}

0 comments on commit b418b3e

Please sign in to comment.