groupStore.spec.tsx 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. import {Actor} from 'sentry-fixture/actor';
  2. import {Project} from 'sentry-fixture/project';
  3. import GroupStore from 'sentry/stores/groupStore';
  4. import {Group, GroupActivityType, GroupStats, TimeseriesValue} from 'sentry/types';
  5. const MOCK_PROJECT = TestStubs.Project();
  6. const g = (id: string, params?: Partial<Group>): Group => {
  7. return TestStubs.Group({id, project: MOCK_PROJECT, ...params});
  8. };
  9. describe('GroupStore', function () {
  10. beforeEach(function () {
  11. GroupStore.reset();
  12. });
  13. describe('add()', function () {
  14. it('should add new entries', function () {
  15. GroupStore.items = [];
  16. GroupStore.add([g('1'), g('2')]);
  17. expect(GroupStore.items).toEqual([g('1'), g('2')]);
  18. });
  19. it('should update matching existing entries', function () {
  20. GroupStore.items = [g('1'), g('2')];
  21. GroupStore.add([g('1', {count: '1337'}), g('3')]);
  22. expect(GroupStore.getAllItemIds()).toEqual(['1', '2', '3']);
  23. expect(GroupStore.items[0]).toEqual(
  24. expect.objectContaining({id: '1', count: '1337'})
  25. );
  26. });
  27. it('should attempt to preserve order of ids', function () {
  28. GroupStore.add([g('2'), g('1'), g('3')]);
  29. expect(GroupStore.getAllItemIds()).toEqual(['2', '1', '3']);
  30. });
  31. });
  32. describe('addToFront()', function () {
  33. it('should add new entries to beginning of the list', function () {
  34. GroupStore.items = [g('2')];
  35. GroupStore.addToFront([g('1'), g('3')]);
  36. expect(GroupStore.items).toEqual([g('1'), g('3'), g('2')]);
  37. });
  38. it('should update matching existing entries', function () {
  39. GroupStore.items = [g('1'), g('2')];
  40. GroupStore.addToFront([g('1', {count: '1337'}), g('3')]);
  41. expect(GroupStore.getAllItems()).toEqual([
  42. expect.objectContaining({id: '1', count: '1337'}),
  43. g('3'),
  44. g('2'),
  45. ]);
  46. });
  47. it('should attempt to preserve order of ids', function () {
  48. GroupStore.addToFront([g('2'), g('1'), g('3')]);
  49. expect(GroupStore.getAllItemIds()).toEqual(['2', '1', '3']);
  50. });
  51. });
  52. describe('remove()', function () {
  53. it('should remove entry', function () {
  54. GroupStore.items = [g('1'), g('2')];
  55. GroupStore.remove(['1']);
  56. expect(GroupStore.items).toEqual([g('2')]);
  57. });
  58. it('should remove multiple entries', function () {
  59. GroupStore.items = [g('1'), g('2'), g('3')];
  60. GroupStore.remove(['1', '2']);
  61. expect(GroupStore.items).toEqual([g('3')]);
  62. });
  63. it('should not remove already removed item', function () {
  64. GroupStore.items = [g('1'), g('2')];
  65. GroupStore.remove(['0']);
  66. expect(GroupStore.items).toEqual([g('1'), g('2')]);
  67. });
  68. });
  69. describe('onMergeSuccess()', function () {
  70. it('should remove the non-parent merged ids', function () {
  71. GroupStore.items = [g('1'), g('2'), g('3'), g('4')];
  72. GroupStore.onMergeSuccess(
  73. '',
  74. ['2', '3', '4'], // items merged
  75. {merge: {parent: '3'}} // merge API response
  76. );
  77. expect(GroupStore.items).toEqual([
  78. g('1'),
  79. g('3'), // parent
  80. ]);
  81. });
  82. });
  83. describe('onPopulateStats()', function () {
  84. const stats: Record<string, TimeseriesValue[]> = {auto: [[1611576000, 10]]};
  85. beforeEach(function () {
  86. jest.spyOn(GroupStore, 'trigger');
  87. GroupStore.items = [g('1'), g('2'), g('3')];
  88. });
  89. afterEach(() => {
  90. jest.restoreAllMocks();
  91. });
  92. it('should merge stats into existing groups', function () {
  93. GroupStore.onPopulateStats(
  94. ['1', '2', '3'],
  95. [
  96. {id: '1', stats} as GroupStats,
  97. {id: '2', stats} as GroupStats,
  98. {id: '3', stats} as GroupStats,
  99. ]
  100. );
  101. const group = GroupStore.getAllItems()[0] as Group;
  102. expect(group.stats).toEqual(stats);
  103. expect(GroupStore.trigger).toHaveBeenCalledWith(new Set(['1', '2', '3']));
  104. });
  105. it('should not change current item ids', function () {
  106. GroupStore.onPopulateStats(
  107. ['2', '3'],
  108. [{id: '2', stats} as GroupStats, {id: '3', stats} as GroupStats]
  109. );
  110. const group1 = GroupStore.getAllItems()[0] as Group;
  111. const group2 = GroupStore.getAllItems()[1] as Group;
  112. expect(GroupStore.trigger).toHaveBeenCalledWith(new Set(['2', '3']));
  113. expect(group1.stats).not.toEqual(stats);
  114. expect(group2.stats).toEqual(stats);
  115. });
  116. });
  117. describe('getAllItems()', function () {
  118. it('Merges pending changes into items', function () {
  119. GroupStore.items = [];
  120. GroupStore.add([g('1'), g('2')]);
  121. GroupStore.onUpdate('1337', ['1'], {someChange: true});
  122. expect(GroupStore.get('1')).toEqual(
  123. expect.objectContaining({id: '1', someChange: true})
  124. );
  125. });
  126. });
  127. describe('update methods', function () {
  128. beforeEach(function () {
  129. jest.spyOn(GroupStore, 'trigger');
  130. GroupStore.items = [g('1'), g('2'), g('3')];
  131. });
  132. afterEach(() => {
  133. jest.restoreAllMocks();
  134. });
  135. describe('onUpdate()', function () {
  136. it("should treat undefined itemIds argument as 'all'", function () {
  137. GroupStore.onUpdate('1337', undefined, {});
  138. expect(GroupStore.trigger).toHaveBeenCalledTimes(1);
  139. expect(GroupStore.trigger).toHaveBeenCalledWith(new Set(['1', '2', '3']));
  140. });
  141. it('should apply optimistic updates', function () {
  142. GroupStore.items = [g('1'), g('2')];
  143. GroupStore.add([g('1'), g('2')]);
  144. // Resolve 2 issues
  145. const itemIds = ['1', '2'];
  146. const data = {status: 'resolved', statusDetails: {}};
  147. GroupStore.onUpdate('12345', itemIds, data);
  148. expect(GroupStore.pendingChanges).toEqual(new Map([['12345', {itemIds, data}]]));
  149. expect(GroupStore.get('1')).toEqual({...g('1'), ...data});
  150. expect(GroupStore.get('2')).toEqual({...g('2'), ...data});
  151. });
  152. });
  153. describe('onUpdateSuccess()', function () {
  154. it("should treat undefined itemIds argument as 'all'", function () {
  155. GroupStore.onUpdateSuccess('1337', undefined, {});
  156. expect(GroupStore.trigger).toHaveBeenCalledTimes(1);
  157. expect(GroupStore.trigger).toHaveBeenCalledWith(new Set(['1', '2', '3']));
  158. });
  159. });
  160. describe('onUpdateError()', function () {
  161. it("should treat undefined itemIds argument as 'all'", function () {
  162. GroupStore.onUpdateError('1337', undefined, false);
  163. expect(GroupStore.trigger).toHaveBeenCalledTimes(1);
  164. expect(GroupStore.trigger).toHaveBeenCalledWith(new Set(['1', '2', '3']));
  165. });
  166. });
  167. describe('onDeleteSuccess()', function () {
  168. it("should treat undefined itemIds argument as 'all'", function () {
  169. GroupStore.onDeleteSuccess('1337', undefined, {});
  170. expect(GroupStore.trigger).toHaveBeenCalledTimes(1);
  171. expect(GroupStore.trigger).toHaveBeenCalledWith(new Set(['1', '2', '3']));
  172. });
  173. });
  174. describe('onAssignToSuccess()', function () {
  175. it("should treat undefined itemIds argument as 'all'", function () {
  176. GroupStore.items = [g('1')];
  177. const assignedGroup = g('1', {assignedTo: Actor()});
  178. GroupStore.onAssignToSuccess('1337', '1', assignedGroup);
  179. expect(GroupStore.trigger).toHaveBeenCalledTimes(1);
  180. expect(GroupStore.trigger).toHaveBeenCalledWith(new Set(['1']));
  181. expect(GroupStore.items[0]).toEqual(assignedGroup);
  182. });
  183. });
  184. describe('updateActivity()', function () {
  185. it("should update activity data text'", function () {
  186. GroupStore.items = [
  187. g('1', {
  188. activity: [
  189. {
  190. id: '1',
  191. type: GroupActivityType.NOTE,
  192. dateCreated: '',
  193. project: Project(),
  194. data: {text: 'Orginal Text'},
  195. },
  196. ],
  197. }),
  198. ];
  199. GroupStore.updateActivity('1', '1', {text: 'Updated Text'});
  200. expect(GroupStore.items[0].activity[0].data).toEqual({text: 'Updated Text'});
  201. });
  202. });
  203. });
  204. });