From 412c54ccaea1e028018f9304e0c76705a89890d2 Mon Sep 17 00:00:00 2001 From: Jermaine Date: Thu, 20 Jun 2024 14:43:18 +0200 Subject: [PATCH] Adding tests for mytokens page (#2290) * Adding tests for mytokens page * Moved tests for pages to separate folder * Updated coverage thresholds --- .../apps/marmalade-marketplace/package.json | 3 +- .../src/__tests__/pages/mytokens.test.tsx | 103 ++++++++++++++++++ .../components/Badge/__tests__/badge.test.tsx | 2 +- .../src/pages/mytokens/index.tsx | 2 - .../apps/marmalade-marketplace/tsconfig.json | 2 +- .../marmalade-marketplace/vitest-globals.ts | 3 - .../marmalade-marketplace/vitest.config.ts | 49 ++++----- pnpm-lock.yaml | 48 +++----- 8 files changed, 145 insertions(+), 67 deletions(-) create mode 100644 packages/apps/marmalade-marketplace/src/__tests__/pages/mytokens.test.tsx delete mode 100644 packages/apps/marmalade-marketplace/vitest-globals.ts diff --git a/packages/apps/marmalade-marketplace/package.json b/packages/apps/marmalade-marketplace/package.json index e40df605e8..6372eebb24 100644 --- a/packages/apps/marmalade-marketplace/package.json +++ b/packages/apps/marmalade-marketplace/package.json @@ -34,6 +34,7 @@ "@types/node": "^20.12.7", "@types/node-cron": "^3.0.11", "@types/react": "^18.2.79", + "@types/react-dom": "^18.2.25", "@types/webpack-env": "^1.18.5", "@vanilla-extract/css": "1.14.2", "@vanilla-extract/next-plugin": "2.4.0", @@ -41,7 +42,7 @@ "@vitejs/plugin-react": "^4.3.1", "@vitest/coverage-v8": "^1.6.0", "dotenv": "~16.4.5", - "jsdom": "^22.1.0", + "happy-dom": "^12.9.1", "next-router-mock": "^0.9.10", "node-cron": "^3.0.3", "ts-node": "~10.9.2", diff --git a/packages/apps/marmalade-marketplace/src/__tests__/pages/mytokens.test.tsx b/packages/apps/marmalade-marketplace/src/__tests__/pages/mytokens.test.tsx new file mode 100644 index 0000000000..178447f123 --- /dev/null +++ b/packages/apps/marmalade-marketplace/src/__tests__/pages/mytokens.test.tsx @@ -0,0 +1,103 @@ +import { expect, test } from 'vitest' +import { render, screen, waitFor } from '@testing-library/react'; +import { useAccount } from '@/hooks/account'; +import { getTokens } from '@/graphql/queries/client'; +import MyTokens from '@/pages/mytokens' + +// Mocking the custom hooks and functions +vi.mock('@/hooks/account'); +vi.mock('@/graphql/queries/client'); + +const mockUseAccount = vi.mocked(useAccount); +const mockGetTokens = vi.mocked(getTokens); + +// Mocking the Token component +vi.mock('@/components/Token', () => ({ + Token: ({ tokenId }: { tokenId: string }) =>
{tokenId}
, +})); + +const dummyAccountContext = { + account: null, + isMounted: false, + login: () => {}, + logout: () => {}, +}; + +describe('MyTokens component', () => { + beforeEach(() => { + // Clear all mocks before each test + vi.clearAllMocks(); + }); + + test('renders the component and fetches tokens', async () => { + const mockAccount = { + accountName: 'test-account', + alias: 'test-alias', + pendingTxIds: [], + credentials: [] + }; + + const mockAccountContext = { ...dummyAccountContext, account: mockAccount }; + + const mockTokens = [ + { accountName: 'test-account', balance: 15, tokenId: '1', chainId: '1' }, + { accountName: 'test-account', balance: 1, tokenId: '2', chainId: '1' }, + ]; + + mockUseAccount.mockReturnValue(mockAccountContext); + mockGetTokens.mockResolvedValue(mockTokens); + + render(); + + // Check if the title is rendered + expect(screen.getByText('My Tokens')).toBeInTheDocument(); + + // Check if tokens are fetched and displayed + await waitFor(() => { + mockTokens.forEach(token => { + expect(screen.getByText(token.tokenId)).toBeInTheDocument(); + }); + }); + }); + + test('displays "No tokens found" when there are no tokens', async () => { + const mockAccount = { + accountName: 'test-account', + alias: 'test-alias', + pendingTxIds: [], + credentials: [] + }; + const mockTokens: any[] = []; + const mockAccountContext = { ...dummyAccountContext, account: mockAccount }; + + mockUseAccount.mockReturnValue(mockAccountContext); + mockGetTokens.mockResolvedValue(mockTokens); + + render(); + + // Check if the title is rendered + expect(screen.getByText('My Tokens')).toBeInTheDocument(); + + // Check if "No tokens found" is displayed + await waitFor(() => { + expect(screen.getByText('No tokens found')).toBeInTheDocument(); + }); + }); + + test('does not fetch tokens if account name is not provided', async () => { + const mockAccountContext = { ...dummyAccountContext, account: undefined }; + mockUseAccount.mockReturnValue(mockAccountContext); + render(); + + // Check if the title is rendered + expect(screen.getByText('My Tokens')).toBeInTheDocument(); + + // Ensure getTokens is not called + await waitFor(() => { + expect(mockGetTokens).not.toHaveBeenCalled(); + }); + + // Check if "No tokens found" is displayed + expect(screen.getByText('No tokens found')).toBeInTheDocument(); + }); +}); \ No newline at end of file diff --git a/packages/apps/marmalade-marketplace/src/components/Badge/__tests__/badge.test.tsx b/packages/apps/marmalade-marketplace/src/components/Badge/__tests__/badge.test.tsx index d1142ba3f0..690c60175b 100644 --- a/packages/apps/marmalade-marketplace/src/components/Badge/__tests__/badge.test.tsx +++ b/packages/apps/marmalade-marketplace/src/components/Badge/__tests__/badge.test.tsx @@ -2,7 +2,7 @@ import { expect, test } from 'vitest' import { render, screen } from '@testing-library/react' import { Badge } from '../' -test('Page', () => { +test('Badge', () => { render() expect(screen.getAllByText('Test Label')).toBeDefined() }) \ No newline at end of file diff --git a/packages/apps/marmalade-marketplace/src/pages/mytokens/index.tsx b/packages/apps/marmalade-marketplace/src/pages/mytokens/index.tsx index 97b44c168f..9267c4a7c9 100644 --- a/packages/apps/marmalade-marketplace/src/pages/mytokens/index.tsx +++ b/packages/apps/marmalade-marketplace/src/pages/mytokens/index.tsx @@ -9,8 +9,6 @@ export default function MyTokens() { const [tokens, setTokens] = useState>([]); const { account } = useAccount(); - console.log(tokens) - const fetchTokens = async (accountName?:string) => { if (!accountName) return; const tokens = await getTokens(accountName); diff --git a/packages/apps/marmalade-marketplace/tsconfig.json b/packages/apps/marmalade-marketplace/tsconfig.json index 151f5197f1..617b6946f8 100644 --- a/packages/apps/marmalade-marketplace/tsconfig.json +++ b/packages/apps/marmalade-marketplace/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "./node_modules/@kadena-dev/shared-config/tsconfig-base.json", "compilerOptions": { - "types": ["node", "vitest/globals"], + "types": ["node", "vitest/globals", "vitest-dom/extend-expect"], "rootDir": ".", "baseUrl": ".", "target": "ES2020", diff --git a/packages/apps/marmalade-marketplace/vitest-globals.ts b/packages/apps/marmalade-marketplace/vitest-globals.ts deleted file mode 100644 index dd2715dc22..0000000000 --- a/packages/apps/marmalade-marketplace/vitest-globals.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const setup = () => { - process.env.TZ = 'UTC'; -}; \ No newline at end of file diff --git a/packages/apps/marmalade-marketplace/vitest.config.ts b/packages/apps/marmalade-marketplace/vitest.config.ts index 87fc93b111..418b5cf093 100644 --- a/packages/apps/marmalade-marketplace/vitest.config.ts +++ b/packages/apps/marmalade-marketplace/vitest.config.ts @@ -1,32 +1,29 @@ +import react from '@vitejs/plugin-react' import baseConfig from '@kadena-dev/shared-config/vitest.config'; -import { defineConfig, mergeConfig } from 'vitest/config' import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'; -import react from '@vitejs/plugin-react' +import { defineConfig, mergeConfig } from 'vitest/config' -export default mergeConfig( - baseConfig, - defineConfig({ - plugins: [react(), vanillaExtractPlugin()], - test: { - globals: true, - globalSetup: './vitest-globals.ts', - setupFiles: ['vitest.setup.ts'], - environment: 'jsdom', - coverage: { - provider: 'v8', - thresholds: { - lines: 1, - functions: 3, - branches: 3, - statements: 1, - autoUpdate: false - }, +const localConfig = defineConfig({ + plugins: [react(), vanillaExtractPlugin()], + test: { + globals: true, + setupFiles: ['vitest.setup.ts'], + environment: 'happy-dom', + coverage: { + thresholds: { + lines: 10, + functions: 8, + branches: 25, + statements: 10, + autoUpdate: false }, }, - resolve: { - alias: { - '@': '/src', - }, + }, + resolve: { + alias: { + '@': '/src', }, - }) -) \ No newline at end of file + }, +}) + +export default mergeConfig(baseConfig, localConfig); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9d13e98116..cd1cdc5484 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -167,7 +167,7 @@ importers: version: 4.2.1(typescript@5.4.5)(vite@5.2.12) vitest: specifier: ^1.6.0 - version: 1.6.0(@types/node@20.12.7)(happy-dom@12.9.1) + version: 1.6.0(@types/node@20.12.7)(jsdom@22.1.0) packages/apps/dev-wallet-desktop: dependencies: @@ -837,6 +837,9 @@ importers: '@types/react': specifier: ^18.2.79 version: 18.2.79 + '@types/react-dom': + specifier: ^18.2.25 + version: 18.2.25 '@types/webpack-env': specifier: ^1.18.5 version: 1.18.5 @@ -858,9 +861,9 @@ importers: dotenv: specifier: ~16.4.5 version: 16.4.5 - jsdom: - specifier: ^22.1.0 - version: 22.1.0 + happy-dom: + specifier: ^12.9.1 + version: 12.9.1 next-router-mock: specifier: ^0.9.10 version: 0.9.10(next@14.2.2)(react@18.2.0) @@ -872,7 +875,7 @@ importers: version: 10.9.2(@types/node@20.12.7)(typescript@5.4.5) vitest: specifier: ^1.6.0 - version: 1.6.0(@types/node@20.12.7)(jsdom@22.1.0) + version: 1.6.0(@types/node@20.12.7)(happy-dom@12.9.1) vitest-dom: specifier: ^0.1.1 version: 0.1.1(vitest@1.6.0) @@ -2143,7 +2146,7 @@ importers: version: link:../pactjs vitest: specifier: ^1.6.0 - version: 1.6.0(@types/node@20.12.7)(happy-dom@12.9.1) + version: 1.6.0(@types/node@20.12.7)(jsdom@22.1.0) webpack: specifier: ~5.88.2 version: 5.88.2(webpack-cli@4.9.2) @@ -3212,7 +3215,7 @@ importers: version: 4.2.1(typescript@5.4.5)(vite@5.2.12) vitest: specifier: ^1.6.0 - version: 1.6.0(@types/node@20.12.7)(happy-dom@12.9.1) + version: 1.6.0(@types/node@20.12.7)(jsdom@22.1.0) packages: @@ -14915,8 +14918,8 @@ packages: /@types/babel__core@7.20.5: resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} dependencies: - '@babel/parser': 7.24.6 - '@babel/types': 7.24.0 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.20.1 @@ -17045,7 +17048,6 @@ packages: /abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} deprecated: Use your platform's native atob() and btoa() methods instead - dev: true /abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -19138,6 +19140,7 @@ packages: /css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + dev: true /cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} @@ -19221,7 +19224,6 @@ packages: engines: {node: '>=14'} dependencies: rrweb-cssom: 0.6.0 - dev: true /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} @@ -19570,7 +19572,6 @@ packages: abab: 2.0.6 whatwg-mimetype: 3.0.0 whatwg-url: 12.0.1 - dev: true /data-view-buffer@1.0.1: resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} @@ -19658,7 +19659,6 @@ packages: /decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - dev: true /decko@1.2.0: resolution: {integrity: sha512-m8FnyHXV1QX+S1cl+KPFDIl6NMkxtKsy6+U/aYyjrOqWMuwAwYWu7ePqrsUHtDR5Y8Yk2pi/KIDSgF+vT4cPOQ==} @@ -20024,7 +20024,6 @@ packages: deprecated: Use your platform's native DOMException instead dependencies: webidl-conversions: 7.0.0 - dev: true /domhandler@4.3.1: resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} @@ -21932,7 +21931,6 @@ packages: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - dev: true /format@0.2.2: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} @@ -22706,6 +22704,7 @@ packages: webidl-conversions: 7.0.0 whatwg-encoding: 2.0.0 whatwg-mimetype: 3.0.0 + dev: true /hard-rejection@2.1.0: resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} @@ -22945,7 +22944,6 @@ packages: engines: {node: '>=12'} dependencies: whatwg-encoding: 2.0.0 - dev: true /html-entities@2.4.0: resolution: {integrity: sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==} @@ -23855,7 +23853,6 @@ packages: /is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - dev: true /is-reference@1.2.1: resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} @@ -24376,7 +24373,6 @@ packages: - bufferutil - supports-color - utf-8-validate - dev: true /jsesc@0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} @@ -27312,7 +27308,6 @@ packages: /nwsapi@2.2.7: resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} - dev: true /nypm@0.3.3: resolution: {integrity: sha512-FHoxtTscAE723e80d2M9cJRb4YVjL82Ra+ZV+YqC6rfNZUWahi+ZhPF+krnR+bdMvibsfHCtgKXnZf5R6kmEPA==} @@ -28975,7 +28970,6 @@ packages: /psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - dev: true /pump@2.0.1: resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} @@ -29060,7 +29054,6 @@ packages: /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - dev: true /queue-lit@1.5.0: resolution: {integrity: sha512-IslToJ4eiCEE9xwMzq3viOO5nH8sUWUCwoElrhNMozzr9IIt2qqvB4I+uHu/zJTQVqc9R5DFwok4ijNK1pU3fA==} @@ -30382,7 +30375,6 @@ packages: /rrweb-cssom@0.6.0: resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} - dev: true /rtl-css-js@1.16.1: resolution: {integrity: sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==} @@ -30490,7 +30482,6 @@ packages: engines: {node: '>=v12.22.7'} dependencies: xmlchars: 2.2.0 - dev: true /scan-directory@1.0.0: resolution: {integrity: sha512-StSp3ahu7EE1oqVfemF9nV7DVusIaVRuZVa4CZX5rzCUwspqO21wWdNshxZuFIQD7zj/HvvglBoycIizZbTBdw==} @@ -31662,7 +31653,6 @@ packages: /symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - dev: true /synckit@0.8.5: resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==} @@ -32076,7 +32066,6 @@ packages: punycode: 2.3.0 universalify: 0.2.0 url-parse: 1.5.10 - dev: true /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -32086,7 +32075,6 @@ packages: engines: {node: '>=14'} dependencies: punycode: 2.3.0 - dev: true /tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} @@ -32916,7 +32904,6 @@ packages: /universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} - dev: true /universalify@2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} @@ -33022,7 +33009,6 @@ packages: dependencies: querystringify: 2.2.0 requires-port: 1.0.0 - dev: true /url-template@2.0.8: resolution: {integrity: sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==} @@ -33517,6 +33503,7 @@ packages: - sugarss - supports-color - terser + dev: true /vitest@1.6.0(@types/node@20.12.7)(jsdom@22.1.0): resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} @@ -33573,7 +33560,6 @@ packages: - sugarss - supports-color - terser - dev: true /vlq@0.2.3: resolution: {integrity: sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==} @@ -33613,7 +33599,6 @@ packages: engines: {node: '>=14'} dependencies: xml-name-validator: 4.0.0 - dev: true /walk-up-path@3.0.1: resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} @@ -33909,7 +33894,6 @@ packages: dependencies: tr46: 4.1.1 webidl-conversions: 7.0.0 - dev: true /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -34123,7 +34107,6 @@ packages: /xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} - dev: true /xml2js@0.6.2: resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} @@ -34140,7 +34123,6 @@ packages: /xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - dev: true /xmlcreate@2.0.4: resolution: {integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==}