/ee/spec/javascripts/related_items_tree/components/related_items_tree_app_spec.js

https://gitlab.com/markglenfletcher/gitlab-ee · JavaScript · 315 lines · 241 code · 74 blank · 0 comment · 0 complexity · a2fe6e7823828b870e08bcc111cd632a MD5 · raw file

  1. import { shallowMount, createLocalVue } from '@vue/test-utils';
  2. import { GlLoadingIcon } from '@gitlab/ui';
  3. import RelatedItemsTreeApp from 'ee/related_items_tree/components/related_items_tree_app.vue';
  4. import RelatedItemsTreeHeader from 'ee/related_items_tree/components/related_items_tree_header.vue';
  5. import createDefaultStore from 'ee/related_items_tree/store';
  6. import { issuableTypesMap } from 'ee/related_issues/constants';
  7. import AddItemForm from 'ee/related_issues/components/add_issuable_form.vue';
  8. import CreateIssueForm from 'ee/related_items_tree/components/create_issue_form.vue';
  9. import IssueActionsSplitButton from 'ee/related_items_tree/components/issue_actions_split_button.vue';
  10. import { mockInitialConfig, mockParentItem } from '../mock_data';
  11. const createComponent = () => {
  12. const store = createDefaultStore();
  13. const localVue = createLocalVue();
  14. store.dispatch('setInitialConfig', mockInitialConfig);
  15. store.dispatch('setInitialParentItem', mockParentItem);
  16. return shallowMount(RelatedItemsTreeApp, {
  17. localVue,
  18. store,
  19. });
  20. };
  21. describe('RelatedItemsTreeApp', () => {
  22. let wrapper;
  23. const findAddItemForm = () => wrapper.find(AddItemForm);
  24. const findCreateIssueForm = () => wrapper.find(CreateIssueForm);
  25. const findIssueActionsSplitButton = () => wrapper.find(IssueActionsSplitButton);
  26. afterEach(() => {
  27. wrapper.destroy();
  28. });
  29. describe('methods', () => {
  30. beforeEach(() => {
  31. wrapper = createComponent();
  32. });
  33. describe('getRawRefs', () => {
  34. it('returns array of references from provided string with spaces', () => {
  35. const value = '&1 &2 &3';
  36. const references = wrapper.vm.getRawRefs(value);
  37. expect(references.length).toBe(3);
  38. expect(references.join(' ')).toBe(value);
  39. });
  40. });
  41. describe('handlePendingItemRemove', () => {
  42. it('calls `removePendingReference` action with provided `index` param', () => {
  43. spyOn(wrapper.vm, 'removePendingReference');
  44. wrapper.vm.handlePendingItemRemove(0);
  45. expect(wrapper.vm.removePendingReference).toHaveBeenCalledWith(0);
  46. });
  47. });
  48. describe('handleAddItemFormInput', () => {
  49. const untouchedRawReferences = ['&1'];
  50. const touchedReference = '&2';
  51. it('calls `addPendingReferences` action with provided `untouchedRawReferences` param', () => {
  52. spyOn(wrapper.vm, 'addPendingReferences');
  53. wrapper.vm.handleAddItemFormInput({ untouchedRawReferences, touchedReference });
  54. expect(wrapper.vm.addPendingReferences).toHaveBeenCalledWith(untouchedRawReferences);
  55. });
  56. it('calls `setItemInputValue` action with provided `touchedReference` param', () => {
  57. spyOn(wrapper.vm, 'setItemInputValue');
  58. wrapper.vm.handleAddItemFormInput({ untouchedRawReferences, touchedReference });
  59. expect(wrapper.vm.setItemInputValue).toHaveBeenCalledWith(touchedReference);
  60. });
  61. });
  62. describe('handleAddItemFormBlur', () => {
  63. const newValue = '&1 &2';
  64. it('calls `addPendingReferences` action with provided `newValue` param', () => {
  65. spyOn(wrapper.vm, 'addPendingReferences');
  66. wrapper.vm.handleAddItemFormBlur(newValue);
  67. expect(wrapper.vm.addPendingReferences).toHaveBeenCalledWith(newValue.split(/\s+/));
  68. });
  69. it('calls `setItemInputValue` action with empty string', () => {
  70. spyOn(wrapper.vm, 'setItemInputValue');
  71. wrapper.vm.handleAddItemFormBlur(newValue);
  72. expect(wrapper.vm.setItemInputValue).toHaveBeenCalledWith('');
  73. });
  74. });
  75. describe('handleAddItemFormSubmit', () => {
  76. it('calls `addItem` action when `pendingReferences` prop in state is not empty', () => {
  77. const newValue = '&1 &2';
  78. spyOn(wrapper.vm, 'addItem');
  79. wrapper.vm.handleAddItemFormSubmit(newValue);
  80. expect(wrapper.vm.addItem).toHaveBeenCalled();
  81. });
  82. });
  83. describe('handleCreateEpicFormSubmit', () => {
  84. it('calls `createItem` action with `itemTitle` param', () => {
  85. const newValue = 'foo';
  86. spyOn(wrapper.vm, 'createItem');
  87. wrapper.vm.handleCreateEpicFormSubmit(newValue);
  88. expect(wrapper.vm.createItem).toHaveBeenCalledWith({
  89. itemTitle: newValue,
  90. });
  91. });
  92. });
  93. describe('handleAddItemFormCancel', () => {
  94. it('calls `toggleAddItemForm` actions with params `toggleState` as `false`', () => {
  95. spyOn(wrapper.vm, 'toggleAddItemForm');
  96. wrapper.vm.handleAddItemFormCancel();
  97. expect(wrapper.vm.toggleAddItemForm).toHaveBeenCalledWith({ toggleState: false });
  98. });
  99. it('calls `setPendingReferences` action with empty array', () => {
  100. spyOn(wrapper.vm, 'setPendingReferences');
  101. wrapper.vm.handleAddItemFormCancel();
  102. expect(wrapper.vm.setPendingReferences).toHaveBeenCalledWith([]);
  103. });
  104. it('calls `setItemInputValue` action with empty string', () => {
  105. spyOn(wrapper.vm, 'setItemInputValue');
  106. wrapper.vm.handleAddItemFormCancel();
  107. expect(wrapper.vm.setItemInputValue).toHaveBeenCalledWith('');
  108. });
  109. });
  110. describe('handleCreateEpicFormCancel', () => {
  111. it('calls `toggleCreateEpicForm` actions with params `toggleState`', () => {
  112. spyOn(wrapper.vm, 'toggleCreateEpicForm');
  113. wrapper.vm.handleCreateEpicFormCancel();
  114. expect(wrapper.vm.toggleCreateEpicForm).toHaveBeenCalledWith({ toggleState: false });
  115. });
  116. it('calls `setItemInputValue` action with empty string', () => {
  117. spyOn(wrapper.vm, 'setItemInputValue');
  118. wrapper.vm.handleCreateEpicFormCancel();
  119. expect(wrapper.vm.setItemInputValue).toHaveBeenCalledWith('');
  120. });
  121. });
  122. });
  123. describe('template', () => {
  124. beforeEach(() => {
  125. wrapper = createComponent();
  126. wrapper.vm.$store.dispatch('receiveItemsSuccess', {
  127. parentItem: mockParentItem,
  128. children: [],
  129. isSubItem: false,
  130. });
  131. });
  132. it('renders loading icon when `state.itemsFetchInProgress` prop is true', done => {
  133. wrapper.vm.$store.dispatch('requestItems', {
  134. parentItem: mockParentItem,
  135. isSubItem: false,
  136. });
  137. wrapper.vm.$nextTick(() => {
  138. expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(true);
  139. done();
  140. });
  141. });
  142. it('renders tree container element when `state.itemsFetchInProgress` prop is false', done => {
  143. wrapper.vm.$nextTick(() => {
  144. expect(wrapper.find('.related-items-tree').isVisible()).toBe(true);
  145. done();
  146. });
  147. });
  148. it('renders tree container element with `disabled-content` class when `state.itemsFetchInProgress` prop is false and `state.itemAddInProgress` or `state.itemCreateInProgress` is true', done => {
  149. wrapper.vm.$store.dispatch('requestAddItem');
  150. wrapper.vm.$nextTick(() => {
  151. expect(wrapper.find('.related-items-tree.disabled-content').isVisible()).toBe(true);
  152. done();
  153. });
  154. });
  155. it('renders tree header component', done => {
  156. wrapper.vm.$nextTick(() => {
  157. expect(wrapper.find(RelatedItemsTreeHeader).isVisible()).toBe(true);
  158. done();
  159. });
  160. });
  161. it('renders item add/create form container element', done => {
  162. wrapper.vm.$store.dispatch('toggleAddItemForm', {
  163. toggleState: true,
  164. issuableType: issuableTypesMap.Epic,
  165. });
  166. wrapper.vm.$nextTick(() => {
  167. expect(wrapper.find('.add-item-form-container').isVisible()).toBe(true);
  168. done();
  169. });
  170. });
  171. it('does not render issue actions split button', () => {
  172. expect(findIssueActionsSplitButton().exists()).toBe(false);
  173. });
  174. it('does not render create issue form', () => {
  175. expect(findCreateIssueForm().exists()).toBe(false);
  176. });
  177. });
  178. describe('with epicNewIssue feature flag enabled', () => {
  179. beforeEach(done => {
  180. window.gon.features = { epicNewIssue: true };
  181. wrapper = createComponent();
  182. wrapper.vm.$store.state.itemsFetchInProgress = false;
  183. wrapper.vm
  184. .$nextTick()
  185. .then(done)
  186. .catch(done.fail);
  187. });
  188. afterEach(() => {
  189. window.gon.features = {};
  190. });
  191. it('renders issue actions split button', () => {
  192. expect(findIssueActionsSplitButton().exists()).toBe(true);
  193. });
  194. describe('after split button emitted showAddIssueForm event', () => {
  195. it('shows add item form', done => {
  196. expect(findAddItemForm().exists()).toBe(false);
  197. findIssueActionsSplitButton().vm.$emit('showAddIssueForm');
  198. wrapper.vm
  199. .$nextTick()
  200. .then(() => {
  201. expect(findAddItemForm().exists()).toBe(true);
  202. })
  203. .then(done)
  204. .catch(done.fail);
  205. });
  206. });
  207. describe('after split button emitted showCreateIssueForm event', () => {
  208. it('shows create item form', done => {
  209. expect(findCreateIssueForm().exists()).toBe(false);
  210. findIssueActionsSplitButton().vm.$emit('showCreateIssueForm');
  211. wrapper.vm
  212. .$nextTick()
  213. .then(() => {
  214. expect(findCreateIssueForm().exists()).toBe(true);
  215. })
  216. .then(done)
  217. .catch(done.fail);
  218. });
  219. });
  220. describe('after create issue form emitted cancel event', () => {
  221. beforeEach(done => {
  222. findIssueActionsSplitButton().vm.$emit('showCreateIssueForm');
  223. wrapper.vm
  224. .$nextTick()
  225. .then(done)
  226. .catch(done.fail);
  227. });
  228. it('hides the form', done => {
  229. expect(findCreateIssueForm().exists()).toBe(true);
  230. findCreateIssueForm().vm.$emit('cancel');
  231. wrapper.vm
  232. .$nextTick()
  233. .then(() => {
  234. expect(findCreateIssueForm().exists()).toBe(false);
  235. })
  236. .then(done)
  237. .catch(done.fail);
  238. });
  239. });
  240. });
  241. });