installed-packages-panel-spec.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. const path = require('path');
  2. const fs = require('fs-plus');
  3. const InstalledPackagesPanel = require('../lib/installed-packages-panel');
  4. const PackageManager = require('../lib/package-manager');
  5. const PackageCard = require('../lib/package-card');
  6. const SettingsView = require('../lib/settings-view');
  7. describe('InstalledPackagesPanel', function() {
  8. describe('when the packages are loading', () => it('filters packages by name once they have loaded', function() {
  9. const settingsView = new SettingsView;
  10. this.packageManager = new PackageManager;
  11. this.installed = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', 'installed.json')));
  12. spyOn(this.packageManager, 'getOutdated').andReturn(new Promise(function() {}));
  13. spyOn(this.packageManager, 'loadCompatiblePackageVersion').andCallFake(function() {});
  14. spyOn(this.packageManager, 'getInstalled').andReturn(Promise.resolve(this.installed));
  15. this.panel = new InstalledPackagesPanel(settingsView, this.packageManager);
  16. this.panel.refs.filterEditor.setText('user-');
  17. window.advanceClock(this.panel.refs.filterEditor.getBuffer().stoppedChangingDelay);
  18. waitsFor(function() {
  19. return (this.packageManager.getInstalled.callCount === 1) && (this.panel.refs.communityCount.textContent.indexOf('…') < 0);
  20. });
  21. runs(function() {
  22. expect(this.panel.refs.communityCount.textContent.trim()).toBe('1/1');
  23. expect(this.panel.refs.communityPackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(1);
  24. expect(this.panel.refs.coreCount.textContent.trim()).toBe('0/1');
  25. expect(this.panel.refs.corePackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(0);
  26. expect(this.panel.refs.devCount.textContent.trim()).toBe('0/1');
  27. expect(this.panel.refs.devPackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(0);
  28. });
  29. }));
  30. describe('when the packages have finished loading', function() {
  31. beforeEach(function() {
  32. const settingsView = new SettingsView;
  33. this.packageManager = new PackageManager;
  34. this.installed = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', 'installed.json')));
  35. spyOn(this.packageManager, 'getOutdated').andReturn(new Promise(function() {}));
  36. spyOn(this.packageManager, 'loadCompatiblePackageVersion').andCallFake(function() {});
  37. spyOn(this.packageManager, 'getInstalled').andReturn(Promise.resolve(this.installed));
  38. this.panel = new InstalledPackagesPanel(settingsView, this.packageManager);
  39. waitsFor(function() {
  40. return (this.packageManager.getInstalled.callCount === 1) && (this.panel.refs.communityCount.textContent.indexOf('…') < 0);
  41. });
  42. });
  43. it('shows packages', function() {
  44. expect(this.panel.refs.communityCount.textContent.trim()).toBe('1');
  45. expect(this.panel.refs.communityPackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(1);
  46. expect(this.panel.refs.coreCount.textContent.trim()).toBe('1');
  47. expect(this.panel.refs.corePackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(1);
  48. expect(this.panel.refs.devCount.textContent.trim()).toBe('1');
  49. expect(this.panel.refs.devPackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(1);
  50. });
  51. it('filters packages by name', function() {
  52. this.panel.refs.filterEditor.setText('user-');
  53. window.advanceClock(this.panel.refs.filterEditor.getBuffer().stoppedChangingDelay);
  54. expect(this.panel.refs.communityCount.textContent.trim()).toBe('1/1');
  55. expect(this.panel.refs.communityPackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(1);
  56. expect(this.panel.refs.coreCount.textContent.trim()).toBe('0/1');
  57. expect(this.panel.refs.corePackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(0);
  58. expect(this.panel.refs.devCount.textContent.trim()).toBe('0/1');
  59. expect(this.panel.refs.devPackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(0);
  60. });
  61. it('adds newly installed packages to the list', function() {
  62. let [installCallback] = [];
  63. spyOn(this.packageManager, 'runCommand').andCallFake(function(args, callback) {
  64. installCallback = callback;
  65. return {onWillThrowError() {}};
  66. });
  67. spyOn(atom.packages, 'activatePackage').andCallFake(name => {
  68. return this.installed.user.push({name});
  69. });
  70. expect(this.panel.refs.communityCount.textContent.trim()).toBe('1');
  71. expect(this.panel.refs.communityPackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(1);
  72. this.packageManager.install({name: 'another-user-package'});
  73. installCallback(0, '', '');
  74. advanceClock(InstalledPackagesPanel.loadPackagesDelay());
  75. waits(1);
  76. runs(function() {
  77. expect(this.panel.refs.communityCount.textContent.trim()).toBe('2');
  78. expect(this.panel.refs.communityPackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(2);
  79. });
  80. });
  81. it('removes uninstalled packages from the list', function() {
  82. let [uninstallCallback] = [];
  83. spyOn(this.packageManager, 'runCommand').andCallFake(function(args, callback) {
  84. uninstallCallback = callback;
  85. return {onWillThrowError() {}};
  86. });
  87. spyOn(this.packageManager, 'unload').andCallFake(name => {
  88. return this.installed.user = [];
  89. });
  90. expect(this.panel.refs.communityCount.textContent.trim()).toBe('1');
  91. expect(this.panel.refs.communityPackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(1);
  92. this.packageManager.uninstall({name: 'user-package'});
  93. uninstallCallback(0, '', '');
  94. advanceClock(InstalledPackagesPanel.loadPackagesDelay());
  95. waits(1);
  96. runs(function() {
  97. expect(this.panel.refs.communityCount.textContent.trim()).toBe('0');
  98. expect(this.panel.refs.communityPackages.querySelectorAll('.package-card:not(.hidden)').length).toBe(0);
  99. });
  100. });
  101. });
  102. describe('expanding and collapsing sub-sections', function() {
  103. beforeEach(function() {
  104. const settingsView = new SettingsView;
  105. this.packageManager = new PackageManager;
  106. this.installed = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', 'installed.json')));
  107. spyOn(this.packageManager, 'getOutdated').andReturn(new Promise(function() {}));
  108. spyOn(this.packageManager, 'loadCompatiblePackageVersion').andCallFake(function() {});
  109. spyOn(this.packageManager, 'getInstalled').andReturn(Promise.resolve(this.installed));
  110. this.panel = new InstalledPackagesPanel(settingsView, this.packageManager);
  111. waitsFor(function() {
  112. return (this.packageManager.getInstalled.callCount === 1) && (this.panel.refs.communityCount.textContent.indexOf('…') < 0);
  113. });
  114. });
  115. it('collapses and expands a sub-section if its header is clicked', function() {
  116. this.panel.element.querySelector('.sub-section.installed-packages .sub-section-heading').click();
  117. expect(this.panel.element.querySelector('.sub-section.installed-packages')).toHaveClass('collapsed');
  118. expect(this.panel.element.querySelector('.sub-section.core-packages')).not.toHaveClass('collapsed');
  119. expect(this.panel.element.querySelector('.sub-section.dev-packages')).not.toHaveClass('collapsed');
  120. this.panel.element.querySelector('.sub-section.installed-packages .sub-section-heading').click();
  121. expect(this.panel.element.querySelector('.sub-section.installed-packages')).not.toHaveClass('collapsed');
  122. });
  123. it('can collapse and expand any of the sub-sections', function() {
  124. let element;
  125. expect(this.panel.element.querySelectorAll('.sub-section-heading.has-items').length).toBe(3);
  126. for (element of Array.from(this.panel.element.querySelectorAll('.sub-section-heading.has-items'))) {
  127. element.click();
  128. }
  129. expect(this.panel.element.querySelector('.sub-section.installed-packages')).toHaveClass('collapsed');
  130. expect(this.panel.element.querySelector('.sub-section.core-packages')).toHaveClass('collapsed');
  131. expect(this.panel.element.querySelector('.sub-section.dev-packages')).toHaveClass('collapsed');
  132. for (element of Array.from(this.panel.element.querySelectorAll('.sub-section-heading.has-items'))) {
  133. element.click();
  134. }
  135. expect(this.panel.element.querySelector('.sub-section.installed-packages')).not.toHaveClass('collapsed');
  136. expect(this.panel.element.querySelector('.sub-section.core-packages')).not.toHaveClass('collapsed');
  137. expect(this.panel.element.querySelector('.sub-section.dev-packages')).not.toHaveClass('collapsed');
  138. });
  139. it('can collapse sub-sections when filtering', function() {
  140. this.panel.refs.filterEditor.setText('user-');
  141. window.advanceClock(this.panel.refs.filterEditor.getBuffer().stoppedChangingDelay);
  142. const hasItems = this.panel.element.querySelectorAll('.sub-section-heading.has-items');
  143. expect(hasItems.length).toBe(1);
  144. expect(hasItems[0].textContent).toMatch(/Community Packages/);
  145. });
  146. });
  147. describe('when there are no packages', function() {
  148. beforeEach(function() {
  149. const settingsView = new SettingsView;
  150. this.packageManager = new PackageManager;
  151. this.installed = {
  152. dev: [],
  153. user: [],
  154. core: []
  155. };
  156. spyOn(this.packageManager, 'getOutdated').andReturn(new Promise(function() {}));
  157. spyOn(this.packageManager, 'loadCompatiblePackageVersion').andCallFake(function() {});
  158. spyOn(this.packageManager, 'getInstalled').andReturn(Promise.resolve(this.installed));
  159. this.panel = new InstalledPackagesPanel(settingsView, this.packageManager);
  160. waitsFor(function() {
  161. return (this.packageManager.getInstalled.callCount === 1) && (this.panel.refs.communityCount.textContent.indexOf('…') < 0);
  162. });
  163. });
  164. it('has a count of zero in all headings', function() {
  165. expect(this.panel.element.querySelector('.section-heading-count').textContent).toMatch(/^0+$/);
  166. expect(this.panel.element.querySelectorAll('.sub-section .icon-package').length).toBe(4);
  167. expect(this.panel.element.querySelectorAll('.sub-section .icon-package.has-items').length).toBe(0);
  168. });
  169. it('can not collapse and expand any of the sub-sections', function() {
  170. let element;
  171. for (element of Array.from(this.panel.element.querySelectorAll('.sub-section .icon-package'))) {
  172. element.click();
  173. }
  174. expect(this.panel.element.querySelector('.sub-section.installed-packages')).not.toHaveClass('collapsed');
  175. expect(this.panel.element.querySelector('.sub-section.core-packages')).not.toHaveClass('collapsed');
  176. expect(this.panel.element.querySelector('.sub-section.dev-packages')).not.toHaveClass('collapsed');
  177. });
  178. it('does not allow collapsing on any section when filtering', function() {
  179. this.panel.refs.filterEditor.setText('user-');
  180. window.advanceClock(this.panel.refs.filterEditor.getBuffer().stoppedChangingDelay);
  181. expect(this.panel.element.querySelector('.section-heading-count').textContent).toMatch(/^(0\/0)+$/);
  182. expect(this.panel.element.querySelectorAll('.sub-section .icon-package').length).toBe(4);
  183. expect(this.panel.element.querySelectorAll('.sub-section .icon-paintcan.has-items').length).toBe(0);
  184. });
  185. });
  186. });