From 2ce2b9dccf800a4ed4c275b8de5648eaf2a37a03 Mon Sep 17 00:00:00 2001 From: mateusz-winiarczyk <mateusz.winiarczyk@appunite.com> Date: Mon, 4 Mar 2024 16:59:09 +0100 Subject: [PATCH] feat(project): add methods for plugins to retrieve data about project --- docs/plugins/project.md | 48 ++++++++++++++++++ index.d.ts | 14 ++++++ src/services/pluginsManager/pluginsManager.ts | 14 ++++++ .../project/data/getDisease.test.ts | 50 +++++++++++++++++++ .../pluginsManager/project/data/getDisease.ts | 16 ++++++ .../project/data/getName.test.ts | 50 +++++++++++++++++++ .../pluginsManager/project/data/getName.ts | 16 ++++++ .../project/data/getOrganism.test.ts | 50 +++++++++++++++++++ .../project/data/getOrganism.ts | 16 ++++++ .../project/data/getProjectId.test.ts | 50 +++++++++++++++++++ .../project/data/getProjectId.ts | 16 ++++++ .../project/data/getVersion.test.ts | 50 +++++++++++++++++++ .../pluginsManager/project/data/getVersion.ts | 16 ++++++ 13 files changed, 406 insertions(+) create mode 100644 docs/plugins/project.md create mode 100644 src/services/pluginsManager/project/data/getDisease.test.ts create mode 100644 src/services/pluginsManager/project/data/getDisease.ts create mode 100644 src/services/pluginsManager/project/data/getName.test.ts create mode 100644 src/services/pluginsManager/project/data/getName.ts create mode 100644 src/services/pluginsManager/project/data/getOrganism.test.ts create mode 100644 src/services/pluginsManager/project/data/getOrganism.ts create mode 100644 src/services/pluginsManager/project/data/getProjectId.test.ts create mode 100644 src/services/pluginsManager/project/data/getProjectId.ts create mode 100644 src/services/pluginsManager/project/data/getVersion.test.ts create mode 100644 src/services/pluginsManager/project/data/getVersion.ts diff --git a/docs/plugins/project.md b/docs/plugins/project.md new file mode 100644 index 00000000..a972b4a6 --- /dev/null +++ b/docs/plugins/project.md @@ -0,0 +1,48 @@ +### Project Info + +Minerva provides an API that allows users to retrieve specific information about a project. This API exposes various methods to access details related to a project. + +**Get Project ID:** +To get project ID, plugins can use the `getProjectId` method defined in `window.minerva.project.data` object. + +##### Example usage of getProjectId method: + +```javascript +window.minerva.project.data.getProjectId(); +``` + +**Get Project Name:** +To get project name, plugins can use the `getName` method defined in `window.minerva.project.data` object. + +##### Example usage of getName method: + +```javascript +window.minerva.project.data.getName(); +``` + +**Get Project Version:** +To get project version, plugins can use the `getVersion` method defined in `window.minerva.project.data` object. + +##### Example usage of getVersion method: + +```javascript +window.minerva.project.data.getVersion(); +``` + +**Get Disease:** +To get disease identifier associated with the project, plugins can use the `getDisease` method defined in `window.minerva.project.data` object. + +##### Example usage of getDisease method: + +```javascript +window.minerva.project.data.getDisease(); +``` + +**Get Organism:** +To get organism identifier associated with the project, plugins can use the `getOrganism` method defined in `window.minerva.project.data` object. + +##### Example usage of getOrganism method: + +```javascript +window.minerva.project.data.getOrganism(); +``` diff --git a/index.d.ts b/index.d.ts index 5cb2d025..fc841282 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,5 +1,10 @@ import { triggerSearch } from '@/services/pluginsManager/map/triggerSearch'; import { MinervaConfiguration } from '@/services/pluginsManager/pluginsManager'; +import { getDisease } from '@/services/pluginsManager/project/data/getDisease'; +import { getName } from '@/services/pluginsManager/project/data/getName'; +import { getOrganism } from '@/services/pluginsManager/project/data/getOrganism'; +import { getProjectId } from '@/services/pluginsManager/project/data/getProjectId'; +import { getVersion } from '@/services/pluginsManager/project/data/getVersion'; type Plugin = { pluginName: string; @@ -29,6 +34,15 @@ declare global { map: { triggerSearch: typeof triggerSearch; }; + project: { + data: { + getProjectId: typeof getProjectId; + getName: typeof getName; + getVersion: typeof getVersion; + getDisease: typeof getDisease; + getOrganism: typeof getOrganism; + }; + }; }; } } diff --git a/src/services/pluginsManager/pluginsManager.ts b/src/services/pluginsManager/pluginsManager.ts index a38faee9..63e46d12 100644 --- a/src/services/pluginsManager/pluginsManager.ts +++ b/src/services/pluginsManager/pluginsManager.ts @@ -5,6 +5,11 @@ import md5 from 'crypto-js/md5'; import { bioEntitiesMethods } from './bioEntities'; import { triggerSearch } from './map/triggerSearch'; import { PluginsEventBus } from './pluginsEventBus'; +import { getProjectId } from './project/data/getProjectId'; +import { getName } from './project/data/getName'; +import { getVersion } from './project/data/getVersion'; +import { getDisease } from './project/data/getDisease'; +import { getOrganism } from './project/data/getOrganism'; import type { PluginsManagerType } from './pluginsManager.types'; import { configurationMapper } from './pluginsManager.utils'; @@ -28,6 +33,15 @@ export const PluginsManager: PluginsManagerType = { map: { triggerSearch, }, + project: { + data: { + getProjectId, + getName, + getVersion, + getDisease, + getOrganism, + }, + }, }; const unsubscribe = store.subscribe(() => { diff --git a/src/services/pluginsManager/project/data/getDisease.test.ts b/src/services/pluginsManager/project/data/getDisease.test.ts new file mode 100644 index 00000000..0f80e378 --- /dev/null +++ b/src/services/pluginsManager/project/data/getDisease.test.ts @@ -0,0 +1,50 @@ +import { RootState, store } from '@/redux/store'; +import { projectFixture } from '@/models/fixtures/projectFixture'; +import { getDisease } from './getDisease'; + +jest.mock('../../../../redux/store'); + +describe('getDisease', () => { + const getStateSpy = jest.spyOn(store, 'getState'); + it('should return the disease from project if project exists and data is valid', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + data: projectFixture, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(getDisease()).toEqual(projectFixture.disease); + }); + it('should throw error if project does not exist', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(() => getDisease()).toThrow('Project does not exist'); + }); + it('returns undefined if project data is invalid', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + data: {}, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(getDisease()).toEqual(undefined); + }); +}); diff --git a/src/services/pluginsManager/project/data/getDisease.ts b/src/services/pluginsManager/project/data/getDisease.ts new file mode 100644 index 00000000..6d7e0ad7 --- /dev/null +++ b/src/services/pluginsManager/project/data/getDisease.ts @@ -0,0 +1,16 @@ +import { projectSchema } from '@/models/projectSchema'; +import { store } from '@/redux/store'; +import { Project } from '@/types/models'; +import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; + +type GetDiseaseReturnType = Project['disease'] | undefined; + +export const getDisease = (): GetDiseaseReturnType => { + const project = store.getState().project.data; + + if (!project) throw new Error('Project does not exist'); + + const isDataValid = validateDataUsingZodSchema(project, projectSchema); + + return isDataValid ? project.disease : undefined; +}; diff --git a/src/services/pluginsManager/project/data/getName.test.ts b/src/services/pluginsManager/project/data/getName.test.ts new file mode 100644 index 00000000..f53903fe --- /dev/null +++ b/src/services/pluginsManager/project/data/getName.test.ts @@ -0,0 +1,50 @@ +import { RootState, store } from '@/redux/store'; +import { projectFixture } from '@/models/fixtures/projectFixture'; +import { getName } from './getName'; + +jest.mock('../../../../redux/store'); + +describe('getName', () => { + const getStateSpy = jest.spyOn(store, 'getState'); + it('should return the project name from project if project exists and data is valid', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + data: projectFixture, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(getName()).toEqual(projectFixture.name); + }); + it('should throw error if project does not exist', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(() => getName()).toThrow('Project does not exist'); + }); + it('should return undefined if project data is invalid', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + data: {}, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(getName()).toEqual(undefined); + }); +}); diff --git a/src/services/pluginsManager/project/data/getName.ts b/src/services/pluginsManager/project/data/getName.ts new file mode 100644 index 00000000..c024ee22 --- /dev/null +++ b/src/services/pluginsManager/project/data/getName.ts @@ -0,0 +1,16 @@ +import { projectSchema } from '@/models/projectSchema'; +import { store } from '@/redux/store'; +import { Project } from '@/types/models'; +import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; + +type GetNameReturnType = Project['name'] | undefined; + +export const getName = (): GetNameReturnType => { + const project = store.getState().project.data; + + if (!project) throw new Error('Project does not exist'); + + const isDataValid = validateDataUsingZodSchema(project, projectSchema); + + return isDataValid ? project.name : undefined; +}; diff --git a/src/services/pluginsManager/project/data/getOrganism.test.ts b/src/services/pluginsManager/project/data/getOrganism.test.ts new file mode 100644 index 00000000..6ddf8e64 --- /dev/null +++ b/src/services/pluginsManager/project/data/getOrganism.test.ts @@ -0,0 +1,50 @@ +import { RootState, store } from '@/redux/store'; +import { projectFixture } from '@/models/fixtures/projectFixture'; +import { getOrganism } from './getOrganism'; + +jest.mock('../../../../redux/store'); + +describe('getOrganism', () => { + const getStateSpy = jest.spyOn(store, 'getState'); + it('should return the project organism from project if project exists and data is valid', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + data: projectFixture, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(getOrganism()).toEqual(projectFixture.organism); + }); + it('should throw error if project does not exist', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(() => getOrganism()).toThrow('Project does not exist'); + }); + it('should return undefined if project data is invalid', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + data: {}, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(getOrganism()).toEqual(undefined); + }); +}); diff --git a/src/services/pluginsManager/project/data/getOrganism.ts b/src/services/pluginsManager/project/data/getOrganism.ts new file mode 100644 index 00000000..a19fe476 --- /dev/null +++ b/src/services/pluginsManager/project/data/getOrganism.ts @@ -0,0 +1,16 @@ +import { projectSchema } from '@/models/projectSchema'; +import { store } from '@/redux/store'; +import { Project } from '@/types/models'; +import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; + +type GetOrganismReturnType = Project['organism'] | undefined; + +export const getOrganism = (): GetOrganismReturnType => { + const project = store.getState().project.data; + + if (!project) throw new Error('Project does not exist'); + + const isDataValid = validateDataUsingZodSchema(project, projectSchema); + + return isDataValid ? project.organism : undefined; +}; diff --git a/src/services/pluginsManager/project/data/getProjectId.test.ts b/src/services/pluginsManager/project/data/getProjectId.test.ts new file mode 100644 index 00000000..cc7cccdc --- /dev/null +++ b/src/services/pluginsManager/project/data/getProjectId.test.ts @@ -0,0 +1,50 @@ +import { RootState, store } from '@/redux/store'; +import { projectFixture } from '@/models/fixtures/projectFixture'; +import { getProjectId } from './getProjectId'; + +jest.mock('../../../../redux/store'); + +describe('getProjectId', () => { + const getStateSpy = jest.spyOn(store, 'getState'); + it('should return the project id from project if project exists and data is valid', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + data: projectFixture, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(getProjectId()).toEqual(projectFixture.projectId); + }); + it('should throw error if project does not exist', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(() => getProjectId()).toThrow('Project does not exist'); + }); + it('should return undefined if project data is invalid', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + data: {}, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(getProjectId()).toEqual(undefined); + }); +}); diff --git a/src/services/pluginsManager/project/data/getProjectId.ts b/src/services/pluginsManager/project/data/getProjectId.ts new file mode 100644 index 00000000..2a8fd53f --- /dev/null +++ b/src/services/pluginsManager/project/data/getProjectId.ts @@ -0,0 +1,16 @@ +import { projectSchema } from '@/models/projectSchema'; +import { store } from '@/redux/store'; +import { Project } from '@/types/models'; +import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; + +type GetProjectIdReturnType = Project['projectId'] | undefined; + +export const getProjectId = (): GetProjectIdReturnType => { + const project = store.getState().project.data; + + if (!project) throw new Error('Project does not exist'); + + const isDataValid = validateDataUsingZodSchema(project, projectSchema); + + return isDataValid ? project.projectId : undefined; +}; diff --git a/src/services/pluginsManager/project/data/getVersion.test.ts b/src/services/pluginsManager/project/data/getVersion.test.ts new file mode 100644 index 00000000..ca35d3cb --- /dev/null +++ b/src/services/pluginsManager/project/data/getVersion.test.ts @@ -0,0 +1,50 @@ +import { RootState, store } from '@/redux/store'; +import { projectFixture } from '@/models/fixtures/projectFixture'; +import { getVersion } from './getVersion'; + +jest.mock('../../../../redux/store'); + +describe('getVersion', () => { + const getStateSpy = jest.spyOn(store, 'getState'); + it('should return the project id from project if project exists and data is valid', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + data: projectFixture, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(getVersion()).toEqual(projectFixture.version); + }); + it('should throw error if project does not exist', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(() => getVersion()).toThrow('Project does not exist'); + }); + it('should return undefined if project data is invalid', () => { + getStateSpy.mockImplementation( + () => + ({ + project: { + data: {}, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }) as RootState, + ); + + expect(getVersion()).toEqual(undefined); + }); +}); diff --git a/src/services/pluginsManager/project/data/getVersion.ts b/src/services/pluginsManager/project/data/getVersion.ts new file mode 100644 index 00000000..882735f4 --- /dev/null +++ b/src/services/pluginsManager/project/data/getVersion.ts @@ -0,0 +1,16 @@ +import { projectSchema } from '@/models/projectSchema'; +import { store } from '@/redux/store'; +import { Project } from '@/types/models'; +import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; + +type GetVersionReturnType = Project['version'] | undefined; + +export const getVersion = (): GetVersionReturnType => { + const project = store.getState().project.data; + + if (!project) throw new Error('Project does not exist'); + + const isDataValid = validateDataUsingZodSchema(project, projectSchema); + + return isDataValid ? project.version : undefined; +}; -- GitLab