Skip to content

Commit

Permalink
Add HexBinaryElementTrait
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Dec 4, 2024
1 parent 525095b commit 83e5414
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 0 deletions.
65 changes: 65 additions & 0 deletions src/HexBinaryElementTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XML;

use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\Exception\SchemaViolationException;

/**
* Trait grouping common functionality for simple elements with hexbinary textContent
*
* @package simplesamlphp/xml-common
*/
trait HexBinaryElementTrait
{
use StringElementTrait;


/**
* Sanitize the content of the element.
*
* Note: There are no processing rules for xs:hexBinary regarding whitespace. General consensus is to strip them
*
* @param string $content The unsanitized textContent
* @throws \Exception on failure
* @return string
*/
protected function sanitizeContent(string $content): string
{
return str_replace(["\f", "\r", "\n", "\t", "\v", ' '], '', $content);
}


/**
* Validate the content of the element.
*
* @param string $content The value to go in the XML textContent
* @throws \Exception on failure
* @return void
*/
protected function validateContent(string $content): void
{
// Note: content must already be sanitized before validating
Assert::regex(
$this->sanitizeContent($content),
'/([0-9A-F]{2})*/i',
SchemaViolationException::class,
);
}


/** @return string */
abstract public static function getLocalName(): string;


/**
* Create a document structure for this element
*
* @param \DOMElement|null $parent The element we should append to.
* @return \DOMElement
*/
abstract public function instantiateParentElement(?DOMElement $parent = null): DOMElement;
}
33 changes: 33 additions & 0 deletions tests/Utils/HexBinaryElement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\XML;

use SimpleSAML\XML\AbstractElement;
use SimpleSAML\XML\HexBinaryElementTrait;

/**
* Empty shell class for testing HexBinaryElement.
*
* @package simplesaml/xml-common
*/
final class HexBinaryElement extends AbstractElement
{
use HexBinaryElementTrait;

/** @var string */
public const NS = 'urn:x-simplesamlphp:namespace';

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


/**
* @param string $content
*/
public function __construct(string $content)
{
$this->setContent($content);
}
}
112 changes: 112 additions & 0 deletions tests/XML/HexBinaryElementTraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\XML;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use SimpleSAML\Test\XML\XMLDumper;
use SimpleSAML\XML\AbstractElement;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\HexBinaryElementTrait;
use SimpleSAML\XML\StringElementTrait;
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;

use function dirname;
use function strval;

/**
* Class \SimpleSAML\XML\HexBinaryElementTraitTest
*
* @package simplesamlphp\xml-common
*/
#[CoversClass(SerializableElementTestTrait::class)]
#[CoversClass(HexBinaryElementTrait::class)]
#[CoversClass(StringElementTrait::class)]
#[CoversClass(AbstractElement::class)]
final class HexBinaryElementTraitTest extends TestCase
{
use SerializableElementTestTrait;


/**
*/
public static function setUpBeforeClass(): void
{
self::$testedClass = HexBinaryElement::class;

self::$xmlRepresentation = DOMDocumentFactory::fromFile(
dirname(__FILE__, 2) . '/resources/xml/ssp_HexBinaryElement.xml',
);
}

/**
*/
public function testMarshalling(): void
{
$hexBinaryElement = new HexBinaryElement(
'3f3c6d78206c657673726f693d6e3122302e20226e656f636964676e223d54552d4622383e3f',
);

$this->assertEquals(
XMLDumper::dumpDOMDocumentXMLWithBase64Content(self::$xmlRepresentation),
strval($hexBinaryElement),
);
}


/**
*/
public function testUnmarshalling(): void
{
/** @var \DOMElement $xml */
$xml = self::$xmlRepresentation->documentElement;
$hexBinaryElement = HexBinaryElement::fromXML($xml);

$this->assertEquals(
'3f3c6d78206c657673726f693d6e3122302e20226e656f636964676e223d54552d4622383e3f',
$hexBinaryElement->getContent(),
);
}


/**
* @param non-empty-string $xml
*/
#[DataProvider('provideHexBinaryCases')]
public function testHexBinaryCases(string $xml): void
{
$xmlRepresentation = DOMDocumentFactory::fromString($xml);
/** @var \DOMElement $xmlElement */
$xmlElement = $xmlRepresentation->documentElement;

$hexBinary = HexBinaryElement::fromXML($xmlElement);

$this->assertStringContainsString($hexBinary->getRawContent(), $xml);
}

/**
* @return array<string, array{0: string}>
*/
public static function provideHexBinaryCases(): array
{
return [
'inline' => [
<<<XML
<ssp:HexBinaryElement xmlns:ssp="urn:x-simplesamlphp:namespace">3f3c6d78206c657673726f693d6e3122302e20226e656f636964676e223d54552d4622383e3f</ssp:HexBinaryElement>
XML
,
],
'multiline' => [
<<<XML
<ssp:HexBinaryElement xmlns:ssp="urn:x-simplesamlphp:namespace">
3f3c6d78206c657673726f693d6e3122302e20226e656f636964676e223d54552d4622383e3f
</ssp:HexBinaryElement>
XML
,
],
];
}
}
1 change: 1 addition & 0 deletions tests/resources/xml/ssp_HexBinaryElement.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<ssp:HexBinaryElement xmlns:ssp="urn:x-simplesamlphp:namespace">3f3c6d78206c657673726f693d6e3122302e20226e656f636964676e223d54552d4622383e3f</ssp:HexBinaryElement>

0 comments on commit 83e5414

Please sign in to comment.