projectSavedSearches.spec.jsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import PropTypes from 'prop-types';
  2. import React from 'react';
  3. import {mount} from 'enzyme';
  4. import ProjectSavedSearches from 'app/views/projectSavedSearches';
  5. describe('ProjectSavedSearches', function() {
  6. let wrapper;
  7. let org = TestStubs.Organization();
  8. let project = TestStubs.Project();
  9. beforeEach(function() {
  10. MockApiClient.mockAsync = false;
  11. MockApiClient.clearMockResponses();
  12. MockApiClient.addMockResponse({
  13. url: `/projects/${org.slug}/${project.slug}/searches/`,
  14. method: 'GET',
  15. body: TestStubs.Searches(),
  16. });
  17. wrapper = mount(
  18. <ProjectSavedSearches params={{orgId: org.slug, projectId: project.slug}} />,
  19. {
  20. context: {
  21. organization: org,
  22. location: TestStubs.location(),
  23. router: TestStubs.router(),
  24. },
  25. childContextTypes: {
  26. organization: PropTypes.object,
  27. location: PropTypes.object,
  28. router: PropTypes.object,
  29. },
  30. }
  31. );
  32. });
  33. it('renders empty', function() {
  34. MockApiClient.clearMockResponses();
  35. MockApiClient.addMockResponse({
  36. url: `/projects/${org.slug}/${project.slug}/searches/`,
  37. method: 'GET',
  38. body: [],
  39. });
  40. wrapper = mount(
  41. <ProjectSavedSearches params={{orgId: org.slug, projectId: project.slug}} />,
  42. {
  43. context: {
  44. organization: org,
  45. location: TestStubs.location(),
  46. router: TestStubs.router(),
  47. },
  48. childContextTypes: {
  49. organization: PropTypes.object,
  50. location: PropTypes.object,
  51. router: PropTypes.object,
  52. },
  53. }
  54. );
  55. expect(wrapper).toMatchSnapshot();
  56. });
  57. it('renders', function() {
  58. expect(wrapper).toMatchSnapshot();
  59. });
  60. it('removes a search query', function() {
  61. let removed = MockApiClient.addMockResponse({
  62. url: `/projects/${org.slug}/${project.slug}/searches/2/`,
  63. method: 'DELETE',
  64. });
  65. expect(removed).not.toHaveBeenCalled();
  66. wrapper
  67. .find('Button')
  68. .first()
  69. .simulate('click');
  70. $(document.body)
  71. .find('.modal button:contains("Confirm")')
  72. .click();
  73. expect(removed).toHaveBeenCalled();
  74. });
  75. it('rolls back update default on error', function() {
  76. let url = `/projects/${org.slug}/${project.slug}/searches/2/`;
  77. let remove = MockApiClient.addMockResponse({
  78. url,
  79. method: 'DELETE',
  80. statusCode: 400,
  81. });
  82. MockApiClient.mockAsync = true;
  83. // Initially has two rows
  84. expect(wrapper.find('SavedSearchRow')).toHaveLength(2);
  85. expect(remove).not.toHaveBeenCalled();
  86. // Remove first row
  87. wrapper
  88. .find('Button')
  89. .first()
  90. .simulate('click');
  91. $(document.body)
  92. .find('.modal button:contains("Confirm")')
  93. .click();
  94. wrapper.update();
  95. // Should update have 1 row remaining
  96. expect(wrapper.find('SavedSearchRow')).toHaveLength(1);
  97. // calls API, API returns an error
  98. setTimeout(() => {
  99. wrapper.update();
  100. // Reverts back to initial state
  101. expect(wrapper.find('SavedSearchRow')).toHaveLength(2);
  102. }, 1);
  103. MockApiClient.mockAsync = false;
  104. });
  105. it('updates a search query to default', function() {
  106. let url = `/projects/${org.slug}/${project.slug}/searches/2/`;
  107. let update = MockApiClient.addMockResponse({
  108. url,
  109. method: 'PUT',
  110. });
  111. expect(update).not.toHaveBeenCalled();
  112. wrapper
  113. .find('input[type="radio"]')
  114. .first()
  115. .simulate('change');
  116. expect(update).toHaveBeenCalledWith(
  117. url,
  118. expect.objectContaining({
  119. method: 'PUT',
  120. data: {
  121. isUserDefault: true,
  122. },
  123. })
  124. );
  125. expect(
  126. wrapper
  127. .find('input[type="radio"]')
  128. .first()
  129. .prop('checked')
  130. ).toBe(true);
  131. // Update Team default
  132. wrapper
  133. .find('input[type="radio"]')
  134. .at(1)
  135. .simulate('change');
  136. expect(update).toHaveBeenCalledWith(
  137. url,
  138. expect.objectContaining({
  139. method: 'PUT',
  140. data: {
  141. isDefault: true,
  142. },
  143. })
  144. );
  145. expect(
  146. wrapper
  147. .find('input[type="radio"]')
  148. .at(1)
  149. .prop('checked')
  150. ).toBe(true);
  151. });
  152. it('rolls back update default on error', function() {
  153. let url = `/projects/${org.slug}/${project.slug}/searches/2/`;
  154. let update = MockApiClient.addMockResponse({
  155. url,
  156. method: 'PUT',
  157. statusCode: 400,
  158. });
  159. MockApiClient.mockAsync = true;
  160. // User default initial value is false
  161. expect(
  162. wrapper
  163. .find('input[type="radio"]')
  164. .first()
  165. .prop('checked')
  166. ).toBe(false);
  167. expect(update).not.toHaveBeenCalled();
  168. // Select as user default
  169. wrapper
  170. .find('input[type="radio"]')
  171. .first()
  172. .simulate('change');
  173. // Should update and be checked
  174. expect(
  175. wrapper
  176. .find('input[type="radio"]')
  177. .first()
  178. .prop('checked')
  179. ).toBe(true);
  180. // calls API, API returns an error
  181. setTimeout(() => {
  182. wrapper.update();
  183. // Reverts back to initial state
  184. expect(
  185. wrapper
  186. .find('input[type="radio"]')
  187. .first()
  188. .prop('checked')
  189. ).toBe(false);
  190. }, 1);
  191. MockApiClient.mockAsync = false;
  192. });
  193. });