DataConverterTest.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\DB\DataConverter;
  7. use Magento\Framework\DB\Adapter\Pdo\Mysql;
  8. use Magento\Framework\DB\FieldDataConverter;
  9. use Magento\Framework\DB\Select;
  10. use Magento\Framework\DB\Select\QueryModifierInterface;
  11. use Magento\Framework\DB\Select\InQueryModifier;
  12. use Magento\TestFramework\Helper\Bootstrap;
  13. use Magento\Framework\DB\Query\Generator;
  14. use Magento\Framework\DB\Query\BatchIterator;
  15. use Magento\Framework\ObjectManagerInterface;
  16. class DataConverterTest extends \PHPUnit\Framework\TestCase
  17. {
  18. /**
  19. * @var InQueryModifier|\PHPUnit_Framework_MockObject_MockObject
  20. */
  21. private $queryModifierMock;
  22. /**
  23. * @var SerializedToJson
  24. */
  25. private $dataConverter;
  26. /**
  27. * @var BatchIterator|\PHPUnit_Framework_MockObject_MockObject
  28. */
  29. private $iteratorMock;
  30. /**
  31. * @var Generator|\PHPUnit_Framework_MockObject_MockObject
  32. */
  33. private $queryGeneratorMock;
  34. /**
  35. * @var Select|\PHPUnit_Framework_MockObject_MockObject
  36. */
  37. private $selectByRangeMock;
  38. /**
  39. * @var Mysql|\PHPUnit_Framework_MockObject_MockObject
  40. */
  41. private $adapterMock;
  42. /**
  43. * @var FieldDataConverter
  44. */
  45. private $fieldDataConverter;
  46. /**
  47. * @var ObjectManagerInterface
  48. */
  49. private $objectManager;
  50. /**
  51. * Set up before test
  52. */
  53. protected function setUp()
  54. {
  55. $this->objectManager = Bootstrap::getObjectManager();
  56. /** @var InQueryModifier $queryModifier */
  57. $this->queryModifierMock = $this->getMockBuilder(QueryModifierInterface::class)
  58. ->disableOriginalConstructor()
  59. ->setMethods(['modify'])
  60. ->getMock();
  61. $this->dataConverter = $this->objectManager->get(SerializedToJson::class);
  62. $this->iteratorMock = $this->getMockBuilder(BatchIterator::class)
  63. ->disableOriginalConstructor()
  64. ->setMethods(['current', 'valid', 'next'])
  65. ->getMock();
  66. $iterationComplete = false;
  67. // mock valid() call so iterator passes only current() result in foreach invocation
  68. $this->iteratorMock->expects($this->any())
  69. ->method('valid')
  70. ->willReturnCallback(
  71. function () use (&$iterationComplete) {
  72. if (!$iterationComplete) {
  73. $iterationComplete = true;
  74. return true;
  75. } else {
  76. return false;
  77. }
  78. }
  79. );
  80. $this->queryGeneratorMock = $this->getMockBuilder(Generator::class)
  81. ->disableOriginalConstructor()
  82. ->setMethods(['generate'])
  83. ->getMock();
  84. $this->selectByRangeMock = $this->getMockBuilder(Select::class)
  85. ->disableOriginalConstructor()
  86. ->setMethods([])
  87. ->getMock();
  88. $this->queryGeneratorMock->expects($this->any())
  89. ->method('generate')
  90. ->will($this->returnValue($this->iteratorMock));
  91. // mocking only current as next() is not supposed to be called
  92. $this->iteratorMock->expects($this->any())
  93. ->method('current')
  94. ->will($this->returnValue($this->selectByRangeMock));
  95. $this->adapterMock = $this->getMockBuilder(Mysql::class)
  96. ->disableOriginalConstructor()
  97. ->setMethods(['fetchPairs', 'quoteInto', 'update'])
  98. ->getMock();
  99. $this->adapterMock->expects($this->any())
  100. ->method('quoteInto')
  101. ->will($this->returnValue('field=value'));
  102. $this->fieldDataConverter = $this->objectManager->create(
  103. FieldDataConverter::class,
  104. [
  105. 'queryGenerator' => $this->queryGeneratorMock,
  106. 'dataConverter' => $this->dataConverter
  107. ]
  108. );
  109. }
  110. /**
  111. * Test that exception with valid text is thrown when data is corrupted
  112. *
  113. * @expectedException \Magento\Framework\DB\FieldDataConversionException
  114. * @expectedExceptionMessage Error converting field `value` in table `table` where `id`=2 using
  115. */
  116. public function testDataConvertErrorReporting()
  117. {
  118. $rows = [
  119. 1 => 'N;',
  120. 2 => 'a:2:{s:3:"foo";s:3:"bar";s:3:"bar";s:',
  121. ];
  122. $this->adapterMock->expects($this->any())
  123. ->method('fetchPairs')
  124. ->with($this->selectByRangeMock)
  125. ->will($this->returnValue($rows));
  126. $this->adapterMock->expects($this->once())
  127. ->method('update')
  128. ->with('table', ['value' => 'null'], ['id IN (?)' => [1]]);
  129. $this->fieldDataConverter->convert($this->adapterMock, 'table', 'id', 'value', $this->queryModifierMock);
  130. }
  131. public function testAlreadyConvertedDataSkipped()
  132. {
  133. $rows = [
  134. 2 => '[]',
  135. 3 => '{}',
  136. 4 => 'null',
  137. 5 => '""',
  138. 6 => '0',
  139. 7 => 'N;',
  140. 8 => '{"valid": "json value"}',
  141. ];
  142. $this->adapterMock->expects($this->any())
  143. ->method('fetchPairs')
  144. ->with($this->selectByRangeMock)
  145. ->will($this->returnValue($rows));
  146. $this->adapterMock->expects($this->once())
  147. ->method('update')
  148. ->with('table', ['value' => 'null'], ['id IN (?)' => [7]]);
  149. $this->fieldDataConverter->convert($this->adapterMock, 'table', 'id', 'value', $this->queryModifierMock);
  150. }
  151. }