Skip to content

Commit

Permalink
feat(efs): vrack services
Browse files Browse the repository at this point in the history
ref: MANAGER-12421

Signed-off-by: Quentin Pavy <contact@quentinpavy.com>
Co-authored-by: Nicolas Pierre-charles <nicolas.pierre-charles.ext@corp.ovh.com>
  • Loading branch information
2 people authored and aboungnaseng-ovhcloud committed Apr 16, 2024
1 parent 50d49bb commit b512795
Show file tree
Hide file tree
Showing 209 changed files with 4,460 additions and 1,321 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ export async function selectActiveItem(
item.href?.endsWith(route)
) {
if (
(item.routeMatcher && !item.routeMatcher.test(route)) ||
(item.routeMatcher && !item.routeMatcher.test(route)) &&
(item.pathMatcher && !item.pathMatcher.test(path))
) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ export default function DedicatedSidebar() {
icon: getIcon('oui-icon oui-icon-bandwidth_concept'),
minSearchItems: 0,
routeMatcher: new RegExp('^(/ip(/|$)|/network-security|/vrack|/cloud-connect|/vrack-services|(/network)?/iplb)'),
pathMatcher: new RegExp('^(/vrack-services/)'),
subItems: [
feature.ip && {
id: 'dedicated-ip',
Expand Down Expand Up @@ -304,7 +305,7 @@ export default function DedicatedSidebar() {
badge: 'beta',
label: t('sidebar_vrack_services'),
icon: getIcon('oui-icon oui-icon-vRack-services_concept'),
routeMatcher: new RegExp('^/vrack-services'),
pathMatcher: new RegExp('^/vrack-services'),
async loader() {
const appId = 'vrack-services';
const items = await loadServices('/vrackServices/resource', undefined, appId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export default function HostedPrivateCloudSidebar() {
icon: getIcon('oui-icon oui-icon-bandwidth_concept'),
minSearchItems: 0,
routeMatcher: new RegExp('^(/ip(/|$)|/network-security|(/network)?/iplb|/vrack|/cloud-connect|/vrack-services)'),
pathMatcher: new RegExp('^(/vrack-services/)'),
subItems: [
feature.ip && {
id: 'hpc-ip',
Expand Down Expand Up @@ -190,7 +191,7 @@ export default function HostedPrivateCloudSidebar() {
badge: 'beta',
label: t('sidebar_vrack_services'),
icon: getIcon('oui-icon oui-icon-vRack-services_concept'),
routeMatcher: new RegExp('^/vrack-services'),
pathMatcher: new RegExp('^/vrack-services'),
async loader() {
const appId = 'vrack-services';
const items = await loadServices('/vrackServices/resource', undefined, appId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,6 @@
"sidebar_pci_analytics_data_analysis": "Datenanalysen",
"sidebar_network_security": "Network Security Dashboard",
"sidebar_nasha_cdn": "HA-NAS und CDN",
"sidebar_vrack_services": "vRack Dienste",
"sidebar_vrack_services": "vRack Services",
"sidebar_all_vrack_services": "Alle Dienste"
}
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,4 @@
"sidebar_vrack_services": "Serviços vRack",
"sidebar_all_vrack_services": "Todos os serviços",
"sidebar_pci_analytics_data_platform": "Data Platform"
}
}
33 changes: 33 additions & 0 deletions packages/manager/apps/vrack-services/e2e/done/dissociate.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Feature: Dissociate from overview page

Scenario Outline: User click on action menu of private network
Given User "<hasVrack>" a vRack associated to a vRack Services
When User navigates to the vRack Services Overview page
Then User "<seeActionMenu>" the action menu with button dissociate
When User click on the private network action menu button
Then User sees button dissociate

Examples:
| hasVrack | seeActionMenu |
| has | see |
| doesn't have | doesn't see |

Scenario Outline: User dissociate a vRack Services from a vRack
Given User "has" a vRack associated to a vRack Services
Given the webservice to dissociate a vRack is <okOrKo>
When User navigates to the vRack Services Overview page
Then User "see" the action menu with button dissociate
When User click on the private network action menu button
Then User sees button dissociate
When User click on dissociate in action menu of private network
Then a modal appear to ask if the user wants to dissociate the vRack
When User <acceptOrCancel> modal
Then User "<returnOverview>" on the Overview page from dissociation modal
Then User sees <anyErrorMessage> error message

Examples:
| okOrKo | acceptOrCancel | returnOverview | anyErrorMessage |
| ok | accept | returns | no |
| ko | accept | doesn't returns | an |
| ok | cancel | returns | no |
| ko | cancel | returns | no |
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,40 @@ Given('User has a vRack Services that {string} a subnet', function(
this.testContext.data.selectedVrackServices = vrackServicesList[index];
this.testContext.data.vsIndex = index;
});

Given('User {string} a vRack associated to a vRack Services', function(
this: ICustomWorld<ConfigParams>,
hasVrack: 'has' | "doesn't have",
) {
this.testContext.initialUrl = getUrl('listing');
this.handlersConfig.nbVs = 20;

const vsIndex = vrackServicesList.findIndex(
(v) =>
(hasVrack === 'has' && v.currentState.vrackId) ||
(hasVrack === "doesn't have" && !v.currentState.vrackId),
);
this.testContext.data.vsIndex = vsIndex;
this.testContext.data.selectedVrackServices = vrackServicesList[vsIndex];
});

Given('User is on Overview page', function(this: ICustomWorld<ConfigParams>) {
this.testContext.initialUrl = getUrl(
'overview',
this.testContext.data.selectedVrackServices.id,
);
});

Given('the webservice to dissociate a vRack is {word}', function(
this: ICustomWorld<ConfigParams>,
okOrKo: 'ok' | 'ko',
) {
this.testContext.initialUrl = getUrl('listing');
this.handlersConfig.nbVs = 20;
this.handlersConfig.dissociateKo = okOrKo === 'ko';

const vsIndex = vrackServicesList.findIndex((v) => v.currentState.vrackId);

this.testContext.data.vsIndex = vsIndex;
this.testContext.data.selectedVrackServices = vrackServicesList[vsIndex];
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import {
deliveringVrackMessage,
deliveringVrackServicesMessage,
modalDissociateDescription,
} from '../../src/public/translations/vrack-services/Messages_fr_FR.json';
import { getUrl } from '../utils';
import { ConfigParams } from '../../mock/handlers';
Expand All @@ -22,7 +23,11 @@ import {
guide1Title,
guide2Title,
} from '../../src/public/translations/vrack-services/onboarding/Messages_fr_FR.json';
import { onboardingDescription } from '../../src/public/translations/vrack-services/subnets/Messages_fr_FR.json';
import {
onboardingDescription,
betaSubnetLimitMessage,
} from '../../src/public/translations/vrack-services/subnets/Messages_fr_FR.json';
import { vrackActionDissociate } from '../../src/public/translations/vrack-services/dashboard/Messages_fr_FR.json';

Then('User sees the create a vRack Services button {word}', async function(
this: ICustomWorld<ConfigParams>,
Expand Down Expand Up @@ -240,3 +245,61 @@ Then('User sees the subnet {word} page', async function(
expect(listing).toBeVisible();
}
});

Then('User {string} the action menu with button dissociate', async function(
this: ICustomWorld<ConfigParams>,
seeActionMenu: 'see' | "doesn't see",
) {
await sleep(1000);
const actionMenu = this.page.getByTestId('action-menu-icon');
if (seeActionMenu === 'see') {
expect(actionMenu).toBeInViewport();
} else {
expect(actionMenu).not.toBeInViewport();
}
});

Then('User sees button dissociate', async function(
this: ICustomWorld<ConfigParams>,
) {
await sleep(1000);
const dissociateButton = this.page.getByText(vrackActionDissociate, {
exact: true,
});
if (await this.page.getByTestId('action-menu-icon').count()) {
expect(dissociateButton).toBeVisible();
} else {
expect(dissociateButton).not.toBeVisible();
}
});

Then(
'a modal appear to ask if the user wants to dissociate the vRack',
async function(this: ICustomWorld<ConfigParams>) {
await sleep(1000);

const modalDescription = await this.page.locator('osds-modal', {
hasText: modalDissociateDescription,
});
await expect(modalDescription).toBeVisible();
},
);

Then(
'User {string} on the Overview page from dissociation modal',
async function(
this: ICustomWorld<ConfigParams>,
returnOverview: 'returns' | "doesn't returns",
) {
await sleep(1000);

const modalDescription = await this.page.locator('osds-modal', {
hasText: modalDissociateDescription,
});
if (returnOverview === 'returns') {
expect(modalDescription).not.toBeVisible();
} else {
expect(modalDescription).toBeVisible();
}
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ import {
modalNoVrackButtonLabel,
} from '../../src/public/translations/vrack-services/create/Messages_fr_FR.json';
import { displayNameInputName } from '../../src/pages/create/constants';
import { subnetsTabLabel } from '../../src/public/translations/vrack-services/dashboard/Messages_fr_FR.json';
import {
subnetsTabLabel,
vrackActionDissociate,
} from '../../src/public/translations/vrack-services/dashboard/Messages_fr_FR.json';
import {
modalConfirmButton,
modalCancelButton,
} from '../../src/public/translations/vrack-services/Messages_fr_FR.json';

When('User navigates to vRack Services Listing page', async function(
this: ICustomWorld<ConfigParams>,
Expand Down Expand Up @@ -186,3 +193,45 @@ When('User navigates to the vRack Services Subnet page', async function(
waitUntil: 'load',
});
});

When('User click on the private network action menu button', async function(
this: ICustomWorld<ConfigParams>,
) {
await setupNetwork(this);

const { selectedVrackServices } = this.testContext.data;

await this.page.waitForURL(getUrl('overview', selectedVrackServices.id), {
waitUntil: 'load',
});

if (await this.page.getByTestId('action-menu-icon').count()) {
await this.page.getByTestId('action-menu-icon').click();
}
});

When(
'User click on dissociate in action menu of private network',
async function(this: ICustomWorld<ConfigParams>) {
await setupNetwork(this);
await sleep(1000);

await this.page.getByText(vrackActionDissociate, { exact: true }).click();
},
);

When('User {word} modal', async function(
this: ICustomWorld<ConfigParams>,
acceptOrCancel: 'accept' | 'cancel',
) {
await setupNetwork(this);

await sleep(1000);
const labelToButton = {
accept: modalConfirmButton,
cancel: modalCancelButton,
};
const buttonLabel = labelToButton[acceptOrCancel];
const button = await this.page.getByText(buttonLabel, { exact: true });
await button.click();
});
2 changes: 1 addition & 1 deletion packages/manager/apps/vrack-services/mock/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export const getConfig = (params: ConfigParams): Handler[] =>
getAuthenticationMocks,
getVrackServicesMocks,
getRegionMocks,
getAssociationMocks,
getVracMocks,
getAssociationMocks,
getOrderDetailsMocks,
getIamMocks,
].flatMap((getMocks) => getMocks(params));
Original file line number Diff line number Diff line change
Expand Up @@ -429,5 +429,51 @@
"subnets": []
},
"updatedAt": "2023-03-10T09:10:00Z"
},
{
"checksum": "e65fa90ceffa95201a49c29b3c031e11",
"createdAt": "2024-02-27T17:43:15.225504Z",
"currentState": {
"displayName": "SUB-test",
"productStatus": "DRAFT",
"region": "LABEUPRE",
"subnets": [
{
"cidr": "10.0.0.0/24",
"displayName": null,
"serviceEndpoints": [],
"serviceRange": {
"cidr": "10.0.0.0/29",
"remainingIps": 3,
"reservedIps": 5,
"usedIps": 0
},
"vlan": null
}
],
"vrackId": "pn-9000030"
},
"currentTasks": [],
"id": "vrs-d18-qi7-5lk-is2",
"resourceStatus": "READY",
"targetSpec": {
"displayName": "SUB-test",
"subnets": [
{
"cidr": "10.0.0.0/24",
"displayName": null,
"serviceEndpoints": [],
"serviceRange": {
"cidr": "10.0.0.0/29"
},
"vlan": null
}
]
},
"updatedAt": "2024-03-26T11:37:49.16237Z",
"iam": {
"id": "685fd9e5-7634-450f-b085-81f23a6ee8e2",
"urn": "urn:v1:labeu:resource:vrackServices:vrs-d18-qi7-5lk-is2"
}
}
]
13 changes: 11 additions & 2 deletions packages/manager/apps/vrack-services/mock/vrack/vrack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,28 @@ const vrackDetails = {

export type GetVrackMocksParams = {
nbVrack?: number;
dissociateKo?: boolean;
};

export const getVracMocks = ({
nbVrack = 5,
dissociateKo = false,
}: GetVrackMocksParams): Handler[] => [
{
url: '/vrack',
response: vrackList.slice(0, nbVrack),
url: '/vrack/:id/vrackServices/:vsId',
response: dissociateKo ? { message: 'Update error' } : {},
status: dissociateKo ? 500 : 200,
api: 'v6',
method: 'delete',
},
{
url: '/vrack/:id',
response: vrackDetails,
api: 'v6',
},
{
url: '/vrack',
response: vrackList.slice(0, nbVrack),
api: 'v6',
},
];
18 changes: 9 additions & 9 deletions packages/manager/apps/vrack-services/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@
"test:e2e:ci": "tsc && node ../../../../scripts/run-playwright-bdd.js --ci"
},
"dependencies": {
"@ovh-ux/manager-config": "^7.3.0",
"@ovh-ux/manager-core-api": "^0.7.1",
"@ovh-ux/manager-module-order": "^0.2.1",
"@ovh-ux/manager-react-shell-client": "^0.4.1",
"@ovh-ux/manager-tailwind-config": "^0.2.0",
"@ovh-ux/shell": "^3.5.1",
"@ovhcloud/manager-components": "^1.10.0",
"@ovh-ux/manager-config": "*",
"@ovh-ux/manager-core-api": "*",
"@ovh-ux/manager-module-order": "*",
"@ovh-ux/manager-react-shell-client": "*",
"@ovh-ux/manager-tailwind-config": "*",
"@ovh-ux/request-tagger": "*",
"@ovhcloud/manager-components": "*",
"@ovhcloud/ods-common-core": "17.2.1",
"@ovhcloud/ods-common-theming": "17.2.1",
"@ovhcloud/ods-components": "17.2.1",
"@ovhcloud/ods-theme-blue-jeans": "17.2.1",
"@tanstack/react-query": "^5.12.2",
"@tanstack/react-query-devtools": "^5.13.3",
"@tanstack/react-query": "5.29.2",
"@tanstack/react-query-devtools": "5.29.2",
"i18next": "^20.4.0",
"i18next-http-backend": "^2.4.2",
"react": "^18.2.0",
Expand Down
Loading

0 comments on commit b512795

Please sign in to comment.