ruleBuilder.spec.jsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import selectEvent from 'react-select-event';
  2. import {
  3. render,
  4. screen,
  5. userEvent,
  6. waitFor,
  7. waitForElementToBeRemoved,
  8. } from 'sentry-test/reactTestingLibrary';
  9. import MemberListStore from 'sentry/stores/memberListStore';
  10. import ProjectsStore from 'sentry/stores/projectsStore';
  11. import TeamStore from 'sentry/stores/teamStore';
  12. import RuleBuilder from 'sentry/views/settings/project/projectOwnership/ruleBuilder';
  13. describe('RuleBuilder', function () {
  14. const organization = TestStubs.Organization();
  15. let project;
  16. let handleAdd;
  17. const USER_1 = TestStubs.User({
  18. id: '1',
  19. name: 'Jane Bloggs',
  20. email: 'janebloggs@example.com',
  21. user: {
  22. id: '1',
  23. name: 'Jane Bloggs',
  24. email: 'janebloggs@example.com',
  25. },
  26. });
  27. const USER_2 = TestStubs.User({
  28. id: '2',
  29. name: 'John Smith',
  30. email: 'johnsmith@example.com',
  31. user: {
  32. id: '2',
  33. name: 'John Smith',
  34. email: 'johnsmith@example.com',
  35. },
  36. });
  37. const TEAM_1 = TestStubs.Team({
  38. id: '3',
  39. slug: 'cool-team',
  40. });
  41. // This team is in project
  42. const TEAM_2 = TestStubs.Team({
  43. id: '4',
  44. slug: 'team-not-in-project',
  45. });
  46. beforeEach(function () {
  47. // User in project
  48. MemberListStore.loadInitialData([USER_1]);
  49. // All teams
  50. jest.spyOn(TeamStore, 'getAll').mockImplementation(() => [TEAM_1, TEAM_2]);
  51. handleAdd = jest.fn();
  52. project = TestStubs.Project({
  53. // Teams in project
  54. teams: [TEAM_1],
  55. });
  56. ProjectsStore.loadInitialData([project]);
  57. jest.spyOn(ProjectsStore, 'getBySlug').mockImplementation(() => project);
  58. MockApiClient.clearMockResponses();
  59. MockApiClient.addMockResponse({
  60. url: '/organizations/org-slug/members/',
  61. body: [USER_1, USER_2],
  62. });
  63. });
  64. it('renders', async function () {
  65. const {container} = render(
  66. <RuleBuilder project={project} organization={organization} onAddRule={handleAdd} />
  67. );
  68. const addButton = screen.getByRole('button', {name: 'Add rule'});
  69. userEvent.click(addButton);
  70. expect(handleAdd).not.toHaveBeenCalled();
  71. userEvent.type(screen.getByRole('textbox', {name: 'Rule pattern'}), 'some/path/*');
  72. expect(addButton).toBeDisabled();
  73. await selectEvent.select(
  74. screen.getByRole('textbox', {name: 'Rule owner'}),
  75. 'Jane Bloggs'
  76. );
  77. expect(addButton).toBeEnabled();
  78. userEvent.click(addButton);
  79. expect(handleAdd).toHaveBeenCalled();
  80. expect(container).toSnapshot();
  81. });
  82. it('renders with suggestions', async function () {
  83. const {container} = render(
  84. <RuleBuilder
  85. project={project}
  86. organization={organization}
  87. onAddRule={handleAdd}
  88. urls={['example.com/a', 'example.com/a/foo']}
  89. paths={['a/bar', 'a/foo']}
  90. />
  91. );
  92. // Open the menu so we can do some assertions.
  93. const ownerInput = screen.getByRole('textbox', {name: 'Rule owner'});
  94. selectEvent.openMenu(ownerInput);
  95. await waitForElementToBeRemoved(() => screen.queryByText('Loading...'));
  96. expect(screen.getByText('Jane Bloggs')).toBeInTheDocument();
  97. expect(screen.getByText('John Smith')).toBeInTheDocument();
  98. expect(screen.getByText('#cool-team')).toBeInTheDocument();
  99. expect(screen.getByText('#team-not-in-project')).toBeInTheDocument();
  100. // TODO Check that the last two are disabled
  101. // Enter to select Jane Bloggs
  102. await selectEvent.select(ownerInput, 'Jane Bloggs');
  103. const candidates = screen.getAllByRole('button', {name: 'Path rule candidate'});
  104. userEvent.click(candidates[0]);
  105. expect(screen.getByRole('textbox', {name: 'Rule pattern'})).toHaveValue('a/bar');
  106. const addButton = screen.getByRole('button', {name: 'Add rule'});
  107. await waitFor(() => expect(addButton).toBeEnabled());
  108. expect(container).toSnapshot();
  109. userEvent.click(addButton);
  110. expect(handleAdd).toHaveBeenCalled();
  111. });
  112. });