contextPickerModal.spec.jsx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. import React from 'react';
  2. import * as OrgActions from 'app/actionCreators/organizations';
  3. import {mount, shallow} from 'enzyme';
  4. import {ContextPickerModal} from 'app/components/contextPickerModal';
  5. jest.mock('jquery');
  6. describe('ContextPickerModal', function() {
  7. let project, project2, org, org2;
  8. const onFinish = jest.fn();
  9. beforeEach(function() {
  10. MockApiClient.clearMockResponses();
  11. onFinish.mockReset();
  12. project = TestStubs.Project();
  13. org = TestStubs.Organization({projects: [project]});
  14. project2 = TestStubs.Project({slug: 'project2'});
  15. org2 = TestStubs.Organization({
  16. slug: 'org2',
  17. id: '21',
  18. });
  19. });
  20. const getComponent = props => (
  21. <ContextPickerModal
  22. Header={() => <div />}
  23. Body="div"
  24. nextPath="/test/:orgId/path/"
  25. organizations={[org, org2]}
  26. needOrg
  27. latestContext={{}}
  28. onFinish={onFinish}
  29. {...props}
  30. />
  31. );
  32. it('renders with only org selector when no org in latest context', function() {
  33. const wrapper = shallow(getComponent());
  34. expect(wrapper.find('StyledSelectControl[name="organization"]').exists()).toBe(true);
  35. expect(wrapper.find('StyledSelectControl[name="project"]').exists()).toBe(false);
  36. });
  37. it('fetches org details and sets as active org if there is only one org', function() {
  38. const spy = jest.spyOn(OrgActions, 'fetchOrganizationDetails');
  39. const api = MockApiClient.addMockResponse({
  40. url: `/organizations/${org2.slug}/`,
  41. });
  42. const wrapper = mount(getComponent({organizations: [org2]}));
  43. wrapper.update();
  44. expect(spy).toHaveBeenCalledWith('org2', {
  45. setActive: true,
  46. loadProjects: true,
  47. });
  48. expect(api).toHaveBeenCalled();
  49. });
  50. it('calls onFinish after latestContext is set, if project id is not needed, and only 1 org', function() {
  51. const spy = jest.spyOn(OrgActions, 'fetchOrganizationDetails');
  52. const api = MockApiClient.addMockResponse({
  53. url: `/organizations/${org2.slug}/`,
  54. });
  55. const wrapper = mount(getComponent({organizations: [org2]}));
  56. expect(spy).toHaveBeenCalledWith('org2', {
  57. setActive: true,
  58. loadProjects: true,
  59. });
  60. expect(api).toHaveBeenCalled();
  61. wrapper.setProps({latestContext: {organization: org2}});
  62. wrapper.update();
  63. expect(onFinish).toHaveBeenCalledWith('/test/org2/path/');
  64. });
  65. it('calls onFinish if there is only 1 org and 1 project', function() {
  66. const spy = jest.spyOn(OrgActions, 'fetchOrganizationDetails');
  67. const api = MockApiClient.addMockResponse({
  68. url: `/organizations/${org2.slug}/`,
  69. });
  70. const wrapper = mount(
  71. getComponent({
  72. needOrg: true,
  73. needProject: true,
  74. nextPath: '/test/:orgId/path/:projectId/',
  75. organizations: [org2],
  76. })
  77. );
  78. expect(spy).toHaveBeenCalledWith('org2', {
  79. setActive: true,
  80. loadProjects: true,
  81. });
  82. expect(api).toHaveBeenCalled();
  83. wrapper.setProps({latestContext: {organization: {...org2, projects: [project2]}}});
  84. wrapper.update();
  85. expect(onFinish).toHaveBeenCalledWith('/test/org2/path/project2/');
  86. });
  87. it('selects an org and calls `onFinish` with URL with organization slug', function() {
  88. const wrapper = mount(getComponent({}));
  89. const mock = MockApiClient.addMockResponse({
  90. url: `/organizations/${org.slug}/`,
  91. });
  92. wrapper.find('StyledSelectControl[name="organization"] input').simulate('focus');
  93. expect(wrapper.find('Select[name="organization"] .Select-menu')).toHaveLength(1);
  94. wrapper
  95. .find('Select[name="organization"] Option')
  96. .first()
  97. .simulate('mouseDown');
  98. expect(onFinish).toHaveBeenCalledWith('/test/org-slug/path/');
  99. // Is not called because we don't need to fetch org details
  100. expect(mock).not.toHaveBeenCalled();
  101. });
  102. it('renders with project selector and org selector selected when org is in latest context', function() {
  103. const wrapper = shallow(
  104. getComponent({
  105. needOrg: true,
  106. needProject: true,
  107. latestContext: {
  108. organization: {
  109. ...org,
  110. projects: [project, project2],
  111. },
  112. },
  113. })
  114. );
  115. // Default to org in latest context
  116. expect(wrapper.find('StyledSelectControl[name="organization"]').prop('value')).toBe(
  117. org.slug
  118. );
  119. expect(wrapper.find('StyledSelectControl[name="project"]').prop('options')).toEqual([
  120. {value: project.slug, label: project.slug},
  121. {value: project2.slug, label: project2.slug},
  122. ]);
  123. });
  124. it('can select org and project', async function() {
  125. const spy = jest.spyOn(OrgActions, 'fetchOrganizationDetails');
  126. const api = MockApiClient.addMockResponse({
  127. url: `/organizations/${org2.slug}/`,
  128. });
  129. const wrapper = mount(
  130. getComponent({
  131. needOrg: true,
  132. needProject: true,
  133. nextPath: '/test/:orgId/path/:projectId/',
  134. organizations: [
  135. {
  136. ...org,
  137. projects: [project],
  138. },
  139. {
  140. ...org2,
  141. projects: [project2],
  142. },
  143. ],
  144. })
  145. );
  146. // Should not have anything selected
  147. expect(wrapper.find('StyledSelectControl[name="organization"]').prop('value')).toBe(
  148. ''
  149. );
  150. spy.mockClear();
  151. // Select org2
  152. wrapper
  153. .find('StyledSelectControl[name="organization"]')
  154. .simulate('change', {value: org2.slug, label: org2.slug});
  155. wrapper.find('StyledSelectControl[name="organization"] input').simulate('focus');
  156. wrapper
  157. .find('Select[name="organization"] Option')
  158. .at(1)
  159. .simulate('mouseDown');
  160. expect(spy).toHaveBeenCalledWith('org2', {
  161. setActive: true,
  162. loadProjects: true,
  163. });
  164. expect(api).toHaveBeenCalled();
  165. // org2 should have 2 projects, project2 and project3
  166. wrapper.setProps({
  167. latestContext: {organization: {...org2, projects: [project2, {slug: 'project3'}]}},
  168. });
  169. wrapper.update();
  170. expect(wrapper.find('StyledSelectControl[name="project"]').prop('options')).toEqual([
  171. {value: project2.slug, label: project2.slug},
  172. {value: 'project3', label: 'project3'},
  173. ]);
  174. // Select project3
  175. wrapper.find('StyledSelectControl[name="project"] input').simulate('focus');
  176. wrapper
  177. .find('Select[name="project"] Option')
  178. .at(1)
  179. .simulate('mouseDown');
  180. expect(onFinish).toHaveBeenCalledWith('/test/org2/path/project3/');
  181. });
  182. });