Skip to content

Commit

Permalink
Re-add element traits
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Jan 16, 2025
1 parent f37d864 commit 17d8036
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 133 deletions.
80 changes: 80 additions & 0 deletions src/TypedTextContentTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XML;

use DOMElement;
use SimpleSAML\XML\Assert\Assert;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Type\{ValueTypeInterface, StringValue};

use function defined;
use function strval;

/**
* Trait for elements that hold a typed textContent value.
*
* @package simplesaml/xml-common
*/
trait TypedTextContentTrait
{
/**
* @param \SimpleSAML\XML\Type\ValueTypeInterface $content
*/
public function __construct(
protected ValueTypeInterface $content,
) {
}


/**
* Create a class from XML
*
* @param \DOMElement $xml
* @return static
*/
public static function fromXML(DOMElement $xml): static
{
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);

$type = self::getTextContentType();
$text = $type::fromString($xml->textContent);

return new static($text);
}


/**
* Create XML from this class
*
* @param \DOMElement|null $parent
* @return \DOMElement
*/
public function toXML(?DOMElement $parent = null): DOMElement
{
$e = $this->instantiateParentElement($parent);
$e->textContent = strval($this->getContent());

return $e;
}


/**
* Get the type the element's textContent value.
*
* @return class-string
*/
public static function getTextContentType(): string
{
if (defined('static::TEXTCONTENT_TYPE')) {
$type = static::TEXTCONTENT_TYPE;
} else {
$type = StringValue::class;
}

Assert::isAOf($type, ValueTypeInterface::class);
return $type;
}
}
48 changes: 6 additions & 42 deletions tests/Utils/Base64BinaryElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,19 @@

namespace SimpleSAML\Test\XML;

use DOMElement;
use SimpleSAML\XML\AbstractElement;
use SimpleSAML\XML\Assert\Assert;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
use SimpleSAML\XML\TypedTextContentTrait;
use SimpleSAML\XML\Type\Base64BinaryValue;

use function strval;

/**
* Empty shell class for testing Base64Binary elements.
* Empty shell class for testing xs:base64Binary elements.
*
* @package simplesaml/xml-common
*/
final class Base64BinaryElement extends AbstractElement implements SchemaValidatableElementInterface
{
use TypedTextContentTrait;
use SchemaValidatableElementTrait;

/** @var string */
Expand All @@ -31,44 +28,11 @@ final class Base64BinaryElement extends AbstractElement implements SchemaValidat
/** @var string */
public const SCHEMA = 'tests/resources/schemas/deliberately-wrong-file.xsd';


/**
* @param \SimpleSAML\XML\Type\Base64BinaryValue $content
*/
public function __construct(
protected Base64BinaryValue $content,
) {
}


/**
* Create a class from XML
*
* @param \DOMElement $xml
* @return static
*/
public static function fromXML(DOMElement $xml): static
{
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);

$text = Base64BinaryValue::fromString($xml->textContent);

return new static($text);
}
/** @var string */
public const TEXTCONTENT_TYPE = AbstractElement::class; // Deliberately wrong class


/**
* Create XML from this class
*
* @param \DOMElement|null $parent
* @return \DOMElement
* NOTE: This class has some deliberately wrong values for testing purposes!!
*/
public function toXML(?DOMElement $parent = null): DOMElement
{
$e = $this->instantiateParentElement($parent);
$e->textContent = strval($this->content);

return $e;
}
}
51 changes: 5 additions & 46 deletions tests/Utils/BooleanElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,20 @@

namespace SimpleSAML\Test\XML;

use DOMElement;
use SimpleSAML\XML\AbstractElement;
use SimpleSAML\XML\Assert\Assert;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
use SimpleSAML\XML\TypedTextContentTrait;
use SimpleSAML\XML\Type\BooleanValue;

use function strval;

/**
* Empty shell class for testing String elements.
* Empty shell class for testing xs:string elements.
*
* @package simplesaml/xml-common
*/
final class BooleanElement extends AbstractElement implements SchemaValidatableElementInterface
{
use SchemaValidatableElementTrait;
use TypedTextContentTrait;

/** @var string */
public const NS = 'urn:x-simplesamlphp:namespace';
Expand All @@ -31,44 +28,6 @@ final class BooleanElement extends AbstractElement implements SchemaValidatableE
/** @var string */
public const SCHEMA = 'tests/resources/schemas/simplesamlphp.xsd';


/**
* @param \SimpleSAML\XML\Type\BooleanValue $content
*/
public function __construct(
protected BooleanValue $content,
) {
}


/**
* Create a class from XML
*
* @param \DOMElement $xml
* @return static
*/
public static function fromXML(DOMElement $xml): static
{
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);

$text = BooleanValue::fromString($xml->textContent);

return new static($text);
}


