teamKeyTransactionField.spec.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  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, waitFor} from 'sentry-test/reactTestingLibrary';
  5. import * as TeamKeyTransactionManager from 'sentry/components/performance/teamKeyTransactionsManager';
  6. import ProjectsStore from 'sentry/stores/projectsStore';
  7. import TeamStore from 'sentry/stores/teamStore';
  8. import TeamKeyTransactionField from 'sentry/utils/discover/teamKeyTransactionField';
  9. describe('TeamKeyTransactionField', function () {
  10. const organization = Organization();
  11. const teams = [
  12. Team({id: '1', slug: 'team1', name: 'Team 1'}),
  13. Team({id: '2', slug: 'team2', name: 'Team 2'}),
  14. ];
  15. const project = Project({teams});
  16. beforeEach(function () {
  17. MockApiClient.clearMockResponses();
  18. act(() => ProjectsStore.loadInitialData([project]));
  19. act(() => TeamStore.loadInitialData(teams));
  20. });
  21. it('renders with all teams checked', async function () {
  22. const getTeamKeyTransactionsMock = MockApiClient.addMockResponse({
  23. method: 'GET',
  24. url: `/organizations/${organization.slug}/key-transactions-list/`,
  25. body: teams.map(({id}) => ({
  26. team: id,
  27. count: 1,
  28. keyed: [{project_id: String(project.id), transaction: 'transaction'}],
  29. })),
  30. });
  31. render(
  32. <TeamKeyTransactionManager.Provider
  33. organization={organization}
  34. teams={teams}
  35. selectedTeams={['myteams']}
  36. >
  37. <TeamKeyTransactionField
  38. isKeyTransaction
  39. organization={organization}
  40. projectSlug={project.slug}
  41. transactionName="transaction"
  42. />
  43. </TeamKeyTransactionManager.Provider>
  44. );
  45. await waitFor(() => {
  46. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  47. });
  48. expect(getTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
  49. userEvent.click(screen.getByRole('button', {name: 'Toggle star for team'}));
  50. const [allTeamsCheckbox, teamOneCheckbox, teamTwoCheckbox] =
  51. screen.getAllByRole('checkbox');
  52. expect(allTeamsCheckbox).toBeChecked();
  53. expect(teamOneCheckbox).toBeChecked();
  54. expect(teamTwoCheckbox).toBeChecked();
  55. });
  56. it('renders with some teams checked', async function () {
  57. const getTeamKeyTransactionsMock = MockApiClient.addMockResponse({
  58. method: 'GET',
  59. url: `/organizations/${organization.slug}/key-transactions-list/`,
  60. body: teams.map(({id}) => ({
  61. team: id,
  62. count: id === teams[0].id ? 1 : 0,
  63. keyed:
  64. id === teams[0].id
  65. ? [{project_id: String(project.id), transaction: 'transaction'}]
  66. : [],
  67. })),
  68. });
  69. render(
  70. <TeamKeyTransactionManager.Provider
  71. organization={organization}
  72. teams={teams}
  73. selectedTeams={['myteams']}
  74. >
  75. <TeamKeyTransactionField
  76. isKeyTransaction
  77. organization={organization}
  78. projectSlug={project.slug}
  79. transactionName="transaction"
  80. />
  81. </TeamKeyTransactionManager.Provider>
  82. );
  83. await waitFor(() => {
  84. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  85. });
  86. expect(getTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
  87. userEvent.click(screen.getByRole('button', {name: 'Toggle star for team'}));
  88. const [allTeamsCheckbox, teamOneCheckbox, teamTwoCheckbox] =
  89. screen.getAllByRole('checkbox');
  90. expect(allTeamsCheckbox).not.toBeChecked();
  91. expect(teamOneCheckbox).toBeChecked();
  92. expect(teamTwoCheckbox).not.toBeChecked();
  93. });
  94. it('renders with no teams checked', async function () {
  95. const getTeamKeyTransactionsMock = MockApiClient.addMockResponse({
  96. method: 'GET',
  97. url: `/organizations/${organization.slug}/key-transactions-list/`,
  98. body: teams.map(({id}) => ({
  99. team: id,
  100. count: 0,
  101. keyed: [],
  102. })),
  103. });
  104. render(
  105. <TeamKeyTransactionManager.Provider
  106. organization={organization}
  107. teams={teams}
  108. selectedTeams={['myteams']}
  109. >
  110. <TeamKeyTransactionField
  111. isKeyTransaction
  112. organization={organization}
  113. projectSlug={project.slug}
  114. transactionName="transaction"
  115. />
  116. </TeamKeyTransactionManager.Provider>
  117. );
  118. await waitFor(() => {
  119. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  120. });
  121. expect(getTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
  122. userEvent.click(screen.getByRole('button', {name: 'Toggle star for team'}));
  123. const [allTeamsCheckbox, teamOneCheckbox, teamTwoCheckbox] =
  124. screen.getAllByRole('checkbox');
  125. expect(allTeamsCheckbox).not.toBeChecked();
  126. expect(teamOneCheckbox).not.toBeChecked();
  127. expect(teamTwoCheckbox).not.toBeChecked();
  128. });
  129. it('should be able to check one team', async function () {
  130. MockApiClient.addMockResponse({
  131. method: 'GET',
  132. url: `/organizations/${organization.slug}/key-transactions-list/`,
  133. body: teams.map(({id}) => ({
  134. team: id,
  135. count: 0,
  136. keyed: [],
  137. })),
  138. });
  139. const postTeamKeyTransactionsMock = MockApiClient.addMockResponse({
  140. method: 'POST',
  141. url: '/organizations/org-slug/key-transactions/',
  142. body: [],
  143. match: [
  144. MockApiClient.matchQuery({project: [project.id]}),
  145. MockApiClient.matchData({team: [teams[0].id], transaction: 'transaction'}),
  146. ],
  147. });
  148. render(
  149. <TeamKeyTransactionManager.Provider
  150. organization={organization}
  151. teams={teams}
  152. selectedTeams={['myteams']}
  153. >
  154. <TeamKeyTransactionField
  155. isKeyTransaction
  156. organization={organization}
  157. projectSlug={project.slug}
  158. transactionName="transaction"
  159. />
  160. </TeamKeyTransactionManager.Provider>
  161. );
  162. await waitFor(() => {
  163. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  164. });
  165. userEvent.click(screen.getByRole('button', {name: 'Toggle star for team'}));
  166. const [_allTeamsCheckbox, teamOneCheckbox, _teamTwoCheckbox] =
  167. screen.getAllByRole('checkbox');
  168. expect(teamOneCheckbox).not.toBeChecked();
  169. userEvent.click(teamOneCheckbox);
  170. expect(postTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
  171. await waitFor(() => {
  172. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  173. });
  174. expect(teamOneCheckbox).toBeChecked();
  175. });
  176. it('should be able to uncheck one team', async function () {
  177. MockApiClient.addMockResponse({
  178. method: 'GET',
  179. url: `/organizations/${organization.slug}/key-transactions-list/`,
  180. body: teams.map(({id}) => ({
  181. team: id,
  182. count: 1,
  183. keyed: [{project_id: String(project.id), transaction: 'transaction'}],
  184. })),
  185. });
  186. const deleteTeamKeyTransactionsMock = MockApiClient.addMockResponse({
  187. method: 'DELETE',
  188. url: '/organizations/org-slug/key-transactions/',
  189. body: [],
  190. match: [
  191. MockApiClient.matchQuery({project: [project.id]}),
  192. MockApiClient.matchData({team: [teams[0].id], transaction: 'transaction'}),
  193. ],
  194. });
  195. render(
  196. <TeamKeyTransactionManager.Provider
  197. organization={organization}
  198. teams={teams}
  199. selectedTeams={['myteams']}
  200. >
  201. <TeamKeyTransactionField
  202. isKeyTransaction
  203. organization={organization}
  204. projectSlug={project.slug}
  205. transactionName="transaction"
  206. />
  207. </TeamKeyTransactionManager.Provider>
  208. );
  209. await waitFor(() => {
  210. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  211. });
  212. userEvent.click(screen.getByRole('button', {name: 'Toggle star for team'}));
  213. const [_allTeamsCheckbox, teamOneCheckbox, _teamTwoCheckbox] =
  214. screen.getAllByRole('checkbox');
  215. expect(teamOneCheckbox).toBeChecked();
  216. userEvent.click(teamOneCheckbox);
  217. expect(deleteTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
  218. await waitFor(() => {
  219. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  220. });
  221. expect(teamOneCheckbox).not.toBeChecked();
  222. });
  223. it('should be able to check all with my teams', async function () {
  224. MockApiClient.addMockResponse({
  225. method: 'GET',
  226. url: `/organizations/${organization.slug}/key-transactions-list/`,
  227. body: teams.map(({id}) => ({
  228. team: id,
  229. count: 0,
  230. keyed: [],
  231. })),
  232. });
  233. const postTeamKeyTransactionsMock = MockApiClient.addMockResponse({
  234. method: 'POST',
  235. url: '/organizations/org-slug/key-transactions/',
  236. body: [],
  237. match: [
  238. MockApiClient.matchQuery({project: [project.id]}),
  239. MockApiClient.matchData({
  240. team: [teams[0].id, teams[1].id],
  241. transaction: 'transaction',
  242. }),
  243. ],
  244. });
  245. render(
  246. <TeamKeyTransactionManager.Provider
  247. organization={organization}
  248. teams={teams}
  249. selectedTeams={['myteams']}
  250. >
  251. <TeamKeyTransactionField
  252. isKeyTransaction
  253. organization={organization}
  254. projectSlug={project.slug}
  255. transactionName="transaction"
  256. />
  257. </TeamKeyTransactionManager.Provider>
  258. );
  259. await waitFor(() => {
  260. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  261. });
  262. userEvent.click(screen.getByRole('button', {name: 'Toggle star for team'}));
  263. const [allTeamsCheckbox, teamOneCheckbox, teamTwoCheckbox] =
  264. screen.getAllByRole('checkbox');
  265. expect(allTeamsCheckbox).not.toBeChecked();
  266. userEvent.click(allTeamsCheckbox);
  267. expect(postTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
  268. await waitFor(() => {
  269. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  270. });
  271. expect(allTeamsCheckbox).toBeChecked();
  272. expect(teamOneCheckbox).toBeChecked();
  273. expect(teamTwoCheckbox).toBeChecked();
  274. });
  275. it('should be able to uncheck all with my teams', async function () {
  276. MockApiClient.addMockResponse({
  277. method: 'GET',
  278. url: `/organizations/${organization.slug}/key-transactions-list/`,
  279. body: teams.map(({id}) => ({
  280. team: id,
  281. count: 1,
  282. keyed: [{project_id: String(project.id), transaction: 'transaction'}],
  283. })),
  284. });
  285. const deleteTeamKeyTransactionsMock = MockApiClient.addMockResponse({
  286. method: 'DELETE',
  287. url: '/organizations/org-slug/key-transactions/',
  288. body: [],
  289. match: [
  290. MockApiClient.matchQuery({project: [project.id]}),
  291. MockApiClient.matchData({
  292. team: [teams[0].id, teams[1].id],
  293. transaction: 'transaction',
  294. }),
  295. ],
  296. });
  297. render(
  298. <TeamKeyTransactionManager.Provider
  299. organization={organization}
  300. teams={teams}
  301. selectedTeams={['myteams']}
  302. >
  303. <TeamKeyTransactionField
  304. isKeyTransaction
  305. organization={organization}
  306. projectSlug={project.slug}
  307. transactionName="transaction"
  308. />
  309. </TeamKeyTransactionManager.Provider>
  310. );
  311. await waitFor(() => {
  312. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  313. });
  314. userEvent.click(screen.getByRole('button', {name: 'Toggle star for team'}));
  315. const [allTeamsCheckbox, teamOneCheckbox, teamTwoCheckbox] =
  316. screen.getAllByRole('checkbox');
  317. expect(allTeamsCheckbox).toBeChecked();
  318. userEvent.click(allTeamsCheckbox);
  319. expect(deleteTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
  320. await waitFor(() => {
  321. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  322. });
  323. expect(allTeamsCheckbox).not.toBeChecked();
  324. expect(teamOneCheckbox).not.toBeChecked();
  325. expect(teamTwoCheckbox).not.toBeChecked();
  326. });
  327. it('should render teams without access separately', async function () {
  328. const myTeams = [...teams, Team({id: '3', slug: 'team3', name: 'Team 3'})];
  329. act(() => {
  330. TeamStore.loadInitialData(myTeams);
  331. });
  332. MockApiClient.addMockResponse({
  333. method: 'GET',
  334. url: `/organizations/${organization.slug}/key-transactions-list/`,
  335. body: myTeams.map(({id}) => ({
  336. team: id,
  337. count: 0,
  338. keyed: [],
  339. })),
  340. });
  341. render(
  342. <TeamKeyTransactionManager.Provider
  343. organization={organization}
  344. teams={myTeams}
  345. selectedTeams={['myteams']}
  346. >
  347. <TeamKeyTransactionField
  348. isKeyTransaction
  349. organization={organization}
  350. projectSlug={project.slug}
  351. transactionName="transaction"
  352. />
  353. </TeamKeyTransactionManager.Provider>
  354. );
  355. await waitFor(() => {
  356. expect(screen.getByRole('button', {name: 'Toggle star for team'})).toBeEnabled();
  357. });
  358. userEvent.click(screen.getByRole('button', {name: 'Toggle star for team'}));
  359. expect(screen.getByText('My Teams with Access')).toBeInTheDocument();
  360. expect(screen.getByText('My Teams without Access')).toBeInTheDocument();
  361. // Only renders checkboxes for teams with access
  362. expect(screen.getAllByRole('checkbox')).toHaveLength(3);
  363. expect(screen.getByText('team3')).toBeInTheDocument();
  364. });
  365. });