♻️(docs-app) Switch from Jest tests to Vitest
We have migrated the testing framework from Jest to Vitest for the Docs application. This change includes updates to test files, configuration files, and the addition of new setup files for Vitest.
This commit is contained in:
@@ -14,6 +14,7 @@ and this project adheres to
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- ♻️(docs-app) Switch from Jest tests to Vitest #1269
|
||||||
- ⚡️(frontend) improve accessibility:
|
- ⚡️(frontend) improve accessibility:
|
||||||
- #1248
|
- #1248
|
||||||
- #1235
|
- #1235
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
NEXT_PUBLIC_API_ORIGIN=http://test.jest
|
NEXT_PUBLIC_API_ORIGIN=http://test.jest
|
||||||
|
NEXT_PUBLIC_PUBLISH_AS_MIT=false
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
import type { Config } from 'jest';
|
|
||||||
import nextJest from 'next/jest.js';
|
|
||||||
|
|
||||||
const createJestConfig = nextJest({
|
|
||||||
dir: './',
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add any custom config to be passed to Jest
|
|
||||||
const config: Config = {
|
|
||||||
coverageProvider: 'v8',
|
|
||||||
moduleNameMapper: {
|
|
||||||
'^@/docs/(.*)$': '<rootDir>/src/features/docs/$1',
|
|
||||||
'^@/(.*)$': '<rootDir>/src/$1',
|
|
||||||
},
|
|
||||||
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
|
|
||||||
testEnvironment: 'jsdom',
|
|
||||||
};
|
|
||||||
|
|
||||||
const jestConfig = async () => {
|
|
||||||
const nextJestConfig = await createJestConfig(config)();
|
|
||||||
return {
|
|
||||||
...nextJestConfig,
|
|
||||||
moduleNameMapper: {
|
|
||||||
'\\.svg$': '<rootDir>/jest/mocks/svg.js',
|
|
||||||
'^.+\\.svg\\?url$': `<rootDir>/jest/mocks/fileMock.js`,
|
|
||||||
BlockNoteEditor: `<rootDir>/jest/mocks/ComponentMock.js`,
|
|
||||||
'custom-blocks': `<rootDir>/jest/mocks/ComponentMock.js`,
|
|
||||||
...nextJestConfig.moduleNameMapper,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default jestConfig;
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
import '@testing-library/jest-dom';
|
|
||||||
import * as dotenv from 'dotenv';
|
|
||||||
|
|
||||||
dotenv.config({ path: './.env.test' });
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
export const ComponentMock = () => {
|
|
||||||
return <div>My component mocked</div>;
|
|
||||||
};
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
src: '/img.jpg',
|
|
||||||
height: 40,
|
|
||||||
width: 40,
|
|
||||||
blurDataURL: 'data:image/png;base64,imagedata',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (
|
|
||||||
(typeof exports.default === 'function' ||
|
|
||||||
(typeof exports.default === 'object' && exports.default !== null)) &&
|
|
||||||
typeof exports.default.__esModule === 'undefined'
|
|
||||||
) {
|
|
||||||
Object.defineProperty(exports.default, '__esModule', { value: true });
|
|
||||||
Object.assign(exports.default, exports);
|
|
||||||
module.exports = exports.default;
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
const nameMock = 'svg';
|
|
||||||
export default nameMock;
|
|
||||||
export const ReactComponent = 'svg';
|
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
"lint": "tsc --noEmit && next lint",
|
"lint": "tsc --noEmit && next lint",
|
||||||
"prettier": "prettier --write .",
|
"prettier": "prettier --write .",
|
||||||
"stylelint": "stylelint \"**/*.css\"",
|
"stylelint": "stylelint \"**/*.css\"",
|
||||||
"test": "jest",
|
"test": "vitest",
|
||||||
"test:watch": "jest --watch"
|
"test:watch": "vitest --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ag-media/react-pdf-table": "2.0.3",
|
"@ag-media/react-pdf-table": "2.0.3",
|
||||||
@@ -67,24 +67,25 @@
|
|||||||
"@testing-library/jest-dom": "6.6.4",
|
"@testing-library/jest-dom": "6.6.4",
|
||||||
"@testing-library/react": "16.3.0",
|
"@testing-library/react": "16.3.0",
|
||||||
"@testing-library/user-event": "14.6.1",
|
"@testing-library/user-event": "14.6.1",
|
||||||
"@types/jest": "30.0.0",
|
|
||||||
"@types/lodash": "4.17.20",
|
"@types/lodash": "4.17.20",
|
||||||
"@types/luxon": "3.7.1",
|
"@types/luxon": "3.7.1",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"@types/react": "*",
|
"@types/react": "*",
|
||||||
"@types/react-dom": "*",
|
"@types/react-dom": "*",
|
||||||
|
"@vitejs/plugin-react": "4.7.0",
|
||||||
"cross-env": "10.0.0",
|
"cross-env": "10.0.0",
|
||||||
"dotenv": "17.2.1",
|
"dotenv": "17.2.1",
|
||||||
"eslint-config-impress": "*",
|
"eslint-config-impress": "*",
|
||||||
"fetch-mock": "9.11.0",
|
"fetch-mock": "9.11.0",
|
||||||
"jest": "30.0.5",
|
"jsdom": "26.1.0",
|
||||||
"jest-environment-jsdom": "30.0.5",
|
|
||||||
"node-fetch": "2.7.0",
|
"node-fetch": "2.7.0",
|
||||||
"prettier": "3.6.2",
|
"prettier": "3.6.2",
|
||||||
"stylelint": "16.23.0",
|
"stylelint": "16.23.0",
|
||||||
"stylelint-config-standard": "39.0.0",
|
"stylelint-config-standard": "39.0.0",
|
||||||
"stylelint-prettier": "5.0.3",
|
"stylelint-prettier": "5.0.3",
|
||||||
"typescript": "*",
|
"typescript": "*",
|
||||||
|
"vite-tsconfig-paths": "5.1.4",
|
||||||
|
"vitest": "3.2.4",
|
||||||
"webpack": "5.101.0",
|
"webpack": "5.101.0",
|
||||||
"workbox-webpack-plugin": "7.1.0"
|
"workbox-webpack-plugin": "7.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
import { APIError, isAPIError } from '@/api';
|
import { APIError, isAPIError } from '@/api';
|
||||||
|
|
||||||
describe('APIError', () => {
|
describe('APIError', () => {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
import { baseApiUrl } from '@/api';
|
import { baseApiUrl } from '@/api';
|
||||||
|
|
||||||
describe('config', () => {
|
describe('config', () => {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import fetchMock from 'fetch-mock';
|
import fetchMock from 'fetch-mock';
|
||||||
|
import { beforeEach, describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
import { fetchAPI } from '@/api';
|
import { fetchAPI } from '@/api';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
import { renderHook, waitFor } from '@testing-library/react';
|
import { renderHook, waitFor } from '@testing-library/react';
|
||||||
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
import { useAPIInfiniteQuery } from '@/api';
|
import { useAPIInfiniteQuery } from '@/api';
|
||||||
|
|
||||||
@@ -21,8 +22,8 @@ const createWrapper = () => {
|
|||||||
|
|
||||||
describe('helpers', () => {
|
describe('helpers', () => {
|
||||||
it('fetches and paginates correctly', async () => {
|
it('fetches and paginates correctly', async () => {
|
||||||
const mockAPI = jest
|
const mockAPI = vi
|
||||||
.fn<Promise<DummyResponse>, [{ page: number; query: string }]>()
|
.fn<(params: { page: number; query: string }) => Promise<DummyResponse>>()
|
||||||
.mockResolvedValueOnce({
|
.mockResolvedValueOnce({
|
||||||
results: [{ id: 1 }],
|
results: [{ id: 1 }],
|
||||||
next: 'url?page=2',
|
next: 'url?page=2',
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
import { errorCauses, getCSRFToken } from '@/api';
|
import { errorCauses, getCSRFToken } from '@/api';
|
||||||
|
|
||||||
describe('utils', () => {
|
describe('utils', () => {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import '@testing-library/jest-dom';
|
||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
import { Box } from '../Box';
|
import { Box } from '../Box';
|
||||||
|
|||||||
@@ -1,42 +1,28 @@
|
|||||||
import { Crisp } from 'crisp-sdk-web';
|
|
||||||
import fetchMock from 'fetch-mock';
|
import fetchMock from 'fetch-mock';
|
||||||
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
import { gotoLogout } from '../utils';
|
import { gotoLogout } from '../utils';
|
||||||
|
|
||||||
jest.mock('crisp-sdk-web', () => ({
|
// Mock the Crisp service
|
||||||
...jest.requireActual('crisp-sdk-web'),
|
vi.mock('@/services/Crisp', () => ({
|
||||||
Crisp: {
|
terminateCrispSession: vi.fn(),
|
||||||
isCrispInjected: jest.fn().mockReturnValue(true),
|
|
||||||
setTokenId: jest.fn(),
|
|
||||||
user: {
|
|
||||||
setEmail: jest.fn(),
|
|
||||||
},
|
|
||||||
session: {
|
|
||||||
reset: jest.fn(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('utils', () => {
|
describe('utils', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
fetchMock.restore();
|
fetchMock.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('checks support session is terminated when logout', () => {
|
it('checks support session is terminated when logout', async () => {
|
||||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
const { terminateCrispSession } = await import('@/services/Crisp');
|
||||||
|
|
||||||
window.$crisp = true;
|
// Mock window.location.replace
|
||||||
const propertyDescriptors = Object.getOwnPropertyDescriptors(window);
|
const mockReplace = vi.fn();
|
||||||
for (const key in propertyDescriptors) {
|
Object.defineProperty(window, 'location', {
|
||||||
propertyDescriptors[key].configurable = true;
|
|
||||||
}
|
|
||||||
const clonedWindow = Object.defineProperties({}, propertyDescriptors);
|
|
||||||
|
|
||||||
Object.defineProperty(clonedWindow, 'location', {
|
|
||||||
value: {
|
value: {
|
||||||
...window.location,
|
...window.location,
|
||||||
replace: jest.fn(),
|
replace: mockReplace,
|
||||||
},
|
},
|
||||||
writable: true,
|
writable: true,
|
||||||
configurable: true,
|
configurable: true,
|
||||||
@@ -44,6 +30,9 @@ describe('utils', () => {
|
|||||||
|
|
||||||
gotoLogout();
|
gotoLogout();
|
||||||
|
|
||||||
expect(Crisp.session.reset).toHaveBeenCalled();
|
expect(terminateCrispSession).toHaveBeenCalled();
|
||||||
|
expect(mockReplace).toHaveBeenCalledWith(
|
||||||
|
'http://test.jest/api/v1.0/logout/',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { renderHook, waitFor } from '@testing-library/react';
|
import { renderHook, waitFor } from '@testing-library/react';
|
||||||
import fetchMock from 'fetch-mock';
|
import fetchMock from 'fetch-mock';
|
||||||
import { Fragment } from 'react';
|
import { Fragment } from 'react';
|
||||||
|
import { beforeEach, describe, expect, vi } from 'vitest';
|
||||||
|
|
||||||
import { AbstractAnalytic } from '@/libs';
|
import { AbstractAnalytic } from '@/libs';
|
||||||
import { AppWrapper } from '@/tests/utils';
|
import { AppWrapper } from '@/tests/utils';
|
||||||
|
|
||||||
import { useAuth } from '../useAuth';
|
import { useAuth } from '../useAuth';
|
||||||
|
|
||||||
const trackEventMock = jest.fn();
|
const trackEventMock = vi.fn();
|
||||||
const flag = true;
|
const flag = true;
|
||||||
class TestAnalytic extends AbstractAnalytic {
|
class TestAnalytic extends AbstractAnalytic {
|
||||||
public constructor() {
|
public constructor() {
|
||||||
@@ -31,11 +32,11 @@ class TestAnalytic extends AbstractAnalytic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jest.mock('next/router', () => ({
|
vi.mock('next/router', async () => ({
|
||||||
...jest.requireActual('next/router'),
|
...(await vi.importActual('next/router')),
|
||||||
useRouter: () => ({
|
useRouter: () => ({
|
||||||
pathname: '/dashboard',
|
pathname: '/dashboard',
|
||||||
replace: jest.fn(),
|
replace: vi.fn(),
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -43,7 +44,7 @@ const dummyUser = { id: '123', email: 'test@example.com' };
|
|||||||
|
|
||||||
describe('useAuth hook - trackEvent effect', () => {
|
describe('useAuth hook - trackEvent effect', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
fetchMock.restore();
|
fetchMock.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,38 @@
|
|||||||
import { act, renderHook, waitFor } from '@testing-library/react';
|
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||||
import fetchMock from 'fetch-mock';
|
import fetchMock from 'fetch-mock';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { AppWrapper } from '@/tests/utils';
|
import { AppWrapper } from '@/tests/utils';
|
||||||
|
|
||||||
import { useSaveDoc } from '../useSaveDoc';
|
import { useSaveDoc } from '../useSaveDoc';
|
||||||
|
|
||||||
jest.mock('next/router', () => ({
|
vi.mock('next/router', () => ({
|
||||||
useRouter: jest.fn(),
|
useRouter: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('@/docs/doc-versioning', () => ({
|
vi.mock('@/docs/doc-versioning', () => ({
|
||||||
KEY_LIST_DOC_VERSIONS: 'test-key-list-doc-versions',
|
KEY_LIST_DOC_VERSIONS: 'test-key-list-doc-versions',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('@/docs/doc-management', () => ({
|
vi.mock('@/docs/doc-management', async () => ({
|
||||||
useUpdateDoc: jest.requireActual('@/docs/doc-management/api/useUpdateDoc')
|
useUpdateDoc: (
|
||||||
.useUpdateDoc,
|
await vi.importActual('@/docs/doc-management/api/useUpdateDoc')
|
||||||
|
).useUpdateDoc,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('useSaveDoc', () => {
|
describe('useSaveDoc', () => {
|
||||||
const mockRouterEvents = {
|
const mockRouterEvents = {
|
||||||
on: jest.fn(),
|
on: vi.fn(),
|
||||||
off: jest.fn(),
|
off: vi.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
fetchMock.restore();
|
fetchMock.restore();
|
||||||
|
|
||||||
(useRouter as jest.Mock).mockReturnValue({
|
(useRouter as Mock).mockReturnValue({
|
||||||
events: mockRouterEvents,
|
events: mockRouterEvents,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -39,7 +41,7 @@ describe('useSaveDoc', () => {
|
|||||||
const yDoc = new Y.Doc();
|
const yDoc = new Y.Doc();
|
||||||
const docId = 'test-doc-id';
|
const docId = 'test-doc-id';
|
||||||
|
|
||||||
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
|
const addEventListenerSpy = vi.spyOn(window, 'addEventListener');
|
||||||
|
|
||||||
renderHook(() => useSaveDoc(docId, yDoc, true, true), {
|
renderHook(() => useSaveDoc(docId, yDoc, true, true), {
|
||||||
wrapper: AppWrapper,
|
wrapper: AppWrapper,
|
||||||
@@ -60,8 +62,8 @@ describe('useSaveDoc', () => {
|
|||||||
addEventListenerSpy.mockRestore();
|
addEventListenerSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not save when canSave is false', async () => {
|
it('should not save when canSave is false', () => {
|
||||||
jest.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
const yDoc = new Y.Doc();
|
const yDoc = new Y.Doc();
|
||||||
const docId = 'test-doc-id';
|
const docId = 'test-doc-id';
|
||||||
|
|
||||||
@@ -80,22 +82,19 @@ describe('useSaveDoc', () => {
|
|||||||
act(() => {
|
act(() => {
|
||||||
// Trigger a local update
|
// Trigger a local update
|
||||||
yDoc.getMap('test').set('key', 'value');
|
yDoc.getMap('test').set('key', 'value');
|
||||||
|
|
||||||
|
// Advance timers to trigger the save interval
|
||||||
|
vi.advanceTimersByTime(61000);
|
||||||
});
|
});
|
||||||
|
|
||||||
act(() => {
|
// Since canSave is false, no API call should be made
|
||||||
// Now advance timers after state has updated
|
expect(fetchMock.calls().length).toBe(0);
|
||||||
jest.advanceTimersByTime(61000);
|
|
||||||
});
|
|
||||||
|
|
||||||
await waitFor(() => {
|
vi.useRealTimers();
|
||||||
expect(fetchMock.calls().length).toBe(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.useRealTimers();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save when there are local changes', async () => {
|
it('should save when there are local changes', async () => {
|
||||||
jest.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
const yDoc = new Y.Doc();
|
const yDoc = new Y.Doc();
|
||||||
const docId = 'test-doc-id';
|
const docId = 'test-doc-id';
|
||||||
|
|
||||||
@@ -117,21 +116,22 @@ describe('useSaveDoc', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
// Now advance timers after state has updated
|
// Advance timers to trigger the save interval
|
||||||
jest.advanceTimersByTime(61000);
|
vi.advanceTimersByTime(61000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Switch to real timers to allow the mutation promise to resolve
|
||||||
|
vi.useRealTimers();
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(fetchMock.lastCall()?.[0]).toBe(
|
expect(fetchMock.lastCall()?.[0]).toBe(
|
||||||
'http://test.jest/api/v1.0/documents/test-doc-id/',
|
'http://test.jest/api/v1.0/documents/test-doc-id/',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.useRealTimers();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not save when there are no local changes', async () => {
|
it('should not save when there are no local changes', () => {
|
||||||
jest.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
const yDoc = new Y.Doc();
|
const yDoc = new Y.Doc();
|
||||||
const docId = 'test-doc-id';
|
const docId = 'test-doc-id';
|
||||||
|
|
||||||
@@ -148,21 +148,20 @@ describe('useSaveDoc', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
// Now advance timers after state has updated
|
// Advance timers without triggering any local updates
|
||||||
jest.advanceTimersByTime(61000);
|
vi.advanceTimersByTime(61000);
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
// Since there are no local changes, no API call should be made
|
||||||
expect(fetchMock.calls().length).toBe(0);
|
expect(fetchMock.calls().length).toBe(0);
|
||||||
});
|
|
||||||
|
|
||||||
jest.useRealTimers();
|
vi.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should cleanup event listeners on unmount', () => {
|
it('should cleanup event listeners on unmount', () => {
|
||||||
const yDoc = new Y.Doc();
|
const yDoc = new Y.Doc();
|
||||||
const docId = 'test-doc-id';
|
const docId = 'test-doc-id';
|
||||||
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
|
const removeEventListenerSpy = vi.spyOn(window, 'removeEventListener');
|
||||||
|
|
||||||
const { unmount } = renderHook(() => useSaveDoc(docId, yDoc, true, true), {
|
const { unmount } = renderHook(() => useSaveDoc(docId, yDoc, true, true), {
|
||||||
wrapper: AppWrapper,
|
wrapper: AppWrapper,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
import { afterAll, afterEach, describe, expect, it, vi } from 'vitest';
|
||||||
const originalEnv = process.env.NEXT_PUBLIC_PUBLISH_AS_MIT;
|
const originalEnv = process.env.NEXT_PUBLIC_PUBLISH_AS_MIT;
|
||||||
|
|
||||||
jest.mock('@/features/docs/doc-export/utils', () => ({
|
vi.mock('@/features/docs/doc-export/utils', () => ({
|
||||||
anything: true,
|
anything: true,
|
||||||
}));
|
}));
|
||||||
jest.mock('@/features/docs/doc-export/components/ModalExport', () => ({
|
vi.mock('@/features/docs/doc-export/components/ModalExport', () => ({
|
||||||
ModalExport: () => <span>ModalExport</span>,
|
ModalExport: () => <span>ModalExport</span>,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -13,8 +14,8 @@ describe('useModuleExport', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
jest.resetModules();
|
vi.resetModules();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return undefined when NEXT_PUBLIC_PUBLISH_AS_MIT is true', async () => {
|
it('should return undefined when NEXT_PUBLIC_PUBLISH_AS_MIT is true', async () => {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
|
import { beforeEach, describe, expect, vi } from 'vitest';
|
||||||
|
|
||||||
import { AbstractAnalytic, Analytics } from '@/libs';
|
import { AbstractAnalytic, Analytics } from '@/libs';
|
||||||
import { AppWrapper } from '@/tests/utils';
|
import { AppWrapper } from '@/tests/utils';
|
||||||
@@ -28,14 +29,10 @@ class TestAnalytic extends AbstractAnalytic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jest.mock('@/features/docs/doc-export/', () => ({
|
vi.mock('next/router', async () => ({
|
||||||
ModalExport: () => <span>ModalExport</span>,
|
...(await vi.importActual('next/router')),
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('next/router', () => ({
|
|
||||||
...jest.requireActual('next/router'),
|
|
||||||
useRouter: () => ({
|
useRouter: () => ({
|
||||||
push: jest.fn(),
|
push: vi.fn(),
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +1,30 @@
|
|||||||
/**
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||||
* @jest-environment node
|
|
||||||
*/
|
|
||||||
|
|
||||||
import '@testing-library/jest-dom';
|
|
||||||
|
|
||||||
import { RequestSerializer } from '../RequestSerializer';
|
import { RequestSerializer } from '../RequestSerializer';
|
||||||
import { ApiPlugin } from '../plugins/ApiPlugin';
|
import { ApiPlugin } from '../plugins/ApiPlugin';
|
||||||
|
|
||||||
const mockedGet = jest.fn().mockResolvedValue({});
|
const mockedGet = vi.fn().mockResolvedValue({});
|
||||||
const mockedGetAllKeys = jest.fn().mockResolvedValue([]);
|
const mockedGetAllKeys = vi.fn().mockResolvedValue([]);
|
||||||
const mockedPut = jest.fn().mockResolvedValue({});
|
const mockedPut = vi.fn().mockResolvedValue({});
|
||||||
const mockedDelete = jest.fn().mockResolvedValue({});
|
const mockedDelete = vi.fn().mockResolvedValue({});
|
||||||
const mockedClose = jest.fn().mockResolvedValue({});
|
const mockedClose = vi.fn().mockResolvedValue({});
|
||||||
const mockedOpendDB = jest.fn().mockResolvedValue({
|
const mockedOpendDB = vi.fn().mockResolvedValue({
|
||||||
get: mockedGet,
|
get: mockedGet,
|
||||||
getAllKeys: mockedGetAllKeys,
|
getAllKeys: mockedGetAllKeys,
|
||||||
getAll: jest.fn().mockResolvedValue([]),
|
getAll: vi.fn().mockResolvedValue([]),
|
||||||
put: mockedPut,
|
put: mockedPut,
|
||||||
delete: mockedDelete,
|
delete: mockedDelete,
|
||||||
clear: jest.fn().mockResolvedValue({}),
|
clear: vi.fn().mockResolvedValue({}),
|
||||||
close: mockedClose,
|
close: mockedClose,
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('idb', () => ({
|
vi.mock('idb', async () => ({
|
||||||
...jest.requireActual('idb'),
|
...(await vi.importActual('idb')),
|
||||||
openDB: () => mockedOpendDB(),
|
openDB: () => mockedOpendDB(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('ApiPlugin', () => {
|
describe('ApiPlugin', () => {
|
||||||
afterEach(() => jest.clearAllMocks());
|
afterEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
[
|
[
|
||||||
{ type: 'item', table: 'doc-item' },
|
{ type: 'item', table: 'doc-item' },
|
||||||
@@ -36,7 +32,7 @@ describe('ApiPlugin', () => {
|
|||||||
{ type: 'update', table: 'doc-item' },
|
{ type: 'update', table: 'doc-item' },
|
||||||
].forEach(({ type, table }) => {
|
].forEach(({ type, table }) => {
|
||||||
it(`calls fetchDidSucceed with type ${type} and status 200`, async () => {
|
it(`calls fetchDidSucceed with type ${type} and status 200`, async () => {
|
||||||
const mockedSync = jest.fn().mockResolvedValue({});
|
const mockedSync = vi.fn().mockResolvedValue({});
|
||||||
const apiPlugin = new ApiPlugin({
|
const apiPlugin = new ApiPlugin({
|
||||||
tableName: table as any,
|
tableName: table as any,
|
||||||
type: type as any,
|
type: type as any,
|
||||||
@@ -55,7 +51,7 @@ describe('ApiPlugin', () => {
|
|||||||
json: () => body,
|
json: () => body,
|
||||||
} as unknown as Request,
|
} as unknown as Request,
|
||||||
} as any;
|
} as any;
|
||||||
const mockedClone = jest.fn().mockReturnValue(requestInit.request);
|
const mockedClone = vi.fn().mockReturnValue(requestInit.request);
|
||||||
await apiPlugin.requestWillFetch?.(requestInit);
|
await apiPlugin.requestWillFetch?.(requestInit);
|
||||||
|
|
||||||
const response = await apiPlugin.fetchDidSucceed?.({
|
const response = await apiPlugin.fetchDidSucceed?.({
|
||||||
@@ -81,7 +77,7 @@ describe('ApiPlugin', () => {
|
|||||||
const apiPlugin = new ApiPlugin({
|
const apiPlugin = new ApiPlugin({
|
||||||
tableName: table as any,
|
tableName: table as any,
|
||||||
type: type as any,
|
type: type as any,
|
||||||
syncManager: jest.fn() as any,
|
syncManager: vi.fn() as any,
|
||||||
});
|
});
|
||||||
|
|
||||||
const body = { lastName: 'Doe' };
|
const body = { lastName: 'Doe' };
|
||||||
@@ -114,7 +110,7 @@ describe('ApiPlugin', () => {
|
|||||||
{ type: 'item', withClone: false },
|
{ type: 'item', withClone: false },
|
||||||
].forEach(({ type, withClone }) => {
|
].forEach(({ type, withClone }) => {
|
||||||
it(`calls requestWillFetch with type ${type}`, async () => {
|
it(`calls requestWillFetch with type ${type}`, async () => {
|
||||||
const mockedSync = jest.fn().mockResolvedValue({});
|
const mockedSync = vi.fn().mockResolvedValue({});
|
||||||
|
|
||||||
const apiPlugin = new ApiPlugin({
|
const apiPlugin = new ApiPlugin({
|
||||||
type: 'update',
|
type: 'update',
|
||||||
@@ -123,7 +119,7 @@ describe('ApiPlugin', () => {
|
|||||||
} as any,
|
} as any,
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockedClone = jest.fn().mockResolvedValue({});
|
const mockedClone = vi.fn().mockResolvedValue({});
|
||||||
const requestInit = {
|
const requestInit = {
|
||||||
request: {
|
request: {
|
||||||
url: 'test-url',
|
url: 'test-url',
|
||||||
@@ -189,9 +185,9 @@ describe('ApiPlugin', () => {
|
|||||||
} as unknown as Request,
|
} as unknown as Request,
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
const mockedClone = jest.fn().mockReturnValue(requestInit.request);
|
const mockedClone = vi.fn().mockReturnValue(requestInit.request);
|
||||||
|
|
||||||
const mockedSync = jest.fn().mockResolvedValue({});
|
const mockedSync = vi.fn().mockResolvedValue({});
|
||||||
const apiPlugin = new ApiPlugin({
|
const apiPlugin = new ApiPlugin({
|
||||||
type: 'update',
|
type: 'update',
|
||||||
syncManager: {
|
syncManager: {
|
||||||
@@ -265,9 +261,9 @@ describe('ApiPlugin', () => {
|
|||||||
} as unknown as Request,
|
} as unknown as Request,
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
const mockedClone = jest.fn().mockReturnValue(requestInit.request);
|
const mockedClone = vi.fn().mockReturnValue(requestInit.request);
|
||||||
|
|
||||||
const mockedSync = jest.fn().mockResolvedValue({});
|
const mockedSync = vi.fn().mockResolvedValue({});
|
||||||
const apiPlugin = new ApiPlugin({
|
const apiPlugin = new ApiPlugin({
|
||||||
type: 'delete',
|
type: 'delete',
|
||||||
syncManager: {
|
syncManager: {
|
||||||
@@ -334,7 +330,7 @@ describe('ApiPlugin', () => {
|
|||||||
Object.defineProperty(global, 'self', {
|
Object.defineProperty(global, 'self', {
|
||||||
value: {
|
value: {
|
||||||
crypto: {
|
crypto: {
|
||||||
randomUUID: jest.fn().mockReturnValue('444555'),
|
randomUUID: vi.fn().mockReturnValue('444555'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -351,9 +347,9 @@ describe('ApiPlugin', () => {
|
|||||||
} as unknown as Request,
|
} as unknown as Request,
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
const mockedClone = jest.fn().mockReturnValue(requestInit.request);
|
const mockedClone = vi.fn().mockReturnValue(requestInit.request);
|
||||||
|
|
||||||
const mockedSync = jest.fn().mockResolvedValue({});
|
const mockedSync = vi.fn().mockResolvedValue({});
|
||||||
const apiPlugin = new ApiPlugin({
|
const apiPlugin = new ApiPlugin({
|
||||||
type: 'create',
|
type: 'create',
|
||||||
syncManager: {
|
syncManager: {
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||||
/**
|
/**
|
||||||
* @jest-environment node
|
* @vitest-environment node
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import '@testing-library/jest-dom';
|
|
||||||
|
|
||||||
import { MESSAGE_TYPE } from '../conf';
|
import { MESSAGE_TYPE } from '../conf';
|
||||||
import { OfflinePlugin } from '../plugins/OfflinePlugin';
|
import { OfflinePlugin } from '../plugins/OfflinePlugin';
|
||||||
|
|
||||||
const mockServiceWorkerScope = {
|
const mockServiceWorkerScope = {
|
||||||
clients: {
|
clients: {
|
||||||
matchAll: jest.fn().mockResolvedValue([]),
|
matchAll: vi.fn().mockResolvedValue([]),
|
||||||
},
|
},
|
||||||
} as unknown as ServiceWorkerGlobalScope;
|
} as unknown as ServiceWorkerGlobalScope;
|
||||||
|
|
||||||
@@ -19,11 +18,11 @@ const mockServiceWorkerScope = {
|
|||||||
} as unknown as ServiceWorkerGlobalScope;
|
} as unknown as ServiceWorkerGlobalScope;
|
||||||
|
|
||||||
describe('OfflinePlugin', () => {
|
describe('OfflinePlugin', () => {
|
||||||
afterEach(() => jest.clearAllMocks());
|
afterEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
it(`calls fetchDidSucceed`, async () => {
|
it(`calls fetchDidSucceed`, async () => {
|
||||||
const apiPlugin = new OfflinePlugin();
|
const apiPlugin = new OfflinePlugin();
|
||||||
const postMessageSpy = jest.spyOn(apiPlugin, 'postMessage');
|
const postMessageSpy = vi.spyOn(apiPlugin, 'postMessage');
|
||||||
|
|
||||||
await apiPlugin.fetchDidSucceed?.({
|
await apiPlugin.fetchDidSucceed?.({
|
||||||
response: new Response(),
|
response: new Response(),
|
||||||
@@ -34,7 +33,7 @@ describe('OfflinePlugin', () => {
|
|||||||
|
|
||||||
it(`calls fetchDidFail`, async () => {
|
it(`calls fetchDidFail`, async () => {
|
||||||
const apiPlugin = new OfflinePlugin();
|
const apiPlugin = new OfflinePlugin();
|
||||||
const postMessageSpy = jest.spyOn(apiPlugin, 'postMessage');
|
const postMessageSpy = vi.spyOn(apiPlugin, 'postMessage');
|
||||||
|
|
||||||
await apiPlugin.fetchDidFail?.({} as any);
|
await apiPlugin.fetchDidFail?.({} as any);
|
||||||
|
|
||||||
@@ -43,12 +42,9 @@ describe('OfflinePlugin', () => {
|
|||||||
|
|
||||||
it(`calls postMessage`, async () => {
|
it(`calls postMessage`, async () => {
|
||||||
const apiPlugin = new OfflinePlugin();
|
const apiPlugin = new OfflinePlugin();
|
||||||
const mockClients = [
|
const mockClients = [{ postMessage: vi.fn() }, { postMessage: vi.fn() }];
|
||||||
{ postMessage: jest.fn() },
|
|
||||||
{ postMessage: jest.fn() },
|
|
||||||
];
|
|
||||||
|
|
||||||
mockServiceWorkerScope.clients.matchAll = jest
|
mockServiceWorkerScope.clients.matchAll = vi
|
||||||
.fn()
|
.fn()
|
||||||
.mockResolvedValue(mockClients);
|
.mockResolvedValue(mockClients);
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||||
/**
|
/**
|
||||||
* @jest-environment node
|
* @jest-environment node
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import '@testing-library/jest-dom';
|
|
||||||
|
|
||||||
import { SyncManager } from '../SyncManager';
|
import { SyncManager } from '../SyncManager';
|
||||||
|
|
||||||
const mockedSleep = jest.fn();
|
const mockedSleep = vi.fn();
|
||||||
jest.mock('@/utils/system', () => ({
|
vi.mock('@/utils/system', () => ({
|
||||||
sleep: jest.fn().mockImplementation((ms) => mockedSleep(ms)),
|
sleep: vi.fn().mockImplementation((ms) => mockedSleep(ms)),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
|
||||||
describe('SyncManager', () => {
|
describe('SyncManager', () => {
|
||||||
afterEach(() => jest.clearAllMocks());
|
afterEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
it('checks SyncManager no sync to do', async () => {
|
it('checks SyncManager no sync to do', async () => {
|
||||||
const toSync = jest.fn();
|
const toSync = vi.fn();
|
||||||
const hasSyncToDo = jest.fn().mockResolvedValue(false);
|
const hasSyncToDo = vi.fn().mockResolvedValue(false);
|
||||||
new SyncManager(toSync, hasSyncToDo);
|
new SyncManager(toSync, hasSyncToDo);
|
||||||
|
|
||||||
await delay(100);
|
await delay(100);
|
||||||
@@ -28,8 +27,8 @@ describe('SyncManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('checks SyncManager sync to do', async () => {
|
it('checks SyncManager sync to do', async () => {
|
||||||
const toSync = jest.fn();
|
const toSync = vi.fn();
|
||||||
const hasSyncToDo = jest.fn().mockResolvedValue(true);
|
const hasSyncToDo = vi.fn().mockResolvedValue(true);
|
||||||
new SyncManager(toSync, hasSyncToDo);
|
new SyncManager(toSync, hasSyncToDo);
|
||||||
|
|
||||||
await delay(100);
|
await delay(100);
|
||||||
@@ -39,10 +38,10 @@ describe('SyncManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('checks SyncManager sync to do trigger error', async () => {
|
it('checks SyncManager sync to do trigger error', async () => {
|
||||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
const toSync = jest.fn().mockRejectedValue(new Error('error'));
|
const toSync = vi.fn().mockRejectedValue(new Error('error'));
|
||||||
const hasSyncToDo = jest.fn().mockResolvedValue(true);
|
const hasSyncToDo = vi.fn().mockResolvedValue(true);
|
||||||
new SyncManager(toSync, hasSyncToDo);
|
new SyncManager(toSync, hasSyncToDo);
|
||||||
|
|
||||||
await delay(100);
|
await delay(100);
|
||||||
@@ -56,8 +55,8 @@ describe('SyncManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('checks SyncManager multiple sync to do', async () => {
|
it('checks SyncManager multiple sync to do', async () => {
|
||||||
const toSync = jest.fn().mockReturnValue(delay(200));
|
const toSync = vi.fn().mockReturnValue(delay(200));
|
||||||
const hasSyncToDo = jest.fn().mockResolvedValue(true);
|
const hasSyncToDo = vi.fn().mockResolvedValue(true);
|
||||||
const syncManager = new SyncManager(toSync, hasSyncToDo);
|
const syncManager = new SyncManager(toSync, hasSyncToDo);
|
||||||
|
|
||||||
await syncManager.sync();
|
await syncManager.sync();
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import '@testing-library/jest-dom';
|
|
||||||
import { act, renderHook } from '@testing-library/react';
|
import { act, renderHook } from '@testing-library/react';
|
||||||
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
import { MESSAGE_TYPE } from '../conf';
|
import { MESSAGE_TYPE } from '../conf';
|
||||||
import { useIsOffline, useOffline } from '../hooks/useOffline';
|
import { useIsOffline, useOffline } from '../hooks/useOffline';
|
||||||
|
|
||||||
const mockAddEventListener = jest.fn();
|
const mockAddEventListener = vi.fn();
|
||||||
const mockRemoveEventListener = jest.fn();
|
const mockRemoveEventListener = vi.fn();
|
||||||
Object.defineProperty(navigator, 'serviceWorker', {
|
Object.defineProperty(navigator, 'serviceWorker', {
|
||||||
value: {
|
value: {
|
||||||
addEventListener: mockAddEventListener,
|
addEventListener: mockAddEventListener,
|
||||||
@@ -16,7 +16,7 @@ Object.defineProperty(navigator, 'serviceWorker', {
|
|||||||
|
|
||||||
describe('useOffline', () => {
|
describe('useOffline', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set isOffline to true when receiving an offline message', () => {
|
it('should set isOffline to true when receiving an offline message', () => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import '@testing-library/jest-dom';
|
|
||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
import { useSWRegister } from '../hooks/useSWRegister';
|
import { useSWRegister } from '../hooks/useSWRegister';
|
||||||
|
|
||||||
@@ -12,9 +12,9 @@ const TestComponent = () => {
|
|||||||
describe('useSWRegister', () => {
|
describe('useSWRegister', () => {
|
||||||
it('checks service-worker is register', () => {
|
it('checks service-worker is register', () => {
|
||||||
process.env.NEXT_PUBLIC_BUILD_ID = '123456';
|
process.env.NEXT_PUBLIC_BUILD_ID = '123456';
|
||||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
const registerSpy = jest.fn();
|
const registerSpy = vi.fn();
|
||||||
registerSpy.mockImplementation(
|
registerSpy.mockImplementation(
|
||||||
() =>
|
() =>
|
||||||
new Promise((reject) => {
|
new Promise((reject) => {
|
||||||
@@ -22,11 +22,13 @@ describe('useSWRegister', () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const addEventListenerSpy = vi.fn();
|
||||||
|
|
||||||
Object.defineProperty(navigator, 'serviceWorker', {
|
Object.defineProperty(navigator, 'serviceWorker', {
|
||||||
value: {
|
value: {
|
||||||
register: registerSpy,
|
register: registerSpy,
|
||||||
addEventListener: jest.fn(),
|
addEventListener: addEventListenerSpy,
|
||||||
removeEventListener: jest.fn(),
|
removeEventListener: vi.fn(),
|
||||||
},
|
},
|
||||||
writable: true,
|
writable: true,
|
||||||
});
|
});
|
||||||
@@ -34,7 +36,7 @@ describe('useSWRegister', () => {
|
|||||||
render(<TestComponent />);
|
render(<TestComponent />);
|
||||||
|
|
||||||
expect(registerSpy).toHaveBeenCalledWith('/service-worker.js?v=123456');
|
expect(registerSpy).toHaveBeenCalledWith('/service-worker.js?v=123456');
|
||||||
expect(navigator.serviceWorker.addEventListener).toHaveBeenCalledWith(
|
expect(addEventListenerSpy).toHaveBeenCalledWith(
|
||||||
'controllerchange',
|
'controllerchange',
|
||||||
expect.any(Function),
|
expect.any(Function),
|
||||||
);
|
);
|
||||||
@@ -44,7 +46,7 @@ describe('useSWRegister', () => {
|
|||||||
process.env.NEXT_PUBLIC_SW_DEACTIVATED = 'true';
|
process.env.NEXT_PUBLIC_SW_DEACTIVATED = 'true';
|
||||||
process.env.NEXT_PUBLIC_BUILD_ID = '123456';
|
process.env.NEXT_PUBLIC_BUILD_ID = '123456';
|
||||||
|
|
||||||
const registerSpy = jest.fn();
|
const registerSpy = vi.fn();
|
||||||
registerSpy.mockImplementation(
|
registerSpy.mockImplementation(
|
||||||
() =>
|
() =>
|
||||||
new Promise((reject) => {
|
new Promise((reject) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import '@testing-library/jest-dom';
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
import { isValidEmail } from '../string';
|
import { isValidEmail } from '../string';
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
import { isSafeUrl } from '@/utils/url';
|
import { isSafeUrl } from '@/utils/url';
|
||||||
|
|
||||||
describe('isSafeUrl', () => {
|
describe('isSafeUrl', () => {
|
||||||
|
|||||||
25
src/frontend/apps/impress/vitest.config.ts
Normal file
25
src/frontend/apps/impress/vitest.config.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/// <reference types="vitest" />
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
react(),
|
||||||
|
tsconfigPaths({
|
||||||
|
root: '.',
|
||||||
|
projects: ['./tsconfig.json'],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'jsdom',
|
||||||
|
setupFiles: './vitest.setup.ts',
|
||||||
|
coverage: {
|
||||||
|
provider: 'v8',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
define: {
|
||||||
|
'process.env.NODE_ENV': 'test',
|
||||||
|
},
|
||||||
|
});
|
||||||
4
src/frontend/apps/impress/vitest.setup.ts
Normal file
4
src/frontend/apps/impress/vitest.setup.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import '@testing-library/jest-dom/vitest';
|
||||||
|
import * as dotenv from 'dotenv';
|
||||||
|
|
||||||
|
dotenv.config({ path: './.env.test', quiet: true });
|
||||||
@@ -75,6 +75,27 @@
|
|||||||
json5 "^2.2.3"
|
json5 "^2.2.3"
|
||||||
semver "^6.3.1"
|
semver "^6.3.1"
|
||||||
|
|
||||||
|
"@babel/core@^7.28.0":
|
||||||
|
version "7.28.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.3.tgz#aceddde69c5d1def69b839d09efa3e3ff59c97cb"
|
||||||
|
integrity sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==
|
||||||
|
dependencies:
|
||||||
|
"@ampproject/remapping" "^2.2.0"
|
||||||
|
"@babel/code-frame" "^7.27.1"
|
||||||
|
"@babel/generator" "^7.28.3"
|
||||||
|
"@babel/helper-compilation-targets" "^7.27.2"
|
||||||
|
"@babel/helper-module-transforms" "^7.28.3"
|
||||||
|
"@babel/helpers" "^7.28.3"
|
||||||
|
"@babel/parser" "^7.28.3"
|
||||||
|
"@babel/template" "^7.27.2"
|
||||||
|
"@babel/traverse" "^7.28.3"
|
||||||
|
"@babel/types" "^7.28.2"
|
||||||
|
convert-source-map "^2.0.0"
|
||||||
|
debug "^4.1.0"
|
||||||
|
gensync "^1.0.0-beta.2"
|
||||||
|
json5 "^2.2.3"
|
||||||
|
semver "^6.3.1"
|
||||||
|
|
||||||
"@babel/generator@^7.27.5", "@babel/generator@^7.28.0":
|
"@babel/generator@^7.27.5", "@babel/generator@^7.28.0":
|
||||||
version "7.28.0"
|
version "7.28.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.0.tgz#9cc2f7bd6eb054d77dc66c2664148a0c5118acd2"
|
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.0.tgz#9cc2f7bd6eb054d77dc66c2664148a0c5118acd2"
|
||||||
@@ -86,6 +107,17 @@
|
|||||||
"@jridgewell/trace-mapping" "^0.3.28"
|
"@jridgewell/trace-mapping" "^0.3.28"
|
||||||
jsesc "^3.0.2"
|
jsesc "^3.0.2"
|
||||||
|
|
||||||
|
"@babel/generator@^7.28.3":
|
||||||
|
version "7.28.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.3.tgz#9626c1741c650cbac39121694a0f2d7451b8ef3e"
|
||||||
|
integrity sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/parser" "^7.28.3"
|
||||||
|
"@babel/types" "^7.28.2"
|
||||||
|
"@jridgewell/gen-mapping" "^0.3.12"
|
||||||
|
"@jridgewell/trace-mapping" "^0.3.28"
|
||||||
|
jsesc "^3.0.2"
|
||||||
|
|
||||||
"@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3":
|
"@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3":
|
||||||
version "7.27.3"
|
version "7.27.3"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5"
|
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5"
|
||||||
@@ -167,6 +199,15 @@
|
|||||||
"@babel/helper-validator-identifier" "^7.27.1"
|
"@babel/helper-validator-identifier" "^7.27.1"
|
||||||
"@babel/traverse" "^7.27.3"
|
"@babel/traverse" "^7.27.3"
|
||||||
|
|
||||||
|
"@babel/helper-module-transforms@^7.28.3":
|
||||||
|
version "7.28.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz#a2b37d3da3b2344fe085dab234426f2b9a2fa5f6"
|
||||||
|
integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-module-imports" "^7.27.1"
|
||||||
|
"@babel/helper-validator-identifier" "^7.27.1"
|
||||||
|
"@babel/traverse" "^7.28.3"
|
||||||
|
|
||||||
"@babel/helper-optimise-call-expression@^7.27.1":
|
"@babel/helper-optimise-call-expression@^7.27.1":
|
||||||
version "7.27.1"
|
version "7.27.1"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz#c65221b61a643f3e62705e5dd2b5f115e35f9200"
|
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz#c65221b61a643f3e62705e5dd2b5f115e35f9200"
|
||||||
@@ -237,6 +278,14 @@
|
|||||||
"@babel/template" "^7.27.2"
|
"@babel/template" "^7.27.2"
|
||||||
"@babel/types" "^7.28.2"
|
"@babel/types" "^7.28.2"
|
||||||
|
|
||||||
|
"@babel/helpers@^7.28.3":
|
||||||
|
version "7.28.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.3.tgz#b83156c0a2232c133d1b535dd5d3452119c7e441"
|
||||||
|
integrity sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/template" "^7.27.2"
|
||||||
|
"@babel/types" "^7.28.2"
|
||||||
|
|
||||||
"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.0":
|
"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.0":
|
||||||
version "7.28.0"
|
version "7.28.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.0.tgz#979829fbab51a29e13901e5a80713dbcb840825e"
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.0.tgz#979829fbab51a29e13901e5a80713dbcb840825e"
|
||||||
@@ -244,6 +293,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/types" "^7.28.0"
|
"@babel/types" "^7.28.0"
|
||||||
|
|
||||||
|
"@babel/parser@^7.28.3":
|
||||||
|
version "7.28.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.3.tgz#d2d25b814621bca5fe9d172bc93792547e7a2a71"
|
||||||
|
integrity sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.28.2"
|
||||||
|
|
||||||
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.27.1":
|
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.27.1":
|
||||||
version "7.27.1"
|
version "7.27.1"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz#61dd8a8e61f7eb568268d1b5f129da3eee364bf9"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz#61dd8a8e61f7eb568268d1b5f129da3eee364bf9"
|
||||||
@@ -751,6 +807,20 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/plugin-transform-react-jsx" "^7.27.1"
|
"@babel/plugin-transform-react-jsx" "^7.27.1"
|
||||||
|
|
||||||
|
"@babel/plugin-transform-react-jsx-self@^7.27.1":
|
||||||
|
version "7.27.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz#af678d8506acf52c577cac73ff7fe6615c85fc92"
|
||||||
|
integrity sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-plugin-utils" "^7.27.1"
|
||||||
|
|
||||||
|
"@babel/plugin-transform-react-jsx-source@^7.27.1":
|
||||||
|
version "7.27.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz#dcfe2c24094bb757bf73960374e7c55e434f19f0"
|
||||||
|
integrity sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-plugin-utils" "^7.27.1"
|
||||||
|
|
||||||
"@babel/plugin-transform-react-jsx@^7.27.1":
|
"@babel/plugin-transform-react-jsx@^7.27.1":
|
||||||
version "7.27.1"
|
version "7.27.1"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz#1023bc94b78b0a2d68c82b5e96aed573bcfb9db0"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz#1023bc94b78b0a2d68c82b5e96aed573bcfb9db0"
|
||||||
@@ -1005,6 +1075,19 @@
|
|||||||
"@babel/types" "^7.28.0"
|
"@babel/types" "^7.28.0"
|
||||||
debug "^4.3.1"
|
debug "^4.3.1"
|
||||||
|
|
||||||
|
"@babel/traverse@^7.28.3":
|
||||||
|
version "7.28.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.3.tgz#6911a10795d2cce43ec6a28cffc440cca2593434"
|
||||||
|
integrity sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.27.1"
|
||||||
|
"@babel/generator" "^7.28.3"
|
||||||
|
"@babel/helper-globals" "^7.28.0"
|
||||||
|
"@babel/parser" "^7.28.3"
|
||||||
|
"@babel/template" "^7.27.2"
|
||||||
|
"@babel/types" "^7.28.2"
|
||||||
|
debug "^4.3.1"
|
||||||
|
|
||||||
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.0", "@babel/types@^7.28.2", "@babel/types@^7.4.4":
|
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.0", "@babel/types@^7.28.2", "@babel/types@^7.4.4":
|
||||||
version "7.28.2"
|
version "7.28.2"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.2.tgz#da9db0856a9a88e0a13b019881d7513588cf712b"
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.2.tgz#da9db0856a9a88e0a13b019881d7513588cf712b"
|
||||||
@@ -1969,19 +2052,6 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz#0ededeae4d071f5c8ffe3678d15f3a1be09156be"
|
resolved "https://registry.yarnpkg.com/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz#0ededeae4d071f5c8ffe3678d15f3a1be09156be"
|
||||||
integrity sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==
|
integrity sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==
|
||||||
|
|
||||||
"@jest/environment-jsdom-abstract@30.0.5":
|
|
||||||
version "30.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.0.5.tgz#7299cca59b3e84547ca3d1bbd4e7d36b4b44d426"
|
|
||||||
integrity sha512-gpWwiVxZunkoglP8DCnT3As9x5O8H6gveAOpvaJd2ATAoSh7ZSSCWbr9LQtUMvr8WD3VjG9YnDhsmkCK5WN1rQ==
|
|
||||||
dependencies:
|
|
||||||
"@jest/environment" "30.0.5"
|
|
||||||
"@jest/fake-timers" "30.0.5"
|
|
||||||
"@jest/types" "30.0.5"
|
|
||||||
"@types/jsdom" "^21.1.7"
|
|
||||||
"@types/node" "*"
|
|
||||||
jest-mock "30.0.5"
|
|
||||||
jest-util "30.0.5"
|
|
||||||
|
|
||||||
"@jest/environment@30.0.5":
|
"@jest/environment@30.0.5":
|
||||||
version "30.0.5"
|
version "30.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-30.0.5.tgz#eaaae0403c7d3f8414053c2224acc3011e1c3a1b"
|
resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-30.0.5.tgz#eaaae0403c7d3f8414053c2224acc3011e1c3a1b"
|
||||||
@@ -4300,6 +4370,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@remirror/core-constants/-/core-constants-3.0.0.tgz#96fdb89d25c62e7b6a5d08caf0ce5114370e3b8f"
|
resolved "https://registry.yarnpkg.com/@remirror/core-constants/-/core-constants-3.0.0.tgz#96fdb89d25c62e7b6a5d08caf0ce5114370e3b8f"
|
||||||
integrity sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==
|
integrity sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==
|
||||||
|
|
||||||
|
"@rolldown/pluginutils@1.0.0-beta.27":
|
||||||
|
version "1.0.0-beta.27"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz#47d2bf4cef6d470b22f5831b420f8964e0bf755f"
|
||||||
|
integrity sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==
|
||||||
|
|
||||||
"@rollup/plugin-babel@^5.2.0":
|
"@rollup/plugin-babel@^5.2.0":
|
||||||
version "5.3.1"
|
version "5.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283"
|
resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283"
|
||||||
@@ -5346,15 +5421,6 @@
|
|||||||
expect "^30.0.0"
|
expect "^30.0.0"
|
||||||
pretty-format "^30.0.0"
|
pretty-format "^30.0.0"
|
||||||
|
|
||||||
"@types/jsdom@^21.1.7":
|
|
||||||
version "21.1.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-21.1.7.tgz#9edcb09e0b07ce876e7833922d3274149c898cfa"
|
|
||||||
integrity sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==
|
|
||||||
dependencies:
|
|
||||||
"@types/node" "*"
|
|
||||||
"@types/tough-cookie" "*"
|
|
||||||
parse5 "^7.0.0"
|
|
||||||
|
|
||||||
"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9":
|
"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9":
|
||||||
version "7.0.15"
|
version "7.0.15"
|
||||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
|
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
|
||||||
@@ -5577,11 +5643,6 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/tough-cookie@*":
|
|
||||||
version "4.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304"
|
|
||||||
integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==
|
|
||||||
|
|
||||||
"@types/trusted-types@^2.0.2":
|
"@types/trusted-types@^2.0.2":
|
||||||
version "2.0.7"
|
version "2.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11"
|
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11"
|
||||||
@@ -5816,6 +5877,18 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz#538b1e103bf8d9864e7b85cc96fa8d6fb6c40777"
|
resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz#538b1e103bf8d9864e7b85cc96fa8d6fb6c40777"
|
||||||
integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==
|
integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==
|
||||||
|
|
||||||
|
"@vitejs/plugin-react@4.7.0":
|
||||||
|
version "4.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz#647af4e7bb75ad3add578e762ad984b90f4a24b9"
|
||||||
|
integrity sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/core" "^7.28.0"
|
||||||
|
"@babel/plugin-transform-react-jsx-self" "^7.27.1"
|
||||||
|
"@babel/plugin-transform-react-jsx-source" "^7.27.1"
|
||||||
|
"@rolldown/pluginutils" "1.0.0-beta.27"
|
||||||
|
"@types/babel__core" "^7.20.5"
|
||||||
|
react-refresh "^0.17.0"
|
||||||
|
|
||||||
"@vitest/expect@3.2.4":
|
"@vitest/expect@3.2.4":
|
||||||
version "3.2.4"
|
version "3.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-3.2.4.tgz#8362124cd811a5ee11c5768207b9df53d34f2433"
|
resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-3.2.4.tgz#8362124cd811a5ee11c5768207b9df53d34f2433"
|
||||||
@@ -8734,6 +8807,11 @@ globjoin@^0.1.4:
|
|||||||
resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
|
resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
|
||||||
integrity sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==
|
integrity sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==
|
||||||
|
|
||||||
|
globrex@^0.1.2:
|
||||||
|
version "0.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
|
||||||
|
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
|
||||||
|
|
||||||
gopd@^1.0.1, gopd@^1.2.0:
|
gopd@^1.0.1, gopd@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
|
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
|
||||||
@@ -9788,17 +9866,6 @@ jest-each@30.0.5:
|
|||||||
jest-util "30.0.5"
|
jest-util "30.0.5"
|
||||||
pretty-format "30.0.5"
|
pretty-format "30.0.5"
|
||||||
|
|
||||||
jest-environment-jsdom@30.0.5:
|
|
||||||
version "30.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-30.0.5.tgz#36351cc8a14fcd54945da0beb029af493d7d5764"
|
|
||||||
integrity sha512-BmnDEoAH+jEjkPrvE9DTKS2r3jYSJWlN/r46h0/DBUxKrkgt2jAZ5Nj4wXLAcV1KWkRpcFqA5zri9SWzJZ1cCg==
|
|
||||||
dependencies:
|
|
||||||
"@jest/environment" "30.0.5"
|
|
||||||
"@jest/environment-jsdom-abstract" "30.0.5"
|
|
||||||
"@types/jsdom" "^21.1.7"
|
|
||||||
"@types/node" "*"
|
|
||||||
jsdom "^26.1.0"
|
|
||||||
|
|
||||||
jest-environment-node@30.0.5:
|
jest-environment-node@30.0.5:
|
||||||
version "30.0.5"
|
version "30.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-30.0.5.tgz#6a98dd80e0384ead67ed05643381395f6cda93c9"
|
resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-30.0.5.tgz#6a98dd80e0384ead67ed05643381395f6cda93c9"
|
||||||
@@ -10080,6 +10147,32 @@ js-yaml@^4.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
argparse "^2.0.1"
|
argparse "^2.0.1"
|
||||||
|
|
||||||
|
jsdom@26.1.0:
|
||||||
|
version "26.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-26.1.0.tgz#ab5f1c1cafc04bd878725490974ea5e8bf0c72b3"
|
||||||
|
integrity sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==
|
||||||
|
dependencies:
|
||||||
|
cssstyle "^4.2.1"
|
||||||
|
data-urls "^5.0.0"
|
||||||
|
decimal.js "^10.5.0"
|
||||||
|
html-encoding-sniffer "^4.0.0"
|
||||||
|
http-proxy-agent "^7.0.2"
|
||||||
|
https-proxy-agent "^7.0.6"
|
||||||
|
is-potential-custom-element-name "^1.0.1"
|
||||||
|
nwsapi "^2.2.16"
|
||||||
|
parse5 "^7.2.1"
|
||||||
|
rrweb-cssom "^0.8.0"
|
||||||
|
saxes "^6.0.0"
|
||||||
|
symbol-tree "^3.2.4"
|
||||||
|
tough-cookie "^5.1.1"
|
||||||
|
w3c-xmlserializer "^5.0.0"
|
||||||
|
webidl-conversions "^7.0.0"
|
||||||
|
whatwg-encoding "^3.1.1"
|
||||||
|
whatwg-mimetype "^4.0.0"
|
||||||
|
whatwg-url "^14.1.1"
|
||||||
|
ws "^8.18.0"
|
||||||
|
xml-name-validator "^5.0.0"
|
||||||
|
|
||||||
jsdom@^25.0.1:
|
jsdom@^25.0.1:
|
||||||
version "25.0.1"
|
version "25.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-25.0.1.tgz#536ec685c288fc8a5773a65f82d8b44badcc73ef"
|
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-25.0.1.tgz#536ec685c288fc8a5773a65f82d8b44badcc73ef"
|
||||||
@@ -10107,32 +10200,6 @@ jsdom@^25.0.1:
|
|||||||
ws "^8.18.0"
|
ws "^8.18.0"
|
||||||
xml-name-validator "^5.0.0"
|
xml-name-validator "^5.0.0"
|
||||||
|
|
||||||
jsdom@^26.1.0:
|
|
||||||
version "26.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-26.1.0.tgz#ab5f1c1cafc04bd878725490974ea5e8bf0c72b3"
|
|
||||||
integrity sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==
|
|
||||||
dependencies:
|
|
||||||
cssstyle "^4.2.1"
|
|
||||||
data-urls "^5.0.0"
|
|
||||||
decimal.js "^10.5.0"
|
|
||||||
html-encoding-sniffer "^4.0.0"
|
|
||||||
http-proxy-agent "^7.0.2"
|
|
||||||
https-proxy-agent "^7.0.6"
|
|
||||||
is-potential-custom-element-name "^1.0.1"
|
|
||||||
nwsapi "^2.2.16"
|
|
||||||
parse5 "^7.2.1"
|
|
||||||
rrweb-cssom "^0.8.0"
|
|
||||||
saxes "^6.0.0"
|
|
||||||
symbol-tree "^3.2.4"
|
|
||||||
tough-cookie "^5.1.1"
|
|
||||||
w3c-xmlserializer "^5.0.0"
|
|
||||||
webidl-conversions "^7.0.0"
|
|
||||||
whatwg-encoding "^3.1.1"
|
|
||||||
whatwg-mimetype "^4.0.0"
|
|
||||||
whatwg-url "^14.1.1"
|
|
||||||
ws "^8.18.0"
|
|
||||||
xml-name-validator "^5.0.0"
|
|
||||||
|
|
||||||
jsesc@^3.0.2:
|
jsesc@^3.0.2:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d"
|
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d"
|
||||||
@@ -12284,6 +12351,11 @@ react-number-format@^5.4.3:
|
|||||||
resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-5.4.4.tgz#d31f0e260609431500c8d3f81bbd3ae1fb7cacad"
|
resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-5.4.4.tgz#d31f0e260609431500c8d3f81bbd3ae1fb7cacad"
|
||||||
integrity sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==
|
integrity sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==
|
||||||
|
|
||||||
|
react-refresh@^0.17.0:
|
||||||
|
version "0.17.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.17.0.tgz#b7e579c3657f23d04eccbe4ad2e58a8ed51e7e53"
|
||||||
|
integrity sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==
|
||||||
|
|
||||||
react-remove-scroll-bar@^2.3.7:
|
react-remove-scroll-bar@^2.3.7:
|
||||||
version "2.3.8"
|
version "2.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz#99c20f908ee467b385b68a3469b4a3e750012223"
|
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz#99c20f908ee467b385b68a3469b4a3e750012223"
|
||||||
@@ -13952,6 +14024,11 @@ tsc-alias@1.8.16:
|
|||||||
normalize-path "^3.0.0"
|
normalize-path "^3.0.0"
|
||||||
plimit-lit "^1.2.6"
|
plimit-lit "^1.2.6"
|
||||||
|
|
||||||
|
tsconfck@^3.0.3:
|
||||||
|
version "3.1.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-3.1.6.tgz#da1f0b10d82237ac23422374b3fce1edb23c3ead"
|
||||||
|
integrity sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==
|
||||||
|
|
||||||
tsconfig-paths@^3.15.0:
|
tsconfig-paths@^3.15.0:
|
||||||
version "3.15.0"
|
version "3.15.0"
|
||||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4"
|
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4"
|
||||||
@@ -14468,6 +14545,15 @@ vite-node@3.2.4:
|
|||||||
pathe "^2.0.3"
|
pathe "^2.0.3"
|
||||||
vite "^5.0.0 || ^6.0.0 || ^7.0.0-0"
|
vite "^5.0.0 || ^6.0.0 || ^7.0.0-0"
|
||||||
|
|
||||||
|
vite-tsconfig-paths@5.1.4:
|
||||||
|
version "5.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz#d9a71106a7ff2c1c840c6f1708042f76a9212ed4"
|
||||||
|
integrity sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==
|
||||||
|
dependencies:
|
||||||
|
debug "^4.1.1"
|
||||||
|
globrex "^0.1.2"
|
||||||
|
tsconfck "^3.0.3"
|
||||||
|
|
||||||
"vite@^5.0.0 || ^6.0.0 || ^7.0.0-0":
|
"vite@^5.0.0 || ^6.0.0 || ^7.0.0-0":
|
||||||
version "7.1.0"
|
version "7.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/vite/-/vite-7.1.0.tgz#6fb13c74c13cfdd0e200ee61d6ea6e8fafc2e8b5"
|
resolved "https://registry.yarnpkg.com/vite/-/vite-7.1.0.tgz#6fb13c74c13cfdd0e200ee61d6ea6e8fafc2e8b5"
|
||||||
|
|||||||
Reference in New Issue
Block a user