/**
* Create XML from this class
*
* @param \DOMElement|null $parent
* @return \DOMElement
*/
public function toXML(?DOMElement $parent = null): DOMElement
{
$e = $this->instantiateParentElement($parent);
$e->textContent = strval($this->content);

return $e;
}
/** @var string */
public const TEXTCONTENT_TYPE = BooleanValue::class;
}
49 changes: 4 additions & 45 deletions tests/Utils/StringElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,11 @@

namespace SimpleSAML\Test\XML;

use DOMElement;
use SimpleSAML\XML\AbstractElement;
use SimpleSAML\XML\Assert\Assert;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
use SimpleSAML\XML\TypedTextContentTrait;
use SimpleSAML\XML\Type\StringValue;

use function strval;

/**
* Empty shell class for testing String elements.
*
Expand All @@ -21,6 +17,7 @@
final class StringElement extends AbstractElement implements SchemaValidatableElementInterface
{
use SchemaValidatableElementTrait;
use TypedTextContentTrait;

/** @var string */
public const NS = 'urn:x-simplesamlphp:namespace';
Expand All @@ -31,44 +28,6 @@ final class StringElement extends AbstractElement implements SchemaValidatableEl
/** @var string */
public const SCHEMA = 'tests/resources/schemas/simplesamlphp.xsd';


/**
* @param \SimpleSAML\XML\Type\StringValue $content
*/
public function __construct(
protected StringValue $content,
) {
}


/**
* Create a class from XML
*
* @param \DOMElement $xml
* @return static
*/
public static function fromXML(DOMElement $xml): static
{
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);

$text = StringValue::fromString($xml->textContent);

return new static($text);
}


/**
* Create XML from this class
*
* @param \DOMElement|null $parent
* @return \DOMElement
*/
public function toXML(?DOMElement $parent = null): DOMElement
{
$e = $this->instantiateParentElement($parent);
$e->textContent = strval($this->content);

return $e;
}
/** @var string */
public const TEXTCONTENT_TYPE = StringValue::class;
}
63 changes: 63 additions & 0 deletions tests/XML/TypedTextContentTraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\XML;

use DOMDocument;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\Exception\IOException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\TypedTextContentTrait;

/**
* Class \SimpleSAML\XML\TypedTextContentTraitTest
*
* @package simplesamlphp\xml-common
*/
#[CoversClass(TypedTextContentTrait::class)]
final class TypedTextContentTraitTest extends TestCase
{
public function testTypedContentPassesForString(): void
{
$file = 'tests/resources/xml/ssp_StringElement.xml';
$chunk = DOMDocumentFactory::fromFile($file);

$stringElt = StringElement::fromXML($chunk->documentElement);
$this->assertInstanceOf(StringElement::class, $stringElt);
}


public function testTypedContentPassesForBoolean(): void
{
$file = 'tests/resources/xml/ssp_BooleanElement.xml';
$chunk = DOMDocumentFactory::fromFile($file);

$stringElt = BooleanElement::fromXML($chunk->documentElement);
$this->assertInstanceOf(BooleanElement::class, $stringElt);
}


public function testTypedContentFailsForWrongType(): void
{
$file = 'tests/resources/xml/ssp_BooleanElement.xml';
$chunk = DOMDocumentFactory::fromFile($file);
$chunk->documentElement->textContent = 'not-a-boolean';

$this->expectException(SchemaViolationException::class);
BooleanElement::fromXML($chunk->documentElement);
}


public function testTypedContentFailsForWrongClass(): void
{
$file = 'tests/resources/xml/ssp_BooleanElement.xml';
$chunk = DOMDocumentFactory::fromFile($file);
$chunk->documentElement->textContent = 'not-a-boolean';

$this->expectException(SchemaViolationException::class);
BooleanElement::fromXML($chunk->documentElement);
}
}

0 comments on commit 17d8036

Please sign in to comment.