mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
144 lines
5.9 KiB
PHP
144 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace SilverStripe\ORM\Tests;
|
|
|
|
use SilverStripe\ORM\FieldType\DBMoney;
|
|
use SilverStripe\ORM\DataObject;
|
|
use SilverStripe\Dev\SapphireTest;
|
|
use InvalidArgumentException;
|
|
|
|
class DBCompositeTest extends SapphireTest
|
|
{
|
|
|
|
protected static $extra_dataobjects = [
|
|
DBCompositeTest\TestObject::class,
|
|
DBCompositeTest\SubclassedDBFieldObject::class,
|
|
];
|
|
|
|
public function testHasDatabaseFieldOnDataObject()
|
|
{
|
|
$obj = singleton(DBCompositeTest\TestObject::class);
|
|
|
|
$this->assertTrue($obj->hasDatabaseField('MyMoneyAmount'));
|
|
$this->assertTrue($obj->hasDatabaseField('MyMoneyCurrency'));
|
|
$this->assertFalse($obj->hasDatabaseField('MyMoney'));
|
|
|
|
// Check that nested fields are exposed properly
|
|
$this->assertTrue($obj->dbObject('MyMoney')->hasField('Amount'));
|
|
$this->assertTrue($obj->dbObject('MyMoney')->hasField('Currency'));
|
|
|
|
// Test getField accessor
|
|
$this->assertTrue($obj->MyMoney instanceof DBMoney);
|
|
$this->assertTrue($obj->MyMoney->hasField('Amount'));
|
|
$obj->MyMoney->Amount = 100.00;
|
|
$this->assertEquals(100.00, $obj->MyMoney->Amount);
|
|
$this->assertEquals(100.00, $obj->MyMoneyAmount);
|
|
|
|
// Not strictly correct
|
|
$this->assertFalse($obj->dbObject('MyMoney')->hasField('MyMoneyAmount'));
|
|
$this->assertFalse($obj->dbObject('MyMoney')->hasField('MyMoneyCurrency'));
|
|
$this->assertFalse($obj->dbObject('MyMoney')->hasField('MyMoney'));
|
|
}
|
|
|
|
/**
|
|
* Test DataObject::composite_fields() and DataObject::is_composite_field()
|
|
*/
|
|
public function testCompositeFieldMetaDataFunctions()
|
|
{
|
|
$schema = DataObject::getSchema();
|
|
$this->assertEquals('Money', $schema->compositeField(DBCompositeTest\TestObject::class, 'MyMoney'));
|
|
$this->assertNull($schema->compositeField(DBCompositeTest\TestObject::class, 'Title'));
|
|
$this->assertEquals(
|
|
[
|
|
'MyMoney' => 'Money',
|
|
'OverriddenMoney' => 'Money',
|
|
'DoubleMoney' => DBCompositeTest\DBDoubleMoney::class
|
|
],
|
|
$schema->compositeFields(DBCompositeTest\TestObject::class)
|
|
);
|
|
|
|
|
|
$this->assertEquals('Money', $schema->compositeField(DBCompositeTest\SubclassedDBFieldObject::class, 'MyMoney'));
|
|
$this->assertEquals('Money', $schema->compositeField(DBCompositeTest\SubclassedDBFieldObject::class, 'OtherMoney'));
|
|
$this->assertNull($schema->compositeField(DBCompositeTest\SubclassedDBFieldObject::class, 'Title'));
|
|
$this->assertNull($schema->compositeField(DBCompositeTest\SubclassedDBFieldObject::class, 'OtherField'));
|
|
$this->assertEquals(
|
|
[
|
|
'MyMoney' => 'Money',
|
|
'OtherMoney' => 'Money',
|
|
'OverriddenMoney' => 'Money',
|
|
'DoubleMoney' => DBCompositeTest\DBDoubleMoney::class
|
|
],
|
|
$schema->compositeFields(DBCompositeTest\SubclassedDBFieldObject::class)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Tests that changes to the fields affect the underlying dataobject, and vice versa
|
|
*/
|
|
public function testFieldBinding()
|
|
{
|
|
$object = new DBCompositeTest\TestObject();
|
|
$object->MyMoney->Currency = 'NZD';
|
|
$object->MyMoney->Amount = 100.0;
|
|
$this->assertEquals('NZD', $object->MyMoneyCurrency);
|
|
$this->assertEquals(100.0, $object->MyMoneyAmount);
|
|
$object->write();
|
|
|
|
$object2 = DBCompositeTest\TestObject::get()->byID($object->ID);
|
|
$this->assertEquals('NZD', $object2->MyMoney->Currency);
|
|
$this->assertEquals(100.0, $object2->MyMoney->Amount);
|
|
|
|
$object2->MyMoneyCurrency = 'USD';
|
|
$this->assertEquals('USD', $object2->MyMoney->Currency);
|
|
|
|
$object2->MyMoney->setValue(['Currency' => 'EUR', 'Amount' => 200.0]);
|
|
$this->assertEquals('EUR', $object2->MyMoneyCurrency);
|
|
$this->assertEquals(200.0, $object2->MyMoneyAmount);
|
|
}
|
|
|
|
/**
|
|
* Ensures that composite fields are assigned to the correct tables
|
|
*/
|
|
public function testInheritedTables()
|
|
{
|
|
$object1 = new DBCompositeTest\TestObject();
|
|
$object2 = new DBCompositeTest\SubclassedDBFieldObject();
|
|
|
|
$this->assertEquals('DBCompositeTest_DataObject', $object1->dbObject('MyMoney')->getTable());
|
|
$this->assertEquals('DBCompositeTest_DataObject', $object1->dbObject('OverriddenMoney')->getTable());
|
|
$this->assertEquals('DBCompositeTest_DataObject', $object2->dbObject('MyMoney')->getTable());
|
|
$this->assertEquals('DBCompositeTest_SubclassedDBFieldObject', $object2->dbObject('OtherMoney')->getTable());
|
|
$this->assertEquals('DBCompositeTest_SubclassedDBFieldObject', $object2->dbObject('OverriddenMoney')->getTable());
|
|
}
|
|
|
|
public function testSetFieldDynamicPropertyException()
|
|
{
|
|
$this->expectException(InvalidArgumentException::class);
|
|
$this->expectExceptionMessage(implode(' ', [
|
|
'Field abc does not exist.',
|
|
'If this was accessed via a dynamic property then call setDynamicData() instead.'
|
|
]));
|
|
$object = new DBCompositeTest\TestObject();
|
|
$object->MyMoney->abc = 'def';
|
|
}
|
|
|
|
public function testWriteToManipuationIsCalledWhenWritingDataObject()
|
|
{
|
|
$obj = DBCompositeTest\TestObject::create();
|
|
$obj->DoubleMoney = ['Amount' => 10, 'Currency' => 'CAD'];
|
|
$moneyField = $obj->dbObject('DoubleMoney');
|
|
$this->assertEquals(10, $moneyField->getAmount());
|
|
|
|
$obj->write();
|
|
|
|
// Custom money class should double the amount before writing
|
|
$this->assertEquals(20, $moneyField->getAmount());
|
|
|
|
// Note: these would fail since dbObject will return a new instance
|
|
// of the DoubleMoney field based on the initial values
|
|
// $this->assertSame($moneyField, $obj->dbObject('DoubleMoney'));
|
|
// $this->assertEquals(20, $obj->dbObject('DoubleMoney')->getAmount());
|
|
}
|
|
}
|