LinkRepositoryTest.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Downloadable\Test\Unit\Model;
  7. use Magento\Downloadable\Model\LinkRepository;
  8. /**
  9. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  10. */
  11. class LinkRepositoryTest extends \PHPUnit\Framework\TestCase
  12. {
  13. /**
  14. * @var \PHPUnit_Framework_MockObject_MockObject
  15. */
  16. protected $repositoryMock;
  17. /**
  18. * @var \PHPUnit_Framework_MockObject_MockObject
  19. */
  20. protected $contentValidatorMock;
  21. /**
  22. * @var \PHPUnit_Framework_MockObject_MockObject
  23. */
  24. protected $contentUploaderMock;
  25. /**
  26. * @var \PHPUnit_Framework_MockObject_MockObject
  27. */
  28. protected $jsonEncoderMock;
  29. /**
  30. * @var \PHPUnit_Framework_MockObject_MockObject
  31. */
  32. protected $linkFactoryMock;
  33. /**
  34. * @var \PHPUnit_Framework_MockObject_MockObject
  35. */
  36. protected $productMock;
  37. /**
  38. * @var \PHPUnit_Framework_MockObject_MockObject
  39. */
  40. protected $productTypeMock;
  41. /**
  42. * @var \PHPUnit_Framework_MockObject_MockObject
  43. */
  44. protected $linkDataObjectFactory;
  45. /**
  46. * @var LinkRepository
  47. */
  48. protected $service;
  49. /**
  50. * @var \PHPUnit_Framework_MockObject_MockObject
  51. */
  52. protected $metadataPoolMock;
  53. /**
  54. * @var \PHPUnit_Framework_MockObject_MockObject
  55. */
  56. protected $linkHandlerMock;
  57. /**
  58. * @var \PHPUnit_Framework_MockObject_MockObject
  59. */
  60. protected $entityMetadataMock;
  61. protected function setUp()
  62. {
  63. $this->repositoryMock = $this->createMock(\Magento\Catalog\Model\ProductRepository::class);
  64. $this->productTypeMock = $this->createMock(\Magento\Downloadable\Model\Product\Type::class);
  65. $this->linkDataObjectFactory = $this->getMockBuilder(\Magento\Downloadable\Api\Data\LinkInterfaceFactory::class)
  66. ->setMethods(
  67. [
  68. 'create',
  69. ]
  70. )
  71. ->disableOriginalConstructor()
  72. ->getMock();
  73. $this->sampleDataObjectFactory = $this->getMockBuilder(
  74. \Magento\Downloadable\Api\Data\SampleInterfaceFactory::class
  75. )->setMethods(['create'])
  76. ->disableOriginalConstructor()
  77. ->getMock();
  78. $this->contentValidatorMock = $this->createMock(\Magento\Downloadable\Model\Link\ContentValidator::class);
  79. $this->contentUploaderMock = $this->createMock(
  80. \Magento\Downloadable\Api\Data\File\ContentUploaderInterface::class
  81. );
  82. $this->jsonEncoderMock = $this->createMock(
  83. \Magento\Framework\Json\EncoderInterface::class
  84. );
  85. $this->linkFactoryMock = $this->createPartialMock(\Magento\Downloadable\Model\LinkFactory::class, ['create']);
  86. $this->productMock = $this->createPartialMock(\Magento\Catalog\Model\Product::class, [
  87. '__wakeup',
  88. 'getTypeId',
  89. 'setDownloadableData',
  90. 'save',
  91. 'getId',
  92. 'getStoreId',
  93. 'getStore',
  94. 'getWebsiteIds',
  95. 'getData'
  96. ]);
  97. $this->service = new \Magento\Downloadable\Model\LinkRepository(
  98. $this->repositoryMock,
  99. $this->productTypeMock,
  100. $this->linkDataObjectFactory,
  101. $this->linkFactoryMock,
  102. $this->contentValidatorMock,
  103. $this->jsonEncoderMock,
  104. $this->contentUploaderMock
  105. );
  106. $this->entityMetadataMock = $this->getMockBuilder(
  107. \Magento\Framework\EntityManager\EntityMetadataInterface::class
  108. )->getMockForAbstractClass();
  109. $linkRepository = new \ReflectionClass(get_class($this->service));
  110. $metadataPoolProperty = $linkRepository->getProperty('metadataPool');
  111. $this->metadataPoolMock = $this->getMockBuilder(
  112. \Magento\Framework\EntityManager\MetadataPool::class
  113. )->disableOriginalConstructor()->getMock();
  114. $metadataPoolProperty->setAccessible(true);
  115. $metadataPoolProperty->setValue(
  116. $this->service,
  117. $this->metadataPoolMock
  118. );
  119. $saveHandlerProperty = $linkRepository->getProperty('linkTypeHandler');
  120. $this->linkHandlerMock = $this->getMockBuilder(
  121. \Magento\Downloadable\Model\Product\TypeHandler\Link::class
  122. )->disableOriginalConstructor()->getMock();
  123. $saveHandlerProperty->setAccessible(true);
  124. $saveHandlerProperty->setValue(
  125. $this->service,
  126. $this->linkHandlerMock
  127. );
  128. $this->metadataPoolMock->expects($this->any())->method('getMetadata')->willReturn($this->entityMetadataMock);
  129. }
  130. /**
  131. * @param array $linkData
  132. * @return \PHPUnit_Framework_MockObject_MockObject
  133. */
  134. protected function getLinkMock(array $linkData)
  135. {
  136. $linkMock = $this->getMockBuilder(\Magento\Downloadable\Api\Data\LinkInterface::class)
  137. ->setMethods(
  138. [
  139. 'getLinkType',
  140. 'getId',
  141. 'getPrice',
  142. 'getTitle',
  143. 'getSortOrder',
  144. 'getNumberOfDownloads',
  145. 'getIsShareable',
  146. 'getLinkUrl',
  147. 'getLinkFile'
  148. ]
  149. )
  150. ->getMockForAbstractClass();
  151. if (isset($linkData['id'])) {
  152. $linkMock->expects($this->any())->method('getId')->willReturn($linkData['id']);
  153. }
  154. $linkMock->expects($this->any())->method('getPrice')->will(
  155. $this->returnValue(
  156. $linkData['price']
  157. )
  158. );
  159. $linkMock->expects($this->any())->method('getTitle')->will(
  160. $this->returnValue(
  161. $linkData['title']
  162. )
  163. );
  164. $linkMock->expects($this->any())->method('getSortOrder')->will(
  165. $this->returnValue(
  166. $linkData['sort_order']
  167. )
  168. );
  169. $linkMock->expects($this->any())->method('getNumberOfDownloads')->will(
  170. $this->returnValue(
  171. $linkData['number_of_downloads']
  172. )
  173. );
  174. $linkMock->expects($this->any())->method('getIsShareable')->will(
  175. $this->returnValue(
  176. $linkData['is_shareable']
  177. )
  178. );
  179. if (isset($linkData['link_type'])) {
  180. $linkMock->expects($this->any())->method('getLinkType')->will(
  181. $this->returnValue(
  182. $linkData['link_type']
  183. )
  184. );
  185. }
  186. if (isset($linkData['link_url'])) {
  187. $linkMock->expects($this->any())->method('getLinkUrl')->will(
  188. $this->returnValue(
  189. $linkData['link_url']
  190. )
  191. );
  192. }
  193. if (isset($linkData['link_file'])) {
  194. $linkMock->expects($this->any())->method('getLinkFile')->will(
  195. $this->returnValue(
  196. $linkData['link_file']
  197. )
  198. );
  199. }
  200. return $linkMock;
  201. }
  202. public function testCreate()
  203. {
  204. $productSku = 'simple';
  205. $linkData = [
  206. 'title' => 'Title',
  207. 'sort_order' => 1,
  208. 'price' => 10.1,
  209. 'is_shareable' => true,
  210. 'number_of_downloads' => 100,
  211. 'link_type' => 'url',
  212. 'link_url' => 'http://example.com/',
  213. ];
  214. $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
  215. ->will($this->returnValue($this->productMock));
  216. $this->productMock->expects($this->any())->method('getTypeId')->will($this->returnValue('downloadable'));
  217. $linkMock = $this->getLinkMock($linkData);
  218. $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock)
  219. ->will($this->returnValue(true));
  220. $downloadableData = [
  221. 'link' => [
  222. [
  223. 'link_id' => 0,
  224. 'is_delete' => 0,
  225. 'type' => $linkData['link_type'],
  226. 'sort_order' => $linkData['sort_order'],
  227. 'title' => $linkData['title'],
  228. 'price' => $linkData['price'],
  229. 'number_of_downloads' => $linkData['number_of_downloads'],
  230. 'is_shareable' => $linkData['is_shareable'],
  231. 'link_url' => $linkData['link_url'],
  232. ],
  233. ],
  234. ];
  235. $this->linkHandlerMock->expects($this->once())->method('save')
  236. ->with($this->productMock, $downloadableData);
  237. $this->service->save($productSku, $linkMock);
  238. }
  239. /**
  240. * @expectedException \Magento\Framework\Exception\InputException
  241. * @expectedExceptionMessage The link title is empty. Enter the link title and try again.
  242. */
  243. public function testCreateThrowsExceptionIfTitleIsEmpty()
  244. {
  245. $productSku = 'simple';
  246. $linkData = [
  247. 'title' => '',
  248. 'sort_order' => 1,
  249. 'price' => 10.1,
  250. 'number_of_downloads' => 100,
  251. 'is_shareable' => true,
  252. 'link_type' => 'url',
  253. 'link_url' => 'http://example.com/',
  254. ];
  255. $this->productMock->expects($this->any())->method('getTypeId')->will($this->returnValue('downloadable'));
  256. $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
  257. ->will($this->returnValue($this->productMock));
  258. $linkMock = $this->getLinkMock($linkData);
  259. $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock)
  260. ->will($this->returnValue(true));
  261. $this->productMock->expects($this->never())->method('save');
  262. $this->service->save($productSku, $linkMock);
  263. }
  264. public function testUpdate()
  265. {
  266. $websiteId = 1;
  267. $linkId = 1;
  268. $productSku = 'simple';
  269. $productId = 1;
  270. $linkData = [
  271. 'id' => $linkId,
  272. 'title' => 'Updated Title',
  273. 'sort_order' => 1,
  274. 'price' => 10.1,
  275. 'is_shareable' => true,
  276. 'number_of_downloads' => 100,
  277. 'link_type' => 'url',
  278. 'link_url' => 'http://example.com/',
  279. ];
  280. $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
  281. ->will($this->returnValue($this->productMock));
  282. $this->productMock->expects($this->any())->method('getData')->will($this->returnValue($productId));
  283. $storeMock = $this->createMock(\Magento\Store\Model\Store::class);
  284. $storeMock->expects($this->any())->method('getWebsiteId')->will($this->returnValue($websiteId));
  285. $this->productMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock));
  286. $existingLinkMock = $this->createPartialMock(\Magento\Downloadable\Model\Link::class, [
  287. '__wakeup',
  288. 'getId',
  289. 'load',
  290. 'getProductId'
  291. ]);
  292. $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($existingLinkMock));
  293. $linkMock = $this->getLinkMock($linkData);
  294. $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock)
  295. ->will($this->returnValue(true));
  296. $existingLinkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId));
  297. $existingLinkMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
  298. $existingLinkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf());
  299. $this->linkHandlerMock->expects($this->once())->method('save')
  300. ->with(
  301. $this->productMock,
  302. [
  303. 'link' => [
  304. [
  305. 'link_id' => $linkId,
  306. 'is_delete' => 0,
  307. 'type' => $linkData['link_type'],
  308. 'sort_order' => $linkData['sort_order'],
  309. 'title' => $linkData['title'],
  310. 'price' => $linkData['price'],
  311. 'number_of_downloads' => $linkData['number_of_downloads'],
  312. 'is_shareable' => $linkData['is_shareable'],
  313. 'link_url' => $linkData['link_url'],
  314. ],
  315. ],
  316. ]
  317. );
  318. $this->assertEquals($linkId, $this->service->save($productSku, $linkMock));
  319. }
  320. public function testUpdateWithExistingFile()
  321. {
  322. $websiteId = 1;
  323. $linkId = 1;
  324. $productSku = 'simple';
  325. $productId = 1;
  326. $linkFile = '/l/i/link.jpg';
  327. $encodedFiles = "something";
  328. $linkData = [
  329. 'id' => $linkId,
  330. 'title' => 'Updated Title',
  331. 'sort_order' => 1,
  332. 'price' => 10.1,
  333. 'is_shareable' => true,
  334. 'number_of_downloads' => 100,
  335. 'link_type' => 'file',
  336. 'link_file' => $linkFile,
  337. ];
  338. $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
  339. ->will($this->returnValue($this->productMock));
  340. $this->productMock->expects($this->any())->method('getData')->will($this->returnValue($productId));
  341. $storeMock = $this->createMock(\Magento\Store\Model\Store::class);
  342. $storeMock->expects($this->any())->method('getWebsiteId')->will($this->returnValue($websiteId));
  343. $this->productMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock));
  344. $existingLinkMock = $this->createPartialMock(\Magento\Downloadable\Model\Link::class, [
  345. '__wakeup',
  346. 'getId',
  347. 'load',
  348. 'getProductId'
  349. ]);
  350. $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($existingLinkMock));
  351. $linkMock = $this->getLinkMock($linkData);
  352. $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock)
  353. ->will($this->returnValue(true));
  354. $existingLinkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId));
  355. $existingLinkMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
  356. $existingLinkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf());
  357. $this->jsonEncoderMock->expects($this->once())
  358. ->method('encode')
  359. ->with(
  360. [
  361. [
  362. 'file' => $linkFile,
  363. 'status' => 'old'
  364. ]
  365. ]
  366. )->willReturn($encodedFiles);
  367. $this->linkHandlerMock->expects($this->once())->method('save')
  368. ->with(
  369. $this->productMock,
  370. [
  371. 'link' => [
  372. [
  373. 'link_id' => $linkId,
  374. 'is_delete' => 0,
  375. 'type' => $linkData['link_type'],
  376. 'sort_order' => $linkData['sort_order'],
  377. 'title' => $linkData['title'],
  378. 'price' => $linkData['price'],
  379. 'number_of_downloads' => $linkData['number_of_downloads'],
  380. 'is_shareable' => $linkData['is_shareable'],
  381. 'file' => $encodedFiles,
  382. ],
  383. ],
  384. ]
  385. );
  386. $this->assertEquals($linkId, $this->service->save($productSku, $linkMock));
  387. }
  388. /**
  389. * @expectedException \Magento\Framework\Exception\InputException
  390. * @expectedExceptionMessage The link title is empty. Enter the link title and try again.
  391. */
  392. public function testUpdateThrowsExceptionIfTitleIsEmptyAndScopeIsGlobal()
  393. {
  394. $linkId = 1;
  395. $productSku = 'simple';
  396. $productId = 1;
  397. $linkData = [
  398. 'id' => $linkId,
  399. 'title' => '',
  400. 'sort_order' => 1,
  401. 'price' => 10.1,
  402. 'number_of_downloads' => 100,
  403. 'is_shareable' => true,
  404. ];
  405. $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
  406. ->will($this->returnValue($this->productMock));
  407. $this->productMock->expects($this->any())->method('getData')->will($this->returnValue($productId));
  408. $existingLinkMock = $this->createPartialMock(
  409. \Magento\Downloadable\Model\Link::class,
  410. ['__wakeup', 'getId', 'load', 'save', 'getProductId']
  411. );
  412. $existingLinkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId));
  413. $existingLinkMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
  414. $existingLinkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf());
  415. $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($existingLinkMock));
  416. $linkContentMock = $this->getLinkMock($linkData);
  417. $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkContentMock)
  418. ->will($this->returnValue(true));
  419. $this->linkHandlerMock->expects($this->never())->method('save');
  420. $this->service->save($productSku, $linkContentMock, true);
  421. }
  422. public function testDelete()
  423. {
  424. $linkId = 1;
  425. $linkMock = $this->createMock(\Magento\Downloadable\Model\Link::class);
  426. $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($linkMock));
  427. $linkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf());
  428. $linkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId));
  429. $linkMock->expects($this->once())->method('delete');
  430. $this->assertTrue($this->service->delete($linkId));
  431. }
  432. /**
  433. * @expectedException \Magento\Framework\Exception\NoSuchEntityException
  434. * @expectedExceptionMessage No downloadable link with the provided ID was found. Verify the ID and try again.
  435. */
  436. public function testDeleteThrowsExceptionIfLinkIdIsNotValid()
  437. {
  438. $linkId = 1;
  439. $linkMock = $this->createMock(\Magento\Downloadable\Model\Link::class);
  440. $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($linkMock));
  441. $linkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf());
  442. $linkMock->expects($this->once())->method('getId');
  443. $linkMock->expects($this->never())->method('delete');
  444. $this->service->delete($linkId);
  445. }
  446. public function testGetList()
  447. {
  448. $productSku = 'downloadable_sku';
  449. $linkData = [
  450. 'id' => 324,
  451. 'store_title' => 'rock melody',
  452. 'title' => 'just melody',
  453. 'price' => 23,
  454. 'number_of_downloads' => 3,
  455. 'sort_order' => 21,
  456. 'is_shareable' => 2,
  457. 'sample_type' => 'file',
  458. 'sample_url' => null,
  459. 'sample_file' => '/r/o/rock.melody.ogg',
  460. 'link_type' => 'url',
  461. 'link_url' => 'http://link.url',
  462. 'link_file' => null
  463. ];
  464. $linkMock = $this->createPartialMock(\Magento\Downloadable\Model\Link::class, [
  465. 'getId',
  466. 'getStoreTitle',
  467. 'getTitle',
  468. 'getPrice',
  469. 'getNumberOfDownloads',
  470. 'getSortOrder',
  471. 'getIsShareable',
  472. 'getData',
  473. '__wakeup',
  474. 'getSampleType',
  475. 'getSampleFile',
  476. 'getSampleUrl',
  477. 'getLinkType',
  478. 'getLinkFile',
  479. 'getLinkUrl'
  480. ]);
  481. $linkInterfaceMock = $this->createMock(\Magento\Downloadable\Api\Data\LinkInterface::class);
  482. $this->repositoryMock->expects($this->once())
  483. ->method('get')
  484. ->with($productSku)
  485. ->will($this->returnValue($this->productMock));
  486. $this->productTypeMock->expects($this->once())
  487. ->method('getLinks')
  488. ->with($this->productMock)
  489. ->will($this->returnValue([$linkMock]));
  490. $this->setLinkAssertions($linkMock, $linkData);
  491. $this->linkDataObjectFactory->expects($this->once())->method('create')->willReturn($linkInterfaceMock);
  492. $this->assertEquals([$linkInterfaceMock], $this->service->getList($productSku));
  493. }
  494. /**
  495. * @param $resource
  496. * @param $inputData
  497. */
  498. protected function setLinkAssertions($resource, $inputData)
  499. {
  500. $resource->expects($this->any())->method('getId')->will($this->returnValue($inputData['id']));
  501. $resource->expects($this->any())->method('getStoreTitle')
  502. ->will($this->returnValue($inputData['store_title']));
  503. $resource->expects($this->any())->method('getTitle')
  504. ->will($this->returnValue($inputData['title']));
  505. $resource->expects($this->any())->method('getSampleType')
  506. ->will($this->returnValue($inputData['sample_type']));
  507. $resource->expects($this->any())->method('getSampleFile')
  508. ->will($this->returnValue($inputData['sample_file']));
  509. $resource->expects($this->any())->method('getSampleUrl')
  510. ->will($this->returnValue($inputData['sample_url']));
  511. $resource->expects($this->any())->method('getPrice')
  512. ->will($this->returnValue($inputData['price']));
  513. $resource->expects($this->once())->method('getNumberOfDownloads')
  514. ->will($this->returnValue($inputData['number_of_downloads']));
  515. $resource->expects($this->once())->method('getSortOrder')
  516. ->will($this->returnValue($inputData['sort_order']));
  517. $resource->expects($this->once())->method('getIsShareable')
  518. ->will($this->returnValue($inputData['is_shareable']));
  519. $resource->expects($this->any())->method('getLinkType')
  520. ->will($this->returnValue($inputData['link_type']));
  521. $resource->expects($this->any())->method('getlinkFile')
  522. ->will($this->returnValue($inputData['link_file']));
  523. $resource->expects($this->any())->method('getLinkUrl')
  524. ->will($this->returnValue($inputData['link_url']));
  525. }
  526. }