From 4d23c888bccd41162d641e9a3b8ee78d9a3b9472 Mon Sep 17 00:00:00 2001 From: Craig Barnes Date: Mon, 3 Feb 2025 14:01:36 -0600 Subject: [PATCH] VADC-1644: add test support for RTKQuery (#8) * add cohortAp and hooks * add teamProjectHooks.ts * setup jest test storybook with rtkQuery hooks * add test support for RTKQ add teamProjectHooks.test * clean up test * clean up test * add sharp * add sharp * update to 0.10.79 * revert CohortDefinitions refactor test-utils * add error to useProjectHooks * remove hook story * remove cohortApi to keep PR smaller --- .env.test | 2 + __mocks__/createWebStorageMock.js | 10 + jest.config.ts | 32 ++ jest.setup.ts | 4 + package-lock.json | 536 ++++++++++++++++-- package.json | 27 +- .../Utils/teamProjectHooks.test.tsx | 103 ++++ .../TeamProject/Utils/teamProjectHooks.ts | 50 ++ src/lib/test/test-utils.tsx | 55 ++ tsconfig.test.json | 5 + 10 files changed, 762 insertions(+), 62 deletions(-) create mode 100644 .env.test create mode 100644 __mocks__/createWebStorageMock.js create mode 100644 jest.config.ts create mode 100644 jest.setup.ts create mode 100644 src/lib/AnalysisApps/SharedUtils/TeamProject/Utils/teamProjectHooks.test.tsx create mode 100644 src/lib/AnalysisApps/SharedUtils/TeamProject/Utils/teamProjectHooks.ts create mode 100644 src/lib/test/test-utils.tsx create mode 100644 tsconfig.test.json diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..edf95e7 --- /dev/null +++ b/.env.test @@ -0,0 +1,2 @@ +GEN3_COMMONS_NAME=gen3 +NEXT_PUBLIC_GEN3_API=https://localhost diff --git a/__mocks__/createWebStorageMock.js b/__mocks__/createWebStorageMock.js new file mode 100644 index 0000000..e1d985c --- /dev/null +++ b/__mocks__/createWebStorageMock.js @@ -0,0 +1,10 @@ +/* global jest */ + +const mockStorage = { + getItem: jest.fn((_key) => Promise.resolve(null)), + setItem: jest.fn((_key, item) => Promise.resolve(item)), + removeItem: jest.fn((_key) => Promise.resolve()), +}; + +const createWebStorage = (_arg) => mockStorage; +module.exports = createWebStorage; diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 0000000..ce479cb --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,32 @@ +import type { JestConfigWithTsJest } from 'ts-jest'; + +const jestConfig: JestConfigWithTsJest = { + preset: 'ts-jest', + rootDir: __dirname, + roots: ['/src'], + moduleNameMapper: { + '^@/components(.*)$': '/src/components/$1', + '^@/lib/(.*)$': '/src/lib/$1', + '^redux-persist/lib/storage/createWebStorage$': + '/__mocks__/createWebStorageMock.js', + }, + testEnvironment: 'jest-fixed-jsdom', + setupFilesAfterEnv: ['/jest.setup.ts'], + transform: { + '^.+\\.(ts|tsx)?$': [ + 'ts-jest', + { + isolatedModules: true, + tsconfig: 'tsconfig.test.json', + }, + ], + 'node_modules/(flat|jsonpath-plus|uuid)/.+\\.(j|t)sx?$': ['ts-jest', {}], + }, + transformIgnorePatterns: ['/node_modules/(?!(flat|jsonpath-plus|uuid))'], + modulePaths: [''], + globals: { + fetch: global.fetch, + }, +}; + +export default jestConfig; diff --git a/jest.setup.ts b/jest.setup.ts new file mode 100644 index 0000000..72c4965 --- /dev/null +++ b/jest.setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { loadEnvConfig } from '@next/env'; + +loadEnvConfig(__dirname, true, { info: () => null, error: console.error }); diff --git a/package-lock.json b/package-lock.json index a2371b6..06cb82a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,8 @@ "@fontsource/montserrat": "^5.0.19", "@fontsource/poppins": "^5.0.15", "@fontsource/source-sans-pro": "^5.0.8", - "@gen3/core": "^0.10.78", - "@gen3/frontend": "^0.10.78", + "@gen3/core": "^0.10.79", + "@gen3/frontend": "^0.10.79", "@grafana/faro-react": "^1.9.1", "@grafana/faro-web-sdk": "^1.9.1", "@grafana/faro-web-tracing": "^1.9.1", @@ -30,12 +30,14 @@ "jsonpath-plus": "^10.2.0", "react": "^18.3.1", "react-dom": "18.3.1", + "sharp": "^0.33.5", "swr": "^2.2.5" }, "devDependencies": { "@axe-core/react": "^4.10.0", "@chromatic-com/storybook": "^3.2.4", - "@gen3/toolsff": "^0.10.78", + "@gen3/toolsff": "^0.10.79", + "@jest/globals": "^29.7.0", "@storybook/addon-a11y": "^8.6.0-alpha.1", "@storybook/addon-essentials": "^8.6.0-alpha.1", "@storybook/addon-interactions": "^8.6.0-alpha.1", @@ -49,6 +51,9 @@ "@tailwindcss/forms": "^0.5.3", "@tailwindcss/line-clamp": "^0.4.2", "@tailwindcss/typography": "^0.5.7", + "@testing-library/dom": "^10.4.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.2.0", "@types/lodash": "^4.14.202", "@types/mdx": "^2.0.11", "@types/react": "^18.2.21", @@ -63,6 +68,9 @@ "eslint-plugin-react": "^7.30.1", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-storybook": "^0.11.2", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jest-fixed-jsdom": "^0.0.9", "msw": "^2.7.0", "msw-storybook-addon": "^2.0.4", "next": "^14.2.23", @@ -75,8 +83,8 @@ "prettier": "^2.7.1", "storybook": "^8.6.0-alpha.1", "tailwindcss": "^3.4.10", - "ts-jest": "^29.1.2", - "ts-node": "^10.9.1", + "ts-jest": "^29.2.5", + "ts-node": "^10.9.2", "typescript": "^5.6.2" }, "engines": { @@ -3003,7 +3011,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -3640,9 +3647,9 @@ "license": "OFL-1.1" }, "node_modules/@gen3/core": { - "version": "0.10.78", - "resolved": "https://registry.npmjs.org/@gen3/core/-/core-0.10.78.tgz", - "integrity": "sha512-4cRQ85wQ/HMDOgI2l/FUZe0ZDUB5eZP7ZLT8bHjFyqz1SbZtgBGd60KrQeUz0HGUXEqKaJyTV3UVxIUvxOgXdw==", + "version": "0.10.79", + "resolved": "https://registry.npmjs.org/@gen3/core/-/core-0.10.79.tgz", + "integrity": "sha512-k7wBEW9Kzeg/XSOde8l1sTPOCr2Ww9/rb7ulql9EYANKEBaCDU5LEh9+qArzM5hqrPl81tkRQOl744w+ptmCwQ==", "license": "Apache-2.0", "dependencies": { "@reduxjs/toolkit": "^2.5.0", @@ -3666,12 +3673,12 @@ } }, "node_modules/@gen3/frontend": { - "version": "0.10.78", - "resolved": "https://registry.npmjs.org/@gen3/frontend/-/frontend-0.10.78.tgz", - "integrity": "sha512-uvyuFrnnNhZn35V2ky5DkrzrswlmOwfXs4fireWnKUP+O6P0Ecscr8x21JKUICIH8I/UMaE77xYPhICduTX9nQ==", + "version": "0.10.79", + "resolved": "https://registry.npmjs.org/@gen3/frontend/-/frontend-0.10.79.tgz", + "integrity": "sha512-qOGo0jcUdavdU1j1atWBCNUcr3UkbPb5beVm1075Ea+pbbsIPC1qR+5ei5M1KLn0xuMdxPcS6Ryeu5MHBOXLqg==", "license": "Apache-2.0", "dependencies": { - "@gen3/core": "^0.10.78", + "@gen3/core": "^0.10.79", "@graphiql/react": "^0.23.1", "@hello-pangea/dnd": "^17.0.0", "@iconify/react": "^5.0.2", @@ -3815,9 +3822,9 @@ } }, "node_modules/@gen3/toolsff": { - "version": "0.10.78", - "resolved": "https://registry.npmjs.org/@gen3/toolsff/-/toolsff-0.10.78.tgz", - "integrity": "sha512-iFF+VlXGNKuOwZ/Jg7gh0RCygUS3S+FDu3G+3qHNnmrpN/KEZvL4yscdxiRSQmCjin99QpuJzla4FNt4raTx/A==", + "version": "0.10.79", + "resolved": "https://registry.npmjs.org/@gen3/toolsff/-/toolsff-0.10.79.tgz", + "integrity": "sha512-HJVOj/YpN6fJRKkKWUVYtVwP3esC3HRjjeGYiaJD00YDuhwG+EdbLP3ahbzAgsr44spSVBvKRrBmzfegfx87pA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4139,7 +4146,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -4162,7 +4168,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -4185,7 +4190,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -4202,7 +4206,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -4219,7 +4222,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -4236,7 +4238,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -4253,7 +4254,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -4270,7 +4270,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -4287,7 +4286,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -4304,7 +4302,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -4321,7 +4318,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -4344,7 +4340,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -4367,7 +4362,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -4390,7 +4384,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -4413,7 +4406,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -4436,7 +4428,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -4459,7 +4450,6 @@ "cpu": [ "wasm32" ], - "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { @@ -4479,7 +4469,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -4499,7 +4488,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -9161,6 +9149,48 @@ "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" } }, + "node_modules/@storybook/test/node_modules/@testing-library/jest-dom": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz", + "integrity": "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@storybook/test/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@storybook/test/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, "node_modules/@storybook/theming": { "version": "8.6.0-alpha.2", "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.0-alpha.2.tgz", @@ -9596,9 +9626,9 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz", - "integrity": "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==", + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz", + "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==", "dev": true, "license": "MIT", "dependencies": { @@ -9637,6 +9667,34 @@ "dev": true, "license": "MIT" }, + "node_modules/@testing-library/react": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.2.0.tgz", + "integrity": "sha512-2cSskAvA1QNtKc8Y9VJQRv0tm3hLVgxRGDB+KYhIaPQJ1I+RHbhIXcM+zClKXzMes/wshsMVzf4B9vS4IZpqDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@testing-library/user-event": { "version": "14.5.2", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", @@ -9651,6 +9709,16 @@ "@testing-library/dom": ">=7.21.4" } }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, "node_modules/@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", @@ -10035,6 +10103,18 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jsdom": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -10912,6 +10992,14 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "license": "Apache-2.0" }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -10944,6 +11032,17 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, "node_modules/acorn-import-attributes": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", @@ -11004,6 +11103,19 @@ "node": ">=8.9.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -13096,9 +13208,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" @@ -13214,9 +13324,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -13872,6 +13980,33 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true, + "license": "MIT" + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -14119,6 +14254,31 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/data-view-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", @@ -14406,9 +14566,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true, "license": "Apache-2.0", - "optional": true, "engines": { "node": ">=8" } @@ -14696,6 +14854,20 @@ ], "license": "BSD-2-Clause" }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "deprecated": "Use your platform's native DOMException instead", + "dev": true, + "license": "MIT", + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", @@ -15458,7 +15630,6 @@ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", @@ -15481,7 +15652,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "license": "BSD-3-Clause", "optional": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -19295,6 +19465,32 @@ "license": "MIT", "peer": true }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-encoding-sniffer/node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/html-entities": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", @@ -19404,6 +19600,21 @@ "entities": "^4.5.0" } }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -19411,6 +19622,20 @@ "dev": true, "license": "MIT" }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -20132,6 +20357,13 @@ "node": ">=0.10.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, "node_modules/is-primitive": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", @@ -20997,6 +21229,34 @@ "dev": true, "license": "MIT" }, + "node_modules/jest-environment-jsdom": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz", + "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/jsdom": "^20.0.0", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0", + "jsdom": "^20.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/jest-environment-node": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", @@ -21015,6 +21275,19 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-fixed-jsdom": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/jest-fixed-jsdom/-/jest-fixed-jsdom-0.0.9.tgz", + "integrity": "sha512-KPfqh2+sn5q2B+7LZktwDcwhCpOpUSue8a1I+BcixWLOQoEVyAjAGfH+IYZGoxZsziNojoHGRTC8xRbB1wDD4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "jest-environment-jsdom": ">=28.0.0" + } + }, "node_modules/jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", @@ -21864,6 +22137,75 @@ "node": ">=12.0.0" } }, + "node_modules/jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jsdom/node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/jsep": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz", @@ -29103,6 +29445,13 @@ "node": ">=0.10.0" } }, + "node_modules/nwsapi": { + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==", + "dev": true, + "license": "MIT" + }, "node_modules/nyc": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", @@ -35818,6 +36167,19 @@ "license": "ISC", "peer": true }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -36026,10 +36388,8 @@ "version": "0.33.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", - "dev": true, "hasInstallScript": true, "license": "Apache-2.0", - "optional": true, "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", @@ -36206,9 +36566,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { "is-arrayish": "^0.3.1" } @@ -36217,9 +36575,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true, - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/sisteransi": { "version": "1.0.5", @@ -37165,6 +37521,13 @@ "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", @@ -37735,6 +38098,19 @@ "node": ">= 4.0.0" } }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -39700,6 +40076,19 @@ "license": "MIT", "peer": true }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/wait-on": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz", @@ -39869,6 +40258,16 @@ "get-canvas-context": "^1.0.1" } }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, "node_modules/webpack": { "version": "5.97.1", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", @@ -40048,6 +40447,20 @@ "node": ">=18" } }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -40331,6 +40744,16 @@ "dev": true, "license": "MIT" }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12" + } + }, "node_modules/xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", @@ -40341,6 +40764,13 @@ "node": ">=8.0" } }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 1f7fc8c..0066b33 100644 --- a/package.json +++ b/package.json @@ -17,19 +17,18 @@ "getSchema": "node ./node_modules/@gen3/toolsff/dist/getSchema.esm.js --out=config/", "getDRSToHostname": "node ./node_modules/@gen3/toolsff/dist/getDRSToHostname.esm.js --out=config/", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" + "build-storybook": "storybook build", + "test": "jest" }, "dependencies": { "@fontsource/montserrat": "^5.0.19", "@fontsource/poppins": "^5.0.15", "@fontsource/source-sans-pro": "^5.0.8", - "jsonpath-plus": "^10.2.0", - "@gen3/core": "^0.10.78", - "@gen3/frontend": "^0.10.78", + "@gen3/core": "^0.10.79", + "@gen3/frontend": "^0.10.79", "@grafana/faro-react": "^1.9.1", "@grafana/faro-web-sdk": "^1.9.1", "@grafana/faro-web-tracing": "^1.9.1", - "idb": "^8.0.0", "@mantine/core": "^7.16.0", "@mantine/dates": "^7.16.0", "@mantine/form": "^7.16.0", @@ -40,6 +39,9 @@ "@mdx-js/react": "^3.0.0", "@next/mdx": "^14.2.15", "cookies-next": "^4.3.0", + "idb": "^8.0.0", + "jsonpath-plus": "^10.2.0", + "sharp": "^0.33.5", "react": "^18.3.1", "react-dom": "18.3.1", "swr": "^2.2.5" @@ -47,7 +49,8 @@ "devDependencies": { "@axe-core/react": "^4.10.0", "@chromatic-com/storybook": "^3.2.4", - "@gen3/toolsff": "^0.10.78", + "@gen3/toolsff": "^0.10.79", + "@jest/globals": "^29.7.0", "@storybook/addon-a11y": "^8.6.0-alpha.1", "@storybook/addon-essentials": "^8.6.0-alpha.1", "@storybook/addon-interactions": "^8.6.0-alpha.1", @@ -61,6 +64,9 @@ "@tailwindcss/forms": "^0.5.3", "@tailwindcss/line-clamp": "^0.4.2", "@tailwindcss/typography": "^0.5.7", + "@testing-library/dom": "^10.4.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.2.0", "@types/lodash": "^4.14.202", "@types/mdx": "^2.0.11", "@types/react": "^18.2.21", @@ -74,10 +80,13 @@ "eslint-plugin-jsx-a11y": "^6.6.1", "eslint-plugin-react": "^7.30.1", "eslint-plugin-react-hooks": "^4.6.0", - "next": "^14.2.23", "eslint-plugin-storybook": "^0.11.2", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jest-fixed-jsdom": "^0.0.9", "msw": "^2.7.0", "msw-storybook-addon": "^2.0.4", + "next": "^14.2.23", "postcss": "^8.4.29", "postcss-import": "^16.1.0", "postcss-loader": "^7.3.2", @@ -87,8 +96,8 @@ "prettier": "^2.7.1", "storybook": "^8.6.0-alpha.1", "tailwindcss": "^3.4.10", - "ts-jest": "^29.1.2", - "ts-node": "^10.9.1", + "ts-jest": "^29.2.5", + "ts-node": "^10.9.2", "typescript": "^5.6.2" }, "msw": { diff --git a/src/lib/AnalysisApps/SharedUtils/TeamProject/Utils/teamProjectHooks.test.tsx b/src/lib/AnalysisApps/SharedUtils/TeamProject/Utils/teamProjectHooks.test.tsx new file mode 100644 index 0000000..9863f9b --- /dev/null +++ b/src/lib/AnalysisApps/SharedUtils/TeamProject/Utils/teamProjectHooks.test.tsx @@ -0,0 +1,103 @@ +// teamProjectHooks.test.ts +import { waitFor } from '@testing-library/react'; +import { useTeamProjects } from './teamProjectHooks'; +import { + describe, + expect, + it, + beforeAll, + afterAll, + afterEach, + beforeEach, +} from '@jest/globals'; +import { renderHook } from '../../../../test/test-utils'; +import { http, HttpResponse } from 'msw'; +import { setupServer } from 'msw/node'; +import { GEN3_AUTHZ_API } from '@gen3/core'; + +const server = setupServer( + http.get(`${GEN3_AUTHZ_API}/mapping`, () => { + return HttpResponse.json({ + '/gwas_projects/project1': [{ abc: 'def' }], + '/gwas_projects/project2': [ + { abc: 'def' }, + { + service: 'atlas-argo-wrapper-and-cohort-middleware', + method: 'access', + }, + ], + '/other/project3': [{ abc: 'def' }], + }); + }), +); + +describe('useTeamProjects', () => { + beforeAll(() => { + // Start the interception. + server.listen(); + }); + beforeEach(() => {}); + + afterEach(() => { + // Remove any handlers you may have added + // in individual tests (runtime handlers). + server.resetHandlers(); + }); + + afterAll(() => { + // Disable request interception and clean up. + server.close(); + }); + + it('fetches and returns team project roles successfully', async () => { + server.use( + http.get(`${GEN3_AUTHZ_API}/mapping`, () => { + return HttpResponse.json({ + '/gwas_projects/project1': [{ abc: 'def' }], + '/gwas_projects/project2': [ + { abc: 'def' }, + { + service: 'atlas-argo-wrapper-and-cohort-middleware', + method: 'access', + }, + ], + '/other/project3': [{ abc: 'def' }], + }); + }), + ); + + const { result } = renderHook(() => useTeamProjects()); + + expect(result.current.isFetching).toBe(true); + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()); + expect(result.current).toEqual({ + isError: false, + isFetching: false, + isSuccess: true, + teams: [ + { + teamName: '/gwas_projects/project2', + }, + ], + }); + }); + it('fetches and returns isError', async () => { + server.use( + http.get(`${GEN3_AUTHZ_API}/mapping`, () => { + // throw error + return new HttpResponse(null, { status: 500 }); + }), + ); + const { result } = renderHook(() => useTeamProjects()); + expect(result.current.isFetching).toBe(true); + await waitFor(() => expect(result.current.isError).toBeTruthy()); + expect(result.current).toEqual({ + isError: true, + isFetching: false, + isSuccess: false, + teams: [], + error: { status: 500, data: null } + }); + }); +}); diff --git a/src/lib/AnalysisApps/SharedUtils/TeamProject/Utils/teamProjectHooks.ts b/src/lib/AnalysisApps/SharedUtils/TeamProject/Utils/teamProjectHooks.ts new file mode 100644 index 0000000..6513105 --- /dev/null +++ b/src/lib/AnalysisApps/SharedUtils/TeamProject/Utils/teamProjectHooks.ts @@ -0,0 +1,50 @@ +import { useGetAuthzMappingsQuery } from '@gen3/core'; + +interface TeamProject { + teamName: string; +} + + +interface UseTeamProjectsResult { + teams: Array; + isFetching: boolean; + isSuccess: boolean; + isError: boolean; + error?: unknown; +} + +/** + * A hook that retrieves and processes team project data by querying authorization mappings. + * It filters the retrieved data to only include mappings associated with specific services + * under the `/gwas_projects/` path and formats them into a list of team projects. + * + * @returns {UseTeamProjectsResult} An object containing the list of team projects, + * and flags indicating the loading, success, or error state of the data retrieval process. + */ +export const useTeamProjects = (): UseTeamProjectsResult => { + const { + data: authorizationMappings, + isFetching, + isSuccess, + isError, + error, + } = useGetAuthzMappingsQuery(); + + let teams : Array = []; + + if (isSuccess && authorizationMappings) { + const entries = Object.entries(authorizationMappings); + teams = entries + .filter( + ([key, value]) => + key.startsWith('/gwas_projects/') && + Array.isArray(value) && + value.some( + (e) => e.service === 'atlas-argo-wrapper-and-cohort-middleware', + ), + ) + .map(([key]) => ({ teamName: key })); + } + + return { teams : teams, isFetching, isSuccess, isError, error }; +}; diff --git a/src/lib/test/test-utils.tsx b/src/lib/test/test-utils.tsx new file mode 100644 index 0000000..e07a8fe --- /dev/null +++ b/src/lib/test/test-utils.tsx @@ -0,0 +1,55 @@ +import React, { ComponentType, ReactElement } from 'react'; +import { + render, + renderHook, + RenderHookOptions, + RenderHookResult, + RenderOptions, + RenderResult, +} from '@testing-library/react'; +import { CoreProvider, gen3Api, useCoreDispatch } from '@gen3/core'; + + +const ResetCoreProvider = () => { + const dispatch = useCoreDispatch(); + dispatch(gen3Api.util.resetApiState()); + return null; +}; + +/** + * AllTheProviders is a React functional component designed to wrap its children + * components with a CoreProvider. This ensures that the children have access to + * the context or functionality provided by CoreProvider. + * + * @type {React.FC<{ children: React.ReactNode }>} + * @param {object} props - Component properties. + * @param {React.ReactNode} props.children - Any valid React node(s) or component(s) + * that will be wrapped by the CoreProvider. + * + * TODO: Add additional providers + */ +const AllTheProviders: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + return {children}; +}; + +const customRender = ( + ui: ReactElement, + options?: Omit, +): RenderResult => + render(ui, { wrapper: AllTheProviders as ComponentType, ...options }); + +// Custom renderHook wrapper +const customRenderHook = ( + render: (props: Props) => Result, + options?: RenderHookOptions, +): RenderHookResult => { + return renderHook(render, { + wrapper: AllTheProviders as ComponentType, + ...options, + }); +}; + +export * from '@testing-library/react'; +export { customRender as render, customRenderHook as renderHook }; diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..864149f --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", +"compilerOptions": { +"jsx": "react-jsx" +}}