You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CreateApplication-test.tsx 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import userEvent from '@testing-library/user-event';
  21. import * as React from 'react';
  22. import { queryToSearchString } from '~sonar-aligned/helpers/urls';
  23. import { ComponentQualifier } from '~sonar-aligned/types/component';
  24. import { createApplication } from '../../../../api/application';
  25. import { getComponentNavigation } from '../../../../api/navigation';
  26. import { mockAppState, mockLoggedInUser, mockRouter } from '../../../../helpers/testMocks';
  27. import { renderComponent } from '../../../../helpers/testReactTestingUtils';
  28. import { byRole, byText } from '../../../../helpers/testSelector';
  29. import { Visibility } from '../../../../types/component';
  30. import { FCProps } from '../../../../types/misc';
  31. import { LoggedInUser } from '../../../../types/users';
  32. import { ApplicationCreation } from '../ApplicationCreation';
  33. jest.mock('../../../../api/application', () => ({
  34. createApplication: jest.fn().mockResolvedValue({}),
  35. }));
  36. jest.mock('../../../../api/navigation', () => ({
  37. getComponentNavigation: jest.fn().mockResolvedValue({}),
  38. }));
  39. const ui = {
  40. buttonAddApplication: byRole('button', { name: 'projects.create_application' }),
  41. createApplicationHeader: byText('qualifiers.create.APP'),
  42. mandatoryFieldWarning: byText('fields_marked_with_x_required'),
  43. formNameField: byRole('textbox', { name: 'name field_required' }),
  44. formKeyField: byRole('textbox', { name: 'key' }),
  45. formDescriptionField: byRole('textbox', { name: 'description' }),
  46. formVisibilityField: byText('visibility'),
  47. formRadioButtonPrivate: byRole('radio', { name: 'visibility.private' }),
  48. formCreateButton: byRole('button', { name: 'create' }),
  49. formCancelButton: byRole('button', { name: 'cancel' }),
  50. };
  51. beforeEach(() => {
  52. jest.clearAllMocks();
  53. });
  54. it('should be able to create application when user is logged in and has permission', async () => {
  55. const user = userEvent.setup();
  56. const routerPush = jest.fn();
  57. const router = mockRouter({ push: routerPush });
  58. jest.mocked(getComponentNavigation).mockResolvedValueOnce({
  59. configuration: { showSettings: true },
  60. name: 'name',
  61. breadcrumbs: [{ key: 'b-key', qualifier: 'qual', name: 'b-name' }],
  62. key: 'key',
  63. });
  64. jest.mocked(createApplication).mockResolvedValueOnce({
  65. application: {
  66. key: 'app',
  67. name: 'app',
  68. description: 'app',
  69. visibility: Visibility.Public,
  70. },
  71. });
  72. renderApplicationCreation(
  73. { router },
  74. mockLoggedInUser({ permissions: { global: ['admin', 'applicationcreator'] } }),
  75. );
  76. await user.click(ui.buttonAddApplication.get());
  77. expect(ui.createApplicationHeader.get()).toBeInTheDocument();
  78. expect(ui.mandatoryFieldWarning.get()).toBeInTheDocument();
  79. expect(ui.formNameField.get()).toBeInTheDocument();
  80. expect(ui.formDescriptionField.get()).toBeInTheDocument();
  81. expect(ui.formKeyField.get()).toBeInTheDocument();
  82. expect(ui.formVisibilityField.get()).toBeInTheDocument();
  83. expect(ui.formCreateButton.get()).toBeInTheDocument();
  84. expect(ui.formCancelButton.get()).toBeInTheDocument();
  85. await user.click(ui.formCancelButton.get());
  86. expect(ui.createApplicationHeader.query()).not.toBeInTheDocument();
  87. await user.click(ui.buttonAddApplication.get());
  88. await user.click(ui.formNameField.get());
  89. await user.keyboard('app');
  90. await user.click(ui.formDescriptionField.get());
  91. await user.keyboard('app description');
  92. await user.click(ui.formKeyField.get());
  93. await user.keyboard('app-key');
  94. await user.click(ui.formRadioButtonPrivate.get());
  95. await user.click(ui.formCreateButton.get());
  96. expect(createApplication).toHaveBeenCalledWith(
  97. 'app',
  98. 'app description',
  99. 'app-key',
  100. Visibility.Private,
  101. );
  102. expect(routerPush).toHaveBeenCalledWith({
  103. pathname: '/project/admin/extension/developer-server/application-console',
  104. search: queryToSearchString({
  105. id: 'app',
  106. }),
  107. });
  108. });
  109. function renderApplicationCreation(
  110. props: Partial<FCProps<typeof ApplicationCreation>> = {},
  111. currentUser: LoggedInUser = mockLoggedInUser(),
  112. ) {
  113. return renderComponent(
  114. <ApplicationCreation
  115. currentUser={currentUser}
  116. router={mockRouter()}
  117. appState={mockAppState({ qualifiers: [ComponentQualifier.Application] })}
  118. {...props}
  119. />,
  120. );
  121. }