diff --git a/plugins/ohif/README.md b/plugins/ohif/README.md
index ed189fc..09743f4 100644
--- a/plugins/ohif/README.md
+++ b/plugins/ohif/README.md
@@ -82,3 +82,36 @@ sudo wget https://lsb.orthanc-server.com/plugin-dicom-web/1.6/libOrthancDicomWeb
sudo service orthanc restart
```
+
+### Unit Tests
+#### Setup
+
+The test pipeline for Javascript is configured in JEST and NPM.
+Add more unit tests, create *.test.js file under `__tests__` folder.
+Here are steps to setup test ENV:
+
+##### Install Jest
+
+```bash
+npm install --save-dev jest
+npm install --save-dev jest-environment-jsdom --legacy-peer-deps
+
+```
+
+##### Configure Jest
+
+```
+"scripts": {
+ "test": "jest"
+},
+"jest": {
+ "verbose": true,
+ "testEnvironment": "jsdom"
+}
+```
+
+##### Run Tests
+
+```bash
+npm test
+```
\ No newline at end of file
diff --git a/plugins/ohif/extensions/monai-service/jest.config.js b/plugins/ohif/extensions/monai-service/jest.config.js
new file mode 100644
index 0000000..6f3d284
--- /dev/null
+++ b/plugins/ohif/extensions/monai-service/jest.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ testEnvironment: 'jest-environment-jsdom'
+};
\ No newline at end of file
diff --git a/plugins/ohif/extensions/monai-service/package.json b/plugins/ohif/extensions/monai-service/package.json
index 7fb2ce3..fa6f3e7 100644
--- a/plugins/ohif/extensions/monai-service/package.json
+++ b/plugins/ohif/extensions/monai-service/package.json
@@ -1,64 +1,5 @@
{
- "name": "@ohif/extension-monai-service",
- "version": "0.0.1",
- "description": "OHIFv3 extension for MONAI Service",
- "author": "OHIF,NVIDIA",
- "license": "MIT",
- "main": "dist/umd/extension-monai-service/index.umd.js",
- "files": [
- "dist/**",
- "public/**",
- "README.md"
- ],
- "repository": "OHIF/Viewers",
- "keywords": [
- "ohif-extension"
- ],
- "module": "src/index.tsx",
- "publishConfig": {
- "access": "public"
- },
- "engines": {
- "node": ">=14",
- "npm": ">=6",
- "yarn": ">=1.18.0"
- },
- "scripts": {
- "dev": "cross-env NODE_ENV=development webpack --config .webpack/webpack.dev.js --watch --output-pathinfo",
- "dev:my-extension": "yarn run dev",
- "build": "cross-env NODE_ENV=production webpack --config .webpack/webpack.prod.js",
- "build:package": "yarn run build",
- "start": "yarn run dev"
- },
- "peerDependencies": {
- "@ohif/core": "^3.7.0-beta.80",
- "@ohif/extension-default": "^3.7.0-beta.80",
- "@ohif/extension-cornerstone": "^3.7.0-beta.80",
- "@ohif/i18n": "^3.7.0-beta.80",
- "prop-types": "^15.6.2",
- "react": "^17.0.2",
- "react-dom": "^17.0.2",
- "react-i18next": "^12.2.2",
- "react-router": "^6.8.1",
- "react-router-dom": "^6.8.1"
- },
- "dependencies": {
- "@babel/runtime": "^7.20.13",
- "md5.js": "^1.3.5",
- "axios": "^0.21.1",
- "arraybuffer-concat": "^0.0.1",
- "ndarray": "^1.0.19",
- "nrrd-js": "^0.2.1",
- "pako": "^2.0.3",
- "react-color": "^2.19.3",
- "bootstrap": "^5.0.2",
- "react-select": "^4.3.1",
- "chroma-js": "^2.1.2"
- },
- "devDependencies": {
- "@cornerstonejs/tools": "^1.16.0",
- "@babel/runtime": "^7.20.13",
- "@cornerstonejs/tools": "^1.16.4",
- "react-color": "^2.19.3"
- }
+ "devDependencies": {
+ "svgo": "^1.3.2"
+ }
}
diff --git a/plugins/ohif/extensions/monai-service/src/__tests__/inference.test.js b/plugins/ohif/extensions/monai-service/src/__tests__/inference.test.js
new file mode 100644
index 0000000..1c08cb8
--- /dev/null
+++ b/plugins/ohif/extensions/monai-service/src/__tests__/inference.test.js
@@ -0,0 +1,73 @@
+import React from 'react';
+import { render, fireEvent, waitFor } from '@testing-library/react';
+import AutoSegmentation from './AutoSegmentation';
+import ModelSelector from '../ModelSelector';
+
+jest.mock('../ModelSelector', () => (props) => (
+
+));
+jest.mock('../../utils/GenericUtils', () => ({
+ hideNotification: jest.fn(),
+}));
+
+describe('AutoSegmentation', () => {
+ let props;
+
+ beforeEach(() => {
+ props = {
+ client: () => ({
+ inference: jest.fn().mockResolvedValue({ status: 201 }),
+ }),
+ updateView: jest.fn(),
+ notification: {
+ show: jest.fn(),
+ hide: jest.fn(),
+ },
+ servicesManager: {
+ services: {
+ displaySetService: {
+ activeDisplaySets: [{ Modality: 'CT', SeriesInstanceUID: '123' }],
+ }
+ }
+ },
+ info: {
+ models: [{ id: 'model1', network_arch: 'monai_vista3d' }],
+ modelLabelNames: { 'model1': ['Label1', 'Label2'] },
+ modelLabelIndices: { 'model1': [1, 2] },
+ modelLabelToIdxMap: {
+ 'model1': { 'kidney': 1, 'lung': 2, 'bone': 3 }
+ }
+ },
+ viewConstants: {
+ SeriesInstanceUID: 'defaultSeriesInstanceUID'
+ }
+ };
+ });
+
+ it('renders correctly', () => {
+ const { getByText } = render();
+ expect(getByText('Auto-Segmentation')).toBeInTheDocument();
+ });
+
+ it('calls onSelectModel when model is selected', () => {
+ const { getByText } = render();
+ const selectButton = getByText('Select Model');
+ fireEvent.click(selectButton);
+ expect(props.info.models.length).toBeGreaterThan(0);
+ });
+
+ it('calls onSegmentation when model is run', async () => {
+ const { getByText } = render();
+ const selectButton = getByText('Select Model');
+ fireEvent.click(selectButton);
+ await waitFor(() => {
+ expect(props.client().inference).toHaveBeenCalled();
+ });
+ expect(props.notification.show).toHaveBeenCalledWith(expect.objectContaining({
+ title: 'MONAI Service',
+ message: 'Run Segmentation - Successful',
+ type: 'success',
+ }));
+ });
+});
+
diff --git a/plugins/ohif/extensions/monai-service/src/__tests__/monaiServicePanel.test.js b/plugins/ohif/extensions/monai-service/src/__tests__/monaiServicePanel.test.js
new file mode 100644
index 0000000..e75819f
--- /dev/null
+++ b/plugins/ohif/extensions/monai-service/src/__tests__/monaiServicePanel.test.js
@@ -0,0 +1,63 @@
+import React from 'react';
+import { MonaiServicePanel } from './MonaiServicePanel';
+import { render, waitFor } from '@testing-library/react';
+
+jest.mock('../services/MonaiServiceClient', () => {
+ return {
+ MonaiServiceClient: jest.fn().mockImplementation(() => ({
+ getAuthorizationHeader: () => ({ Authorization: 'Bearer fake_token' }),
+ list_models: jest.fn().mockResolvedValue({
+ status: 200,
+ data: []
+ }),
+ cache_image: jest.fn().mockResolvedValue({})
+ }))
+ };
+});
+
+const mockNotificationService = {
+ show: jest.fn(),
+ hide: jest.fn()
+};
+
+const mockDisplaySetService = {
+ activeDisplaySets: [{
+ SeriesInstanceUID: '123',
+ StudyInstanceUID: '456',
+ instances: [{
+ FrameOfReferenceUID: '789'
+ }],
+ displaySetInstanceUID: '101112'
+ }]
+};
+
+// Test suite
+describe('MonaiServicePanel', () => {
+ it('handles model and dataset information on successful connection', async () => {
+ const props = {
+ servicesManager: {
+ services: {
+ uiNotificationService: mockNotificationService,
+ displaySetService: mockDisplaySetService
+ }
+ }
+ };
+
+ const { container } = render();
+
+ const instance = container.querySelector('MonaiServicePanel');
+ await instance.onInfo();
+
+ expect(mockNotificationService.show).toHaveBeenCalledWith(expect.objectContaining({
+ type: 'info',
+ message: 'Connecting to MONAI Service'
+ }));
+ await waitFor(() => {
+ expect(mockNotificationService.show).toHaveBeenCalledWith(expect.objectContaining({
+ type: 'success',
+ message: 'Connected to MONAI Service Server - Successful'
+ }));
+ });
+ expect(instance.state.info.models.length).toBeGreaterThan(0);
+ });
+});
diff --git a/plugins/ohif/jest.config.js b/plugins/ohif/jest.config.js
new file mode 100644
index 0000000..6f3d284
--- /dev/null
+++ b/plugins/ohif/jest.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ testEnvironment: 'jest-environment-jsdom'
+};
\ No newline at end of file