diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/iam/iam.mock.ts b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/iam/iam.mock.ts index 5596b16852fd..9c7b36f89c6a 100644 --- a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/iam/iam.mock.ts +++ b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/iam/iam.mock.ts @@ -1,25 +1,22 @@ import { IamCheckResponse } from '@ovh-ux/manager-react-components'; import { organizationList } from '../vcd-organization/vcd-organization.mock'; +import { iamActions } from '@/utils/iam.constants'; export const resourceList: IamCheckResponse[] = [ { urn: organizationList[0].iam.urn, authorizedActions: [ - 'vmwareCloudDirectorBackup:apiovh:get', - 'vmwareCloudDirector:apiovh:organization/get', - 'account:apiovh:iam/resource/edit', - 'account:apiovh:service/terminate', + iamActions.vmwareCloudDirectorApiovhOrganizationEdit, + iamActions.vmwareCloudDirectorApiovhOrganizationVirtualDataCenterEdit, ], unauthorizedActions: [], }, { urn: organizationList[1].iam.urn, - authorizedActions: [], - unauthorizedActions: [ - 'vmwareCloudDirectorBackup:apiovh:get', - 'vmwareCloudDirector:apiovh:organization/get', - 'account:apiovh:iam/resource/edit', - 'account:apiovh:service/terminate', + authorizedActions: [ + iamActions.vmwareCloudDirectorApiovhOrganizationEdit, + iamActions.vmwareCloudDirectorApiovhOrganizationVirtualDataCenterEdit, ], + unauthorizedActions: [], }, ]; diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-datacentre.mock.ts b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-datacentre.mock.ts new file mode 100644 index 000000000000..f3830048da4b --- /dev/null +++ b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-datacentre.mock.ts @@ -0,0 +1,32 @@ +import IVcdDatacentre from '../../src/types/vcd-datacenter.interface'; + +export const datacentreList: IVcdDatacentre[] = [ + { + id: 'vdc-eu-central-waw-adc311b5-0c0b-4071-b48f-b20813868bcf', + resourceStatus: 'READY', + currentState: { + commercialRange: 'STANDARD', + description: + 'Pour vous proposer une description adaptée, pourriez-vous me donner plus de détails sur votre service ? Cela me permettra de créer une description précise et impactante qui tient dans la limite des 255 caractères.', + ipQuota: 10, + memoryQuota: 64, + name: 'vdc-eu-central-waw-adc311b5-0c0b-4071-b48f-b20813868bcf', + region: 'EU-CENTRAL-WAW', + storageQuota: 1, + vCPUCount: 16, + vCPUSpeed: 3, + }, + currentTasks: [], + targetSpec: { + description: + 'Pour vous proposer une description adaptée, pourriez-vous me donner plus de détails sur votre service ? Cela me permettra de créer une description précise et impactante qui tient dans la limite des 255 caractères.', + vCPUSpeed: 3, + }, + updatedAt: '2024-09-23T13:53:49Z', + iam: { + id: '33dda1c2-b24e-4db2-b7f3-4f3a8e08d68f', + urn: + 'urn:v1:eu:resource:vmwareCloudDirector:org-eu-central-waw-366861de-e0e4-4ad5-a4c5-e9f80d744142/virtualDataCenter/vdc-eu-central-waw-adc311b5-0c0b-4071-b48f-b20813868bcf', + }, + }, +]; diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-organization.handler.ts b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-organization.handler.ts index 53259f03e15a..f7946ad71e6a 100644 --- a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-organization.handler.ts +++ b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/vcd-organization/vcd-organization.handler.ts @@ -1,11 +1,15 @@ import { PathParams } from 'msw'; import { Handler } from '../../../../../../playwright-helpers'; import { organizationList } from './vcd-organization.mock'; +import { datacentreList } from './vcd-datacentre.mock'; export type GetOrganizationMocksParams = { isOrganizationKo?: boolean; + isOrganizationUpdateKo?: boolean; nbOrganization?: number; allOrgsBackedUp?: boolean; + isDatacentresKo?: boolean; + nbDatacentres?: number; }; const findOrganizationById = (params: PathParams) => @@ -13,16 +17,45 @@ const findOrganizationById = (params: PathParams) => export const getOrganizationMocks = ({ isOrganizationKo, + isOrganizationUpdateKo, nbOrganization = Number.POSITIVE_INFINITY, allOrgsBackedUp, + isDatacentresKo, + nbDatacentres = Number.POSITIVE_INFINITY, }: GetOrganizationMocksParams): Handler[] => { const nb = allOrgsBackedUp ? 1 : nbOrganization; return [ + { + url: '/vmwareCloudDirector/organization/:id/virtualDataCenter', + response: isDatacentresKo + ? { + message: 'Datacentres error', + } + : datacentreList.slice(0, nbDatacentres), + api: 'v2', + status: isDatacentresKo ? 500 : 200, + }, + { + url: '/vmwareCloudDirector/organization/:id', + response: isOrganizationUpdateKo + ? { + message: 'Organization update error', + } + : {}, + method: 'put', + api: 'v2', + status: isOrganizationUpdateKo ? 500 : 200, + }, { url: '/vmwareCloudDirector/organization/:id', response: (_: unknown, params: PathParams) => - findOrganizationById(params), + isOrganizationKo + ? { + message: 'Organization error', + } + : findOrganizationById(params), api: 'v2', + status: isOrganizationKo ? 500 : 200, }, { url: '/vmwareCloudDirector/organization', diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/veeam-backup/veeam-backup.handler.ts b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/veeam-backup/veeam-backup.handler.ts index a5ddcaf46743..f27b17cbeb17 100644 --- a/packages/manager/apps/hpc-vmware-managed-vcd/mocks/veeam-backup/veeam-backup.handler.ts +++ b/packages/manager/apps/hpc-vmware-managed-vcd/mocks/veeam-backup/veeam-backup.handler.ts @@ -16,7 +16,12 @@ export const getVeeamBackupMocks = ({ }: GetVeeamBackupMocksParams): Handler[] => [ { url: '/vmwareCloudDirector/backup/:id', - response: (_: unknown, params: PathParams) => findBackupById(params), + response: (_: unknown, params: PathParams) => + isBackupKo + ? { + message: 'Backup error', + } + : findBackupById(params), status: isBackupKo ? 500 : 200, api: 'v2', }, diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/package.json b/packages/manager/apps/hpc-vmware-managed-vcd/package.json index 6171a958e1c3..8ad5ce188c82 100644 --- a/packages/manager/apps/hpc-vmware-managed-vcd/package.json +++ b/packages/manager/apps/hpc-vmware-managed-vcd/package.json @@ -54,6 +54,7 @@ "@testing-library/dom": "^10.1.0", "@testing-library/jest-dom": "^6.4.6", "@testing-library/react": "^16.0.0", + "@testing-library/user-event": "^13.2.1", "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "@vitejs/plugin-react": "^4.2.1", diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/data/api/hpc-vmware-managed-vcd.ts b/packages/manager/apps/hpc-vmware-managed-vcd/src/data/api/hpc-vmware-managed-vcd.ts index dd9384ee8b89..113cee5b6970 100644 --- a/packages/manager/apps/hpc-vmware-managed-vcd/src/data/api/hpc-vmware-managed-vcd.ts +++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/data/api/hpc-vmware-managed-vcd.ts @@ -30,7 +30,7 @@ export const getVcdOrganizationBackup = async ( organizationId: string, ): Promise> => apiClient.v2.get( - `${VCD_ORGANIZATION_ROUTE}/backup/${organizationId}-veeam-backup`, + `/vmwareCloudDirector/backup/${organizationId}-veeam-backup`, ); /** diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/OrganizationDashboard.spec.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/OrganizationDashboard.spec.tsx new file mode 100644 index 000000000000..1b8937e08a26 --- /dev/null +++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/OrganizationDashboard.spec.tsx @@ -0,0 +1,37 @@ +import userEvents from '@testing-library/user-event'; +import { screen, waitFor } from '@testing-library/react'; +import { renderTest, labels } from '../../../test-utils'; +import { organizationList } from '../../../../mocks/vcd-organization/vcd-organization.mock'; + +describe('Organization Dashboard Page', () => { + it('display the dashboard page', async () => { + await renderTest(); + const link = screen.getByText(organizationList[0].currentState.fullName); + await waitFor(() => userEvents.click(link)); + + await waitFor( + () => + expect( + screen.getByText( + labels.dashboard.managed_vcd_dashboard_data_protection, + ), + ).toBeVisible(), + { timeout: 30000 }, + ); + + expect( + screen.getByText(organizationList[0].currentState.description), + ).toBeVisible(); + }); + + it('display an error', async () => { + await renderTest({ + initialRoute: `/${organizationList[0].id}`, + isOrganizationKo: true, + }); + await waitFor( + () => expect(screen.getByText('Organization error')).toBeVisible(), + { timeout: 30000 }, + ); + }); +}); diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/general-information/OrganizationGeneralInformation.spec.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/general-information/OrganizationGeneralInformation.spec.tsx new file mode 100644 index 000000000000..1f99d56cac88 --- /dev/null +++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/dashboard/organization/general-information/OrganizationGeneralInformation.spec.tsx @@ -0,0 +1,159 @@ +import userEvents from '@testing-library/user-event'; +import { screen, waitFor, fireEvent, within } from '@testing-library/react'; +import { renderTest, labels } from '../../../../test-utils'; +import { organizationList } from '../../../../../mocks/vcd-organization/vcd-organization.mock'; + +const changeInputAndSubmit = async () => { + const input = screen.getByLabelText('edit-input'); + const event = new CustomEvent('odsValueChange'); + Object.defineProperty(event, 'target', { value: { value: 'new name' } }); + await waitFor(() => fireEvent(input, event)); + + const modifyButton = screen.getByText( + labels.dashboard.managed_vcd_dashboard_edit_modal_cta_edit, + { exact: true }, + ); + + return waitFor(() => userEvents.click(modifyButton)); +}; + +const checkModal = async ({ + container, + isVisible, +}: { + container: HTMLElement; + isVisible: boolean; +}) => + waitFor( + () => { + const modal = container.querySelector('osds-modal'); + return isVisible + ? expect(modal).toBeInTheDocument() + : expect(modal).not.toBeInTheDocument(); + }, + { timeout: 30000 }, + ); + +describe('Organization General Information Page', () => { + it('modify the name of the company', async () => { + const { container } = await renderTest({ + initialRoute: `/${organizationList[1].id}`, + }); + + await waitFor( + () => + expect( + screen.getByText( + labels.dashboard.managed_vcd_dashboard_data_protection, + ), + ).toBeVisible(), + { timeout: 30000 }, + ); + + let editButton; + await waitFor( + () => { + editButton = screen.getAllByTestId('editIcon').at(0); + return expect(editButton).not.toHaveAttribute('disabled'); + }, + { timeout: 30000 }, + ); + await waitFor(() => userEvents.click(editButton)); + + await checkModal({ container, isVisible: true }); + + await changeInputAndSubmit(); + + await checkModal({ container, isVisible: false }); + + expect( + screen.queryByText( + labels.dashboard.managed_vcd_dashboard_edit_name_modal_success, + ), + ).toBeVisible(); + }); + + it('trying to update name displays an error if update organization service is KO', async () => { + const { container } = await renderTest({ + initialRoute: `/${organizationList[0].id}/edit-name`, + isOrganizationUpdateKo: true, + }); + + await checkModal({ container, isVisible: true }); + + await changeInputAndSubmit(); + + await checkModal({ container, isVisible: true }); + + await waitFor( + () => + expect( + within( + container.querySelector('osds-modal') as HTMLElement, + ).getByText('Organization update error', { exact: false }), + ).toBeVisible(), + { timeout: 30000 }, + ); + }); + + it('modify the description of the company', async () => { + const { container } = await renderTest({ + initialRoute: `/${organizationList[1].id}`, + }); + + await waitFor( + () => + expect( + screen.getByText( + labels.dashboard.managed_vcd_dashboard_data_protection, + ), + ).toBeVisible(), + { timeout: 30000 }, + ); + + let editButton; + await waitFor( + () => { + editButton = screen.getAllByTestId('editIcon').at(1); + return expect(editButton).not.toHaveAttribute('disabled'); + }, + { timeout: 30000 }, + ); + await waitFor(() => userEvents.click(editButton)); + + await checkModal({ container, isVisible: true }); + + await changeInputAndSubmit(); + + await checkModal({ container, isVisible: false }); + + expect( + screen.queryByText( + labels.dashboard.managed_vcd_dashboard_edit_description_modal_success, + ), + ).toBeVisible(); + }); + + it('trying to update description displays an error if update organization service is KO', async () => { + const { container } = await renderTest({ + initialRoute: `/${organizationList[0].id}/edit-description`, + isOrganizationUpdateKo: true, + }); + + await checkModal({ container, isVisible: true }); + + await changeInputAndSubmit(); + + await checkModal({ container, isVisible: true }); + + await waitFor( + () => + expect( + within( + container.querySelector('osds-modal') as HTMLElement, + ).getByText('Organization update error', { exact: false }), + ).toBeVisible(), + { timeout: 30000 }, + ); + }); +}); diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/listing/organizations/Organizations.page.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/listing/organizations/Organizations.page.tsx index 0bf4079e7909..b163ca53ff90 100644 --- a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/listing/organizations/Organizations.page.tsx +++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/listing/organizations/Organizations.page.tsx @@ -10,9 +10,7 @@ import { } from '@ovh-ux/manager-react-components'; import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; -import DatagridContainer, { - TDatagridContainerProps, -} from '@/components/datagrid/container/DatagridContainer.component'; +import DatagridContainer from '@/components/datagrid/container/DatagridContainer.component'; import { urls } from '@/routes/routes.constant'; import IVcdOrganization from '@/types/vcd-organization.interface'; import { VCD_ORGANIZATION_ROUTE } from '@/data/api/hpc-vmware-managed-vcd.constants'; diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/listing/organizations/Organizations.spec.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/listing/organizations/Organizations.spec.tsx index abedd114ab3c..1b9eabbdbb84 100644 --- a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/listing/organizations/Organizations.spec.tsx +++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/listing/organizations/Organizations.spec.tsx @@ -1,13 +1,21 @@ import { screen, waitFor } from '@testing-library/react'; import { renderTest, labels } from '../../../test-utils'; +import { organizationList } from '../../../../mocks/vcd-organization/vcd-organization.mock'; describe('Organizations Listing Page', () => { - it('display the listing page', async () => { - await renderTest(); + it('display the listing page if there is at least one organization', async () => { + await renderTest({ nbOrganization: 1 }); + await waitFor(() => expect( screen.getByText(labels.listing.managed_vcd_listing_description), ).toBeVisible(), ); + + await waitFor(() => + expect( + screen.getByText(organizationList[0].currentState.fullName), + ).toBeVisible(), + ); }); }); diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/onboarding/Onboarding.spec.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/onboarding/Onboarding.spec.tsx new file mode 100644 index 000000000000..74612cb296ea --- /dev/null +++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/pages/onboarding/Onboarding.spec.tsx @@ -0,0 +1,15 @@ +import { screen, waitFor } from '@testing-library/react'; +import { renderTest, labels } from '../../test-utils'; + +describe('Onboarding Page', () => { + it('display the onboarding page if there is no VCD Organization', async () => { + await renderTest({ nbOrganization: 0 }); + await waitFor(() => + expect( + screen.getByText( + labels.onboarding.managed_vcd_onboarding_description_part1, + ), + ).toBeVisible(), + ); + }); +}); diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/TestApp.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/TestApp.tsx index 9c9392e49627..f2fe8695cbc1 100644 --- a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/TestApp.tsx +++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/TestApp.tsx @@ -3,9 +3,9 @@ import { QueryClientProvider, QueryClient } from '@tanstack/react-query'; import { createMemoryRouter, RouterProvider } from 'react-router-dom'; import { Routes } from '../routes/routes'; -export function TestApp() { +export function TestApp({ initialRoute = '/' }) { const router = createMemoryRouter(Routes, { - initialEntries: ['/'], + initialEntries: [initialRoute], initialIndex: 0, }); diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/render-test.tsx b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/render-test.tsx index f89875fac0e5..1d58a246af9f 100644 --- a/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/render-test.tsx +++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/test-utils/render-test.tsx @@ -29,11 +29,14 @@ import { APP_NAME } from '@/tracking.constant'; let context: ShellContextType; let i18nState: i18n; -export const renderTest = async ( - mockParams: GetOrganizationMocksParams & - GetVeeamBackupMocksParams & - GetServicesMocksParams = {}, -) => { +export const renderTest = async ({ + initialRoute, + ...mockParams +}: { + initialRoute?: string; +} & GetOrganizationMocksParams & + GetVeeamBackupMocksParams & + GetServicesMocksParams = {}) => { ((global as unknown) as { server: SetupServer }).server?.resetHandlers( ...toMswHandlers([ ...getAuthenticationMocks({ isAuthMocked: true }), @@ -55,20 +58,22 @@ export const renderTest = async ( const result = render( - + , ); - await waitFor( - () => - expect( - screen.getAllByText(labels.listing.managed_vcd_listing_title, { - exact: false, - }).length, - ).toBeGreaterThan(0), - { timeout: 30000 }, - ); + if (!initialRoute || initialRoute === '/') { + await waitFor( + () => + expect( + screen.getAllByText(labels.listing.managed_vcd_listing_title, { + exact: false, + }).length, + ).toBeGreaterThan(0), + { timeout: 30000 }, + ); + } return result; }; diff --git a/packages/manager/apps/hpc-vmware-managed-vcd/src/types/vcd-datacenter.interface.ts b/packages/manager/apps/hpc-vmware-managed-vcd/src/types/vcd-datacenter.interface.ts index d8e2cf8ea54f..f08cd1fdc29c 100644 --- a/packages/manager/apps/hpc-vmware-managed-vcd/src/types/vcd-datacenter.interface.ts +++ b/packages/manager/apps/hpc-vmware-managed-vcd/src/types/vcd-datacenter.interface.ts @@ -22,4 +22,5 @@ export default interface IVcdDatacentre { targetSpec: IVcdDatacentreState; currentTasks?: any[]; iam: IamObject; + updatedAt: string; }