Skip to content

Commit 09e52e8

Browse files
committed
Re-add element traits
1 parent f37d864 commit 09e52e8

File tree

5 files changed

+156
-134
lines changed

5 files changed

+156
-134
lines changed

src/TypedTextContentTrait.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\XML;
6+
7+
use DOMElement;
8+
use SimpleSAML\XML\Assert\Assert;
9+
use SimpleSAML\XML\Exception\InvalidDOMElementException;
10+
use SimpleSAML\XML\Type\{ValueTypeInterface, StringValue};
11+
12+
use function defined;
13+
use function strval;
14+
15+
/**
16+
* Trait for elements that hold a typed textContent value.
17+
*
18+
* @package simplesaml/xml-common
19+
*/
20+
trait TypedTextContentTrait
21+
{
22+
/**
23+
* @param \SimpleSAML\XML\Type\ValueTypeInterface $content
24+
*/
25+
public function __construct(
26+
protected ValueTypeInterface $content,
27+
) {
28+
}
29+
30+
31+
/**
32+
* Create a class from XML
33+
*
34+
* @param \DOMElement $xml
35+
* @return static
36+
*/
37+
public static function fromXML(DOMElement $xml): static
38+
{
39+
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
40+
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
41+
42+
$type = self::getTextContentType();
43+
$text = $type::fromString($xml->textContent);
44+
45+
return new static($text);
46+
}
47+
48+
49+
/**
50+
* Create XML from this class
51+
*
52+
* @param \DOMElement|null $parent
53+
* @return \DOMElement
54+
*/
55+
public function toXML(?DOMElement $parent = null): DOMElement
56+
{
57+
$e = $this->instantiateParentElement($parent);
58+
$e->textContent = strval($this->getContent());
59+
60+
return $e;
61+
}
62+
63+
64+
/**
65+
* Get the type the element's textContent value.
66+
*
67+
* @return class-string
68+
*/
69+
public static function getTextContentType(): string
70+
{
71+
if (defined('static::TEXTCONTENT_TYPE')) {
72+
$type = static::TEXTCONTENT_TYPE;
73+
} else {
74+
$type = StringValue::class;
75+
}
76+
77+
Assert::isAOf($type, ValueTypeInterface::class);
78+
return $type;
79+
}
80+
}

tests/Utils/Base64BinaryElement.php

Lines changed: 6 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,18 @@
44

55
namespace SimpleSAML\Test\XML;
66

7-
use DOMElement;
87
use SimpleSAML\XML\AbstractElement;
9-
use SimpleSAML\XML\Assert\Assert;
10-
use SimpleSAML\XML\Exception\InvalidDOMElementException;
118
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
12-
use SimpleSAML\XML\Type\Base64BinaryValue;
13-
14-
use function strval;
9+
use SimpleSAML\XML\TypedTextContentTrait;
1510

1611
/**
17-
* Empty shell class for testing Base64Binary elements.
12+
* Empty shell class for testing xs:base64Binary elements.
1813
*
1914
* @package simplesaml/xml-common
2015
*/
2116
final class Base64BinaryElement extends AbstractElement implements SchemaValidatableElementInterface
2217
{
18+
use TypedTextContentTrait;
2319
use SchemaValidatableElementTrait;
2420

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

34-
35-
/**
36-
* @param \SimpleSAML\XML\Type\Base64BinaryValue $content
37-
*/
38-
public function __construct(
39-
protected Base64BinaryValue $content,
40-
) {
41-
}
42-
43-
44-
/**
45-
* Create a class from XML
46-
*
47-
* @param \DOMElement $xml
48-
* @return static
49-
*/
50-
public static function fromXML(DOMElement $xml): static
51-
{
52-
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
53-
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
54-
55-
$text = Base64BinaryValue::fromString($xml->textContent);
56-
57-
return new static($text);
58-
}
30+
/** @var string */
31+
public const TEXTCONTENT_TYPE = AbstractElement::class; // Deliberately wrong class
5932

6033

6134
/**
62-
* Create XML from this class
63-
*
64-
* @param \DOMElement|null $parent
65-
* @return \DOMElement
35+
* NOTE: This class has some deliberately wrong values for testing purposes!!
6636
*/
67-
public function toXML(?DOMElement $parent = null): DOMElement
68-
{
69-
$e = $this->instantiateParentElement($parent);
70-
$e->textContent = strval($this->content);
71-
72-
return $e;
73-
}
7437
}

tests/Utils/BooleanElement.php

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,20 @@
44

55
namespace SimpleSAML\Test\XML;
66

7-
use DOMElement;
87
use SimpleSAML\XML\AbstractElement;
9-
use SimpleSAML\XML\Assert\Assert;
10-
use SimpleSAML\XML\Exception\InvalidDOMElementException;
118
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
9+
use SimpleSAML\XML\TypedTextContentTrait;
1210
use SimpleSAML\XML\Type\BooleanValue;
1311

