From 5b7db8da2afe4efe2c134bb34b415979e22c41a8 Mon Sep 17 00:00:00 2001 From: kahboom Date: Fri, 29 Nov 2024 13:12:43 +0000 Subject: [PATCH] test(search): extract, add test for filter function --- client/config/jest.config.ts | 24 +- client/jest.setup.ts | 1 - .../{src/app/test-config => }/setupTests.ts | 0 .../pages/search/components/SearchMenu.tsx | 242 ++++++------- .../filterEntityListByValue.test.ts | 317 ++++++++++++++++++ client/src/mocks/fileMock.ts | 1 + client/src/mocks/styleMock.ts | 1 + client/tsconfig.json | 2 +- jest.config.ts | 16 - 9 files changed, 466 insertions(+), 138 deletions(-) delete mode 100644 client/jest.setup.ts rename client/{src/app/test-config => }/setupTests.ts (100%) create mode 100644 client/src/app/pages/search/components/filterEntityListByValue.test.ts create mode 100644 client/src/mocks/fileMock.ts create mode 100644 client/src/mocks/styleMock.ts delete mode 100644 jest.config.ts diff --git a/client/config/jest.config.ts b/client/config/jest.config.ts index 23d6246e..d575a84a 100644 --- a/client/config/jest.config.ts +++ b/client/config/jest.config.ts @@ -13,15 +13,17 @@ const config: JestConfigWithTsJest = { // The directory where Jest should output its coverage files coverageDirectory: "coverage", + moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], + // Stub out resources and provide handling for tsconfig.json paths moduleNameMapper: { // stub out files that don't matter for tests - "\\.(css|less)$": "/__mocks__/styleMock.js", - "\\.(xsd)$": "/__mocks__/styleMock.js", + "\\.(css|less)$": "/src/mocks/styleMock.ts", + "\\.(xsd)$": "/mocks/styleMock.ts", "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": - "/__mocks__/fileMock.js", + "/src/mocks/fileMock.ts", "@patternfly/react-icons/dist/esm/icons/": - "/__mocks__/fileMock.js", + "/src/mocks/fileMock.ts", // match the paths in tsconfig.json "@app/(.*)": "/src/app/$1", @@ -29,11 +31,20 @@ const config: JestConfigWithTsJest = { "../node_modules/@patternfly/react-core/dist/styles/assets/$1", }, + // moduleNameMapper: { + // "^@app/(.*)$": "/client/src/app/$1", + // "^@mocks/(.*)$": "/client/src/mocks/$1", + // }, + // A list of paths to directories that Jest should use to search for files roots: ["/src"], + // Code to set up the testing framework before each test file in the suite is executed + setupFilesAfterEnv: ["/setupTests.ts"], + // The test environment that will be used for testing - testEnvironment: "jest-environment-jsdom", + // testEnvironment: "jest-environment-jsdom", + testEnvironment: "jsdom", // or "node" for non-DOM tests // The pattern or patterns Jest uses to find test files testMatch: ["/src/**/*.{test,spec}.{js,jsx,ts,tsx}"], @@ -42,9 +53,6 @@ const config: JestConfigWithTsJest = { transform: { "^.+\\.(js|mjs|ts|mts)x?$": "ts-jest", }, - - // Code to set up the testing framework before each test file in the suite is executed - setupFilesAfterEnv: ["/src/app/test-config/setupTests.ts"], }; export default config; diff --git a/client/jest.setup.ts b/client/jest.setup.ts deleted file mode 100644 index d0de870d..00000000 --- a/client/jest.setup.ts +++ /dev/null @@ -1 +0,0 @@ -import "@testing-library/jest-dom"; diff --git a/client/src/app/test-config/setupTests.ts b/client/setupTests.ts similarity index 100% rename from client/src/app/test-config/setupTests.ts rename to client/setupTests.ts diff --git a/client/src/app/pages/search/components/SearchMenu.tsx b/client/src/app/pages/search/components/SearchMenu.tsx index 278f3d6f..19091806 100644 --- a/client/src/app/pages/search/components/SearchMenu.tsx +++ b/client/src/app/pages/search/components/SearchMenu.tsx @@ -8,11 +8,12 @@ import { SearchInput, } from "@patternfly/react-core"; import { FILTER_TEXT_CATEGORY_KEY } from "@app/Constants"; -import { VulnerabilitySearchContext } from "@app/pages/vulnerability-list/vulnerability-context"; -import { SbomSearchContext } from "@app/pages/sbom-list/sbom-context"; import { Label } from "@patternfly/react-core"; -import { AdvisorySearchContext } from "@app/pages/advisory-list/advisory-context"; -import { PackageSearchContext } from "@app/pages/package-list/package-context"; +import { useFetchAdvisories } from "@app/queries/advisories"; +import { HubRequestParams } from "@app/api/models"; +import { useFetchPackages } from "@app/queries/packages"; +import { useFetchSBOMs } from "@app/queries/sboms"; +import { useFetchVulnerabilities } from "@app/queries/vulnerabilities"; export interface IEntity { id: string; @@ -32,91 +33,144 @@ export interface IEntity { | undefined; } -function useAllEntities() { - const [entityList, setEntityList] = React.useState([]); +// Filter function +export function filterEntityListByValue(list: IEntity[], searchString: string) { + // When the value of the search input changes, build a list of no more than 10 autocomplete options. + // Options which start with the search input value are listed first, followed by options which contain + // the search input value. + let options: React.JSX.Element[] = list + .filter( + (option) => + option.id.toLowerCase().startsWith(searchString.toLowerCase()) || + option.title?.toLowerCase().startsWith(searchString.toLowerCase()) || + option.description?.toLowerCase().startsWith(searchString.toLowerCase()) + ) + .map((option) => ( + + {option.title} + + )); + + if (options.length > 10) { + options = options.slice(0, 10); + } else { + options = [ + ...options, + ...list + .filter( + (option: IEntity) => + !option.id.startsWith(searchString.toLowerCase()) && + option.id.includes(searchString.toLowerCase()) + ) + .map((option: IEntity) => ( + + {option.title} + + )), + ].slice(0, 10); + } + + return options; +} + +function useAllEntities(filterText: string) { + const params: HubRequestParams = { + filters: [ + { field: FILTER_TEXT_CATEGORY_KEY, operator: "~", value: filterText }, + ], + page: { pageNumber: 1, itemsPerPage: 10 }, + }; const { - tableControls: { currentPageItems: advisories }, - } = React.useContext(AdvisorySearchContext); + result: { data: advisories }, + } = useFetchAdvisories({ ...params }); const { - tableControls: { currentPageItems: packages }, - } = React.useContext(PackageSearchContext); + result: { data: packages }, + } = useFetchPackages({ ...params }); const { - tableControls: { currentPageItems: sboms, filterState: sbomFilterState }, - } = React.useContext(SbomSearchContext); + result: { data: sboms }, + } = useFetchSBOMs({ ...params }); const { - tableControls: { currentPageItems: vulnerabilities }, - } = React.useContext(VulnerabilitySearchContext); + result: { data: vulnerabilities }, + } = useFetchVulnerabilities({ ...params }); + + const tmpArray: IEntity[] = []; + + const transformedAdvisories: IEntity[] = advisories.map((item) => ({ + id: item.identifier, + title: item.identifier, + description: item.title?.substring(0, 75), + navLink: `/advisories/${item.uuid}`, + type: "Advisory", + typeColor: "blue", + })); + + const transformedPackages: IEntity[] = packages.map((item) => ({ + id: item.uuid, + title: "item.decomposedPurl ? item.decomposedPurl?.name : item.purl", + description: "item.decomposedPurl?.namespace", + navLink: `/packages/${item.uuid}`, + type: "Package", + typeColor: "cyan", + })); + + const transformedSboms: IEntity[] = sboms.map((item) => ({ + id: item.id, + title: item.name, + description: item.authors.join(", "), + navLink: `/sboms/${item.id}`, + type: "SBOM", + typeColor: "purple", + })); + + const transformedVulnerabilities: IEntity[] = vulnerabilities.map((item) => ({ + id: item.identifier, + title: item.identifier, + description: item.description?.substring(0, 75), + navLink: `/vulnerabilities/${item.identifier}`, + type: "CVE", + typeColor: "orange", + })); + + tmpArray.push( + ...transformedAdvisories, + ...transformedPackages, + ...transformedSboms, + ...transformedVulnerabilities + ); - React.useEffect(() => { - function fetchAllEntities() { - const tmpArray: IEntity[] = []; - - const transformedAdvisories: IEntity[] = advisories.map((item) => ({ - id: item.identifier, - title: item.identifier, - description: item.title?.substring(0, 75), - navLink: `/advisories/${item.uuid}`, - type: "Advisory", - typeColor: "blue", - })); - - const transformedPackages: IEntity[] = packages.map((item) => ({ - id: item.uuid, - title: item.decomposedPurl ? item.decomposedPurl?.name : item.purl, - description: item.decomposedPurl?.namespace, - navLink: `/packages/${item.uuid}`, - type: "Package", - typeColor: "cyan", - })); - - const transformedSboms: IEntity[] = sboms.map((item) => ({ - id: item.id, - title: item.name, - description: item.authors.join(", "), - navLink: `/sboms/${item.id}`, - type: "SBOM", - typeColor: "purple", - })); - - const transformedVulnerabilities: IEntity[] = vulnerabilities.map( - (item) => ({ - id: item.identifier, - title: item.identifier, - description: item.description?.substring(0, 75), - navLink: `/vulnerabilities/${item.identifier}`, - type: "CVE", - typeColor: "orange", - }) - ); - - tmpArray.push( - ...transformedAdvisories, - ...transformedPackages, - ...transformedSboms, - ...transformedVulnerabilities - ); - setEntityList(tmpArray); - } - // fetch on load - fetchAllEntities(); - }, [advisories, packages, sboms, vulnerabilities]); return { - list: entityList, - defaultValue: - sbomFilterState.filterValues[FILTER_TEXT_CATEGORY_KEY]?.[0] || "", + list: tmpArray, + defaultValue: "", }; } export interface ISearchMenu { + filterFunction?: ( + list: IEntity[], + searchString: string + ) => React.JSX.Element[]; onChangeSearch: (searchValue: string | undefined) => void; } -export const SearchMenu: React.FC = ({ onChangeSearch }) => { - const { list: entityList, defaultValue } = useAllEntities(); +export const SearchMenu: React.FC = ({ + filterFunction = filterEntityListByValue, + onChangeSearch, +}) => { + const { list: entityList, defaultValue } = useAllEntities(""); const [searchValue, setSearchValue] = React.useState( defaultValue @@ -139,45 +193,10 @@ export const SearchMenu: React.FC = ({ onChangeSearch }) => { ) { setIsAutocompleteOpen(true); - // When the value of the search input changes, build a list of no more than 10 autocomplete options. - // Options which start with the search input value are listed first, followed by options which contain - // the search input value. - let options: React.JSX.Element[] = entityList - .filter( - (option) => - option.id.toLowerCase().startsWith(newValue.toLowerCase()) || - option.title?.toLowerCase().startsWith(newValue.toLowerCase()) || - option.description?.toLowerCase().startsWith(newValue.toLowerCase()) - ) - .map((option) => ( - - {option.title} - - )); - - if (options.length > 10) { - options = options.slice(0, 10); - } else { - options = [ - ...options, - ...entityList - .filter( - (option: IEntity) => - !option.id.startsWith(newValue.toLowerCase()) && - option.id.includes(newValue.toLowerCase()) - ) - .map((option: IEntity) => ( - - {option.id} - - )), - ].slice(0, 10); - } + console.table(entityList); + console.log(newValue); + const options = filterFunction(entityList, newValue); + console.log(options); // The menu is hidden if there are no options setIsAutocompleteOpen(options.length > 0); @@ -191,7 +210,6 @@ export const SearchMenu: React.FC = ({ onChangeSearch }) => { const onClearSearchValue = () => { setSearchValue(""); - onChangeSearch(""); }; const onSubmitInput = () => { diff --git a/client/src/app/pages/search/components/filterEntityListByValue.test.ts b/client/src/app/pages/search/components/filterEntityListByValue.test.ts new file mode 100644 index 00000000..d7e29740 --- /dev/null +++ b/client/src/app/pages/search/components/filterEntityListByValue.test.ts @@ -0,0 +1,317 @@ +import { filterEntityListByValue, IEntity } from "./SearchMenu"; + +const arrayList: IEntity[] = [ + { + id: "CVE-2023-24815", + title: "CVE-2023-24815", + description: + "Disclosure of classpath resources on Windows when mounted on a wildcard rou", + navLink: "/advisories/urn:uuid:d30fc342-ee13-4711-9b5d-43c5d9ea7fd3", + type: "Advisory", + typeColor: "blue", + }, + { + id: "CVE-2023-34454", + title: "CVE-2023-34454", + description: + "snappy-java's Integer Overflow vulnerability in compress leads to DoS", + navLink: "/advisories/urn:uuid:e2534aa1-b631-4066-9eee-7c33aa23d634", + type: "Advisory", + typeColor: "blue", + }, + { + id: "CVE-2023-26464", + title: "CVE-2023-26464", + description: + "Apache Log4j 1.x (EOL) allows DoS in Chainsaw and SocketAppender", + navLink: "/advisories/urn:uuid:8a456db4-2e8f-4ed4-a427-178161a94a9b", + type: "Advisory", + typeColor: "blue", + }, + { + id: "CVE-2023-20862", + title: "CVE-2023-20862", + description: + "In Spring Security, versions 5.7.x prior to 5.7.8, versions 5.8.x prior to ", + navLink: "/advisories/urn:uuid:4f5ccdd5-3176-4fb7-844d-34a7f1419938", + type: "Advisory", + typeColor: "blue", + }, + { + id: "https://www.redhat.com/#CVE-2023-1108", + title: "https://www.redhat.com/#CVE-2023-1108", + description: "Undertow: Infinite loop in SslConduit during close", + navLink: "/advisories/urn:uuid:4af3ac1c-fa69-45e4-a2af-7886e0ec8300", + type: "Advisory", + typeColor: "blue", + }, + { + id: "CVE-2023-0481", + title: "CVE-2023-0481", + description: + "In RestEasy Reactive implementation of Quarkus the insecure File.createTemp", + navLink: "/advisories/urn:uuid:671dd85b-409f-4509-9a50-c4b2404ac10a", + type: "Advisory", + typeColor: "blue", + }, + { + id: "CVE-2023-20861", + title: "CVE-2023-20861", + description: + "In Spring Framework versions 6.0.0 - 6.0.6, 5.3.0 - 5.3.25, 5.2.0.RELEASE -", + navLink: "/advisories/urn:uuid:b3c691ea-96e8-4b3b-b9ef-ee7a5ec85a24", + type: "Advisory", + typeColor: "blue", + }, + { + id: "CVE-2023-4853", + title: "CVE-2023-4853", + description: "Quarkus: http security policy bypass", + navLink: "/advisories/urn:uuid:58eec6a5-f0db-4eab-a7d9-67ca5f2595f5", + type: "Advisory", + typeColor: "blue", + }, + { + id: "https://www.redhat.com/#CVE-2023-33201", + title: "https://www.redhat.com/#CVE-2023-33201", + description: + "bouncycastle: potential blind LDAP injection attack using a self-signed ce", + navLink: "/advisories/urn:uuid:84ac3e13-0a96-4c3b-9a89-6db277957ca2", + type: "Advisory", + typeColor: "blue", + }, + { + id: "https://www.redhat.com/#CVE-2023-4853", + title: "https://www.redhat.com/#CVE-2023-4853", + description: "quarkus: HTTP security policy bypass", + navLink: "/advisories/urn:uuid:e116bbd2-840e-4254-9f5c-6f77dd7b1877", + type: "Advisory", + typeColor: "blue", + }, + { + id: "2e05fb3a-cda9-5e54-96b2-d8c7ea390f8d", + title: "item.decomposedPurl ? item.decomposedPurl?.name : item.purl", + description: "item.decomposedPurl?.namespace", + navLink: "/packages/2e05fb3a-cda9-5e54-96b2-d8c7ea390f8d", + type: "Package", + typeColor: "cyan", + }, + { + id: "e0b74cfd-e0b0-512b-8814-947f868bc50e", + title: "item.decomposedPurl ? item.decomposedPurl?.name : item.purl", + description: "item.decomposedPurl?.namespace", + navLink: "/packages/e0b74cfd-e0b0-512b-8814-947f868bc50e", + type: "Package", + typeColor: "cyan", + }, + { + id: "f4f6b460-82e5-59f0-a7f6-da5f226a9b24", + title: "item.decomposedPurl ? item.decomposedPurl?.name : item.purl", + description: "item.decomposedPurl?.namespace", + navLink: "/packages/f4f6b460-82e5-59f0-a7f6-da5f226a9b24", + type: "Package", + typeColor: "cyan", + }, + { + id: "f357b0cc-75d5-532e-b7d9-2233f6f752c8", + title: "item.decomposedPurl ? item.decomposedPurl?.name : item.purl", + description: "item.decomposedPurl?.namespace", + navLink: "/packages/f357b0cc-75d5-532e-b7d9-2233f6f752c8", + type: "Package", + typeColor: "cyan", + }, + { + id: "b9a43108-525d-59ea-bc31-ff217d4c7925", + title: "item.decomposedPurl ? item.decomposedPurl?.name : item.purl", + description: "item.decomposedPurl?.namespace", + navLink: "/packages/b9a43108-525d-59ea-bc31-ff217d4c7925", + type: "Package", + typeColor: "cyan", + }, + { + id: "d6dea366-e8a6-5500-9aef-14464b717295", + title: "item.decomposedPurl ? item.decomposedPurl?.name : item.purl", + description: "item.decomposedPurl?.namespace", + navLink: "/packages/d6dea366-e8a6-5500-9aef-14464b717295", + type: "Package", + typeColor: "cyan", + }, + { + id: "14c5c61d-c4cc-56fb-9db6-f62541076b80", + title: "item.decomposedPurl ? item.decomposedPurl?.name : item.purl", + description: "item.decomposedPurl?.namespace", + navLink: "/packages/14c5c61d-c4cc-56fb-9db6-f62541076b80", + type: "Package", + typeColor: "cyan", + }, + { + id: "25ddc770-5fde-53a8-8451-41091d5fcb3b", + title: "item.decomposedPurl ? item.decomposedPurl?.name : item.purl", + description: "item.decomposedPurl?.namespace", + navLink: "/packages/25ddc770-5fde-53a8-8451-41091d5fcb3b", + type: "Package", + typeColor: "cyan", + }, + { + id: "62c9cfab-997b-5126-ad5c-90bc277e048f", + title: "item.decomposedPurl ? item.decomposedPurl?.name : item.purl", + description: "item.decomposedPurl?.namespace", + navLink: "/packages/62c9cfab-997b-5126-ad5c-90bc277e048f", + type: "Package", + typeColor: "cyan", + }, + { + id: "81293bba-1ab5-5524-8444-0bd55d19b9b3", + title: "item.decomposedPurl ? item.decomposedPurl?.name : item.purl", + description: "item.decomposedPurl?.namespace", + navLink: "/packages/81293bba-1ab5-5524-8444-0bd55d19b9b3", + type: "Package", + typeColor: "cyan", + }, + { + id: "urn:uuid:01932ff3-0f06-74e0-b673-f92bac24a6b0", + title: "ubi8-micro-container", + description: "Organization: Red Hat Product Security (secalert@redhat.com)", + navLink: "/sboms/urn:uuid:01932ff3-0f06-74e0-b673-f92bac24a6b0", + type: "SBOM", + typeColor: "purple", + }, + { + id: "urn:uuid:01932ff3-0f90-7e51-9c9d-1fac54a371f3", + title: "ubi9-minimal-container", + description: "Organization: Red Hat Product Security (secalert@redhat.com)", + navLink: "/sboms/urn:uuid:01932ff3-0f90-7e51-9c9d-1fac54a371f3", + type: "SBOM", + typeColor: "purple", + }, + { + id: "urn:uuid:01932ff3-0f91-7543-af38-c399c1e9a923", + title: "ubi8-minimal-container", + description: "Organization: Red Hat Product Security (secalert@redhat.com)", + navLink: "/sboms/urn:uuid:01932ff3-0f91-7543-af38-c399c1e9a923", + type: "SBOM", + typeColor: "purple", + }, + { + id: "urn:uuid:01932ff3-0fbc-7b82-b9c2-18044dbbb574", + title: "ubi9-container", + description: "Organization: Red Hat Product Security (secalert@redhat.com)", + navLink: "/sboms/urn:uuid:01932ff3-0fbc-7b82-b9c2-18044dbbb574", + type: "SBOM", + typeColor: "purple", + }, + { + id: "urn:uuid:01932ff3-0fc4-7bf2-8201-5d5e9dc471bd", + title: "ubi8-container", + description: "Organization: Red Hat Product Security (secalert@redhat.com)", + navLink: "/sboms/urn:uuid:01932ff3-0fc4-7bf2-8201-5d5e9dc471bd", + type: "SBOM", + typeColor: "purple", + }, + { + id: "urn:uuid:01932ff3-0fe1-7ca0-8ba6-c26de2fe81d9", + title: "quarkus-bom", + description: "Organization: Red Hat Product Security (secalert@redhat.com)", + navLink: "/sboms/urn:uuid:01932ff3-0fe1-7ca0-8ba6-c26de2fe81d9", + type: "SBOM", + typeColor: "purple", + }, + { + id: "CVE-2022-45787", + title: "CVE-2022-45787", + description: + "Unproper laxist permissions on the temporary files used by MIME4J TempFileS", + navLink: "/vulnerabilities/CVE-2022-45787", + type: "CVE", + typeColor: "orange", + }, + { + id: "CVE-2023-0044", + title: "CVE-2023-0044", + description: + "If the Quarkus Form Authentication session cookie Path attribute is set to ", + navLink: "/vulnerabilities/CVE-2023-0044", + type: "CVE", + typeColor: "orange", + }, + { + id: "CVE-2023-0481", + title: "CVE-2023-0481", + description: + "In RestEasy Reactive implementation of Quarkus the insecure File.createTemp", + navLink: "/vulnerabilities/CVE-2023-0481", + type: "CVE", + typeColor: "orange", + }, + { + id: "CVE-2023-0482", + title: "CVE-2023-0482", + description: + "In RESTEasy the insecure File.createTempFile() is used in the DataSourcePro", + navLink: "/vulnerabilities/CVE-2023-0482", + type: "CVE", + typeColor: "orange", + }, + { + id: "CVE-2023-1108", + title: "CVE-2023-1108", + description: + "A flaw was found in undertow. This issue makes achieving a denial of servic", + navLink: "/vulnerabilities/CVE-2023-1108", + type: "CVE", + typeColor: "orange", + }, + { + id: "CVE-2023-1370", + title: "CVE-2023-1370", + description: + "[Json-smart](https://netplex.github.io/json-smart/) is a performance focuse", + navLink: "/vulnerabilities/CVE-2023-1370", + type: "CVE", + typeColor: "orange", + }, + { + id: "CVE-2023-1436", + title: "CVE-2023-1436", + description: + "An infinite recursion is triggered in Jettison when constructing a JSONArra", + navLink: "/vulnerabilities/CVE-2023-1436", + type: "CVE", + typeColor: "orange", + }, + { + id: "CVE-2023-1584", + title: "CVE-2023-1584", + description: + "A flaw was found in Quarkus. Quarkus OIDC can leak both ID and access token", + navLink: "/vulnerabilities/CVE-2023-1584", + type: "CVE", + typeColor: "orange", + }, + { + id: "CVE-2023-1664", + title: "CVE-2023-1664", + description: + "A flaw was found in Keycloak. This flaw depends on a non-default configurat", + navLink: "/vulnerabilities/CVE-2023-1664", + type: "CVE", + typeColor: "orange", + }, + { + id: "CVE-2023-20860", + title: "CVE-2023-20860", + description: + 'Spring Framework running version 6.0.0 - 6.0.6 or 5.3.0 - 5.3.25 using "**"', + navLink: "/vulnerabilities/CVE-2023-20860", + type: "CVE", + typeColor: "orange", + }, +]; + +describe("filterEntityListByValue", () => { + it("builds an array of elements based on string provided", () => { + const searchString = "quarkus"; + const result = filterEntityListByValue(arrayList, searchString); + expect(result).toHaveLength(3); + }); +}); diff --git a/client/src/mocks/fileMock.ts b/client/src/mocks/fileMock.ts new file mode 100644 index 00000000..0a445d06 --- /dev/null +++ b/client/src/mocks/fileMock.ts @@ -0,0 +1 @@ +module.exports = "test-file-stub"; diff --git a/client/src/mocks/styleMock.ts b/client/src/mocks/styleMock.ts new file mode 100644 index 00000000..f053ebf7 --- /dev/null +++ b/client/src/mocks/styleMock.ts @@ -0,0 +1 @@ +module.exports = {}; diff --git a/client/tsconfig.json b/client/tsconfig.json index 38dd6ff4..c2d176d5 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/tsconfig", - "include": ["src/**/*", "config/**/*", "types/**/*"], + "include": ["src/**/*", "config/**/*", "types/**/*", "setupTests.ts"], "compilerOptions": { "outDir": "dist", "baseUrl": ".", diff --git a/jest.config.ts b/jest.config.ts deleted file mode 100644 index 2434a88b..00000000 --- a/jest.config.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { Config } from "jest"; - -const config: Config = { - testEnvironment: "jsdom", // or "node" for non-DOM tests - setupFilesAfterEnv: ["/jest.setup.ts"], - moduleNameMapper: { - "^@app/(.*)$": "/client/src/app/$1", - "^@mocks/(.*)$": "/client/src/mocks/$1", - }, - transform: { - "^.+\\.[t|j]sx?$": "ts-jest", // Use ts-jest for TypeScript files - }, - moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], -}; - -export default config;