Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge f/ds-projects to main #2118

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion backend/src/routes/api/namespaces/namespaceUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ export const applyNamespaceChange = async (
case NamespaceApplicationCase.DSG_CREATION:
labels = {
'opendatahub.io/dashboard': 'true',
'modelmesh-enabled': 'true',
};
break;
case NamespaceApplicationCase.MODEL_SERVING_PROMOTION:
Expand Down
42 changes: 41 additions & 1 deletion frontend/src/__mocks__/mockProjectK8sResource.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { K8sResourceListResult } from '@openshift/dynamic-plugin-sdk-utils';
import { KnownLabels, ProjectKind } from '~/k8sTypes';

type MockResourceConfigType = {
Expand All @@ -6,6 +7,7 @@ type MockResourceConfigType = {
description?: string;
k8sName?: string;
enableModelMesh?: boolean;
isDSProject?: boolean;
};

export const mockProjectK8sResource = ({
Expand All @@ -14,6 +16,7 @@ export const mockProjectK8sResource = ({
k8sName = 'test-project',
enableModelMesh = true,
description = '',
isDSProject = true,
}: MockResourceConfigType): ProjectKind => ({
kind: 'Project',
apiVersion: 'project.openshift.io/v1',
Expand All @@ -23,7 +26,7 @@ export const mockProjectK8sResource = ({
labels: {
'kubernetes.io/metadata.name': k8sName,
[KnownLabels.MODEL_SERVING_PROJECT]: enableModelMesh ? 'true' : 'false',
[KnownLabels.DASHBOARD_RESOURCE]: 'true',
...(isDSProject && { [KnownLabels.DASHBOARD_RESOURCE]: 'true' }),
},
annotations: {
'openshift.io/description': description,
Expand All @@ -35,3 +38,40 @@ export const mockProjectK8sResource = ({
phase: 'Active',
},
});

export const mockProjectsK8sList = (): K8sResourceListResult<ProjectKind> => ({
apiVersion: 'project.openshift.io/v1',
metadata: { continue: '', resourceVersion: '1462210' },
items: [
mockProjectK8sResource({
k8sName: 'ds-project-1',
displayName: 'DS Project 1',
isDSProject: true,
}),
mockProjectK8sResource({
k8sName: 'ds-project-2',
displayName: 'DS Project 2',
isDSProject: true,
}),
mockProjectK8sResource({
k8sName: 'ds-project-3',
displayName: 'DS Project 3',
isDSProject: true,
}),
mockProjectK8sResource({
k8sName: 'non-ds-project-1',
displayName: 'Non-DS Project 1',
isDSProject: false,
}),
mockProjectK8sResource({
k8sName: 'non-ds-project-2',
displayName: 'Non-DS Project 2',
isDSProject: false,
}),
mockProjectK8sResource({
k8sName: 'non-ds-project-3',
displayName: 'Non-DS Project 3',
isDSProject: false,
}),
],
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
import { test, expect } from '@playwright/test';
import { navigateToStory } from '~/__tests__/integration/utils';

test('Project view page', async ({ page }) => {
await page.goto(
'./iframe.html?id=tests-integration-pages-projects-projectview--default&viewMode=story',
);

// wait for page to load
await page.waitForSelector('text=Data science projects');

// Test that it only shows DS Projects at first
await expect(page.getByText('DS Project 1', { exact: true })).toBeVisible();
await expect(page.getByText('DS Project 2', { exact: true })).toBeVisible();
await expect(page.getByText('DS Project 3', { exact: true })).toBeVisible();
await expect(page.getByText('Non-DS Project 1', { exact: true })).toBeHidden();
await expect(page.getByText('Non-DS Project 2', { exact: true })).toBeHidden();
await expect(page.getByText('Non-DS Project 3', { exact: true })).toBeHidden();

// Change the selection and make sure it shows all projects
await page.locator('#project-scope-selection').click();
await page.getByText('All available projects', { exact: true }).click();
await expect(page.getByText('DS Project 1', { exact: true })).toBeVisible();
await expect(page.getByText('DS Project 2', { exact: true })).toBeVisible();
await expect(page.getByText('DS Project 3', { exact: true })).toBeVisible();
await expect(page.getByText('Non-DS Project 1', { exact: true })).toBeVisible();
await expect(page.getByText('Non-DS Project 2', { exact: true })).toBeVisible();
await expect(page.getByText('Non-DS Project 3', { exact: true })).toBeVisible();
});

test('Create project', async ({ page }) => {
await page.goto(navigateToStory('pages-projects-projectview', 'create-project'));

Expand Down Expand Up @@ -76,7 +103,7 @@ test('Delete project', async ({ page }) => {
// Test that can submit on valid form
await expect(page.getByRole('button', { name: 'Delete project' })).toBeDisabled();

await page.getByRole('textbox', { name: 'Delete modal input' }).fill('Test Project');
await page.getByRole('textbox', { name: 'Delete modal input' }).fill('DS Project 1');
await expect(page.getByRole('button', { name: 'Delete project' })).toBeEnabled();

// Test if error alert will pop up
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Meta, StoryObj } from '@storybook/react';
import { rest } from 'msw';
import { within, userEvent } from '@storybook/testing-library';
import { mockProjectK8sResource } from '~/__mocks__/mockProjectK8sResource';
import { mockProjectsK8sList } from '~/__mocks__/mockProjectK8sResource';
import { mockNotebookK8sResource } from '~/__mocks__/mockNotebookK8sResource';
import { mockK8sResourceList } from '~/__mocks__/mockK8sResourceList';
import { mockPodK8sResource } from '~/__mocks__/mockPodK8sResource';
Expand All @@ -26,7 +26,7 @@ export default {
(req, res, ctx) => res(ctx.json(mockK8sResourceList([mockNotebookK8sResource({})]))),
),
rest.get('/api/k8s/apis/project.openshift.io/v1/projects', (req, res, ctx) =>
res(ctx.json(mockK8sResourceList([mockProjectK8sResource({})]))),
res(ctx.json(mockProjectsK8sList())),
),
rest.delete(
'/api/k8s/apis/project.openshift.io/v1/projects/test-project',
Expand All @@ -45,6 +45,14 @@ export default {
},
} as Meta<typeof ProjectView>;

export const Default: StoryObj = {
play: async ({ canvasElement }) => {
// load page and wait until settled
const canvas = within(canvasElement);
await canvas.findByText('DS Project 1', undefined, { timeout: 5000 });
},
};

export const EditProject: StoryObj = {
parameters: {
a11y: {
Expand All @@ -56,10 +64,10 @@ export const EditProject: StoryObj = {
play: async ({ canvasElement }) => {
// load page and wait until settled
const canvas = within(canvasElement);
await canvas.findByText('Test Project', undefined, { timeout: 5000 });
await canvas.findByText('DS Project 1', undefined, { timeout: 5000 });

// user flow for editing a project
await userEvent.click(canvas.getByLabelText('Actions', { selector: 'button' }));
await userEvent.click(canvas.getAllByLabelText('Actions', { selector: 'button' })[0]);
await userEvent.click(canvas.getByText('Edit project', { selector: 'button' }));
},
};
Expand All @@ -74,10 +82,10 @@ export const DeleteProject: StoryObj = {
play: async ({ canvasElement }) => {
// load page and wait until settled
const canvas = within(canvasElement);
await canvas.findByText('Test Project', undefined, { timeout: 5000 });
await canvas.findByText('DS Project 1', undefined, { timeout: 5000 });

// user flow for deleting a project
await userEvent.click(canvas.getByLabelText('Actions', { selector: 'button' }));
await userEvent.click(canvas.getAllByLabelText('Actions', { selector: 'button' })[0]);
await userEvent.click(canvas.getByText('Delete project', { selector: 'button' }));
},
};
Expand All @@ -92,7 +100,7 @@ export const CreateProject: StoryObj = {
play: async ({ canvasElement }) => {
// load page and wait until settled
const canvas = within(canvasElement);
await canvas.findByText('Test Project', undefined, { timeout: 5000 });
await canvas.findByText('DS Project 1', undefined, { timeout: 5000 });

// user flow for deleting a project
await userEvent.click(canvas.getByText('Create data science project', { selector: 'button' }));
Expand Down
26 changes: 16 additions & 10 deletions frontend/src/api/k8s/notebooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ export const attachNotebookPVC = (
namespace: string,
pvcName: string,
mountSuffix: string,
opts?: K8sAPIOptions,
): Promise<NotebookKind> => {
const patches: Patch[] = [
{
Expand All @@ -397,17 +398,20 @@ export const attachNotebookPVC = (
},
];

return k8sPatchResource<NotebookKind>({
model: NotebookModel,
queryOptions: { name: notebookName, ns: namespace },
patches,
});
return k8sPatchResource<NotebookKind>(
applyK8sAPIOptions(opts, {
model: NotebookModel,
queryOptions: { name: notebookName, ns: namespace },
patches,
}),
);
};

export const removeNotebookPVC = (
notebookName: string,
namespace: string,
pvcName: string,
opts?: K8sAPIOptions,
): Promise<NotebookKind> =>
new Promise((resolve, reject) => {
getNotebook(notebookName, namespace)
Expand Down Expand Up @@ -436,11 +440,13 @@ export const removeNotebookPVC = (
},
];

k8sPatchResource<NotebookKind>({
model: NotebookModel,
queryOptions: { name: notebookName, ns: namespace },
patches,
})
k8sPatchResource<NotebookKind>(
applyK8sAPIOptions(opts, {
model: NotebookModel,
queryOptions: { name: notebookName, ns: namespace },
patches,
}),
)
.then(resolve)
.catch(reject);
})
Expand Down
3 changes: 0 additions & 3 deletions frontend/src/api/k8s/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ export const getProjects = (withLabel?: string): Promise<ProjectKind[]> =>
queryOptions: withLabel ? { queryParams: { labelSelector: withLabel } } : undefined,
}).then((listResource) => listResource.items);

export const getDSGProjects = (): Promise<ProjectKind[]> =>
getProjects(LABEL_SELECTOR_DASHBOARD_RESOURCE);

export const createProject = (
username: string,
displayName: string,
Expand Down
Loading
Loading