Skip to content
Draft
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
33 changes: 33 additions & 0 deletions plugins/ohif/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
3 changes: 3 additions & 0 deletions plugins/ohif/extensions/monai-service/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
testEnvironment: 'jest-environment-jsdom'
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing new line

65 changes: 3 additions & 62 deletions plugins/ohif/extensions/monai-service/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -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) => (
<button onClick={props.onSelectModel}>Select Model</button>
));
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(<AutoSegmentation {...props} />);
expect(getByText('Auto-Segmentation')).toBeInTheDocument();
});

it('calls onSelectModel when model is selected', () => {
const { getByText } = render(<AutoSegmentation {...props} />);
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(<AutoSegmentation {...props} />);
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',
}));
});
});

Original file line number Diff line number Diff line change
@@ -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(<MonaiServicePanel {...props} />);

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);
});
});
3 changes: 3 additions & 0 deletions plugins/ohif/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
testEnvironment: 'jest-environment-jsdom'
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing new line