jsonForm.spec.tsx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. import {render, screen} from 'sentry-test/reactTestingLibrary';
  2. import JsonForm from 'sentry/components/forms/jsonForm';
  3. import accountDetailsFields from 'sentry/data/forms/accountDetails';
  4. import {fields} from 'sentry/data/forms/projectGeneralSettings';
  5. import {JsonFormObject} from './types';
  6. const user = TestStubs.User();
  7. describe('JsonForm', function () {
  8. describe('form prop', function () {
  9. it('default', function () {
  10. const {container} = render(
  11. <JsonForm forms={accountDetailsFields} additionalFieldProps={{user}} />
  12. );
  13. expect(container).toSnapshot();
  14. });
  15. it('initiallyCollapsed json form prop collapses forms', function () {
  16. const forms: JsonFormObject[] = [
  17. {
  18. title: 'Form1 title',
  19. fields: [
  20. {
  21. name: 'name',
  22. type: 'string',
  23. required: true,
  24. label: 'Field Label 1 ',
  25. placeholder: 'e.g. John Doe',
  26. },
  27. ],
  28. },
  29. {
  30. title: 'Form2 title',
  31. fields: [
  32. {
  33. name: 'name',
  34. type: 'string',
  35. required: true,
  36. label: 'Field Label 2',
  37. placeholder: 'e.g. Abdullah Khan',
  38. },
  39. ],
  40. },
  41. ];
  42. render(
  43. <JsonForm
  44. forms={forms}
  45. additionalFieldProps={{user}}
  46. collapsible
  47. initiallyCollapsed
  48. />
  49. );
  50. expect(screen.getByText('Form1 title')).toBeInTheDocument();
  51. expect(screen.getByText('Form2 title')).toBeInTheDocument();
  52. expect(screen.queryByText('Field Label 1')).not.toBeVisible();
  53. expect(screen.queryByText('Field Label 2')).not.toBeVisible();
  54. });
  55. it('initiallyCollapsed prop from children form groups override json form initiallyCollapsed prop', function () {
  56. const forms: JsonFormObject[] = [
  57. {
  58. title: 'Form1 title',
  59. fields: [
  60. {
  61. name: 'name',
  62. type: 'string',
  63. required: true,
  64. label: 'Field Label 1 ',
  65. placeholder: 'e.g. John Doe',
  66. },
  67. ],
  68. },
  69. {
  70. title: 'Form2 title',
  71. fields: [
  72. {
  73. name: 'name',
  74. type: 'string',
  75. required: true,
  76. label: 'Field Label 2',
  77. placeholder: 'e.g. Abdullah Khan',
  78. },
  79. ],
  80. initiallyCollapsed: false, // Prevents this form group from being collapsed
  81. },
  82. ];
  83. render(
  84. <JsonForm
  85. forms={forms}
  86. additionalFieldProps={{user}}
  87. collapsible
  88. initiallyCollapsed
  89. />
  90. );
  91. expect(screen.getByText('Form1 title')).toBeInTheDocument();
  92. expect(screen.getByText('Form2 title')).toBeInTheDocument();
  93. expect(screen.queryByText('Field Label 1')).not.toBeVisible();
  94. expect(screen.queryByText('Field Label 2')).toBeVisible();
  95. });
  96. it('missing additionalFieldProps required in "valid" prop', function () {
  97. // eslint-disable-next-line no-console
  98. jest.spyOn(console, 'error').mockImplementation(jest.fn());
  99. try {
  100. render(<JsonForm forms={accountDetailsFields} />);
  101. } catch (error) {
  102. expect(error.message).toBe(
  103. "Cannot read properties of undefined (reading 'email')"
  104. );
  105. }
  106. });
  107. it('should ALWAYS hide panel, if all fields have visible set to false AND there is no renderHeader & renderFooter - visible prop is of type boolean', function () {
  108. const modifiedAccountDetails = accountDetailsFields.map(accountDetailsField => ({
  109. ...accountDetailsField,
  110. fields: accountDetailsField.fields.map(field => ({...field, visible: false})),
  111. }));
  112. render(<JsonForm forms={modifiedAccountDetails} additionalFieldProps={{user}} />);
  113. expect(screen.queryByText('Account Details')).not.toBeInTheDocument();
  114. });
  115. it('should ALWAYS hide panel, if all fields have visible set to false AND there is no renderHeader & renderFooter - visible prop is of type func', function () {
  116. const modifiedAccountDetails = accountDetailsFields.map(accountDetailsField => ({
  117. ...accountDetailsField,
  118. fields: accountDetailsField.fields.map(field => ({
  119. ...field,
  120. visible: () => false,
  121. })),
  122. }));
  123. render(<JsonForm forms={modifiedAccountDetails} additionalFieldProps={{user}} />);
  124. expect(screen.queryByText('Account Details')).not.toBeInTheDocument();
  125. });
  126. it('should NOT hide panel, if at least one field has visible set to true - no visible prop (1 field) + visible prop is of type func (2 field)', function () {
  127. // accountDetailsFields has two fields. The second field will always have visible set to false, because the username and the email are the same 'foo@example.com'
  128. render(<JsonForm forms={accountDetailsFields} additionalFieldProps={{user}} />);
  129. expect(screen.getByText('Account Details')).toBeInTheDocument();
  130. expect(screen.getByRole('textbox')).toBeInTheDocument();
  131. });
  132. it('should NOT hide panel, if all fields have visible set to false AND a prop renderHeader is passed', function () {
  133. const modifiedAccountDetails = accountDetailsFields.map(accountDetailsField => ({
  134. ...accountDetailsField,
  135. fields: accountDetailsField.fields.map(field => ({...field, visible: false})),
  136. }));
  137. render(
  138. <JsonForm
  139. forms={modifiedAccountDetails}
  140. additionalFieldProps={{user}}
  141. renderHeader={() => <div>this is a Header </div>}
  142. />
  143. );
  144. expect(screen.getByText('Account Details')).toBeInTheDocument();
  145. expect(screen.queryByRole('textbox')).not.toBeInTheDocument();
  146. });
  147. });
  148. describe('fields prop', function () {
  149. const jsonFormFields = [fields.name, fields.platform];
  150. it('default', function () {
  151. const {container} = render(<JsonForm fields={jsonFormFields} />);
  152. expect(container).toSnapshot();
  153. });
  154. it('missing additionalFieldProps required in "valid" prop', function () {
  155. // eslint-disable-next-line no-console
  156. jest.spyOn(console, 'error').mockImplementation(jest.fn());
  157. try {
  158. render(
  159. <JsonForm
  160. fields={[{...jsonFormFields[0], visible: ({test}) => !!test.email}]}
  161. />
  162. );
  163. } catch (error) {
  164. expect(error.message).toBe(
  165. "Cannot read properties of undefined (reading 'email')"
  166. );
  167. }
  168. });
  169. it('should NOT hide panel, if at least one field has visible set to true - no visible prop', function () {
  170. // slug and platform have no visible prop, that means they will be always visible
  171. render(<JsonForm title={accountDetailsFields[0].title} fields={jsonFormFields} />);
  172. expect(screen.getByText('Account Details')).toBeInTheDocument();
  173. expect(screen.getAllByRole('textbox')).toHaveLength(2);
  174. });
  175. it('should NOT hide panel, if at least one field has visible set to true - visible prop is of type boolean', function () {
  176. // slug and platform have no visible prop, that means they will be always visible
  177. render(
  178. <JsonForm
  179. title={accountDetailsFields[0].title}
  180. fields={jsonFormFields.map(field => ({...field, visible: true}))}
  181. />
  182. );
  183. expect(screen.getByText('Account Details')).toBeInTheDocument();
  184. expect(screen.getAllByRole('textbox')).toHaveLength(2);
  185. });
  186. it('should NOT hide panel, if at least one field has visible set to true - visible prop is of type func', function () {
  187. // slug and platform have no visible prop, that means they will be always visible
  188. render(
  189. <JsonForm
  190. title={accountDetailsFields[0].title}
  191. fields={jsonFormFields.map(field => ({...field, visible: () => true}))}
  192. />
  193. );
  194. expect(screen.getByText('Account Details')).toBeInTheDocument();
  195. expect(screen.getAllByRole('textbox')).toHaveLength(2);
  196. });
  197. it('should ALWAYS hide panel, if all fields have visible set to false - visible prop is of type boolean', function () {
  198. // slug and platform have no visible prop, that means they will be always visible
  199. render(
  200. <JsonForm
  201. title={accountDetailsFields[0].title}
  202. fields={jsonFormFields.map(field => ({...field, visible: false}))}
  203. />
  204. );
  205. expect(screen.queryByText('Account Details')).not.toBeInTheDocument();
  206. });
  207. it('should ALWAYS hide panel, if all fields have visible set to false - visible prop is of type function', function () {
  208. // slug and platform have no visible prop, that means they will be always visible
  209. render(
  210. <JsonForm
  211. title={accountDetailsFields[0].title}
  212. fields={jsonFormFields.map(field => ({...field, visible: () => false}))}
  213. />
  214. );
  215. expect(screen.queryByText('Account Details')).not.toBeInTheDocument();
  216. });
  217. });
  218. });