diff --git a/src/utils/absoluteUrl.js b/src/utils/absoluteUrl.js index 1722297..faf2369 100644 --- a/src/utils/absoluteUrl.js +++ b/src/utils/absoluteUrl.js @@ -1,6 +1,8 @@ -export default function absoluteUrl(path) { +const absoluteUrl = path => { let absolutePath = '/'; + if (!path) return absolutePath; + // TODO: Find another way to get root url const absoluteUrl = window.location.origin; const absoluteUrlParts = absoluteUrl.split('/'); @@ -13,4 +15,6 @@ export default function absoluteUrl(path) { } return absolutePath.replace(/\/\/+/g, '/'); -} +}; + +export default absoluteUrl; diff --git a/src/utils/absoluteUrl.test.js b/src/utils/absoluteUrl.test.js new file mode 100644 index 0000000..7e69f69 --- /dev/null +++ b/src/utils/absoluteUrl.test.js @@ -0,0 +1,51 @@ +import absoluteUrl from './absoluteUrl'; + +describe('absoluteUrl', () => { + test('should return /path_1/path_2/path_3/path_to_destination when the window.location.origin is http://dummy.com/path_1/path_2 and the path is /path_3/path_to_destination', () => { + let global = { + window: Object.create(window), + }; + const url = 'http://dummy.com/path_1/path_2'; + Object.defineProperty(window, 'location', { + value: { + origin: url, + }, + writable: true, + }); + const absoluteUrlOutput = absoluteUrl('/path_3/path_to_destination'); + expect(absoluteUrlOutput).toEqual( + '/path_1/path_2/path_3/path_to_destination' + ); + }); + + test('should return / when the path is not defined', () => { + const absoluteUrlOutput = absoluteUrl(undefined); + expect(absoluteUrlOutput).toBe('/'); + }); + + test('should return the original path when there path in the window.origin after the domain and port', () => { + global.window = Object.create(window); + const url = 'http://dummy.com'; + Object.defineProperty(window, 'location', { + value: { + origin: url, + }, + writable: true, + }); + const absoluteUrlOutput = absoluteUrl('path_1/path_2/path_3'); + expect(absoluteUrlOutput).toEqual('/path_1/path_2/path_3'); + }); + + test('should be able to return the absolute path even when the path contains duplicates', () => { + global.window = Object.create(window); + const url = 'http://dummy.com'; + Object.defineProperty(window, 'location', { + value: { + origin: url, + }, + writable: true, + }); + const absoluteUrlOutput = absoluteUrl('path_1/path_1/path_1'); + expect(absoluteUrlOutput).toEqual('/path_1/path_1/path_1'); + }); +}); diff --git a/src/utils/addServer.test.js b/src/utils/addServer.test.js new file mode 100644 index 0000000..c5981bb --- /dev/null +++ b/src/utils/addServer.test.js @@ -0,0 +1,82 @@ +import addServers from './addServers'; + +describe('addServers', () => { + const servers = { + dicomWeb: [ + { + name: 'DCM4CHEE', + wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado', + qidoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs', + wadoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs', + qidoSupportsIncludeField: true, + imageRendering: 'wadors', + thumbnailRendering: 'wadors', + requestOptions: { + requestFromBrowser: true, + }, + }, + ], + oidc: [ + { + authority: 'http://127.0.0.1/auth/realms/ohif', + client_id: 'ohif-viewer', + redirect_uri: 'http://127.0.0.1/callback', + response_type: 'code', + scope: 'openid', + post_logout_redirect_uri: '/logout-redirect.html', + }, + ], + }; + + const store = { + dispatch: jest.fn(), + }; + + test('should be able to add a server and dispatch to the store successfuly', () => { + addServers(servers, store); + expect(store.dispatch).toBeCalledWith({ + server: { + authority: 'http://127.0.0.1/auth/realms/ohif', + client_id: 'ohif-viewer', + post_logout_redirect_uri: '/logout-redirect.html', + redirect_uri: 'http://127.0.0.1/callback', + response_type: 'code', + scope: 'openid', + type: 'oidc', + }, + type: 'ADD_SERVER', + }); + expect(store.dispatch).toBeCalledWith({ + server: { + imageRendering: 'wadors', + name: 'DCM4CHEE', + qidoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs', + qidoSupportsIncludeField: true, + requestOptions: { requestFromBrowser: true }, + thumbnailRendering: 'wadors', + type: 'dicomWeb', + wadoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs', + wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado', + }, + type: 'ADD_SERVER', + }); + }); + + test('should throw an error if servers list is not defined', () => { + expect(() => addServers(undefined, store)).toThrowError( + new Error('The servers and store must be defined') + ); + }); + + test('should throw an error if store is not defined', () => { + expect(() => addServers(servers, undefined)).toThrowError( + new Error('The servers and store must be defined') + ); + }); + + test('should throw an error when both server and store are not defined', () => { + expect(() => addServers(undefined, undefined)).toThrowError( + new Error('The servers and store must be defined') + ); + }); +}); diff --git a/src/utils/addServers.js b/src/utils/addServers.js index 0ff6c7f..c825243 100644 --- a/src/utils/addServers.js +++ b/src/utils/addServers.js @@ -1,5 +1,9 @@ // TODO: figure out where else to put this function -export default function addServers(servers, store) { +const addServers = (servers, store) => { + if (!servers || !store) { + throw new Error('The servers and store must be defined'); + } + Object.keys(servers).forEach(serverType => { const endpoints = servers[serverType]; endpoints.forEach(endpoint => { @@ -12,4 +16,6 @@ export default function addServers(servers, store) { }); }); }); -} +}; + +export default addServers; diff --git a/src/utils/guid.js b/src/utils/guid.js index a26f535..6ec6f82 100644 --- a/src/utils/guid.js +++ b/src/utils/guid.js @@ -3,24 +3,26 @@ * * @return {string} */ -export default function guid() { - function s4() { +const guid = () => { + const getFourRandomValues = () => { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); - } + }; return ( - s4() + - s4() + + getFourRandomValues() + + getFourRandomValues() + '-' + - s4() + + getFourRandomValues() + '-' + - s4() + + getFourRandomValues() + '-' + - s4() + + getFourRandomValues() + '-' + - s4() + - s4() + - s4() + getFourRandomValues() + + getFourRandomValues() + + getFourRandomValues() ); -} +}; + +export default guid; diff --git a/src/utils/guid.test.js b/src/utils/guid.test.js new file mode 100644 index 0000000..25d0d75 --- /dev/null +++ b/src/utils/guid.test.js @@ -0,0 +1,46 @@ +import guid from './guid'; + +describe('guid', () => { + Math.random = jest.fn(() => 0.4677647565236618); + const guidValue = guid(); + + afterAll(() => { + jest.clearAllMocks(); + }); + + test('should return 77bf77bf-77bf-77bf-77bf-77bf77bf77bf when the random value is fixed on 0.4677647565236618', () => { + expect(guidValue).toBe('77bf77bf-77bf-77bf-77bf-77bf77bf77bf'); + }); + + test('should always return a guid of size 36', () => { + expect(guidValue.length).toBe(36); + }); + + test('should always return a guid with five sequences', () => { + expect(guidValue.split('-').length).toBe(5); + }); + + test('should always return a guid with four dashes', () => { + expect(guidValue.split('-').length - 1).toBe(4); + }); + + test('should return the first sequence with length of eigth', () => { + expect(guidValue.split('-')[0].length).toBe(8); + }); + + test('should return the second sequence with length of four', () => { + expect(guidValue.split('-')[1].length).toBe(4); + }); + + test('should return the third sequence with length of four', () => { + expect(guidValue.split('-')[2].length).toBe(4); + }); + + test('should return the fourth sequence with length of four', () => { + expect(guidValue.split('-')[3].length).toBe(4); + }); + + test('should return the last sequence with length of twelve', () => { + expect(guidValue.split('-')[4].length).toBe(12); + }); +}); diff --git a/src/utils/index.test.js b/src/utils/index.test.js new file mode 100644 index 0000000..a9d1d5b --- /dev/null +++ b/src/utils/index.test.js @@ -0,0 +1,23 @@ +import * as utils from './index.js'; + +describe('Top level exports', () => { + test('should export the modules ', () => { + const expectedExports = [ + 'guid', + 'ObjectPath', + 'absoluteUrl', + 'addServers', + 'sortBy', + 'writeScript', + 'StackManager', + 'studyMetadataManager', + // Updates WADO-RS metaDataManager + 'updateMetaDataManager', + 'DICOMTagDescriptions', + ].sort(); + + const exports = Object.keys(utils.default).sort(); + + expect(exports).toEqual(expectedExports); + }); +}); diff --git a/src/utils/isImage.js b/src/utils/isImage.js index fc092f4..db1f79d 100644 --- a/src/utils/isImage.js +++ b/src/utils/isImage.js @@ -1,76 +1,62 @@ import { sopClassDictionary } from './sopClassDictionary'; +const imagesTypes = [ + sopClassDictionary.ComputedRadiographyImageStorage, + sopClassDictionary.DigitalXRayImageStorageForPresentation, + sopClassDictionary.DigitalXRayImageStorageForProcessing, + sopClassDictionary.DigitalMammographyXRayImageStorageForPresentation, + sopClassDictionary.DigitalMammographyXRayImageStorageForProcessing, + sopClassDictionary.DigitalIntraOralXRayImageStorageForPresentation, + sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing, + sopClassDictionary.CTImageStorage, + sopClassDictionary.EnhancedCTImageStorage, + sopClassDictionary.LegacyConvertedEnhancedCTImageStorage, + sopClassDictionary.UltrasoundMultiframeImageStorage, + sopClassDictionary.MRImageStorage, + sopClassDictionary.EnhancedMRImageStorage, + sopClassDictionary.EnhancedMRColorImageStorage, + sopClassDictionary.LegacyConvertedEnhancedMRImageStorage, + sopClassDictionary.UltrasoundImageStorage, + sopClassDictionary.SecondaryCaptureImageStorage, + sopClassDictionary.MultiframeSingleBitSecondaryCaptureImageStorage, + sopClassDictionary.MultiframeGrayscaleByteSecondaryCaptureImageStorage, + sopClassDictionary.MultiframeGrayscaleWordSecondaryCaptureImageStorage, + sopClassDictionary.MultiframeTrueColorSecondaryCaptureImageStorage, + sopClassDictionary.XRayAngiographicImageStorage, + sopClassDictionary.EnhancedXAImageStorage, + sopClassDictionary.XRayRadiofluoroscopicImageStorage, + sopClassDictionary.EnhancedXRFImageStorage, + sopClassDictionary.XRay3DAngiographicImageStorage, + sopClassDictionary.XRay3DCraniofacialImageStorage, + sopClassDictionary.BreastTomosynthesisImageStorage, + sopClassDictionary.BreastProjectionXRayImageStorageForPresentation, + sopClassDictionary.BreastProjectionXRayImageStorageForProcessing, + sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForPresentation, + sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForProcessing, + sopClassDictionary.NuclearMedicineImageStorage, + sopClassDictionary.VLEndoscopicImageStorage, + sopClassDictionary.VideoEndoscopicImageStorage, + sopClassDictionary.VLMicroscopicImageStorage, + sopClassDictionary.VideoMicroscopicImageStorage, + sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage, + sopClassDictionary.VLPhotographicImageStorage, + sopClassDictionary.VideoPhotographicImageStorage, + sopClassDictionary.OphthalmicPhotography8BitImageStorage, + sopClassDictionary.OphthalmicPhotography16BitImageStorage, + sopClassDictionary.OphthalmicTomographyImageStorage, + sopClassDictionary.VLWholeSlideMicroscopyImageStorage, + sopClassDictionary.PositronEmissionTomographyImageStorage, + sopClassDictionary.EnhancedPETImageStorage, + sopClassDictionary.LegacyConvertedEnhancedPETImageStorage, + sopClassDictionary.RTImageStorage, +]; + /** * Checks whether dicom files with specified SOP Class UID have image data * @param {string} sopClassUid - SOP Class UID to be checked * @returns {boolean} - true if it has image data */ -export function isImage(sopClassUid) { - if ( - sopClassUid === sopClassDictionary.ComputedRadiographyImageStorage || - sopClassUid === sopClassDictionary.DigitalXRayImageStorageForPresentation || - sopClassUid === sopClassDictionary.DigitalXRayImageStorageForProcessing || - sopClassUid === - sopClassDictionary.DigitalMammographyXRayImageStorageForPresentation || - sopClassUid === - sopClassDictionary.DigitalMammographyXRayImageStorageForProcessing || - sopClassUid === - sopClassDictionary.DigitalIntraOralXRayImageStorageForPresentation || - sopClassUid === - sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing || - sopClassUid === sopClassDictionary.CTImageStorage || - sopClassUid === sopClassDictionary.EnhancedCTImageStorage || - sopClassUid === sopClassDictionary.LegacyConvertedEnhancedCTImageStorage || - sopClassUid === sopClassDictionary.UltrasoundMultiframeImageStorage || - sopClassUid === sopClassDictionary.MRImageStorage || - sopClassUid === sopClassDictionary.EnhancedMRImageStorage || - sopClassUid === sopClassDictionary.EnhancedMRColorImageStorage || - sopClassUid === sopClassDictionary.LegacyConvertedEnhancedMRImageStorage || - sopClassUid === sopClassDictionary.UltrasoundImageStorage || - sopClassUid === sopClassDictionary.SecondaryCaptureImageStorage || - sopClassUid === - sopClassDictionary.MultiframeSingleBitSecondaryCaptureImageStorage || - sopClassUid === - sopClassDictionary.MultiframeGrayscaleByteSecondaryCaptureImageStorage || - sopClassUid === - sopClassDictionary.MultiframeGrayscaleWordSecondaryCaptureImageStorage || - sopClassUid === - sopClassDictionary.MultiframeTrueColorSecondaryCaptureImageStorage || - sopClassUid === sopClassDictionary.XRayAngiographicImageStorage || - sopClassUid === sopClassDictionary.EnhancedXAImageStorage || - sopClassUid === sopClassDictionary.XRayRadiofluoroscopicImageStorage || - sopClassUid === sopClassDictionary.EnhancedXRFImageStorage || - sopClassUid === sopClassDictionary.XRay3DAngiographicImageStorage || - sopClassUid === sopClassDictionary.XRay3DCraniofacialImageStorage || - sopClassUid === sopClassDictionary.BreastTomosynthesisImageStorage || - sopClassUid === - sopClassDictionary.BreastProjectionXRayImageStorageForPresentation || - sopClassUid === - sopClassDictionary.BreastProjectionXRayImageStorageForProcessing || - sopClassUid === - sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForPresentation || - sopClassUid === - sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForProcessing || - sopClassUid === sopClassDictionary.NuclearMedicineImageStorage || - sopClassUid === sopClassDictionary.VLEndoscopicImageStorage || - sopClassUid === sopClassDictionary.VideoEndoscopicImageStorage || - sopClassUid === sopClassDictionary.VLMicroscopicImageStorage || - sopClassUid === sopClassDictionary.VideoMicroscopicImageStorage || - sopClassUid === - sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage || - sopClassUid === sopClassDictionary.VLPhotographicImageStorage || - sopClassUid === sopClassDictionary.VideoPhotographicImageStorage || - sopClassUid === sopClassDictionary.OphthalmicPhotography8BitImageStorage || - sopClassUid === sopClassDictionary.OphthalmicPhotography16BitImageStorage || - sopClassUid === sopClassDictionary.OphthalmicTomographyImageStorage || - sopClassUid === sopClassDictionary.VLWholeSlideMicroscopyImageStorage || - sopClassUid === sopClassDictionary.PositronEmissionTomographyImageStorage || - sopClassUid === sopClassDictionary.EnhancedPETImageStorage || - sopClassUid === sopClassDictionary.LegacyConvertedEnhancedPETImageStorage || - sopClassUid === sopClassDictionary.RTImageStorage - ) { - return true; - } - - return false; -} +export const isImage = sopClassUid => { + if (!sopClassUid) return false; + return imagesTypes.indexOf(sopClassUid) !== -1; +}; diff --git a/src/utils/isImage.test.js b/src/utils/isImage.test.js new file mode 100644 index 0000000..1f53cce --- /dev/null +++ b/src/utils/isImage.test.js @@ -0,0 +1,333 @@ +import { sopClassDictionary } from './sopClassDictionary'; +import { isImage } from './isImage'; + +describe('isImage', () => { + test('should return true when the image is of type sopClassDictionary.ComputedRadiographyImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.ComputedRadiographyImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.DigitalXRayImageStorageForPresentation', () => { + const isImageStatus = isImage( + sopClassDictionary.DigitalXRayImageStorageForPresentation + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.DigitalXRayImageStorageForProcessing', () => { + const isImageStatus = isImage( + sopClassDictionary.DigitalXRayImageStorageForProcessing + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.DigitalMammographyXRayImageStorageForPresentation', () => { + const isImageStatus = isImage( + sopClassDictionary.DigitalMammographyXRayImageStorageForPresentation + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.DigitalMammographyXRayImageStorageForProcessing', () => { + const isImageStatus = isImage( + sopClassDictionary.DigitalMammographyXRayImageStorageForProcessing + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.DigitalIntraOralXRayImageStorageForPresentation', () => { + const isImageStatus = isImage( + sopClassDictionary.DigitalIntraOralXRayImageStorageForPresentation + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing', () => { + const isImageStatus = isImage( + sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.CTImageStorage', () => { + const isImageStatus = isImage(sopClassDictionary.CTImageStorage); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.EnhancedCTImageStorage', () => { + const isImageStatus = isImage(sopClassDictionary.EnhancedCTImageStorage); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.LegacyConvertedEnhancedCTImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.LegacyConvertedEnhancedCTImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.UltrasoundMultiframeImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.UltrasoundMultiframeImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.MRImageStorage', () => { + const isImageStatus = isImage(sopClassDictionary.MRImageStorage); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.EnhancedMRImageStorage', () => { + const isImageStatus = isImage(sopClassDictionary.EnhancedMRImageStorage); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.EnhancedMRColorImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.EnhancedMRColorImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.LegacyConvertedEnhancedMRImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.LegacyConvertedEnhancedMRImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.UltrasoundImageStorage', () => { + const isImageStatus = isImage(sopClassDictionary.UltrasoundImageStorage); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.SecondaryCaptureImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.SecondaryCaptureImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.MultiframeSingleBitSecondaryCaptureImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.MultiframeSingleBitSecondaryCaptureImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.MultiframeGrayscaleByteSecondaryCaptureImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.MultiframeGrayscaleByteSecondaryCaptureImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.MultiframeGrayscaleWordSecondaryCaptureImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.MultiframeGrayscaleWordSecondaryCaptureImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.MultiframeTrueColorSecondaryCaptureImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.MultiframeTrueColorSecondaryCaptureImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.XRayAngiographicImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.XRayAngiographicImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.EnhancedXAImageStorage', () => { + const isImageStatus = isImage(sopClassDictionary.EnhancedXAImageStorage); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.XRayRadiofluoroscopicImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.XRayRadiofluoroscopicImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.EnhancedXRFImageStorage', () => { + const isImageStatus = isImage(sopClassDictionary.EnhancedXRFImageStorage); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.XRay3DAngiographicImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.XRay3DAngiographicImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.XRay3DCraniofacialImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.XRay3DCraniofacialImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.BreastTomosynthesisImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.BreastTomosynthesisImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.BreastProjectionXRayImageStorageForPresentation', () => { + const isImageStatus = isImage( + sopClassDictionary.BreastProjectionXRayImageStorageForPresentation + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.BreastProjectionXRayImageStorageForProcessing', () => { + const isImageStatus = isImage( + sopClassDictionary.BreastProjectionXRayImageStorageForProcessing + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForPresentation', () => { + const isImageStatus = isImage( + sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForPresentation + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForProcessing', () => { + const isImageStatus = isImage( + sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForProcessing + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.NuclearMedicineImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.NuclearMedicineImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.VLEndoscopicImageStorage', () => { + const isImageStatus = isImage(sopClassDictionary.VLEndoscopicImageStorage); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.VideoEndoscopicImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.VideoEndoscopicImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.VLMicroscopicImageStorage', () => { + const isImageStatus = isImage(sopClassDictionary.VLMicroscopicImageStorage); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.VideoMicroscopicImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.VideoMicroscopicImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.VLPhotographicImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.VLPhotographicImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.VideoPhotographicImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.VideoPhotographicImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.OphthalmicPhotography8BitImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.OphthalmicPhotography8BitImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.OphthalmicPhotography16BitImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.OphthalmicPhotography16BitImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.OphthalmicTomographyImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.OphthalmicTomographyImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.VLWholeSlideMicroscopyImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.VLWholeSlideMicroscopyImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.PositronEmissionTomographyImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.PositronEmissionTomographyImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.EnhancedPETImageStorage', () => { + const isImageStatus = isImage(sopClassDictionary.EnhancedPETImageStorage); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.LegacyConvertedEnhancedPETImageStorage', () => { + const isImageStatus = isImage( + sopClassDictionary.LegacyConvertedEnhancedPETImageStorage + ); + expect(isImageStatus).toBe(true); + }); + + test('should return true when the image is of type sopClassDictionary.RTImageStorage', () => { + const isImageStatus = isImage(sopClassDictionary.RTImageStorage); + expect(isImageStatus).toBe(true); + }); + + test('should return false when the image is of type sopClassDictionary.SpatialFiducialsStorage', () => { + const isImageStatus = isImage(sopClassDictionary.SpatialFiducialsStorage); + expect(isImageStatus).toBe(false); + }); + + test('should return false when the image is undefined', () => { + const isImageStatus = isImage(undefined); + expect(isImageStatus).toBe(false); + }); + + test('should return false when the image is null', () => { + const isImageStatus = isImage(null); + expect(isImageStatus).toBe(false); + }); +}); diff --git a/src/utils/objectPath.test.js b/src/utils/objectPath.test.js new file mode 100644 index 0000000..49cd4cd --- /dev/null +++ b/src/utils/objectPath.test.js @@ -0,0 +1,99 @@ +import objectPath from './objectPath'; + +describe('objectPath', () => { + test('should return false when the supplied argument is not a real JavaScript Object instance such as undefined', () => { + expect(objectPath.isValidObject(undefined)).toBe(false); + }); + + test('should return false when the supplied argument is not a real JavaScript Object instance such as null', () => { + expect(objectPath.isValidObject(null)).toBe(false); + }); + + test('should return true when the supplied argument is a real JavaScript Object instance', () => { + expect(objectPath.isValidObject({})).toBe(true); + }); + + test('should return [path1, path2, path3] when the path is path1.path2.path3', () => { + const path = 'path1.path2.path3'; + const expectedPathComponents = objectPath.getPathComponents(path); + expect(expectedPathComponents).toEqual(['path1', 'path2', 'path3']); + }); + + test('should return null when the path is not a string', () => { + const path = 20; + const expectedPathComponents = objectPath.getPathComponents(path); + expect(expectedPathComponents).toEqual(null); + }); + + test('should return [path1path2path3] when the path is path1path2path3', () => { + const path = 'path1path2path3'; + const expectedPathComponents = objectPath.getPathComponents(path); + expect(expectedPathComponents).toEqual(['path1path2path3']); + }); + + test('should return the property obj.myProperty when the object contains myProperty', () => { + const searchObject = { + obj: { + myProperty: 'MOCK_VALUE', + }, + }; + const path = 'obj.myProperty'; + const expectedPathComponents = objectPath.get(searchObject, path); + expect(expectedPathComponents).toEqual(searchObject.obj.myProperty); + }); + + test('should return undefined when the object does not contain a property', () => { + const searchObject = { + obj: { + myProperty: 'MOCK_VALUE', + }, + }; + const path = 'obj.unknownProperty'; + const expectedPathComponents = objectPath.get(searchObject, path); + expect(expectedPathComponents).toEqual(undefined); + }); + + test('should return undefined when the object is not a valid object', () => { + const searchObject = undefined; + const path = 'obj.unknownProperty'; + const expectedPathComponents = objectPath.get(searchObject, path); + expect(expectedPathComponents).toEqual(undefined); + }); + + test('should return undefined when the inner object is not a valid object', () => { + const searchObject = { + obj: { + myProperty: null, + }, + }; + const path = 'obj.unknownProperty'; + const expectedPathComponents = objectPath.get(searchObject, path); + expect(expectedPathComponents).toEqual(undefined); + }); + + test('should set the property obj.myProperty when the object does not contain myProperty', () => { + const searchObject = { + obj: { + anyProperty: 'MOCK_VALUE', + }, + }; + const newValue = 'NEW_VALUE'; + const path = 'obj.myProperty'; + const output = objectPath.set(searchObject, path, newValue); + expect(output).toBe(true); + expect(searchObject.obj.myProperty).toEqual(newValue); + }); + + test('should return false when the object which is being set is not in a valid path', () => { + const searchObject = { + obj: { + myProperty: 'MOCK_VALUE', + }, + }; + const path = undefined; + const newValue = 'NEW_VALUE'; + + const output = objectPath.set(searchObject, path, newValue); + expect(output).toEqual(false); + }); +});