autofixMessageBox.analytics.spec.tsx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import {AutofixCodebaseChangeData} from 'sentry-fixture/autofixCodebaseChangeData';
  2. import {AutofixStepFixture} from 'sentry-fixture/autofixStep';
  3. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  4. import {Button} from 'sentry/components/button';
  5. import AutofixMessageBox from 'sentry/components/events/autofix/autofixMessageBox';
  6. import {AutofixStepType} from 'sentry/components/events/autofix/types';
  7. jest.mock('sentry/components/button', () => ({
  8. Button: jest.fn(props => {
  9. // Forward the click handler while allowing us to inspect props
  10. return <button onClick={props.onClick}>{props.children}</button>;
  11. }),
  12. LinkButton: jest.fn(props => {
  13. return <a href={props.href}>{props.children}</a>;
  14. }),
  15. }));
  16. const mockButton = Button as jest.MockedFunction<typeof Button>;
  17. describe('AutofixMessageBox Analytics', () => {
  18. const defaultProps = {
  19. displayText: 'Test display text',
  20. groupId: '123',
  21. runId: '456',
  22. actionText: 'Send',
  23. allowEmptyMessage: false,
  24. responseRequired: false,
  25. step: null,
  26. onSend: null,
  27. };
  28. const changesStepProps = {
  29. ...defaultProps,
  30. isChangesStep: true,
  31. step: AutofixStepFixture({
  32. type: AutofixStepType.CHANGES,
  33. changes: [AutofixCodebaseChangeData()],
  34. }),
  35. };
  36. beforeEach(() => {
  37. MockApiClient.clearMockResponses();
  38. mockButton.mockClear();
  39. });
  40. it('passes correct analytics props for suggested root cause without instructions', async () => {
  41. const onSendMock = jest.fn();
  42. render(
  43. <AutofixMessageBox {...defaultProps} onSend={onSendMock} isRootCauseSelectionStep />
  44. );
  45. await userEvent.click(screen.getByRole('button', {name: 'Use suggested root cause'}));
  46. expect(mockButton).toHaveBeenLastCalledWith(
  47. expect.objectContaining({
  48. analyticsEventKey: 'autofix.create_fix_clicked',
  49. analyticsEventName: 'Autofix: Create Fix Clicked',
  50. analyticsParams: {
  51. group_id: '123',
  52. type: 'suggested',
  53. },
  54. }),
  55. expect.anything()
  56. );
  57. });
  58. it('passes correct analytics props for suggested root cause with instructions', async () => {
  59. const onSendMock = jest.fn();
  60. render(
  61. <AutofixMessageBox {...defaultProps} onSend={onSendMock} isRootCauseSelectionStep />
  62. );
  63. await userEvent.click(screen.getByRole('button', {name: 'Use suggested root cause'}));
  64. const input = screen.getByPlaceholderText(
  65. '(Optional) Provide any instructions for the fix...'
  66. );
  67. await userEvent.type(input, 'Some instructions');
  68. expect(mockButton).toHaveBeenLastCalledWith(
  69. expect.objectContaining({
  70. analyticsEventKey: 'autofix.create_fix_clicked',
  71. analyticsEventName: 'Autofix: Create Fix Clicked',
  72. analyticsParams: {
  73. group_id: '123',
  74. type: 'suggested_with_instructions',
  75. },
  76. }),
  77. expect.anything()
  78. );
  79. });
  80. it('passes correct analytics props for custom root cause', async () => {
  81. const onSendMock = jest.fn();
  82. render(
  83. <AutofixMessageBox {...defaultProps} onSend={onSendMock} isRootCauseSelectionStep />
  84. );
  85. await userEvent.click(screen.getAllByText('Propose your own root cause')[0]);
  86. const customInput = screen.getByPlaceholderText('Propose your own root cause...');
  87. await userEvent.type(customInput, 'Custom root cause');
  88. expect(mockButton).toHaveBeenLastCalledWith(
  89. expect.objectContaining({
  90. analyticsEventKey: 'autofix.create_fix_clicked',
  91. analyticsEventName: 'Autofix: Create Fix Clicked',
  92. analyticsParams: {
  93. group_id: '123',
  94. type: 'custom',
  95. },
  96. }),
  97. expect.anything()
  98. );
  99. });
  100. it('passes correct analytics props for Create PR button', async () => {
  101. MockApiClient.addMockResponse({
  102. url: '/issues/123/autofix/setup/?check_write_access=true',
  103. method: 'GET',
  104. body: {
  105. genAIConsent: {ok: true},
  106. integration: {ok: true},
  107. githubWriteIntegration: {
  108. repos: [{ok: true, owner: 'owner', name: 'hello-world', id: 100}],
  109. },
  110. },
  111. });
  112. render(<AutofixMessageBox {...changesStepProps} />);
  113. await userEvent.click(screen.getByRole('button', {name: 'Approve'}));
  114. // Find the last call to Button that matches our Create PR button
  115. const createPRButtonCall = mockButton.mock.calls.find(
  116. call => call[0]?.analyticsEventKey === 'autofix.create_pr_clicked'
  117. );
  118. expect(createPRButtonCall?.[0]).toEqual(
  119. expect.objectContaining({
  120. analyticsEventKey: 'autofix.create_pr_clicked',
  121. analyticsEventName: 'Autofix: Create PR Clicked',
  122. analyticsParams: {group_id: '123'},
  123. })
  124. );
  125. });
  126. it('passes correct analytics props for Create PR Setup button', async () => {
  127. MockApiClient.addMockResponse({
  128. url: '/issues/123/autofix/setup/?check_write_access=true',
  129. method: 'GET',
  130. body: {
  131. genAIConsent: {ok: true},
  132. integration: {ok: true},
  133. githubWriteIntegration: {
  134. repos: [{ok: false, owner: 'owner', name: 'hello-world', id: 100}],
  135. },
  136. },
  137. });
  138. render(<AutofixMessageBox {...changesStepProps} />);
  139. await userEvent.click(screen.getByRole('button', {name: 'Approve'}));
  140. // Find the last call to Button that matches our Setup button
  141. const setupButtonCall = mockButton.mock.calls.find(
  142. call => call[0].children === 'Create PRs'
  143. );
  144. expect(setupButtonCall?.[0]).toEqual(
  145. expect.objectContaining({
  146. analyticsEventKey: 'autofix.create_pr_setup_clicked',
  147. analyticsEventName: 'Autofix: Create PR Setup Clicked',
  148. analyticsParams: {
  149. group_id: '123',
  150. },
  151. })
  152. );
  153. });
  154. });