Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
AbstractDbTest.php
Go to the documentation of this file.
1 <?php
8 
13 
17 class AbstractDbTest extends \PHPUnit\Framework\TestCase
18 {
22  protected $_model;
23 
27  protected $_resourcesMock;
28 
33 
38 
39  protected function setUp()
40  {
41  $this->_resourcesMock = $this->createMock(\Magento\Framework\App\ResourceConnection::class);
42 
43  $this->relationProcessorMock =
44  $this->createMock(\Magento\Framework\Model\ResourceModel\Db\ObjectRelationProcessor::class);
45  $this->transactionManagerMock = $this->createMock(
46  \Magento\Framework\Model\ResourceModel\Db\TransactionManagerInterface::class
47  );
48  $contextMock = $this->createMock(\Magento\Framework\Model\ResourceModel\Db\Context::class);
49  $contextMock->expects($this->once())->method('getResources')->willReturn($this->_resourcesMock);
50  $contextMock->expects($this->once())
51  ->method('getObjectRelationProcessor')
52  ->willReturn($this->relationProcessorMock);
53  $contextMock->expects($this->once())
54  ->method('getTransactionManager')
55  ->willReturn($this->transactionManagerMock);
56 
57  $this->_model = $this->getMockForAbstractClass(
58  AbstractDb::class,
59  [$contextMock],
60  '',
61  true,
62  true,
63  true,
64  ['_prepareDataForTable']
65  );
66  }
67 
73  public function testAddUniqueField($fieldNameType, $expectedResult)
74  {
75  $this->_model->addUniqueField($fieldNameType);
76  $this->assertEquals($expectedResult, $this->_model->getUniqueFields());
77  }
78 
82  public function addUniqueFieldDataProvider()
83  {
84  return [
85  [
86  'fieldNameString',
87  ['fieldNameString'],
88  ],
89  [
90  [
91  'fieldNameArray',
92  'FieldNameArraySecond',
93  ],
94  [
95  [
96  'fieldNameArray',
97  'FieldNameArraySecond',
98  ]
99  ]
100  ],
101  [
102  null,
103  [null]
104  ]
105  ];
106  }
107 
108  public function testAddUniqueFieldArray()
109  {
110  $this->assertInstanceOf(
111  AbstractDb::class,
112  $this->_model->addUniqueField(['someField'])
113  );
114  }
115 
120  public function testGetIdFieldNameException()
121  {
122  $this->_model->getIdFieldName();
123  }
124 
125  public function testGetIdFieldname()
126  {
127  $data = 'MainTableName';
128  $idFieldNameProperty = new \ReflectionProperty(
129  AbstractDb::class,
130  '_idFieldName'
131  );
132  $idFieldNameProperty->setAccessible(true);
133  $idFieldNameProperty->setValue($this->_model, $data);
134  $this->assertEquals($data, $this->_model->getIdFieldName());
135  }
136 
141  public function testGetMainTableException()
142  {
143  $this->_model->getMainTable();
144  }
145 
151  public function testGetMainTable($tableName, $expectedResult)
152  {
153  $mainTableProperty = new \ReflectionProperty(
154  AbstractDb::class,
155  '_mainTable'
156  );
157  $mainTableProperty->setAccessible(true);
158  $mainTableProperty->setValue($this->_model, $tableName);
159  $this->_resourcesMock->expects($this->once())
160  ->method('getTableName')
161  ->with($expectedResult)
162  ->will($this->returnValue($expectedResult));
163  $this->assertEquals($expectedResult, $this->_model->getMainTable());
164  }
165 
169  public function getTableDataProvider()
170  {
171  return [
172  [
173  'tableName',
174  'tableName',
175  ],
176  [
177  [
178  'tableName',
179  'entity_suffix',
180  ],
181  'tableName_entity_suffix'
182  ]
183  ];
184  }
185 
186  public function testGetTable()
187  {
188  $data = 'tableName';
189  $this->_resourcesMock->expects($this->once())->method('getTableName')->with($data)->will(
190  $this->returnValue('tableName')
191  );
192  $tablesProperty = new \ReflectionProperty(
193  AbstractDb::class,
194  '_tables'
195  );
196  $tablesProperty->setAccessible(true);
197  $tablesProperty->setValue($this->_model, [$data]);
198  $this->assertEquals($data, $this->_model->getTable($data));
199  }
200 
201  public function testGetChecksumNegative()
202  {
203  $this->assertEquals(false, $this->_model->getChecksum(null));
204  }
205 
211  public function testGetChecksum($checksum, $expected)
212  {
213  $connectionMock = $this->createMock(AdapterInterface::class);
214  $connectionMock->expects($this->once())->method('getTablesChecksum')->with($checksum)->will(
215  $this->returnValue([$checksum => 'checksum'])
216  );
217  $this->_resourcesMock->expects($this->any())->method('getConnection')->will(
218  $this->returnValue($connectionMock)
219  );
220  $this->assertEquals($expected, $this->_model->getChecksum($checksum));
221  }
222 
226  public function getChecksumProvider()
227  {
228  return [
229  [
230  'checksum',
231  'checksum',
232  ],
233  [
234  14,
235  'checksum'
236  ]
237  ];
238  }
239 
240  public function testResetUniqueField()
241  {
242  $uniqueFields = new \ReflectionProperty(
243  AbstractDb::class,
244  '_uniqueFields'
245  );
246  $uniqueFields->setAccessible(true);
247  $uniqueFields->setValue($this->_model, ['uniqueField1', 'uniqueField2']);
248  $this->_model->resetUniqueField();
249  $this->assertEquals([], $this->_model->getUniqueFields());
250  }
251 
252  public function testGetUniqueFields()
253  {
254  $uniqueFieldsReflection = new \ReflectionProperty(
255  AbstractDb::class,
256  '_uniqueFields'
257  );
258  $uniqueFieldsReflection->setAccessible(true);
259  $uniqueFieldsReflection->setValue($this->_model, null);
260  $this->assertEquals([], $this->_model->getUniqueFields());
261  }
262 
264  {
265  $this->assertNull($this->_model->getValidationRulesBeforeSave());
266  }
267 
268  public function testLoad()
269  {
271  $object = $this->getMockBuilder(\Magento\Framework\Model\AbstractModel::class)
272  ->disableOriginalConstructor()
273  ->getMock();
274  $object->expects($this->once())->method('beforeLoad')->with('some_value', 'field_name');
275  $object->expects($this->once())->method('afterLoad')->willReturnSelf();
276  $object->expects($this->once())->method('setOrigData')->willReturnSelf();
277  $object->expects($this->once())->method('setHasDataChanges')->with(false)->willReturnSelf();
278  $result = $this->_model->load($object, 'some_value', 'field_name');
279  $this->assertEquals($this->_model, $result);
280  $this->assertInstanceOf(
281  \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
282  $result
283  );
284  }
285 
286  public function testDelete()
287  {
288  $connectionInterfaceMock = $this->createMock(AdapterInterface::class);
289  $contextMock = $this->createMock(\Magento\Framework\Model\Context::class);
290  $registryMock = $this->createMock(\Magento\Framework\Registry::class);
291  $abstractModelMock = $this->getMockForAbstractClass(
292  AbstractModel::class,
293  [$contextMock, $registryMock],
294  '',
295  false,
296  true,
297  true,
298  ['__wakeup', 'getId', 'beforeDelete', 'afterDelete', 'afterDeleteCommit', 'getData']
299  );
300  $this->_resourcesMock->expects($this->any())
301  ->method('getConnection')
302  ->will($this->returnValue($connectionInterfaceMock));
303 
304  $abstractModelMock->expects($this->atLeastOnce())->method('getId')->willReturn(1);
305  $abstractModelMock->expects($this->once())->method('getData')->willReturn(['data' => 'value']);
306  $connectionMock = $this->createMock(AdapterInterface::class);
307  $this->transactionManagerMock->expects($this->once())
308  ->method('start')
309  ->with($connectionInterfaceMock)
310  ->willReturn($connectionMock);
311 
312  $this->relationProcessorMock->expects($this->once())
313  ->method('delete')
314  ->with(
315  $this->transactionManagerMock,
316  $connectionMock,
317  'tableName',
318  'idFieldName',
319  ['data' => 'value']
320  );
321 
322  $this->transactionManagerMock->expects($this->once())->method('commit');
323 
324  $data = 'tableName';
325  $this->_resourcesMock->expects($this->any())->method('getTableName')->with($data)->will(
326  $this->returnValue('tableName')
327  );
328  $mainTableReflection = new \ReflectionProperty(
329  AbstractDb::class,
330  '_mainTable'
331  );
332  $mainTableReflection->setAccessible(true);
333  $mainTableReflection->setValue($this->_model, 'tableName');
334  $idFieldNameReflection = new \ReflectionProperty(
335  AbstractDb::class,
336  '_idFieldName'
337  );
338  $idFieldNameReflection->setAccessible(true);
339  $idFieldNameReflection->setValue($this->_model, 'idFieldName');
340  $connectionInterfaceMock->expects($this->any())->method('delete')->with('tableName', 'idFieldName');
341  $connectionInterfaceMock->expects($this->any())->method('quoteInto')->will($this->returnValue('idFieldName'));
342  $abstractModelMock->expects($this->once())->method('beforeDelete');
343  $abstractModelMock->expects($this->once())->method('afterDelete');
344  $abstractModelMock->expects($this->once())->method('afterDeleteCommit');
345  $this->assertInstanceOf(
346  AbstractDb::class,
347  $this->_model->delete($abstractModelMock)
348  );
349  }
350 
351  public function testHasDataChangedNegative()
352  {
353  $contextMock = $this->createMock(\Magento\Framework\Model\Context::class);
354  $registryMock = $this->createMock(\Magento\Framework\Registry::class);
355  $abstractModelMock = $this->getMockForAbstractClass(
356  AbstractModel::class,
357  [$contextMock, $registryMock],
358  '',
359  false,
360  true,
361  true,
362  ['__wakeup', 'getOrigData']
363  );
364  $abstractModelMock->expects($this->any())->method('getOrigData')->will($this->returnValue(false));
365  $this->assertTrue($this->_model->hasDataChanged($abstractModelMock));
366  }
367 
373  public function testGetDataChanged($getOriginData, $expected)
374  {
375  $connectionInterfaceMock = $this->createMock(AdapterInterface::class);
376  $this->_resourcesMock->expects($this->any())->method('getConnection')->will(
377  $this->returnValue($connectionInterfaceMock)
378  );
379  $contextMock = $this->createMock(\Magento\Framework\Model\Context::class);
380  $registryMock = $this->createMock(\Magento\Framework\Registry::class);
381  $abstractModelMock = $this->getMockForAbstractClass(
382  AbstractModel::class,
383  [$contextMock, $registryMock],
384  '',
385  false,
386  true,
387  true,
388  ['__wakeup', 'getOrigData', 'getData']
389  );
390  $mainTableProperty = new \ReflectionProperty(
391  AbstractDb::class,
392  '_mainTable'
393  );
394  $mainTableProperty->setAccessible(true);
395  $mainTableProperty->setValue($this->_model, 'table');
396 
397  $this->_resourcesMock->expects($this->once())
398  ->method('getTableName')
399  ->with('table')
400  ->will($this->returnValue('tableName'));
401  $abstractModelMock->expects($this->at(0))->method('getOrigData')->will($this->returnValue(true));
402  $abstractModelMock->expects($this->at(1))->method('getOrigData')->will($this->returnValue($getOriginData));
403  $connectionInterfaceMock->expects($this->any())->method('describeTable')->with('tableName')->will(
404  $this->returnValue(['tableName'])
405  );
406  $this->assertEquals($expected, $this->_model->hasDataChanged($abstractModelMock));
407  }
408 
412  public function hasDataChangedDataProvider()
413  {
414  return [
415  [true, true],
416  [null, false]
417  ];
418  }
419 
423  public function testPrepareDataForUpdate()
424  {
425  $connectionMock = $this->getMockBuilder(AdapterInterface::class)
426  ->setMethods(['save'])
427  ->getMockForAbstractClass();
428  $context = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject(
429  \Magento\Framework\Model\Context::class
430  );
431  $registryMock = $this->createMock(\Magento\Framework\Registry::class);
432  $resourceMock = $this->createPartialMock(AbstractDb::class, [
433  '_construct',
434  'getConnection',
435  '__wakeup',
436  'getIdFieldName'
437  ]);
438  $connectionInterfaceMock = $this->createMock(AdapterInterface::class);
439  $resourceMock->expects($this->any())
440  ->method('getConnection')
441  ->will($this->returnValue($connectionInterfaceMock));
442  $resourceCollectionMock = $this->getMockBuilder(\Magento\Framework\Data\Collection\AbstractDb::class)
443  ->disableOriginalConstructor()
444  ->getMockForAbstractClass();
445  $abstractModelMock = $this->getMockForAbstractClass(
446  AbstractModel::class,
447  [$context, $registryMock, $resourceMock, $resourceCollectionMock]
448  );
449  $data = 'tableName';
450  $this->_resourcesMock->expects($this->any())
451  ->method('getConnection')
452  ->will($this->returnValue($connectionMock));
453  $this->_resourcesMock->expects($this->any())->method('getTableName')->with($data)->will(
454  $this->returnValue('tableName')
455  );
456  $mainTableReflection = new \ReflectionProperty(
457  AbstractDb::class,
458  '_mainTable'
459  );
460  $mainTableReflection->setAccessible(true);
461  $mainTableReflection->setValue($this->_model, 'tableName');
462  $idFieldNameReflection = new \ReflectionProperty(
463  AbstractDb::class,
464  '_idFieldName'
465  );
466  $idFieldNameReflection->setAccessible(true);
467  $idFieldNameReflection->setValue($this->_model, 'idFieldName');
468  $connectionMock->expects($this->any())->method('save')->with('tableName', 'idFieldName');
469  $connectionMock->expects($this->any())->method('quoteInto')->will($this->returnValue('idFieldName'));
470  $abstractModelMock->setIdFieldName('id');
471  $abstractModelMock->setData(
472  [
473  'id' => 0,
474  'name' => 'Test Name',
475  'value' => 'Test Value'
476  ]
477  );
478  $abstractModelMock->afterLoad();
479  $this->assertEquals($abstractModelMock->getData(), $abstractModelMock->getStoredData());
480  $newData = ['value' => 'Test Value New'];
481  $this->_model->expects($this->atLeastOnce())
482  ->method('_prepareDataForTable')
483  ->will($this->returnValue($newData));
484  $abstractModelMock->addData($newData);
485  $this->assertNotEquals($abstractModelMock->getData(), $abstractModelMock->getStoredData());
486  $abstractModelMock->isObjectNew(false);
487  $connectionMock->expects($this->once())
488  ->method('update')
489  ->with(
490  'tableName',
491  $newData,
492  'idFieldName'
493  );
494  $select = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
495  ->disableOriginalConstructor()
496  ->getMock();
497  $select->expects($this->once())
498  ->method('from')
499  ->with('tableName')
500  ->willReturnSelf();
501  $connectionMock->expects($this->once())
502  ->method('select')
503  ->willReturn($select);
504  $select->expects($this->once())
505  ->method('reset')
506  ->with(\Magento\Framework\DB\Select::WHERE);
507  $select->expects($this->exactly(2))
508  ->method('where')
509  ->withConsecutive(['uniqueField IS NULL'], ['idFieldName!=?', 0]);
510  $this->_model->addUniqueField(['field' => 'uniqueField']);
511  $this->_model->save($abstractModelMock);
512  }
513 
520  public function testSaveNewObject($pkIncrement)
521  {
525  $model = $this->getMockBuilder(AbstractDb::class)
526  ->disableOriginalConstructor()
527  ->setMethods(['_prepareDataForSave', 'getIdFieldName', 'getConnection', 'getMainTable'])
528  ->getMockForAbstractClass();
535  $reflectionMethod = new \ReflectionMethod($model, 'saveNewObject');
536  $reflectionMethod->setAccessible(true);
537  $reflectionProperty = new \ReflectionProperty($model, '_isPkAutoIncrement');
538  $reflectionProperty->setAccessible(true);
539  $reflectionProperty->setValue($model, $pkIncrement);
540 
541  // Mocked behavior
542  $connectionMock = $this->getMockBuilder(AdapterInterface::class)
543  ->disableOriginalConstructor()
544  ->setMethods(['lastInsertId'])
545  ->getMockForAbstractClass();
546  $getConnectionInvokedCount = $pkIncrement ? 2 : 1;
547  $model->expects($this->exactly($getConnectionInvokedCount))
548  ->method('getConnection')
549  ->willReturn($connectionMock);
550 
551  $idFieldName = 'id_field_name';
552  $model->expects($this->once())->method('_prepareDataForSave')->willReturn([$idFieldName => 'id']);
553 
554  // Test expectations
555  // Only get object's id field name if not PK autoincrement
556  $getIdFieldNameInvokedCount = $pkIncrement ? 1 : 0;
557  $model->expects($this->exactly($getIdFieldNameInvokedCount))
558  ->method('getIdFieldName')
559  ->willReturn($idFieldName);
560 
561  // Only set object id if not PK autoincrement
562  $setIdInvokedCount = $pkIncrement ? 1 : 0;
563  $inputObject = $this->getMockBuilder(AbstractModel::class)
564  ->disableOriginalConstructor()
565  ->getMock();
566  $inputObject->expects($this->exactly($setIdInvokedCount))->method('setId');
567 
568  // Only call lastInsertId if not PK autoincrement
569  $lastInsertIdInvokedCount = $pkIncrement ? 1 : 0;
570  $connectionMock->expects($this->exactly($lastInsertIdInvokedCount))->method('lastInsertId');
571 
572  $reflectionMethod->invokeArgs($model, [$inputObject]);
573  }
574 
578  public function saveNewObjectDataProvider()
579  {
580  return [[true], [false]];
581  }
582 
586  public function testDuplicateExceptionProcessingOnSave()
587  {
588  $connection = $this->createMock(AdapterInterface::class);
589  $connection->expects($this->once())->method('rollback');
590 
592  $model = $this->getMockBuilder(AbstractDb::class)
593  ->disableOriginalConstructor()
594  ->setMethods(['getConnection'])
595  ->getMockForAbstractClass();
596  $model->expects($this->any())->method('getConnection')->willReturn($connection);
597 
599  $object = $this->getMockBuilder(AbstractModel::class)
600  ->disableOriginalConstructor()
601  ->getMock();
602  $object->expects($this->once())->method('hasDataChanges')->willReturn(true);
603  $object->expects($this->once())->method('beforeSave')->willThrowException(new DuplicateException());
604  $object->expects($this->once())->method('setHasDataChanges')->with(true);
605 
606  $model->save($object);
607  }
608 }
$tableName
Definition: trigger.php:13
$connection
Definition: bulk.php:13