codeOwnerFileTable.spec.tsx 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import {CodeOwnerFixture} from 'sentry-fixture/codeOwner';
  2. import {OrganizationFixture} from 'sentry-fixture/organization';
  3. import {ProjectFixture} from 'sentry-fixture/project';
  4. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  5. import {CodeOwnerFileTable} from './codeOwnerFileTable';
  6. describe('CodeOwnerFileTable', () => {
  7. const organization = OrganizationFixture();
  8. const project = ProjectFixture();
  9. const codeowner = CodeOwnerFixture();
  10. it('renders empty', () => {
  11. const {container} = render(
  12. <CodeOwnerFileTable
  13. project={project}
  14. codeowners={[]}
  15. onDelete={() => {}}
  16. onUpdate={() => {}}
  17. disabled={false}
  18. />
  19. );
  20. expect(container).toBeEmptyDOMElement();
  21. });
  22. it('renders table w/ sync & delete actions', async () => {
  23. const newCodeowner = {
  24. ...codeowner,
  25. raw: '# new codeowner rules',
  26. };
  27. const codeOwnerSyncData = {
  28. ...codeowner,
  29. raw: '# new codeowner rules',
  30. date_updated: new Date('2023-10-03'),
  31. };
  32. MockApiClient.addMockResponse({
  33. method: 'GET',
  34. url: `/organizations/${organization.slug}/code-mappings/${codeowner.codeMappingId}/codeowners/`,
  35. body: newCodeowner,
  36. });
  37. MockApiClient.addMockResponse({
  38. method: 'PUT',
  39. url: `/projects/${organization.slug}/${project.slug}/codeowners/${codeowner.id}/`,
  40. body: codeOwnerSyncData,
  41. });
  42. MockApiClient.addMockResponse({
  43. method: 'DELETE',
  44. url: `/projects/${organization.slug}/${project.slug}/codeowners/${codeowner.id}/`,
  45. body: {},
  46. });
  47. const onDelete = jest.fn();
  48. const onUpdate = jest.fn();
  49. render(
  50. <CodeOwnerFileTable
  51. project={project}
  52. codeowners={[codeowner]}
  53. onDelete={onDelete}
  54. onUpdate={onUpdate}
  55. disabled={false}
  56. />,
  57. {
  58. organization,
  59. }
  60. );
  61. expect(screen.getByText('example/repo-name')).toBeInTheDocument();
  62. await userEvent.click(screen.getByRole('button', {name: 'Actions'}));
  63. await userEvent.click(screen.getByRole('menuitemradio', {name: 'Sync'}));
  64. await waitFor(() => {
  65. expect(onUpdate).toHaveBeenCalledWith(codeOwnerSyncData);
  66. });
  67. await userEvent.click(screen.getByRole('button', {name: 'Actions'}));
  68. await userEvent.click(screen.getByRole('menuitemradio', {name: 'Delete'}));
  69. await waitFor(() => {
  70. expect(onDelete).toHaveBeenCalledWith(codeowner);
  71. });
  72. });
  73. });