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 @@ class XMLDataFormatter extends DataFormatter
{
$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 @@ class XMLDataFormatter extends DataFormatter
$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
. "\">$relName>\n";
}
@@ -190,8 +190,8 @@ class XMLDataFormatter extends DataFormatter
$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}\">$relClass>\n";
+ $href = Director::absoluteURL($this->config()->api_base . "$relClass/$item->ID" . ".xml");
+ $xml .= "<$relClass href=\"$href\" id=\"{$item->ID}\">$relClass>\n";
}
}
$xml .= "$relName>\n";
@@ -221,8 +221,8 @@ class XMLDataFormatter extends DataFormatter
$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}\">$relClass>\n";
+ $href = Director::absoluteURL($this->config()->api_base . "$relClass/$item->ID" . ".xml");
+ $xml .= "<$relClass href=\"$href\" id=\"{$item->ID}\">$relClass>\n";
}
}
$xml .= "$relName>\n";
diff --git a/tests/unit/XMLDataFormatterTest.php b/tests/unit/XMLDataFormatterTest.php
index 8da70a1..328068a 100644
--- a/tests/unit/XMLDataFormatterTest.php
+++ b/tests/unit/XMLDataFormatterTest.php
@@ -5,6 +5,8 @@ namespace SilverStripe\RestfulServer\Tests;
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,71 @@ XML
$formatter = new XMLDataFormatter();
$formatter->convertStringToArray($inputXML);
}
+
+ /**
+ * Tests wrapper output of {@link XMLDataFormatter::convertDataObjectWithoutHeader()}
+ */
+ public function testConvertDataObjectWithoutHeaderClassNameAttribute(): void
+ {
+ // Create a mock object
+ $mock = DataObject::create();
+ $mock->ID = 1;
+
+ // Disable trailing slash by default
+ Controller::config()->set('add_trailing_slash', false);
+
+ // 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%s>',
+ $expectedClass,
+ $expectedHref,
+ $mock->ID,
+ $expectedClass
+ );
+
+ $actualOutput = $formatter->convertDataObjectWithoutHeader($mock);
+
+ // remove line breaks and compare
+ $actualOutput = str_replace(["\n", "\r"], '', $actualOutput);
+ $this->assertEquals($expectedOutput, $actualOutput);
+ }
+
+ /**
+ * Tests wrapper output of {@link XMLDataFormatter::convertDataObjectWithoutHeader()} when
+ * used with a forced trailing slash
+ */
+ public function testConvertDataObjectWithoutHeaderClassNameAttributeWithTrailingSlash(): void
+ {
+ // Create a mock object
+ $mock = DataObject::create();
+ $mock->ID = 1;
+
+ // Enable trailing slash by default
+ Controller::config()->set('add_trailing_slash', true);
+
+ // 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%s>',
+ $expectedClass,
+ $expectedHref,
+ $mock->ID,
+ $expectedClass
+ );
+
+ $actualOutput = $formatter->convertDataObjectWithoutHeader($mock);
+
+ // remove line breaks and compare
+ $actualOutput = str_replace(["\n", "\r"], '', $actualOutput);
+ $this->assertEquals($expectedOutput, $actualOutput);
+ }
}