teamSelector.spec.jsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import {Organization} from 'fixtures/js-stubs/organization';
  2. import {Project} from 'fixtures/js-stubs/project';
  3. import {Team} from 'fixtures/js-stubs/team';
  4. import {act, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  5. import {addTeamToProject} from 'sentry/actionCreators/projects';
  6. import OrganizationStore from 'sentry/stores/organizationStore';
  7. import TeamStore from 'sentry/stores/teamStore';
  8. import {TeamSelector} from './teamSelector';
  9. jest.mock('sentry/actionCreators/projects', () => ({
  10. addTeamToProject: jest.fn(),
  11. }));
  12. const teamData = [
  13. {
  14. id: '1',
  15. slug: 'team1',
  16. name: 'Team 1',
  17. },
  18. {
  19. id: '2',
  20. slug: 'team2',
  21. name: 'Team 2',
  22. },
  23. {
  24. id: '3',
  25. slug: 'team3',
  26. name: 'Team 3',
  27. },
  28. ];
  29. const teams = teamData.map(data => Team(data));
  30. const project = Project({teams: [teams[0]]});
  31. const organization = Organization({access: ['project:write']});
  32. act(() => OrganizationStore.onUpdate(organization, {replace: true}));
  33. function createWrapper(props = {}) {
  34. return render(
  35. <TeamSelector
  36. organization={organization}
  37. name="teamSelector"
  38. aria-label="Select a team"
  39. {...props}
  40. />
  41. );
  42. }
  43. describe('Team Selector', function () {
  44. beforeEach(function () {
  45. TeamStore.loadInitialData(teams);
  46. });
  47. it('renders options', function () {
  48. createWrapper();
  49. userEvent.type(screen.getByText('Select...'), '{keyDown}');
  50. expect(screen.getByText('#team1')).toBeInTheDocument();
  51. expect(screen.getByText('#team2')).toBeInTheDocument();
  52. expect(screen.getByText('#team3')).toBeInTheDocument();
  53. });
  54. it('selects an option', function () {
  55. const onChangeMock = jest.fn();
  56. createWrapper({onChange: onChangeMock});
  57. userEvent.type(screen.getByText('Select...'), '{keyDown}');
  58. const option = screen.getByText('#team1');
  59. userEvent.click(option);
  60. expect(onChangeMock).toHaveBeenCalledWith(
  61. expect.objectContaining({value: 'team1'}),
  62. expect.anything()
  63. );
  64. });
  65. it('respects the team filter', function () {
  66. const teamFilter = team => team.slug === 'team1';
  67. createWrapper({teamFilter});
  68. userEvent.type(screen.getByText('Select...'), '{keyDown}');
  69. expect(screen.getByText('#team1')).toBeInTheDocument();
  70. // These options should be filtered out
  71. expect(screen.queryByText('#team2')).not.toBeInTheDocument();
  72. expect(screen.queryByText('#team3')).not.toBeInTheDocument();
  73. });
  74. it('respects the project filter', function () {
  75. createWrapper({project});
  76. userEvent.type(screen.getByText('Select...'), '{keyDown}');
  77. expect(screen.getByText('#team1')).toBeInTheDocument();
  78. // team2 and team3 should have add to project buttons
  79. expect(screen.getAllByRole('button').length).toBe(2);
  80. });
  81. it('respects the team and project filter', function () {
  82. const teamFilter = team => team.slug === 'team1' || team.slug === 'team2';
  83. createWrapper({teamFilter, project});
  84. userEvent.type(screen.getByText('Select...'), '{keyDown}');
  85. expect(screen.getByText('#team1')).toBeInTheDocument();
  86. // team3 should be filtered out
  87. expect(screen.queryByText('#team3')).not.toBeInTheDocument();
  88. // team2 should have add to project buttons
  89. expect(screen.getAllByRole('button').length).toBe(1);
  90. });
  91. it('allows you to add teams outside of project', function () {
  92. createWrapper({project});
  93. userEvent.type(screen.getByText('Select...'), '{keyDown}');
  94. expect(screen.getByText('#team1')).toBeInTheDocument();
  95. // team2 and team3 should have add to project buttons
  96. const addToProjectButtons = screen.getAllByRole('button');
  97. userEvent.click(addToProjectButtons[0]);
  98. expect(addTeamToProject).toHaveBeenCalled();
  99. });
  100. it('allows searching by slug with useId', async function () {
  101. const onChangeMock = jest.fn();
  102. createWrapper({useId: true, onChange: onChangeMock});
  103. userEvent.type(screen.getByText('Select...'), '{keyDown}');
  104. MockApiClient.addMockResponse({
  105. url: `/organizations/${organization.slug}/teams/`,
  106. });
  107. userEvent.type(screen.getByLabelText('Select a team'), 'team2');
  108. expect(screen.getByText('#team2')).toBeInTheDocument();
  109. userEvent.click(screen.getByText('#team2'));
  110. expect(onChangeMock).toHaveBeenCalledWith(
  111. expect.objectContaining({value: '2'}),
  112. expect.anything()
  113. );
  114. // Wait for store to be updated from API response
  115. await act(tick);
  116. });
  117. });