useCommitters.spec.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import {reactHooks} from 'sentry-test/reactTestingLibrary';
  2. import CommitterStore from 'sentry/stores/committerStore';
  3. import useCommitters from 'sentry/utils/useCommitters';
  4. import {OrganizationContext} from 'sentry/views/organizationContext';
  5. describe('useCommitters hook', function () {
  6. const organization = TestStubs.Organization();
  7. const wrapper = ({children}) => (
  8. <OrganizationContext.Provider value={organization}>
  9. {children}
  10. </OrganizationContext.Provider>
  11. );
  12. const project = TestStubs.Project();
  13. const event = TestStubs.Event();
  14. const group = TestStubs.Group({firstRelease: {}});
  15. let mockApiEndpoint: ReturnType<typeof MockApiClient.addMockResponse>;
  16. const endpoint = `/projects/${organization.slug}/${project.slug}/events/${event.id}/committers/`;
  17. const mockData = {
  18. committers: [
  19. {
  20. author: TestStubs.CommitAuthor(),
  21. commits: [TestStubs.Commit()],
  22. },
  23. ],
  24. };
  25. beforeEach(() => {
  26. mockApiEndpoint = MockApiClient.addMockResponse({
  27. url: endpoint,
  28. body: mockData,
  29. });
  30. CommitterStore.init();
  31. });
  32. afterEach(() => {
  33. MockApiClient.clearMockResponses();
  34. jest.clearAllMocks();
  35. CommitterStore.teardown();
  36. });
  37. it('returns committers', async () => {
  38. const {result, waitFor} = reactHooks.renderHook(
  39. () => useCommitters({group, eventId: event.id, projectSlug: project.slug}),
  40. {wrapper}
  41. );
  42. await waitFor(() => expect(result.current.committers).toEqual(mockData.committers));
  43. expect(result.current.fetching).toBe(false);
  44. expect(mockApiEndpoint).toHaveBeenCalledTimes(1);
  45. });
  46. it('prevents repeated calls', async () => {
  47. const {result, waitFor} = reactHooks.renderHook(
  48. () => useCommitters({group, eventId: event.id, projectSlug: project.slug}),
  49. {wrapper}
  50. );
  51. await waitFor(() => expect(result.current.committers).toEqual(mockData.committers));
  52. reactHooks.renderHook(
  53. () => useCommitters({group, eventId: event.id, projectSlug: project.slug}),
  54. {wrapper}
  55. );
  56. reactHooks.renderHook(
  57. () => useCommitters({group, eventId: event.id, projectSlug: project.slug}),
  58. {wrapper}
  59. );
  60. expect(mockApiEndpoint).toHaveBeenCalledTimes(1);
  61. });
  62. /**
  63. * Same as 'prevents repeated calls', but with the async fetch/checks
  64. * happening on same tick.
  65. *
  66. * Additionally, this test checks that withCommitters.fetchCommitters does
  67. * not check for (store.orgSlug !== orgSlug) as the short-circuit does not
  68. * change the value for orgSlug
  69. */
  70. it('prevents simultaneous calls', async () => {
  71. // Mount and run duplicates
  72. reactHooks.renderHook(
  73. () => useCommitters({group, eventId: event.id, projectSlug: project.slug}),
  74. {wrapper}
  75. );
  76. const {result, waitFor} = reactHooks.renderHook(
  77. () => useCommitters({group, eventId: event.id, projectSlug: project.slug}),
  78. {wrapper}
  79. );
  80. await waitFor(() => expect(result.current.committers).toEqual(mockData.committers));
  81. expect(mockApiEndpoint).toHaveBeenCalledTimes(1);
  82. });
  83. });