14-
use function strval;
15-
1612
/**
17-
* Empty shell class for testing String elements.
13+
* Empty shell class for testing xs:string elements.
1814
*
1915
* @package simplesaml/xml-common
2016
*/
2117
final class BooleanElement extends AbstractElement implements SchemaValidatableElementInterface
2218
{
2319
use SchemaValidatableElementTrait;
20+
use TypedTextContentTrait;
2421

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

34-
35-
/**
36-
* @param \SimpleSAML\XML\Type\BooleanValue $content
37-
*/
38-
public function __construct(
39-
protected BooleanValue $content,
40-
) {
41-
}
42-
43-
44-
/**
45-
* Create a class from XML
46-
*
47-
* @param \DOMElement $xml
48-
* @return static
49-
*/
50-
public static function fromXML(DOMElement $xml): static
51-
{
52-
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
53-
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
54-
55-
$text = BooleanValue::fromString($xml->textContent);
56-
57-
return new static($text);
58-
}
59-
60-
61-
/**
62-
* Create XML from this class
63-
*
64-
* @param \DOMElement|null $parent
65-
* @return \DOMElement
66-
*/
67-
public function toXML(?DOMElement $parent = null): DOMElement
68-
{
69-
$e = $this->instantiateParentElement($parent);
70-
$e->textContent = strval($this->content);
71-
72-
return $e;
73-
}
31+
/** @var string */
32+
public const TEXTCONTENT_TYPE = BooleanValue::class;
7433
}

tests/Utils/StringElement.php

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,11 @@
44

55
namespace SimpleSAML\Test\XML;
66

7-
use DOMElement;
87
use SimpleSAML\XML\AbstractElement;
9-
use SimpleSAML\XML\Assert\Assert;
10-
use SimpleSAML\XML\Exception\InvalidDOMElementException;
118
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
9+
use SimpleSAML\XML\TypedTextContentTrait;
1210
use SimpleSAML\XML\Type\StringValue;
1311

14-
use function strval;
15-
1612
/**
1713
* Empty shell class for testing String elements.
1814
*
@@ -21,6 +17,7 @@
2117
final class StringElement extends AbstractElement implements SchemaValidatableElementInterface
2218
{
2319
use SchemaValidatableElementTrait;
20+
use TypedTextContentTrait;
2421

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

34-
35-
/**
36-
* @param \SimpleSAML\XML\Type\StringValue $content
37-
*/
38-
public function __construct(
39-
protected StringValue $content,
40-
) {
41-
}
42-
43-
44-
/**
45-
* Create a class from XML
46-
*
47-
* @param \DOMElement $xml
48-
* @return static
49-
*/
50-
public static function fromXML(DOMElement $xml): static
51-
{
52-
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
53-
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
54-
55-
$text = StringValue::fromString($xml->textContent);
56-
57-
return new static($text);
58-
}
59-
60-
61-
/**
62-
* Create XML from this class
63-
*
64-
* @param \DOMElement|null $parent
65-
* @return \DOMElement
66-
*/
67-
public function toXML(?DOMElement $parent = null): DOMElement
68-
{
69-
$e = $this->instantiateParentElement($parent);
70-
$e->textContent = strval($this->content);
71-
72-
return $e;
73-
}
31+
/** @var string */
32+
public const TEXTCONTENT_TYPE = StringValue::class;
7433
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\Test\XML;
6+
7+
use PHPUnit\Framework\Attributes\CoversClass;
8+
use PHPUnit\Framework\TestCase;
9+
use SimpleSAML\XML\DOMDocumentFactory;
10+
use SimpleSAML\XML\Exception\SchemaViolationException;
11+
use SimpleSAML\XML\TypedTextContentTrait;
12+
13+
/**
14+
* Class \SimpleSAML\XML\TypedTextContentTraitTest
15+
*
16+
* @package simplesamlphp\xml-common
17+
*/
18+
#[CoversClass(TypedTextContentTrait::class)]
19+
final class TypedTextContentTraitTest extends TestCase
20+
{
21+
public function testTypedContentPassesForString(): void
22+
{
23+
$file = 'tests/resources/xml/ssp_StringElement.xml';
24+
$chunk = DOMDocumentFactory::fromFile($file);
25+
26+
$stringElt = StringElement::fromXML($chunk->documentElement);
27+
$this->assertInstanceOf(StringElement::class, $stringElt);
28+
}
29+
30+
31+
public function testTypedContentPassesForBoolean(): void
32+
{
33+
$file = 'tests/resources/xml/ssp_BooleanElement.xml';
34+
$chunk = DOMDocumentFactory::fromFile($file);
35+
36+
$stringElt = BooleanElement::fromXML($chunk->documentElement);
37+
$this->assertInstanceOf(BooleanElement::class, $stringElt);
38+
}
39+
40+
41+
public function testTypedContentFailsForWrongType(): void
42+
{
43+
$file = 'tests/resources/xml/ssp_BooleanElement.xml';
44+
$chunk = DOMDocumentFactory::fromFile($file);
45+
$chunk->documentElement->textContent = 'not-a-boolean';
46+
47+
$this->expectException(SchemaViolationException::class);
48+
BooleanElement::fromXML($chunk->documentElement);
49+
}
50+
51+
52+
public function testTypedContentFailsForWrongClass(): void
53+
{
54+
$file = 'tests/resources/xml/ssp_BooleanElement.xml';
55+
$chunk = DOMDocumentFactory::fromFile($file);
56+
$chunk->documentElement->textContent = 'not-a-boolean';
57+
58+
$this->expectException(SchemaViolationException::class);
59+
BooleanElement::fromXML($chunk->documentElement);
60+
}
61+
}

0 commit comments

Comments
 (0)