topics.spec.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import { act, renderHook, waitFor } from '@testing-library/react';
  2. import { renderQueryHook, TestQueryClientProvider } from 'lib/testHelpers';
  3. import * as hooks from 'lib/hooks/api/topics';
  4. import fetchMock from 'fetch-mock';
  5. import { UseQueryResult } from '@tanstack/react-query';
  6. import { externalTopicPayload, topicConfigPayload } from 'lib/fixtures/topics';
  7. import { TopicFormData, TopicFormDataRaw } from 'redux/interfaces';
  8. import { CreateTopicMessage } from 'generated-sources';
  9. const clusterName = 'test-cluster';
  10. const topicName = 'test-topic';
  11. const expectQueryWorks = async (
  12. mock: fetchMock.FetchMockStatic,
  13. result: { current: UseQueryResult<unknown, unknown> }
  14. ) => {
  15. await waitFor(() => expect(result.current.isFetched).toBeTruthy());
  16. expect(mock.calls()).toHaveLength(1);
  17. expect(result.current.data).toBeDefined();
  18. };
  19. const topicsPath = `/api/clusters/${clusterName}/topics`;
  20. const topicPath = `${topicsPath}/${topicName}`;
  21. const topicParams = { clusterName, topicName };
  22. describe('Topics hooks', () => {
  23. beforeEach(() => fetchMock.restore());
  24. it('handles useTopics', async () => {
  25. const mock = fetchMock.getOnce(topicsPath, []);
  26. const { result } = renderQueryHook(() => hooks.useTopics({ clusterName }));
  27. await expectQueryWorks(mock, result);
  28. });
  29. it('handles useTopicDetails', async () => {
  30. const mock = fetchMock.getOnce(topicPath, externalTopicPayload);
  31. const { result } = renderQueryHook(() =>
  32. hooks.useTopicDetails(topicParams)
  33. );
  34. await expectQueryWorks(mock, result);
  35. });
  36. it('handles useTopicConfig', async () => {
  37. const mock = fetchMock.getOnce(`${topicPath}/config`, topicConfigPayload);
  38. const { result } = renderQueryHook(() => hooks.useTopicConfig(topicParams));
  39. await expectQueryWorks(mock, result);
  40. });
  41. it('handles useTopicConsumerGroups', async () => {
  42. const mock = fetchMock.getOnce(`${topicPath}/consumer-groups`, []);
  43. const { result } = renderQueryHook(() =>
  44. hooks.useTopicConsumerGroups(topicParams)
  45. );
  46. await expectQueryWorks(mock, result);
  47. });
  48. it('handles useTopicMessageSchema', async () => {
  49. const mock = fetchMock.getOnce(`${topicPath}/messages/schema`, {});
  50. const { result } = renderQueryHook(() =>
  51. hooks.useTopicMessageSchema(topicParams)
  52. );
  53. await expectQueryWorks(mock, result);
  54. });
  55. describe('mutatations', () => {
  56. it('useCreateTopic', async () => {
  57. const mock = fetchMock.postOnce(topicsPath, {});
  58. const { result } = renderHook(() => hooks.useCreateTopic(clusterName), {
  59. wrapper: TestQueryClientProvider,
  60. });
  61. const formData: TopicFormData = {
  62. name: 'Topic Name',
  63. partitions: 0,
  64. replicationFactor: 0,
  65. minInSyncReplicas: 0,
  66. cleanupPolicy: '',
  67. retentionMs: 0,
  68. retentionBytes: 0,
  69. maxMessageBytes: 0,
  70. customParams: [],
  71. };
  72. await act(() => {
  73. result.current.mutateAsync(formData);
  74. });
  75. await waitFor(() => expect(result.current.isSuccess).toBeTruthy());
  76. expect(mock.calls()).toHaveLength(1);
  77. });
  78. it('useUpdateTopic', async () => {
  79. const mock = fetchMock.patchOnce(topicPath, {});
  80. const { result } = renderHook(() => hooks.useUpdateTopic(topicParams), {
  81. wrapper: TestQueryClientProvider,
  82. });
  83. const formData: TopicFormDataRaw = {
  84. name: 'Topic Name',
  85. partitions: 0,
  86. replicationFactor: 0,
  87. minInSyncReplicas: 0,
  88. cleanupPolicy: '',
  89. retentionMs: 0,
  90. retentionBytes: 0,
  91. maxMessageBytes: 0,
  92. customParams: {
  93. byIndex: {},
  94. allIndexes: [],
  95. },
  96. };
  97. await act(() => {
  98. result.current.mutateAsync(formData);
  99. });
  100. await waitFor(() => expect(result.current.isSuccess).toBeTruthy());
  101. expect(mock.calls()).toHaveLength(1);
  102. });
  103. it('useIncreaseTopicPartitionsCount', async () => {
  104. const mock = fetchMock.patchOnce(`${topicPath}/partitions`, {});
  105. const { result } = renderHook(
  106. () => hooks.useIncreaseTopicPartitionsCount(topicParams),
  107. { wrapper: TestQueryClientProvider }
  108. );
  109. await act(() => {
  110. result.current.mutateAsync(3);
  111. });
  112. await waitFor(() => expect(result.current.isSuccess).toBeTruthy());
  113. expect(mock.calls()).toHaveLength(1);
  114. });
  115. it('useUpdateTopicReplicationFactor', async () => {
  116. const mock = fetchMock.patchOnce(`${topicPath}/replications`, {});
  117. const { result } = renderHook(
  118. () => hooks.useUpdateTopicReplicationFactor(topicParams),
  119. { wrapper: TestQueryClientProvider }
  120. );
  121. await act(() => {
  122. result.current.mutateAsync(3);
  123. });
  124. await waitFor(() => expect(result.current.isSuccess).toBeTruthy());
  125. expect(mock.calls()).toHaveLength(1);
  126. });
  127. it('useDeleteTopic', async () => {
  128. const mock = fetchMock.deleteOnce(topicPath, {});
  129. const { result } = renderHook(() => hooks.useDeleteTopic(clusterName), {
  130. wrapper: TestQueryClientProvider,
  131. });
  132. await act(() => {
  133. result.current.mutateAsync(topicName);
  134. });
  135. await waitFor(() => expect(result.current.isSuccess).toBeTruthy());
  136. expect(mock.calls()).toHaveLength(1);
  137. });
  138. it('useRecreateTopic', async () => {
  139. const mock = fetchMock.postOnce(topicPath, {});
  140. const { result } = renderHook(() => hooks.useRecreateTopic(topicParams), {
  141. wrapper: TestQueryClientProvider,
  142. });
  143. await act(() => {
  144. result.current.mutateAsync();
  145. });
  146. await waitFor(() => expect(result.current.isSuccess).toBeTruthy());
  147. expect(mock.calls()).toHaveLength(1);
  148. });
  149. it('useSendMessage', async () => {
  150. const mock = fetchMock.postOnce(`${topicPath}/messages`, {});
  151. const { result } = renderHook(() => hooks.useSendMessage(topicParams), {
  152. wrapper: TestQueryClientProvider,
  153. });
  154. const message: CreateTopicMessage = {
  155. partition: 0,
  156. content: 'Hello World',
  157. };
  158. await act(() => {
  159. result.current.mutateAsync(message);
  160. });
  161. await waitFor(() => expect(result.current.isSuccess).toBeTruthy());
  162. expect(mock.calls()).toHaveLength(1);
  163. });
  164. });
  165. });