Skip to content

Commit

Permalink
Add NotificationContext and useNotification hook (#524)
Browse files Browse the repository at this point in the history
Signed-off-by: Griffin-Sullivan <[email protected]>
  • Loading branch information
Griffin-Sullivan authored Nov 7, 2024
1 parent d4ced02 commit 962d135
Show file tree
Hide file tree
Showing 20 changed files with 599 additions and 274 deletions.
11 changes: 11 additions & 0 deletions clients/ui/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions clients/ui/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@types/dompurify": "^3.0.5",
"@types/jest": "^29.5.13",
"@types/lodash-es": "^4.17.8",
"@types/react-dom": "^18.3.1",
"@types/react-router-dom": "^5.3.3",
"@types/showdown": "^2.0.3",
"chai-subset": "^1.6.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export class ToastNotification {
constructor(private title: string) {}

find(): Cypress.Chainable<JQuery<HTMLElement>> {
return cy.findByText(this.title);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ class ModelRegistry {
return this.findModelVersionsTable().find('tbody tr');
}

// TODO: Uncomment when the table row is implemented
getRow(name: string) {
return new ModelRegistryTableRow(() =>
this.findTable().find(`[data-label="Model name"]`).contains(name).parents('tr'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ declare global {
options: {
path: { modelRegistryName: string; apiVersion: string; modelVersionId: number };
},
response: ApiResponse<ModelVersion | undefined>,
response: ApiResponse<ModelRegistryBody<ModelVersion | undefined>>,
) => Cypress.Chainable<null>) &
((
type: 'GET /api/:apiVersion/model_registry',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ Cypress.Commands.add(
if ($el.attr('aria-expanded') === 'false') {
cy.wrap($el).click();
}
return cy.wrap($el.parent()).findByRole('menuitem', { name });
return cy.get('body').findByRole('menuitem', { name });
});
},
);
Expand All @@ -182,7 +182,7 @@ Cypress.Commands.add('findDropdownItem', { prevSubject: 'element' }, (subject, n
if ($el.attr('aria-expanded') === 'false') {
cy.wrap($el).click();
}
return cy.wrap($el).parent().findByRole('menuitem', { name });
return cy.get('body').findByRole('menuitem', { name });
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import { mockModelVersionList } from '~/__mocks__/mockModelVersionList';
import { mockModelVersion } from '~/__mocks__/mockModelVersion';
import { mockRegisteredModel } from '~/__mocks__/mockRegisteredModel';
import { verifyRelativeURL } from '~/__tests__/cypress/cypress/utils/url';
import { labelModal } from '~/__tests__/cypress/cypress/pages/modelRegistry';
import { labelModal, modelRegistry } from '~/__tests__/cypress/cypress/pages/modelRegistry';
import type { ModelRegistry, ModelVersion } from '~/app/types';
import { ModelState } from '~/app/types';
import { mockModelRegistry } from '~/__mocks__/mockModelRegistry';
import { mockBFFResponse } from '~/__mocks__/utils';
import { modelVersionArchive } from '~/__tests__/cypress/cypress/pages/modelRegistryView/modelVersionArchive';
import {
archiveVersionModal,
modelVersionArchive,
restoreVersionModal,
} from '~/__tests__/cypress/cypress/pages/modelRegistryView/modelVersionArchive';
import { MODEL_REGISTRY_API_VERSION } from '~/__tests__/cypress/cypress/support/commands/api';
import { ToastNotification } from '~/__tests__/cypress/cypress/pages/components/Notification';

type HandlersProps = {
registeredModelsSize?: number;
Expand Down Expand Up @@ -129,12 +134,10 @@ describe('Model version archive list', () => {
initIntercepts({ modelVersions: [mockModelVersion({ id: '3', name: 'model version 2' })] });
modelVersionArchive.visitModelVersionList();
verifyRelativeURL('/modelRegistry/modelregistry-sample/registeredModels/1/versions');
// TODO: Uncomment when dropdowns are fixed and remove the visit after the comments
// modelVersionArchive
// .findModelVersionsTableKebab()
// .findDropdownItem('View archived versions')
// .click();
modelVersionArchive.visit();
modelVersionArchive
.findModelVersionsTableKebab()
.findDropdownItem('View archived versions')
.click();
modelVersionArchive.shouldArchiveVersionsEmpty();
});

Expand Down Expand Up @@ -185,119 +188,124 @@ describe('Model version archive list', () => {
});
});

// TODO: Uncomment when we have restoring and archiving mocked
// describe('Restoring archive version', () => {
// it('Restore from archive table', () => {
// cy.interceptApi(
// 'PATCH /api/:apiVersion/model_registry/:modelRegistryName/model_versions/:modelVersionId',
// {
// path: {
// modelRegistryName: 'modelregistry-sample',
// apiVersion: MODEL_REGISTRY_API_VERSION,
// modelVersionId: 2,
// },
// },
// mockModelVersion({}),
// ).as('versionRestored');

// initIntercepts({});
// modelVersionArchive.visit();

// const archiveVersionRow = modelVersionArchive.getRow('model version 2');
// archiveVersionRow.findKebabAction('Restore version').click();

// restoreVersionModal.findRestoreButton().click();

// cy.wait('@versionRestored').then((interception) => {
// expect(interception.request.body).to.eql({
// state: 'LIVE',
// });
// });
// });

// it('Restore from archive version details', () => {
// cy.interceptApi(
// 'PATCH /api/:apiVersion/model_registry/:modelRegistryName/model_versions/:modelVersionId',
// {
// path: {
// modelRegistryName: 'modelregistry-sample',
// apiVersion: MODEL_REGISTRY_API_VERSION,
// modelVersionId: 2,
// },
// },
// mockModelVersion({}),
// ).as('versionRestored');

// initIntercepts({});
// modelVersionArchive.visitArchiveVersionDetail();

// modelVersionArchive.findRestoreButton().click();
// restoreVersionModal.findRestoreButton().click();

// cy.wait('@versionRestored').then((interception) => {
// expect(interception.request.body).to.eql({
// state: 'LIVE',
// });
// });
// });
// });

// describe('Archiving version', () => {
// it('Archive version from versions table', () => {
// cy.interceptApi(
// 'PATCH /api/service/modelregistry/:serviceName/api/model_registry/:apiVersion/model_versions/:modelVersionId',
// {
// path: {
// serviceName: 'modelregistry-sample',
// apiVersion: MODEL_REGISTRY_API_VERSION,
// modelVersionId: 3,
// },
// },
// mockModelVersion({}),
// ).as('versionArchived');

// initIntercepts({});
// modelVersionArchive.visitModelVersionList();

// const modelVersionRow = modelRegistry.getModelVersionRow('model version 3');
// modelVersionRow.findKebabAction('Archive model version').click();
// archiveVersionModal.findArchiveButton().should('be.disabled');
// archiveVersionModal.findModalTextInput().fill('model version 3');
// archiveVersionModal.findArchiveButton().should('be.enabled').click();
// cy.wait('@versionArchived').then((interception) => {
// expect(interception.request.body).to.eql({
// state: 'ARCHIVED',
// });
// });
// });

// it('Archive version from versions details', () => {
// cy.interceptApi(
// 'PATCH /api/service/modelregistry/:serviceName/api/model_registry/:apiVersion/model_versions/:modelVersionId',
// {
// path: {
// serviceName: 'modelregistry-sample',
// apiVersion: MODEL_REGISTRY_API_VERSION,
// modelVersionId: 3,
// },
// },
// mockModelVersion({}),
// ).as('versionArchived');

// initIntercepts({});
// modelVersionArchive.visitModelVersionDetails();
// modelVersionArchive
// .findModelVersionsDetailsHeaderAction()
// .findDropdownItem('Archive version')
// .click();

// archiveVersionModal.findArchiveButton().should('be.disabled');
// archiveVersionModal.findModalTextInput().fill('model version 3');
// archiveVersionModal.findArchiveButton().should('be.enabled').click();
// cy.wait('@versionArchived').then((interception) => {
// expect(interception.request.body).to.eql({
// state: 'ARCHIVED',
// });
// });
// });
// });
describe('Restoring archive version', () => {
it('Restore from archive table', () => {
cy.interceptApi(
'PATCH /api/:apiVersion/model_registry/:modelRegistryName/model_versions/:modelVersionId',
{
path: {
modelRegistryName: 'modelregistry-sample',
apiVersion: MODEL_REGISTRY_API_VERSION,
modelVersionId: 2,
},
},
mockBFFResponse(mockModelVersion({})),
).as('versionRestored');

initIntercepts({});
modelVersionArchive.visit();

const archiveVersionRow = modelVersionArchive.getRow('model version 2');
archiveVersionRow.findKebabAction('Restore version').click();

restoreVersionModal.findRestoreButton().click();

const notification = new ToastNotification('model version 2 restored.');
notification.find();

cy.wait('@versionRestored').then((interception) => {
expect(interception.request.body).to.eql(mockBFFResponse({ state: 'LIVE' }));
});
});

it('Restore from archive version details', () => {
cy.interceptApi(
'PATCH /api/:apiVersion/model_registry/:modelRegistryName/model_versions/:modelVersionId',
{
path: {
modelRegistryName: 'modelregistry-sample',
apiVersion: MODEL_REGISTRY_API_VERSION,
modelVersionId: 2,
},
},
mockBFFResponse(mockModelVersion({})),
).as('versionRestored');

initIntercepts({});
modelVersionArchive.visitArchiveVersionDetail();

modelVersionArchive.findRestoreButton().click();
restoreVersionModal.findRestoreButton().click();

const notification = new ToastNotification('model version 2 restored.');
notification.find();

cy.wait('@versionRestored').then((interception) => {
expect(interception.request.body).to.eql(mockBFFResponse({ state: 'LIVE' }));
});
});
});

describe('Archiving version', () => {
it('Archive version from versions table', () => {
cy.interceptApi(
'PATCH /api/:apiVersion/model_registry/:modelRegistryName/model_versions/:modelVersionId',
{
path: {
modelRegistryName: 'modelregistry-sample',
apiVersion: MODEL_REGISTRY_API_VERSION,
modelVersionId: 3,
},
},
mockBFFResponse(mockModelVersion({})),
).as('versionArchived');

initIntercepts({});
modelVersionArchive.visitModelVersionList();

const modelVersionRow = modelRegistry.getModelVersionRow('model version 3');
modelVersionRow.findKebabAction('Archive model version').click();
archiveVersionModal.findArchiveButton().should('be.disabled');
archiveVersionModal.findModalTextInput().fill('model version 3');
archiveVersionModal.findArchiveButton().should('be.enabled').click();

const notification = new ToastNotification('model version 3 archived.');
notification.find();

cy.wait('@versionArchived').then((interception) => {
expect(interception.request.body).to.eql(mockBFFResponse({ state: 'ARCHIVED' }));
});
});

it('Archive version from versions details', () => {
cy.interceptApi(
'PATCH /api/:apiVersion/model_registry/:modelRegistryName/model_versions/:modelVersionId',
{
path: {
modelRegistryName: 'modelregistry-sample',
apiVersion: MODEL_REGISTRY_API_VERSION,
modelVersionId: 3,
},
},
mockBFFResponse(mockModelVersion({})),
).as('versionArchived');

initIntercepts({});
modelVersionArchive.visitModelVersionDetails();
modelVersionArchive
.findModelVersionsDetailsHeaderAction()
.findDropdownItem('Archive version')
.click();

archiveVersionModal.findArchiveButton().should('be.disabled');
archiveVersionModal.findModalTextInput().fill('model version 3');
archiveVersionModal.findArchiveButton().should('be.enabled').click();

const notification = new ToastNotification('model version 3 archived.');
notification.find();

cy.wait('@versionArchived').then((interception) => {
expect(interception.request.body).to.eql(mockBFFResponse({ state: 'ARCHIVED' }));
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ describe('Model Versions', () => {
});

it('Model versions table', () => {
// TODO: Uncomment when we fix finding dropdown items
// TODO: Uncomment when we fix finding listbox items

initIntercepts({
modelRegistries: [
Expand Down
Loading

0 comments on commit 962d135

Please sign in to comment.