suggestedOwners.spec.jsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import {
  2. render,
  3. screen,
  4. userEvent,
  5. waitFor,
  6. waitForElementToBeRemoved,
  7. } from 'sentry-test/reactTestingLibrary';
  8. import {Client} from 'sentry/api';
  9. import SuggestedOwners from 'sentry/components/group/suggestedOwners/suggestedOwners';
  10. import CommitterStore from 'sentry/stores/committerStore';
  11. import MemberListStore from 'sentry/stores/memberListStore';
  12. import TeamStore from 'sentry/stores/teamStore';
  13. describe('SuggestedOwners', function () {
  14. const user = TestStubs.User();
  15. const organization = TestStubs.Organization();
  16. const project = TestStubs.Project();
  17. const event = TestStubs.Event();
  18. const group = TestStubs.Group({firstRelease: {}});
  19. const endpoint = `/projects/${organization.slug}/${project.slug}/events/${event.id}`;
  20. beforeEach(function () {
  21. CommitterStore.init();
  22. TeamStore.init();
  23. MemberListStore.loadInitialData([user, TestStubs.CommitAuthor()]);
  24. Client.addMockResponse({
  25. url: `/projects/${organization.slug}/${project.slug}/codeowners/`,
  26. body: [],
  27. });
  28. Client.addMockResponse({
  29. url: `/prompts-activity/`,
  30. body: {},
  31. });
  32. Client.addMockResponse({
  33. url: `/organizations/${organization.slug}/code-mappings/`,
  34. query: {project: -1},
  35. method: 'GET',
  36. body: [],
  37. });
  38. });
  39. afterEach(function () {
  40. Client.clearMockResponses();
  41. TeamStore.teardown();
  42. CommitterStore.teardown();
  43. });
  44. it('Renders suggested owners', async function () {
  45. Client.addMockResponse({
  46. url: `${endpoint}/committers/`,
  47. body: {
  48. committers: [
  49. {
  50. author: TestStubs.CommitAuthor(),
  51. commits: [TestStubs.Commit()],
  52. },
  53. ],
  54. },
  55. });
  56. Client.addMockResponse({
  57. url: `${endpoint}/owners/`,
  58. body: {
  59. owners: [{type: 'user', ...user}],
  60. rules: [[['path', 'sentry/tagstore/*'], [['user', user.email]]]],
  61. },
  62. });
  63. render(<SuggestedOwners project={project} group={group} event={event} />, {
  64. organization,
  65. });
  66. await waitFor(() =>
  67. expect(screen.getAllByTestId('suggested-assignee')).toHaveLength(2)
  68. );
  69. userEvent.hover(screen.getAllByTestId('suggested-assignee')[0]);
  70. });
  71. it('does not call committers endpoint if `group.firstRelease` does not exist', async function () {
  72. const committers = Client.addMockResponse({
  73. url: `${endpoint}/committers/`,
  74. body: {
  75. committers: [
  76. {
  77. author: TestStubs.CommitAuthor(),
  78. commits: [TestStubs.Commit()],
  79. },
  80. ],
  81. },
  82. });
  83. Client.addMockResponse({
  84. url: `${endpoint}/owners/`,
  85. body: {
  86. owners: [{type: 'user', ...user}],
  87. rules: [[['path', 'sentry/tagstore/*'], [['user', user.email]]]],
  88. },
  89. });
  90. render(
  91. <SuggestedOwners project={project} group={TestStubs.Group()} event={event} />,
  92. {organization}
  93. );
  94. await waitForElementToBeRemoved(() => screen.queryByTestId('loading-indicator'));
  95. expect(committers).not.toHaveBeenCalled();
  96. });
  97. it('Merges owner matching rules and having suspect commits', async function () {
  98. const author = TestStubs.CommitAuthor();
  99. Client.addMockResponse({
  100. url: `${endpoint}/committers/`,
  101. body: {
  102. committers: [{author, commits: [TestStubs.Commit()]}],
  103. },
  104. });
  105. Client.addMockResponse({
  106. url: `${endpoint}/owners/`,
  107. body: {
  108. owners: [{type: 'user', ...author}],
  109. rules: [[['path', 'sentry/tagstore/*'], [['user', author.email]]]],
  110. },
  111. });
  112. render(<SuggestedOwners project={project} group={group} event={event} />, {
  113. organization,
  114. });
  115. userEvent.hover(await screen.findByTestId('suggested-assignee'));
  116. expect(await screen.findByText('sentry/tagstore/*')).toBeInTheDocument();
  117. expect(screen.getByText('Matching Ownership Rules')).toBeInTheDocument();
  118. });
  119. it('displays two teams when there are committers', async function () {
  120. const team1 = TestStubs.Team({slug: 'team-1', id: '1'});
  121. const team2 = TestStubs.Team({slug: 'team-2', id: '2'});
  122. TeamStore.loadInitialData([team1, team2], false, null);
  123. Client.addMockResponse({
  124. url: `${endpoint}/committers/`,
  125. body: {
  126. committers: [{author: TestStubs.CommitAuthor(), commits: [TestStubs.Commit()]}],
  127. },
  128. });
  129. Client.addMockResponse({
  130. url: `${endpoint}/owners/`,
  131. body: {
  132. owners: [
  133. {type: 'team', id: team1.id, name: team1.slug},
  134. {type: 'team', id: team2.id, name: team2.slug},
  135. ],
  136. rules: [[['path', 'sentry/tagstore/*'], [['team', team1.slug]]]],
  137. },
  138. });
  139. render(<SuggestedOwners project={project} group={group} event={event} />, {
  140. organization,
  141. });
  142. await waitFor(() =>
  143. expect(screen.getAllByTestId('suggested-assignee')).toHaveLength(3)
  144. );
  145. });
  146. });