selectedGroupStore.spec.tsx 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. import GroupStore from 'sentry/stores/groupStore';
  2. import SelectedGroupStore from 'sentry/stores/selectedGroupStore';
  3. function setRecords(records: Record<string, boolean>) {
  4. SelectedGroupStore.onGroupChange(new Set(Object.keys(records)));
  5. for (const [key, isSelected] of Object.entries(records)) {
  6. if (isSelected) {
  7. SelectedGroupStore.toggleSelect(key);
  8. }
  9. }
  10. }
  11. describe('SelectedGroupStore', function () {
  12. let trigger: jest.SpyInstance;
  13. beforeEach(function () {
  14. SelectedGroupStore.init();
  15. trigger = jest.spyOn(SelectedGroupStore, 'trigger').mockImplementation(() => {});
  16. });
  17. afterEach(function () {
  18. trigger.mockRestore();
  19. });
  20. describe('prune()', function () {
  21. it('removes records no longer in the GroupStore', function () {
  22. jest.spyOn(GroupStore, 'getAllItemIds').mockImplementation(() => ['3']);
  23. setRecords({1: true, 2: true, 3: true});
  24. SelectedGroupStore.prune();
  25. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([['3', true]]);
  26. });
  27. it("doesn't have any effect when already in sync", function () {
  28. jest.spyOn(GroupStore, 'getAllItemIds').mockImplementation(() => ['1', '2', '3']);
  29. setRecords({1: true, 2: true, 3: true});
  30. SelectedGroupStore.prune();
  31. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([
  32. ['1', true],
  33. ['2', true],
  34. ['3', true],
  35. ]);
  36. });
  37. });
  38. describe('add()', function () {
  39. it("defaults value of new ids to 'allSelected()'", function () {
  40. setRecords({1: true});
  41. SelectedGroupStore.add(['2']);
  42. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([
  43. ['1', true],
  44. ['2', true],
  45. ]);
  46. });
  47. it('does not update existing ids', function () {
  48. setRecords({1: false, 2: true});
  49. SelectedGroupStore.add(['3']);
  50. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([
  51. ['1', false],
  52. ['2', true],
  53. ['3', false],
  54. ]);
  55. });
  56. });
  57. describe('onGroupChange()', function () {
  58. let prune: jest.SpyInstance;
  59. let add: jest.SpyInstance;
  60. beforeEach(function () {
  61. prune = jest.spyOn(SelectedGroupStore, 'prune');
  62. add = jest.spyOn(SelectedGroupStore, 'add');
  63. });
  64. afterEach(function () {});
  65. it('adds new ids', function () {
  66. SelectedGroupStore.onGroupChange(new Set());
  67. expect(add).toHaveBeenCalled();
  68. });
  69. it('prunes stale records', function () {
  70. SelectedGroupStore.onGroupChange(new Set());
  71. expect(prune).toHaveBeenCalled();
  72. });
  73. it('triggers an update', function () {
  74. SelectedGroupStore.onGroupChange(new Set());
  75. expect(trigger).toHaveBeenCalled();
  76. });
  77. });
  78. describe('allSelected()', function () {
  79. it('returns true when all ids are selected', function () {
  80. setRecords({1: true, 2: true});
  81. expect(SelectedGroupStore.allSelected()).toBe(true);
  82. });
  83. it('returns false when some ids are selected', function () {
  84. setRecords({1: true, 2: false});
  85. expect(SelectedGroupStore.allSelected()).toBe(false);
  86. });
  87. it('returns false when no ids are selected', function () {
  88. setRecords({1: false, 2: false});
  89. expect(SelectedGroupStore.allSelected()).toBe(false);
  90. });
  91. it('returns false when there are no ids', function () {
  92. expect(SelectedGroupStore.allSelected()).toBe(false);
  93. });
  94. });
  95. describe('anySelected()', function () {
  96. it('returns true if any ids are selected', function () {
  97. setRecords({1: true, 2: false});
  98. expect(SelectedGroupStore.anySelected()).toBe(true);
  99. });
  100. it('returns false when no ids are selected', function () {
  101. setRecords({1: false, 2: false});
  102. expect(SelectedGroupStore.anySelected()).toBe(false);
  103. });
  104. });
  105. describe('multiSelected()', function () {
  106. it('returns true when multiple ids are selected', function () {
  107. setRecords({1: true, 2: true, 3: false});
  108. expect(SelectedGroupStore.multiSelected()).toBe(true);
  109. });
  110. it('returns false when a single id is selected', function () {
  111. setRecords({1: true, 2: false});
  112. expect(SelectedGroupStore.multiSelected()).toBe(false);
  113. });
  114. it('returns false when no ids are selected', function () {
  115. setRecords({1: false, 2: false});
  116. expect(SelectedGroupStore.multiSelected()).toBe(false);
  117. });
  118. });
  119. describe('getSelectedIds()', function () {
  120. it('returns selected ids', function () {
  121. setRecords({1: true, 2: false, 3: true});
  122. const ids = SelectedGroupStore.getSelectedIds();
  123. expect(ids.has('1')).toBe(true);
  124. expect(ids.has('3')).toBe(true);
  125. expect(ids.size).toEqual(2);
  126. });
  127. it('returns empty set with no selected ids', function () {
  128. setRecords({1: false});
  129. const ids = SelectedGroupStore.getSelectedIds();
  130. expect(ids.has('1')).toBe(false);
  131. expect(ids.size).toEqual(0);
  132. });
  133. });
  134. describe('isSelected()', function () {
  135. it('returns true if id is selected', function () {
  136. setRecords({1: true});
  137. expect(SelectedGroupStore.isSelected('1')).toBe(true);
  138. });
  139. it('returns false if id is unselected or unknown', function () {
  140. setRecords({1: false});
  141. expect(SelectedGroupStore.isSelected('1')).toBe(false);
  142. expect(SelectedGroupStore.isSelected('2')).toBe(false);
  143. expect(SelectedGroupStore.isSelected('')).toBe(false);
  144. });
  145. });
  146. describe('deselectAll()', function () {
  147. it('sets all records to false', function () {
  148. setRecords({1: true, 2: true, 3: false});
  149. SelectedGroupStore.deselectAll();
  150. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([
  151. ['1', false],
  152. ['2', false],
  153. ['3', false],
  154. ]);
  155. });
  156. it('triggers an update', function () {
  157. SelectedGroupStore.deselectAll();
  158. expect(trigger).toHaveBeenCalled();
  159. });
  160. });
  161. describe('toggleSelect()', function () {
  162. it('toggles state given pre-existing id', function () {
  163. setRecords({1: true});
  164. SelectedGroupStore.toggleSelect('1');
  165. expect(SelectedGroupStore.getState().records.get('1')).toBe(false);
  166. });
  167. it('does not toggle state given unknown id', function () {
  168. SelectedGroupStore.toggleSelect('1');
  169. SelectedGroupStore.toggleSelect('');
  170. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([]);
  171. });
  172. it('triggers an update given pre-existing id', function () {
  173. setRecords({1: true});
  174. SelectedGroupStore.toggleSelect('1');
  175. expect(trigger).toHaveBeenCalled();
  176. });
  177. it('does not trigger an update given unknown id', function () {
  178. SelectedGroupStore.toggleSelect('');
  179. expect(trigger).not.toHaveBeenCalled();
  180. });
  181. });
  182. describe('toggleSelectAll()', function () {
  183. it('selects all ids if any are unselected', function () {
  184. setRecords({1: true, 2: false});
  185. SelectedGroupStore.toggleSelectAll();
  186. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([
  187. ['1', true],
  188. ['2', true],
  189. ]);
  190. });
  191. it('unselects all ids if all are selected', function () {
  192. setRecords({1: true, 2: true});
  193. SelectedGroupStore.toggleSelectAll();
  194. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([
  195. ['1', false],
  196. ['2', false],
  197. ]);
  198. });
  199. it('triggers an update', function () {
  200. SelectedGroupStore.toggleSelectAll();
  201. expect(trigger).toHaveBeenCalled();
  202. });
  203. });
  204. describe('shiftSelectItems()', function () {
  205. it('toggles all between last selected and new selection', function () {
  206. const ids = ['11', '12', '13', '14', '15'];
  207. jest.spyOn(GroupStore, 'getAllItemIds').mockImplementation(() => ids);
  208. SelectedGroupStore.add(ids);
  209. SelectedGroupStore.toggleSelect('12');
  210. SelectedGroupStore.shiftToggleItems('14');
  211. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([
  212. ['11', false],
  213. ['12', true],
  214. ['13', true],
  215. ['14', true],
  216. ['15', false],
  217. ]);
  218. });
  219. it('toggles all between last selected and new selection backwards', function () {
  220. const ids = ['11', '12', '13', '14', '15'];
  221. jest.spyOn(GroupStore, 'getAllItemIds').mockImplementation(() => ids);
  222. SelectedGroupStore.add(ids);
  223. SelectedGroupStore.toggleSelect('14');
  224. SelectedGroupStore.shiftToggleItems('12');
  225. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([
  226. ['11', false],
  227. ['12', true],
  228. ['13', true],
  229. ['14', true],
  230. ['15', false],
  231. ]);
  232. });
  233. it('deslects after selecting', function () {
  234. const ids = ['11', '12', '13', '14', '15'];
  235. jest.spyOn(GroupStore, 'getAllItemIds').mockImplementation(() => ids);
  236. SelectedGroupStore.add(ids);
  237. SelectedGroupStore.toggleSelect('11');
  238. // Select everything
  239. SelectedGroupStore.shiftToggleItems('15');
  240. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([
  241. ['11', true],
  242. ['12', true],
  243. ['13', true],
  244. ['14', true],
  245. ['15', true],
  246. ]);
  247. // Deslect between 14 and 12
  248. SelectedGroupStore.toggleSelect('14');
  249. SelectedGroupStore.shiftToggleItems('12');
  250. expect([...SelectedGroupStore.getState().records.entries()]).toEqual([
  251. ['11', true],
  252. ['12', false],
  253. ['13', false],
  254. ['14', false],
  255. ['15', true],
  256. ]);
  257. });
  258. });
  259. it('returns a stable reference from getState', function () {
  260. setRecords({1: true, 2: true});
  261. const state = SelectedGroupStore.getState();
  262. expect(Object.is(state, SelectedGroupStore.getState())).toBe(true);
  263. });
  264. });