FIX Make sure the href attribute is constructed correctly when trailing slash is used

Prior to the fix, when trailing slash is enabled the url output is incorrect; the second test fails because the href output contains: `/api/v1/SilverStripe-ORM-DataObject/1/.xml`.
This commit is contained in:
Ed Wilde 2024-10-17 10:17:12 +13:00
parent 3a3fd02367
commit 4acfe9d1d8
2 changed files with 71 additions and 2 deletions

View File

@ -117,9 +117,9 @@ class XMLDataFormatter extends DataFormatter
{ {
$className = $this->sanitiseClassName(get_class($obj)); $className = $this->sanitiseClassName(get_class($obj));
$id = $obj->ID; $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) { foreach ($this->getFieldsForObj($obj) as $fieldName => $fieldType) {
// Field filtering // Field filtering
if ($fields && !in_array($fieldName, $fields ?? [])) { if ($fields && !in_array($fieldName, $fields ?? [])) {

View File

@ -5,6 +5,8 @@ namespace SilverStripe\RestfulServer\Tests;
use SilverStripe\Dev\SapphireTest; use SilverStripe\Dev\SapphireTest;
use SilverStripe\RestfulServer\DataFormatter\XMLDataFormatter; use SilverStripe\RestfulServer\DataFormatter\XMLDataFormatter;
use Exception; use Exception;
use SilverStripe\Control\Controller;
use SilverStripe\ORM\DataObject;
class XMLDataFormatterTest extends SapphireTest class XMLDataFormatterTest extends SapphireTest
{ {
@ -74,4 +76,71 @@ XML
$formatter = new XMLDataFormatter(); $formatter = new XMLDataFormatter();
$formatter->convertStringToArray($inputXML); $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"><ID>%d</ID></%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"><ID>%d</ID></%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);
}
} }