diff --git a/src/DataFormatter/XMLDataFormatter.php b/src/DataFormatter/XMLDataFormatter.php index c4ba879..db91c34 100644 --- a/src/DataFormatter/XMLDataFormatter.php +++ b/src/DataFormatter/XMLDataFormatter.php @@ -117,9 +117,9 @@ public function convertDataObjectWithoutHeader(DataObject $obj, $fields = null, { $className = $this->sanitiseClassName(get_class($obj)); $id = $obj->ID; - $objHref = Director::absoluteURL($this->config()->api_base . "$className/$obj->ID"); + $objHref = Director::absoluteURL($this->config()->api_base . "$className/$obj->ID" . ".xml"); - $xml = "<$className href=\"$objHref.xml\">\n"; + $xml = "<$className href=\"$objHref\">\n"; foreach ($this->getFieldsForObj($obj) as $fieldName => $fieldType) { // Field filtering if ($fields && !in_array($fieldName, $fields ?? [])) { @@ -160,11 +160,11 @@ public function convertDataObjectWithoutHeader(DataObject $obj, $fields = null, $fieldName = $relName . 'ID'; if ($obj->$fieldName) { - $href = Director::absoluteURL($this->config()->api_base . "$relClass/" . $obj->$fieldName); + $href = Director::absoluteURL($this->config()->api_base . "$relClass/" . $obj->$fieldName . ".xml"); } else { - $href = Director::absoluteURL($this->config()->api_base . "$className/$id/$relName"); + $href = Director::absoluteURL($this->config()->api_base . "$className/$id/$relName" . ".xml"); } - $xml .= "<$relName linktype=\"has_one\" href=\"$href.xml\" id=\"" . $obj->$fieldName + $xml .= "<$relName linktype=\"has_one\" href=\"$href\" id=\"" . $obj->$fieldName . "\">\n"; } @@ -190,8 +190,8 @@ public function convertDataObjectWithoutHeader(DataObject $obj, $fields = null, $items = $obj->$relName(); if ($items) { foreach ($items as $item) { - $href = Director::absoluteURL($this->config()->api_base . "$relClass/$item->ID"); - $xml .= "<$relClass href=\"$href.xml\" id=\"{$item->ID}\">\n"; + $href = Director::absoluteURL($this->config()->api_base . "$relClass/$item->ID" . ".xml"); + $xml .= "<$relClass href=\"$href\" id=\"{$item->ID}\">\n"; } } $xml .= "\n"; @@ -221,8 +221,8 @@ public function convertDataObjectWithoutHeader(DataObject $obj, $fields = null, $items = $obj->$relName(); if ($items) { foreach ($items as $item) { - $href = Director::absoluteURL($this->config()->api_base . "$relClass/$item->ID"); - $xml .= "<$relClass href=\"$href.xml\" id=\"{$item->ID}\">\n"; + $href = Director::absoluteURL($this->config()->api_base . "$relClass/$item->ID" . ".xml"); + $xml .= "<$relClass href=\"$href\" id=\"{$item->ID}\">\n"; } } $xml .= "\n"; diff --git a/tests/unit/XMLDataFormatterTest.php b/tests/unit/XMLDataFormatterTest.php index 8da70a1..9b3ffe1 100644 --- a/tests/unit/XMLDataFormatterTest.php +++ b/tests/unit/XMLDataFormatterTest.php @@ -5,6 +5,8 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\RestfulServer\DataFormatter\XMLDataFormatter; use Exception; +use SilverStripe\Control\Controller; +use SilverStripe\ORM\DataObject; class XMLDataFormatterTest extends SapphireTest { @@ -74,4 +76,51 @@ public function testConvertStringToArrayMultipleEntitiesException() $formatter = new XMLDataFormatter(); $formatter->convertStringToArray($inputXML); } + + /** + * Data provider for trailing slash configuration + */ + public function trailingSlashProvider(): array + { + return [ + 'without trailing slash' => [false], + 'with trailing slash' => [true], + ]; + } + + /** + * Tests wrapper output of {@link XMLDataFormatter::convertDataObjectWithoutHeader()} + * + * @param bool $addTrailingSlash - Whether to add a trailing slash to the API endpoint + * @dataProvider trailingSlashProvider + */ + public function testConvertDataObjectWithoutHeaderClassNameAttribute(bool $addTrailingSlash): void + { + // Create a mock object + $mock = DataObject::create(); + $mock->ID = 1; + + // Set trailing slash configuration + Controller::config()->set('add_trailing_slash', $addTrailingSlash); + + // Create a formatter + $formatter = new XMLDataFormatter(); + + // Test the output + $expectedClass = 'SilverStripe-ORM-DataObject'; + $expectedHref = sprintf('http://localhost/api/v1/%s/%d.xml', $expectedClass, $mock->ID); + $expectedOutput = sprintf( + '<%s href="%s">%d', + $expectedClass, + $expectedHref, + $mock->ID, + $expectedClass + ); + + $actualOutput = $formatter->convertDataObjectWithoutHeader($mock); + + // remove line breaks and compare + $actualOutput = str_replace(["\n", "\r"], '', $actualOutput); + $this->assertEquals($expectedOutput, $actualOutput); + } }