Skip to content

Commit

Permalink
[RHOAIENG-10312] Connection type table view
Browse files Browse the repository at this point in the history
  • Loading branch information
jeff-phillips-18 committed Aug 14, 2024
1 parent da75c87 commit f29765b
Show file tree
Hide file tree
Showing 33 changed files with 864 additions and 189 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ export const patchConnectionType = async (
const { dashboardNamespace } = getNamespaces(fastify);

if (
(partialConfigMap.metadata.labels?.[KnownLabels.DASHBOARD_RESOURCE] &&
(partialConfigMap.metadata?.labels?.[KnownLabels.DASHBOARD_RESOURCE] &&
partialConfigMap.metadata.labels[KnownLabels.DASHBOARD_RESOURCE] !== 'true') ||
(partialConfigMap.metadata.labels?.[KnownLabels.CONNECTION_TYPE] &&
(partialConfigMap.metadata?.labels?.[KnownLabels.CONNECTION_TYPE] &&
partialConfigMap.metadata.labels[KnownLabels.CONNECTION_TYPE] !== 'true')
) {
const error = 'Unable to update connection type, incorrect labels.';
Expand Down
116 changes: 116 additions & 0 deletions frontend/src/__tests__/cypress/cypress/pages/connectionTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { appChrome } from '~/__tests__/cypress/cypress/pages/appChrome';
import { TableRow } from './components/table';
import { TableToolbar } from './components/TableToolbar';

class CreateConnectionTypeTableRow extends TableRow {
findSectionHeading() {
Expand Down Expand Up @@ -70,4 +72,118 @@ class CreateConnectionTypePage {
}
}

class ConnectionTypesTableToolbar extends TableToolbar {}
class ConnectionTypeRow extends TableRow {
findConnectionTypeName() {
return this.find().findByTestId('connection-type-name');
}

shouldHaveName(name: string) {
return this.findConnectionTypeName().should('have.text', name);
}

findConnectionTypeDescription() {
return this.find().findByTestId('table-row-title-description');
}

findConnectionTypeCreator() {
return this.find().findByTestId('connection-type-creator');
}

shouldHaveDescription(description: string) {
return this.findConnectionTypeDescription().should('have.text', description);
}

shouldHaveCreator(creator: string) {
return this.findConnectionTypeCreator().should('have.text', creator);
}

shouldShowPreInstalledLabel() {
return this.find().findByTestId('connection-type-user-label').should('exist');
}

findEnabled() {
return this.find().pfSwitchValue('connection-type-enable-switch');
}

findEnableSwitch() {
return this.find().pfSwitch('connection-type-enable-switch');
}

findEnableSwitchInput() {
return this.find().findByTestId('connection-type-enable-switch');
}

shouldBeEnabled() {
this.findEnabled().should('be.checked');
}

shouldBeDisabled() {
this.findEnabled().should('not.be.checked');
}

findEnableStatus() {
return this.find().findByTestId('connection-type-enable-status');
}
}

class ConnectionTypesPage {
visit() {
cy.visitWithLogin('/connectionTypes');
this.wait();
}

private wait() {
cy.findByTestId('app-page-title');
cy.testA11y();
}

findNavItem() {
return appChrome.findNavItem('Connection types');
}

navigate() {
this.findNavItem().click();
this.wait();
}

shouldHaveConnectionTypes() {
this.findTable().should('exist');
return this;
}

shouldReturnNotFound() {
cy.findByTestId('not-found-page').should('exist');
return this;
}

shouldBeEmpty() {
cy.findByTestId('connection-types-empty-state').should('exist');
return this;
}

findTable() {
return cy.findByTestId('connection-types-table');
}

getConnectionTypeRow(name: string) {
return new ConnectionTypeRow(() =>
this.findTable().findAllByTestId(`table-row-title`).contains(name).parents('tr'),
);
}

findEmptyFilterResults() {
return cy.findByTestId('no-result-found-title');
}

findSortButton(name: string) {
return this.findTable().find('thead').findByRole('button', { name });
}

getTableToolbar() {
return new ConnectionTypesTableToolbar(() => cy.findByTestId('connection-types-table-toolbar'));
}
}

export const connectionTypesPage = new ConnectionTypesPage();
export const createConnectionTypePage = new CreateConnectionTypePage();
Original file line number Diff line number Diff line change
Expand Up @@ -594,14 +594,14 @@ declare global {
) => Cypress.Chainable<null>) &
((
type: 'GET /api/connection-types',
response: ConnectionTypeConfigMap[],
response: OdhResponse<ConnectionTypeConfigMap[]>,
) => Cypress.Chainable<null>) &
((
type: 'PATCH /api/connection-types/:name',
options: {
path: { name: string };
},
response: { success: boolean; error: string },
response: OdhResponse<SuccessErrorResponse>,
) => Cypress.Chainable<null>) &
((
type: 'GET /api/connection-types/:name',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { pageNotfound } from '~/__tests__/cypress/cypress/pages/pageNotFound';
import {
asProductAdminUser,
asProjectAdminUser,
} from '~/__tests__/cypress/cypress/utils/mockUsers';
import { connectionTypesPage } from '~/__tests__/cypress/cypress/pages/connectionTypes';
import { mockDashboardConfig } from '~/__mocks__';
import { mockConnectionTypeConfigMap } from '~/__mocks__/mockConnectionType';

it('Connection types should not be available for non product admins', () => {
asProjectAdminUser();
cy.visitWithLogin('/connectionTypes');
pageNotfound.findPage().should('exist');
connectionTypesPage.findNavItem().should('not.exist');
});

it('Connection types should be hidden by feature flag', () => {
asProductAdminUser();

cy.visitWithLogin('/connectionTypes');
connectionTypesPage.shouldReturnNotFound();

cy.interceptOdh(
'GET /api/config',
mockDashboardConfig({
disableConnectionTypes: false,
}),
);

connectionTypesPage.visit();
});

describe('Connection types', () => {
beforeEach(() => {
asProductAdminUser();

cy.interceptOdh(
'GET /api/config',
mockDashboardConfig({
disableConnectionTypes: false,
}),
);
cy.interceptOdh('GET /api/connection-types', [
mockConnectionTypeConfigMap({}),
mockConnectionTypeConfigMap({
name: 'no-display-name',
displayName: '',
description: 'description 2',
enabled: false,
preInstalled: true,
}),
mockConnectionTypeConfigMap({
name: 'test-2',
displayName: 'Test display name',
description: 'Test description',
}),
]);
});

it('should show the empty state when there are no results', () => {
cy.interceptOdh('GET /api/connection-types', []);
connectionTypesPage.visit();
connectionTypesPage.shouldBeEmpty();
});

it('should show the correct column values', () => {
connectionTypesPage.visit();

const row = connectionTypesPage.getConnectionTypeRow('Test display name');
row.shouldHaveDescription('Test description');
row.shouldHaveCreator('dashboard-admin');
row.shouldBeEnabled();

const row2 = connectionTypesPage.getConnectionTypeRow('no-display-name');
row2.shouldHaveDescription('description 2');
row2.shouldShowPreInstalledLabel();
row2.shouldBeDisabled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,22 @@ import {
mockConnectionTypeConfigMapObj,
} from '~/__mocks__/mockConnectionType';
import { createConnectionTypePage } from '~/__tests__/cypress/cypress/pages/connectionTypes';
import { asClusterAdminUser } from '~/__tests__/cypress/cypress/utils/mockUsers';
import { asProductAdminUser } from '~/__tests__/cypress/cypress/utils/mockUsers';
import { mockDashboardConfig } from '~/__mocks__';

describe('create', () => {
beforeEach(() => {
asProductAdminUser();

cy.interceptOdh(
'GET /api/config',
mockDashboardConfig({
disableConnectionTypes: false,
}),
);
});

it('Display base page', () => {
asClusterAdminUser();
createConnectionTypePage.visitCreatePage();

createConnectionTypePage.findConnectionTypeName().should('exist');
Expand All @@ -17,7 +28,6 @@ describe('create', () => {
});

it('Allows create button with valid name', () => {
asClusterAdminUser();
createConnectionTypePage.visitCreatePage();

createConnectionTypePage.findConnectionTypeName().should('have.value', '');
Expand All @@ -32,7 +42,14 @@ describe('duplicate', () => {
const existing = mockConnectionTypeConfigMapObj({ name: 'existing' });

beforeEach(() => {
asClusterAdminUser();
asProductAdminUser();

cy.interceptOdh(
'GET /api/config',
mockDashboardConfig({
disableConnectionTypes: false,
}),
);
cy.interceptOdh(
'GET /api/connection-types/:name',
{ path: { name: 'existing' } },
Expand All @@ -47,11 +64,11 @@ describe('duplicate', () => {
.findConnectionTypeName()
.should(
'have.value',
`Duplicate of ${existing.metadata.annotations['openshift.io/display-name']}`,
`Duplicate of ${existing.metadata.annotations?.['openshift.io/display-name']}`,
);
createConnectionTypePage
.findConnectionTypeDesc()
.should('have.value', existing.metadata.annotations['openshift.io/description']);
.should('have.value', existing.metadata.annotations?.['openshift.io/description']);
createConnectionTypePage.findConnectionTypeEnableCheckbox().should('be.checked');
});

Expand Down
6 changes: 5 additions & 1 deletion frontend/src/app/AppRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const AppRoutes: React.FC = () => {
const { isAdmin, isAllowed } = useUser();
const isJupyterEnabled = useCheckJupyterEnabled();
const isHomeAvailable = useIsAreaAvailable(SupportedArea.HOME).status;
const isConnectionTypesAvailable = useIsAreaAvailable(SupportedArea.CONNECTION_TYPES).status;

if (!isAllowed) {
return (
Expand All @@ -79,6 +80,7 @@ const AppRoutes: React.FC = () => {
);
}

console.log(isConnectionTypesAvailable);

Check failure on line 83 in frontend/src/app/AppRoutes.tsx

View workflow job for this annotation

GitHub Actions / Tests (18.x)

Unexpected console statement
return (
<React.Suspense fallback={<ApplicationsPage title="" description="" loaded={false} empty />}>
<InvalidArgoDeploymentAlert />
Expand Down Expand Up @@ -124,9 +126,11 @@ const AppRoutes: React.FC = () => {
<Route path="/clusterSettings" element={<ClusterSettingsPage />} />
<Route path="/acceleratorProfiles/*" element={<AcceleratorProfileRoutes />} />
<Route path="/servingRuntimes/*" element={<CustomServingRuntimeRoutes />} />
{isConnectionTypesAvailable ? (
<Route path="/connectionTypes/*" element={<ConnectionTypeRoutes />} />
) : null}
<Route path="/modelRegistrySettings/*" element={<ModelRegistrySettingsRoutes />} />
<Route path="/groupSettings" element={<GroupSettingsPage />} />
<Route path="/connectionTypes/*" element={<ConnectionTypeRoutes />} />
</>
)}

Expand Down
Loading

0 comments on commit f29765b

Please sign in to comment.