EntityTest.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test\AppFramework\Db;
  8. use OCP\AppFramework\Db\Entity;
  9. use OCP\DB\Types;
  10. use PHPUnit\Framework\Constraint\IsType;
  11. /**
  12. * @method integer getId()
  13. * @method void setId(integer $id)
  14. * @method integer getTestId()
  15. * @method void setTestId(integer $id)
  16. * @method string getName()
  17. * @method void setName(string $name)
  18. * @method string getEmail()
  19. * @method void setEmail(string $email)
  20. * @method string getPreName()
  21. * @method void setPreName(string $preName)
  22. * @method bool getTrueOrFalse()
  23. * @method bool isTrueOrFalse()
  24. * @method void setTrueOrFalse(bool $trueOrFalse)
  25. * @method bool getAnotherBool()
  26. * @method bool isAnotherBool()
  27. * @method string getLongText()
  28. * @method void setLongText(string $longText)
  29. * @method \DateTime getTime()
  30. * @method void setTime(\DateTime $time)
  31. * @method \DateTimeImmutable getDatetime()
  32. * @method void setDatetime(\DateTimeImmutable $datetime)
  33. */
  34. class TestEntity extends Entity {
  35. protected $name;
  36. protected $email;
  37. protected $testId;
  38. protected $smallInt;
  39. protected $bigInt;
  40. protected $preName;
  41. protected $trueOrFalse;
  42. protected $anotherBool;
  43. protected $text;
  44. protected $longText;
  45. protected $time;
  46. protected $datetime;
  47. public function __construct($name = null) {
  48. $this->addType('testId', Types::INTEGER);
  49. $this->addType('smallInt', Types::SMALLINT);
  50. $this->addType('bigInt', Types::BIGINT);
  51. $this->addType('anotherBool', Types::BOOLEAN);
  52. $this->addType('text', Types::TEXT);
  53. $this->addType('longText', Types::BLOB);
  54. $this->addType('time', Types::TIME);
  55. $this->addType('datetime', Types::DATETIME_IMMUTABLE);
  56. // Legacy types
  57. $this->addType('trueOrFalse', 'bool');
  58. $this->addType('legacyInt', 'int');
  59. $this->addType('doubleNowFloat', 'double');
  60. $this->name = $name;
  61. }
  62. public function setAnotherBool(bool $anotherBool): void {
  63. parent::setAnotherBool($anotherBool);
  64. }
  65. }
  66. class EntityTest extends \Test\TestCase {
  67. private $entity;
  68. protected function setUp(): void {
  69. parent::setUp();
  70. $this->entity = new TestEntity();
  71. }
  72. public function testResetUpdatedFields(): void {
  73. $entity = new TestEntity();
  74. $entity->setId(3);
  75. $entity->resetUpdatedFields();
  76. $this->assertEquals([], $entity->getUpdatedFields());
  77. }
  78. public function testFromRow(): void {
  79. $row = [
  80. 'pre_name' => 'john',
  81. 'email' => 'john@something.com',
  82. 'another_bool' => 1,
  83. ];
  84. $this->entity = TestEntity::fromRow($row);
  85. $this->assertEquals($row['pre_name'], $this->entity->getPreName());
  86. $this->assertEquals($row['email'], $this->entity->getEmail());
  87. $this->assertEquals($row['another_bool'], $this->entity->getAnotherBool());
  88. }
  89. public function testGetSetId(): void {
  90. $id = 3;
  91. $this->entity->setId(3);
  92. $this->assertEquals($id, $this->entity->getId());
  93. }
  94. public function testColumnToPropertyNoReplacement(): void {
  95. $column = 'my';
  96. $this->assertEquals('my',
  97. $this->entity->columnToProperty($column));
  98. }
  99. public function testColumnToProperty(): void {
  100. $column = 'my_attribute';
  101. $this->assertEquals('myAttribute',
  102. $this->entity->columnToProperty($column));
  103. }
  104. public function testPropertyToColumnNoReplacement(): void {
  105. $property = 'my';
  106. $this->assertEquals('my',
  107. $this->entity->propertyToColumn($property));
  108. }
  109. public function testSetterMarksFieldUpdated(): void {
  110. $this->entity->setId(3);
  111. $this->assertContains('id', array_keys($this->entity->getUpdatedFields()));
  112. }
  113. public function testCallShouldOnlyWorkForGetterSetter(): void {
  114. $this->expectException(\BadFunctionCallException::class);
  115. $this->entity->something();
  116. }
  117. public function testGetterShouldFailIfAttributeNotDefined(): void {
  118. $this->expectException(\BadFunctionCallException::class);
  119. $this->entity->getTest();
  120. }
  121. public function testSetterShouldFailIfAttributeNotDefined(): void {
  122. $this->expectException(\BadFunctionCallException::class);
  123. $this->entity->setTest();
  124. }
  125. public function testFromRowShouldNotAssignEmptyArray(): void {
  126. $row = [];
  127. $entity2 = new TestEntity();
  128. $this->entity = TestEntity::fromRow($row);
  129. $this->assertEquals($entity2, $this->entity);
  130. }
  131. public function testIdGetsConvertedToInt(): void {
  132. $row = ['id' => '4'];
  133. $this->entity = TestEntity::fromRow($row);
  134. $this->assertSame(4, $this->entity->getId());
  135. }
  136. public function testSetType(): void {
  137. $row = ['testId' => '4'];
  138. $this->entity = TestEntity::fromRow($row);
  139. $this->assertSame(4, $this->entity->getTestId());
  140. }
  141. public function testFromParams(): void {
  142. $params = [
  143. 'testId' => 4,
  144. 'email' => 'john@doe'
  145. ];
  146. $entity = TestEntity::fromParams($params);
  147. $this->assertEquals($params['testId'], $entity->getTestId());
  148. $this->assertEquals($params['email'], $entity->getEmail());
  149. $this->assertTrue($entity instanceof TestEntity);
  150. }
  151. public function testSlugify(): void {
  152. $entity = new TestEntity();
  153. $entity->setName('Slugify this!');
  154. $this->assertEquals('slugify-this', $entity->slugify('name'));
  155. $entity->setName('°!"§$%&/()=?`´ß\}][{³²#\'+~*-_.:,;<>|äöüÄÖÜSlugify this!');
  156. $this->assertEquals('slugify-this', $entity->slugify('name'));
  157. }
  158. public function dataSetterCasts(): array {
  159. return [
  160. ['Id', '3', 3],
  161. ['smallInt', '3', 3],
  162. ['bigInt', '' . PHP_INT_MAX, PHP_INT_MAX],
  163. ['trueOrFalse', 0, false],
  164. ['trueOrFalse', 1, true],
  165. ['anotherBool', 0, false],
  166. ['anotherBool', 1, true],
  167. ['text', 33, '33'],
  168. ['longText', PHP_INT_MAX, '' . PHP_INT_MAX],
  169. ];
  170. }
  171. /**
  172. * @dataProvider dataSetterCasts
  173. */
  174. public function testSetterCasts(string $field, mixed $in, mixed $out): void {
  175. $entity = new TestEntity();
  176. $entity->{'set' . $field}($in);
  177. $this->assertSame($out, $entity->{'get' . $field}());
  178. }
  179. public function testSetterDoesNotCastOnNull(): void {
  180. $entity = new TestEntity();
  181. $entity->setId(null);
  182. $this->assertSame(null, $entity->getId());
  183. }
  184. public function testSetterConvertsResourcesToStringProperly(): void {
  185. $string = 'Definitely a string';
  186. $stream = fopen('php://memory', 'r+');
  187. fwrite($stream, $string);
  188. rewind($stream);
  189. $entity = new TestEntity();
  190. $entity->setLongText($stream);
  191. fclose($stream);
  192. $this->assertSame($string, $entity->getLongText());
  193. }
  194. public function testSetterConvertsDatetime() {
  195. $entity = new TestEntity();
  196. $entity->setDatetime('2024-08-19 15:26:00');
  197. $this->assertEquals(new \DateTimeImmutable('2024-08-19 15:26:00'), $entity->getDatetime());
  198. }
  199. public function testSetterDoesNotConvertNullOnDatetime() {
  200. $entity = new TestEntity();
  201. $entity->setDatetime(null);
  202. $this->assertNull($entity->getDatetime());
  203. }
  204. public function testSetterConvertsTime() {
  205. $entity = new TestEntity();
  206. $entity->setTime('15:26:00');
  207. $this->assertEquals(new \DateTime('15:26:00'), $entity->getTime());
  208. }
  209. public function testGetFieldTypes(): void {
  210. $entity = new TestEntity();
  211. $this->assertEquals([
  212. 'id' => Types::INTEGER,
  213. 'testId' => Types::INTEGER,
  214. 'smallInt' => Types::SMALLINT,
  215. 'bigInt' => Types::BIGINT,
  216. 'anotherBool' => Types::BOOLEAN,
  217. 'text' => Types::TEXT,
  218. 'longText' => Types::BLOB,
  219. 'time' => Types::TIME,
  220. 'datetime' => Types::DATETIME_IMMUTABLE,
  221. 'trueOrFalse' => Types::BOOLEAN,
  222. 'legacyInt' => Types::INTEGER,
  223. 'doubleNowFloat' => Types::FLOAT,
  224. ], $entity->getFieldTypes());
  225. }
  226. public function testGetItInt(): void {
  227. $entity = new TestEntity();
  228. $entity->setId(3);
  229. $this->assertEquals(Types::INTEGER, gettype($entity->getId()));
  230. }
  231. public function testFieldsNotMarkedUpdatedIfNothingChanges(): void {
  232. $entity = new TestEntity('hey');
  233. $entity->setName('hey');
  234. $this->assertEquals(0, count($entity->getUpdatedFields()));
  235. }
  236. public function testIsGetter(): void {
  237. $entity = new TestEntity();
  238. $entity->setTrueOrFalse(false);
  239. $entity->setAnotherBool(false);
  240. $this->assertThat($entity->isTrueOrFalse(), new IsType(IsType::TYPE_BOOL));
  241. $this->assertThat($entity->isAnotherBool(), new IsType(IsType::TYPE_BOOL));
  242. }
  243. public function testIsGetterShoudFailForOtherType(): void {
  244. $this->expectException(\BadFunctionCallException::class);
  245. $entity = new TestEntity();
  246. $entity->setName('hello');
  247. $this->assertThat($entity->isName(), new IsType(IsType::TYPE_BOOL));
  248. }
  249. }