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.

GithubProvisioningServiceMock.ts 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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 { cloneDeep } from 'lodash';
  21. import { mockTask } from '../../helpers/mocks/tasks';
  22. import {
  23. GitHubConfigurationStatus,
  24. GitHubMapping,
  25. GitHubProvisioningStatus,
  26. } from '../../types/provisioning';
  27. import { Task, TaskStatuses, TaskTypes } from '../../types/tasks';
  28. import {
  29. activateGithubProvisioning,
  30. addGithubRolesMapping,
  31. checkConfigurationValidity,
  32. deactivateGithubProvisioning,
  33. deleteGithubRolesMapping,
  34. fetchGithubProvisioningStatus,
  35. fetchGithubRolesMapping,
  36. updateGithubRolesMapping,
  37. } from '../github-provisioning';
  38. jest.mock('../github-provisioning');
  39. const defaultConfigurationStatus: GitHubConfigurationStatus = {
  40. application: {
  41. jit: {
  42. status: GitHubProvisioningStatus.Success,
  43. },
  44. autoProvisioning: {
  45. status: GitHubProvisioningStatus.Success,
  46. },
  47. },
  48. installations: [
  49. {
  50. organization: 'testOrg',
  51. autoProvisioning: {
  52. status: GitHubProvisioningStatus.Success,
  53. },
  54. jit: {
  55. status: GitHubProvisioningStatus.Success,
  56. },
  57. },
  58. ],
  59. };
  60. const githubMappingMock = (
  61. id: string,
  62. permissions: (keyof GitHubMapping['permissions'])[],
  63. baseRole = false,
  64. ) => ({
  65. id,
  66. githubRole: id,
  67. baseRole,
  68. permissions: {
  69. user: permissions.includes('user'),
  70. codeViewer: permissions.includes('codeViewer'),
  71. issueAdmin: permissions.includes('issueAdmin'),
  72. securityHotspotAdmin: permissions.includes('securityHotspotAdmin'),
  73. admin: permissions.includes('admin'),
  74. scan: permissions.includes('scan'),
  75. },
  76. });
  77. const defaultMapping: GitHubMapping[] = [
  78. githubMappingMock('read', ['user', 'codeViewer'], true),
  79. githubMappingMock(
  80. 'write',
  81. ['user', 'codeViewer', 'issueAdmin', 'securityHotspotAdmin', 'scan'],
  82. true,
  83. ),
  84. githubMappingMock('triage', ['user', 'codeViewer'], true),
  85. githubMappingMock(
  86. 'maintain',
  87. ['user', 'codeViewer', 'issueAdmin', 'securityHotspotAdmin', 'scan'],
  88. true,
  89. ),
  90. githubMappingMock(
  91. 'admin',
  92. ['user', 'codeViewer', 'issueAdmin', 'securityHotspotAdmin', 'admin', 'scan'],
  93. true,
  94. ),
  95. ];
  96. export default class GithubProvisioningServiceMock {
  97. githubProvisioningStatus: boolean;
  98. githubConfigurationStatus: GitHubConfigurationStatus;
  99. githubMapping: GitHubMapping[];
  100. tasks: Task[];
  101. constructor() {
  102. this.githubProvisioningStatus = false;
  103. this.githubConfigurationStatus = cloneDeep(defaultConfigurationStatus);
  104. this.githubMapping = cloneDeep(defaultMapping);
  105. this.tasks = [];
  106. jest
  107. .mocked(activateGithubProvisioning)
  108. .mockImplementation(this.handleActivateGithubProvisioning);
  109. jest
  110. .mocked(deactivateGithubProvisioning)
  111. .mockImplementation(this.handleDeactivateGithubProvisioning);
  112. jest
  113. .mocked(fetchGithubProvisioningStatus)
  114. .mockImplementation(this.handleFetchGithubProvisioningStatus);
  115. jest
  116. .mocked(checkConfigurationValidity)
  117. .mockImplementation(this.handleCheckConfigurationValidity);
  118. jest.mocked(fetchGithubRolesMapping).mockImplementation(this.handleFetchGithubRolesMapping);
  119. jest.mocked(updateGithubRolesMapping).mockImplementation(this.handleUpdateGithubRolesMapping);
  120. jest.mocked(addGithubRolesMapping).mockImplementation(this.handleAddGithubRolesMapping);
  121. jest.mocked(deleteGithubRolesMapping).mockImplementation(this.handleDeleteGithubRolesMapping);
  122. }
  123. addProvisioningTask = (overrides: Partial<Omit<Task, 'type'>> = {}) => {
  124. this.tasks.push(
  125. mockTask({
  126. id: Math.random().toString(),
  127. type: TaskTypes.GithubProvisioning,
  128. ...overrides,
  129. }),
  130. );
  131. };
  132. setConfigurationValidity = (overrides: Partial<GitHubConfigurationStatus> = {}) => {
  133. this.githubConfigurationStatus = {
  134. ...this.githubConfigurationStatus,
  135. ...overrides,
  136. };
  137. };
  138. enableGithubProvisioning = () => {
  139. this.githubProvisioningStatus = true;
  140. };
  141. handleActivateGithubProvisioning = () => {
  142. this.githubProvisioningStatus = true;
  143. return Promise.resolve();
  144. };
  145. handleDeactivateGithubProvisioning = () => {
  146. this.githubProvisioningStatus = false;
  147. return Promise.resolve();
  148. };
  149. handleFetchGithubProvisioningStatus = () => {
  150. if (!this.githubProvisioningStatus) {
  151. return Promise.resolve({ enabled: false });
  152. }
  153. const nextSync = this.tasks.find((t: Task) =>
  154. [TaskStatuses.InProgress, TaskStatuses.Pending].includes(t.status),
  155. );
  156. const lastSync = this.tasks.find(
  157. (t: Task) => ![TaskStatuses.InProgress, TaskStatuses.Pending].includes(t.status),
  158. );
  159. return Promise.resolve({
  160. enabled: true,
  161. nextSync: nextSync ? { status: nextSync.status } : undefined,
  162. lastSync: lastSync
  163. ? {
  164. status: lastSync.status,
  165. finishedAt: lastSync.executedAt,
  166. startedAt: lastSync.startedAt,
  167. executionTimeMs: lastSync.executionTimeMs,
  168. summary: lastSync.status === TaskStatuses.Success ? 'Test summary' : undefined,
  169. errorMessage: lastSync.errorMessage,
  170. warningMessage: lastSync.warnings?.join() ?? undefined,
  171. }
  172. : undefined,
  173. });
  174. };
  175. handleCheckConfigurationValidity = () => {
  176. return Promise.resolve(this.githubConfigurationStatus);
  177. };
  178. handleFetchGithubRolesMapping: typeof fetchGithubRolesMapping = () => {
  179. return Promise.resolve(this.githubMapping);
  180. };
  181. handleUpdateGithubRolesMapping: typeof updateGithubRolesMapping = (id, data) => {
  182. this.githubMapping = this.githubMapping.map((mapping) =>
  183. mapping.id === id ? { ...mapping, ...data } : mapping,
  184. );
  185. return Promise.resolve(
  186. this.githubMapping.find((mapping) => mapping.id === id) as GitHubMapping,
  187. );
  188. };
  189. handleAddGithubRolesMapping: typeof addGithubRolesMapping = (data) => {
  190. const newRole = { ...data, id: data.githubRole };
  191. this.githubMapping = [...this.githubMapping, newRole];
  192. return Promise.resolve(newRole);
  193. };
  194. handleDeleteGithubRolesMapping: typeof deleteGithubRolesMapping = (id) => {
  195. this.githubMapping = this.githubMapping.filter((el) => el.id !== id);
  196. return Promise.resolve();
  197. };
  198. addGitHubCustomRole = (id: string, permissions: (keyof GitHubMapping['permissions'])[]) => {
  199. this.githubMapping = [...this.githubMapping, githubMappingMock(id, permissions)];
  200. };
  201. reset = () => {
  202. this.githubProvisioningStatus = false;
  203. this.githubConfigurationStatus = cloneDeep(defaultConfigurationStatus);
  204. this.githubMapping = cloneDeep(defaultMapping);
  205. this.tasks = [];
  206. };
  207. }