BitmaskedBehaviorTest.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <?php
  2. namespace Tools\Test\TestCase\Model\Behavior;
  3. use App\Model\Entity\BitmaskedComment;
  4. use Cake\ORM\TableRegistry;
  5. use Tools\TestSuite\TestCase;
  6. class BitmaskedBehaviorTest extends TestCase {
  7. /**
  8. * @var array
  9. */
  10. public $fixtures = [
  11. 'plugin.tools.bitmasked_comments'
  12. ];
  13. /**
  14. * @var \Tools\Model\Table\Table|\Tools\Model\Behavior\BitmaskedBehavior
  15. */
  16. public $Comments;
  17. /**
  18. * @return void
  19. */
  20. public function setUp() {
  21. parent::setUp();
  22. $this->Comments = TableRegistry::get('BitmaskedComments');
  23. $this->Comments->addBehavior('Tools.Bitmasked', ['mappedField' => 'statuses']);
  24. }
  25. /**
  26. * @return void
  27. */
  28. public function testEncodeBitmask() {
  29. $res = $this->Comments->encodeBitmask([BitmaskedComment::STATUS_PUBLISHED, BitmaskedComment::STATUS_APPROVED]);
  30. $expected = BitmaskedComment::STATUS_PUBLISHED | BitmaskedComment::STATUS_APPROVED;
  31. $this->assertSame($expected, $res);
  32. }
  33. /**
  34. * @return void
  35. */
  36. public function testDecodeBitmask() {
  37. $res = $this->Comments->decodeBitmask(BitmaskedComment::STATUS_PUBLISHED | BitmaskedComment::STATUS_APPROVED);
  38. $expected = [BitmaskedComment::STATUS_PUBLISHED, BitmaskedComment::STATUS_APPROVED];
  39. $this->assertSame($expected, $res);
  40. }
  41. /**
  42. * @return void
  43. */
  44. public function testFind() {
  45. $res = $this->Comments->find('all')->toArray();
  46. $this->assertTrue(!empty($res) && is_array($res));
  47. $this->assertTrue(!empty($res[1]['statuses']) && is_array($res[1]['statuses']));
  48. }
  49. /**
  50. * @return void
  51. */
  52. public function testSaveBasic() {
  53. $data = [
  54. 'comment' => 'test save',
  55. 'statuses' => [],
  56. ];
  57. $entity = $this->Comments->newEntity($data);
  58. $res = $this->Comments->save($entity);
  59. $this->assertTrue((bool)$res);
  60. $this->assertSame('0', $entity->get('status'));
  61. $data = [
  62. 'comment' => 'test save',
  63. 'statuses' => [BitmaskedComment::STATUS_PUBLISHED, BitmaskedComment::STATUS_APPROVED],
  64. ];
  65. $entity = $this->Comments->newEntity($data);
  66. $res = $this->Comments->save($entity);
  67. $this->assertTrue((bool)$res);
  68. $is = $entity->get('status');
  69. $this->assertSame(BitmaskedComment::STATUS_PUBLISHED | BitmaskedComment::STATUS_APPROVED, $is);
  70. // save + find
  71. $entity = $this->Comments->newEntity($data);
  72. $this->assertEmpty($entity->errors());
  73. $res = $this->Comments->save($entity);
  74. $this->assertTrue((bool)$res);
  75. $res = $this->Comments->find('first', ['conditions' => ['statuses' => $data['statuses']]]);
  76. $this->assertTrue(!empty($res));
  77. $expected = BitmaskedComment::STATUS_APPROVED | BitmaskedComment::STATUS_PUBLISHED; // 6
  78. $this->assertEquals($expected, $res['status']);
  79. $expected = $data['statuses'];
  80. $this->assertEquals($expected, $res['statuses']);
  81. // model.field syntax
  82. $res = $this->Comments->find('first', ['conditions' => ['BitmaskedComments.statuses' => $data['statuses']]]);
  83. $this->assertTrue((bool)$res->toArray());
  84. // explicit
  85. $activeApprovedAndPublished = BitmaskedComment::STATUS_ACTIVE | BitmaskedComment::STATUS_APPROVED | BitmaskedComment::STATUS_PUBLISHED;
  86. $data = [
  87. 'comment' => 'another post comment',
  88. 'status' => $activeApprovedAndPublished,
  89. ];
  90. $entity = $this->Comments->newEntity($data);
  91. $res = $this->Comments->save($entity);
  92. $this->assertTrue((bool)$res);
  93. $res = $this->Comments->find('first', ['conditions' => ['status' => $activeApprovedAndPublished]]);
  94. $this->assertTrue((bool)$res);
  95. $this->assertEquals($activeApprovedAndPublished, $res['status']);
  96. $expected = [BitmaskedComment::STATUS_ACTIVE, BitmaskedComment::STATUS_PUBLISHED, BitmaskedComment::STATUS_APPROVED];
  97. $this->assertEquals($expected, $res['statuses']);
  98. }
  99. /**
  100. * Assert that you can manually trigger "notEmpty" rule with null instead of 0 for "not null" db fields
  101. *
  102. * @return void
  103. */
  104. public function testSaveWithDefaultValue() {
  105. $data = [
  106. 'comment' => 'test save',
  107. 'statuses' => [],
  108. ];
  109. $entity = $this->Comments->newEntity($data);
  110. $res = $this->Comments->save($entity);
  111. $this->assertTrue((bool)$res);
  112. $this->assertSame('0', $entity->get('status'));
  113. $this->skipIf(true, '//FIXME');
  114. // Now let's set the default value
  115. $this->Comments->removeBehavior('Bitmasked');
  116. $this->Comments->addBehavior('Tools.Bitmasked', ['mappedField' => 'statuses', 'defaultValue' => '']);
  117. $data = [
  118. 'comment' => 'test save',
  119. 'statuses' => [],
  120. ];
  121. $entity = $this->Comments->newEntity($data);
  122. $res = $this->Comments->save($entity);
  123. $this->assertFalse($res);
  124. $this->assertSame('', $entity->get('status'));
  125. }
  126. /**
  127. * Assert that it also works with beforeSave event callback.
  128. *
  129. * @return void
  130. */
  131. public function testSaveOnBeforeSave() {
  132. $this->Comments->removeBehavior('Bitmasked');
  133. $this->Comments->addBehavior('Tools.Bitmasked', ['mappedField' => 'statuses', 'on' => 'beforeSave']);
  134. $data = [
  135. 'comment' => 'test save',
  136. 'statuses' => [BitmaskedComment::STATUS_PUBLISHED, BitmaskedComment::STATUS_APPROVED],
  137. ];
  138. $entity = $this->Comments->newEntity($data);
  139. $this->assertEmpty($entity->errors());
  140. $res = $this->Comments->save($entity);
  141. $this->assertTrue((bool)$res);
  142. $this->assertSame(BitmaskedComment::STATUS_PUBLISHED | BitmaskedComment::STATUS_APPROVED, $res['status']);
  143. }
  144. /**
  145. * @return void
  146. */
  147. public function testIs() {
  148. $res = $this->Comments->isBit(BitmaskedComment::STATUS_PUBLISHED);
  149. $expected = ['BitmaskedComments.status' => 2];
  150. $this->assertEquals($expected, $res);
  151. }
  152. /**
  153. * @return void
  154. */
  155. public function testIsNot() {
  156. $res = $this->Comments->isNotBit(BitmaskedComment::STATUS_PUBLISHED);
  157. $expected = ['NOT' => ['BitmaskedComments.status' => 2]];
  158. $this->assertEquals($expected, $res);
  159. }
  160. /**
  161. * @return void
  162. */
  163. public function testContains() {
  164. $config = $this->Comments->connection()->config();
  165. $isPostgres = strpos($config['driver'], 'Postgres') !== false;
  166. $res = $this->Comments->containsBit(BitmaskedComment::STATUS_PUBLISHED);
  167. $expected = ['(BitmaskedComments.status & 2 = 2)'];
  168. if ($isPostgres) {
  169. $expected = ['("BitmaskedComments"."status" & 2 = 2)'];
  170. }
  171. $this->assertEquals($expected, $res);
  172. $conditions = $res;
  173. $res = $this->Comments->find('all', ['conditions' => $conditions])->toArray();
  174. $this->assertTrue(!empty($res) && count($res) === 3);
  175. // multiple (AND)
  176. $res = $this->Comments->containsBit([BitmaskedComment::STATUS_PUBLISHED, BitmaskedComment::STATUS_ACTIVE]);
  177. $expected = ['(BitmaskedComments.status & 3 = 3)'];
  178. if ($isPostgres) {
  179. $expected = ['("BitmaskedComments"."status" & 3 = 3)'];
  180. }
  181. $this->assertEquals($expected, $res);
  182. $conditions = $res;
  183. $res = $this->Comments->find('all', ['conditions' => $conditions])->toArray();
  184. $this->assertTrue(!empty($res) && count($res) === 2);
  185. }
  186. /**
  187. * @return void
  188. */
  189. public function testNotContains() {
  190. $config = $this->Comments->connection()->config();
  191. $isPostgres = strpos($config['driver'], 'Postgres') !== false;
  192. $res = $this->Comments->containsNotBit(BitmaskedComment::STATUS_PUBLISHED);
  193. $expected = ['(BitmaskedComments.status & 2 != 2)'];
  194. if ($isPostgres) {
  195. $expected = ['("BitmaskedComments"."status" & 2 != 2)'];
  196. }
  197. $this->assertEquals($expected, $res);
  198. $conditions = $res;
  199. $res = $this->Comments->find('all', ['conditions' => $conditions])->toArray();
  200. $this->assertTrue(!empty($res) && count($res) === 4);
  201. // multiple (AND)
  202. $res = $this->Comments->containsNotBit([BitmaskedComment::STATUS_PUBLISHED, BitmaskedComment::STATUS_ACTIVE]);
  203. $expected = ['(BitmaskedComments.status & 3 != 3)'];
  204. if ($isPostgres) {
  205. $expected = ['("BitmaskedComments"."status" & 3 != 3)'];
  206. }
  207. $this->assertEquals($expected, $res);
  208. $conditions = $res;
  209. $res = $this->Comments->find('all', ['conditions' => $conditions])->toArray();
  210. $this->assertTrue(!empty($res) && count($res) === 5);
  211. }
  212. }