ModuleUninstallVendorTest.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <?php
  2. use PHPUnit\Framework\Attributes\Group;
  3. /**
  4. * Uninstalling a module whose sys_modules row was stored with an older vendor.
  5. *
  6. * Ticket #4577 renamed the vendor in modules' config.php from 'BoonEx' to 'UNA INC',
  7. * but installed sites keep the vendor the module was installed with. The uninstall
  8. * used to look the row up by vendor and path, so it ran the uninstall SQL and removed
  9. * the language category, but left the sys_modules row and its file tracks behind.
  10. */
  11. #[Group('integration')]
  12. class ModuleUninstallVendorTest extends BxDolIntegrationTestCase
  13. {
  14. private const URI = 'bx_test_vendor_rename';
  15. private const PATH = 'boonex/bx_test_vendor_rename/';
  16. private BxDolStudioInstallerQuery $_oDb;
  17. protected function setUp(): void
  18. {
  19. parent::setUp();
  20. $this->_oDb = new BxDolStudioInstallerQuery();
  21. $this->cleanup();
  22. }
  23. protected function tearDown(): void
  24. {
  25. $this->cleanup();
  26. parent::tearDown();
  27. }
  28. /**
  29. * Removes the fixture without deleteModule, which is the code under test.
  30. */
  31. private function cleanup(): void
  32. {
  33. $aModule = $this->_oDb->getModuleByUri(self::URI, false);
  34. if (empty($aModule))
  35. return;
  36. $this->_oDb->deleteModuleTrackFiles((int)$aModule['id']);
  37. $this->_oDb->query("DELETE FROM `sys_modules` WHERE `id` = :id", ['id' => (int)$aModule['id']]);
  38. $this->_oDb->cleanCache('sys_modules_list');
  39. }
  40. private function config(string $sVendor): array
  41. {
  42. return [
  43. 'type' => BX_DOL_MODULE_TYPE_MODULE,
  44. 'name' => 'bx_test_vendor_rename',
  45. 'title' => 'Vendor rename fixture',
  46. 'vendor' => $sVendor,
  47. 'version' => '12.0.1',
  48. 'home_dir' => self::PATH,
  49. 'home_uri' => self::URI,
  50. 'class_prefix' => 'BxTestVendorRename',
  51. 'db_prefix' => 'bx_test_vendor_rename_',
  52. 'language_category' => 'Vendor rename fixture',
  53. ];
  54. }
  55. private function install(string $sVendor): int
  56. {
  57. $aConfig = $this->config($sVendor);
  58. $iId = $this->_oDb->insertModule($aConfig);
  59. $this->assertGreaterThan(0, $iId, 'The fixture module was not inserted.');
  60. $aFile = ['file' => 'install/config.php', 'hash' => md5('fixture')];
  61. $this->_oDb->insertModuleTrack($iId, $aFile);
  62. return $iId;
  63. }
  64. public function testUninstallRemovesRowStoredWithOldVendor(): void
  65. {
  66. $iId = $this->install('BoonEx');
  67. $this->assertSame($iId, $this->_oDb->deleteModule($this->config('UNA INC')));
  68. $this->assertEmpty($this->_oDb->getModuleById($iId, false));
  69. $this->assertEmpty($this->_oDb->getModuleTrackFiles($iId));
  70. }
  71. public function testUninstallRemovesRowStoredWithSameVendor(): void
  72. {
  73. $iId = $this->install('UNA INC');
  74. $this->assertSame($iId, $this->_oDb->deleteModule($this->config('UNA INC')));
  75. $this->assertEmpty($this->_oDb->getModuleById($iId, false));
  76. $this->assertEmpty($this->_oDb->getModuleTrackFiles($iId));
  77. }
  78. public function testUninstallLeavesModuleWithAnotherPath(): void
  79. {
  80. $iId = $this->install('BoonEx');
  81. $this->_oDb->updateModule(['path' => 'boonex/bx_test_vendor_rename_other/'], ['id' => $iId]);
  82. $this->assertSame(0, $this->_oDb->deleteModule($this->config('UNA INC')));
  83. $this->assertNotEmpty($this->_oDb->getModuleById($iId, false));
  84. $this->assertNotEmpty($this->_oDb->getModuleTrackFiles($iId));
  85. }
  86. /**
  87. * Sites that already hit the bug have the row but no language category. Removing
  88. * the module's strings must succeed then, or the second uninstall fails with
  89. * "Update languages: An error occurred".
  90. */
  91. public function testRemovingLanguageOfMissingCategorySucceeds(): void
  92. {
  93. $aConfig = $this->config('UNA INC');
  94. $aModule = [
  95. 'name' => $aConfig['name'],
  96. 'path' => $aConfig['home_dir'],
  97. 'uri' => $aConfig['home_uri'],
  98. 'lang_category' => $aConfig['language_category'],
  99. ];
  100. $this->assertTrue(BxDolStudioLanguagesUtils::getInstance()->removeLanguageByModule($aModule, false));
  101. }
  102. }