chore(deps): upgrade vitest and msw (#1852)
This commit is contained in:
@@ -139,15 +139,18 @@ overrides:
|
||||
'react/jsx-props-no-spreading': off
|
||||
- files:
|
||||
- app/**/*.test.*
|
||||
plugins:
|
||||
- '@vitest'
|
||||
extends:
|
||||
- 'plugin:vitest/recommended'
|
||||
- 'plugin:@vitest/legacy-recommended'
|
||||
env:
|
||||
'vitest/env': true
|
||||
'@vitest/env': true
|
||||
rules:
|
||||
'react/jsx-no-constructed-context-values': off
|
||||
'@typescript-eslint/no-restricted-imports': off
|
||||
no-restricted-imports: off
|
||||
'react/jsx-props-no-spreading': off
|
||||
'@vitest/no-conditional-expect': warn
|
||||
- files:
|
||||
- app/**/*.stories.*
|
||||
rules:
|
||||
|
||||
@@ -61,11 +61,8 @@ angular
|
||||
.config(configApp);
|
||||
|
||||
if (require) {
|
||||
const req = require.context('./', true, /^(.*\.(js$))[^.]*$/im);
|
||||
req
|
||||
.keys()
|
||||
.filter((path) => !path.includes('.test'))
|
||||
.forEach(function (key) {
|
||||
const req = require.context('./', true, /^(?!.*\.test\.js$).*\.js$/im);
|
||||
req.keys().forEach(function (key) {
|
||||
req(key);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,9 +19,7 @@ test('renders TemplateSelector component', async () => {
|
||||
});
|
||||
|
||||
// TODO skipped select tests because the tests take too long to run
|
||||
|
||||
// eslint-disable-next-line vitest/expect-expect
|
||||
test.skip('selects an edge app template', async () => {
|
||||
test.todo('selects an edge app template', async () => {
|
||||
const onChange = vi.fn();
|
||||
|
||||
const selectedTemplate = {
|
||||
@@ -50,8 +48,8 @@ test.skip('selects an edge app template', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
// eslint-disable-next-line vitest/expect-expect
|
||||
test.skip('selects an edge custom template', async () => {
|
||||
// eslint-disable-next-line @vitest/expect-expect
|
||||
test.todo('selects an edge custom template', async () => {
|
||||
const onChange = vi.fn();
|
||||
|
||||
const selectedTemplate = {
|
||||
@@ -87,7 +85,9 @@ test('renders with error', async () => {
|
||||
expect(errorElement).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test.skip('renders TemplateSelector component with no custom templates available', async () => {
|
||||
test.todo(
|
||||
'renders TemplateSelector component with no custom templates available',
|
||||
async () => {
|
||||
renderComponent({
|
||||
customTemplates: [],
|
||||
});
|
||||
@@ -101,7 +101,8 @@ test.skip('renders TemplateSelector component with no custom templates available
|
||||
'No edge custom templates available'
|
||||
);
|
||||
expect(noCustomTemplatesElement).toBeInTheDocument();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
function renderComponent({
|
||||
onChange = vi.fn(),
|
||||
|
||||
@@ -32,7 +32,7 @@ describe('getValidEditorTypes', () => {
|
||||
];
|
||||
|
||||
tests.forEach((test) => {
|
||||
// eslint-disable-next-line vitest/valid-title
|
||||
// eslint-disable-next-line @vitest/valid-title
|
||||
it(test.title, () => {
|
||||
expect(getValidEditorTypes(test.endpointTypes)).toEqual(test.expected);
|
||||
});
|
||||
|
||||
@@ -436,7 +436,7 @@ describe('getCreateAppSummaries', () => {
|
||||
},
|
||||
];
|
||||
tests.forEach((test) => {
|
||||
// eslint-disable-next-line vitest/valid-title
|
||||
// eslint-disable-next-line @vitest/valid-title
|
||||
it(test.title, () => {
|
||||
expect(
|
||||
getAppResourceSummaries(test.newFormValues, test.oldFormValues)
|
||||
@@ -522,7 +522,7 @@ describe('getUpdateAppSummaries', () => {
|
||||
},
|
||||
];
|
||||
tests.forEach((test) => {
|
||||
// eslint-disable-next-line vitest/valid-title
|
||||
// eslint-disable-next-line @vitest/valid-title
|
||||
it(test.title, () => {
|
||||
expect(
|
||||
getAppResourceSummaries(test.newFormValues, test.oldFormValues)
|
||||
|
||||
@@ -11,16 +11,25 @@ import { KubectlShellView } from './KubectlShellView';
|
||||
|
||||
// Mock modules first
|
||||
vi.mock('xterm', () => ({
|
||||
Terminal: vi.fn(() => ({
|
||||
open: vi.fn(),
|
||||
setOption: vi.fn(),
|
||||
focus: vi.fn(),
|
||||
writeln: vi.fn(),
|
||||
writeUtf8: vi.fn(),
|
||||
onData: vi.fn(),
|
||||
onKey: vi.fn(),
|
||||
dispose: vi.fn(),
|
||||
})),
|
||||
Terminal: vi.fn(
|
||||
class {
|
||||
open = vi.fn();
|
||||
|
||||
setOption = vi.fn();
|
||||
|
||||
focus = vi.fn();
|
||||
|
||||
writeln = vi.fn();
|
||||
|
||||
writeUtf8 = vi.fn();
|
||||
|
||||
onData = vi.fn();
|
||||
|
||||
onKey = vi.fn();
|
||||
|
||||
dispose = vi.fn();
|
||||
}
|
||||
),
|
||||
}));
|
||||
|
||||
vi.mock('xterm/lib/addons/fit/fit', () => ({
|
||||
@@ -70,9 +79,9 @@ beforeEach(() => {
|
||||
};
|
||||
|
||||
// Mock Terminal constructor to return our mock instance
|
||||
vi.mocked(Terminal).mockImplementation(
|
||||
() => mockTerminalInstance as Terminal
|
||||
);
|
||||
vi.mocked(Terminal).mockImplementation(function (this: Terminal) {
|
||||
Object.assign(this, mockTerminalInstance);
|
||||
});
|
||||
|
||||
// Create mock WebSocket instance
|
||||
mockWebSocket = {
|
||||
@@ -83,7 +92,17 @@ beforeEach(() => {
|
||||
readyState: WebSocket.OPEN,
|
||||
};
|
||||
|
||||
global.WebSocket = vi.fn(() => mockWebSocket) as unknown as typeof WebSocket;
|
||||
global.WebSocket = vi.fn(function (this: WebSocket) {
|
||||
this.send = mockWebSocket.send;
|
||||
this.close = mockWebSocket.close;
|
||||
this.addEventListener = mockWebSocket.addEventListener;
|
||||
this.removeEventListener = mockWebSocket.removeEventListener;
|
||||
Object.defineProperty(this, 'readyState', {
|
||||
get: () => mockWebSocket.readyState,
|
||||
configurable: true,
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
}) as any;
|
||||
|
||||
// Reset window methods
|
||||
Object.defineProperty(window, 'location', {
|
||||
|
||||
@@ -201,9 +201,7 @@ function renderComponent() {
|
||||
return render(<Wrapped />);
|
||||
}
|
||||
|
||||
describe(
|
||||
'HelmApplicationView',
|
||||
() => {
|
||||
describe('HelmApplicationView', () => {
|
||||
beforeEach(() => {
|
||||
// Set up default mock values
|
||||
mockUseEnvironmentId.mockReturnValue(3);
|
||||
@@ -303,8 +301,4 @@ describe(
|
||||
// Check for the app version in the summary section
|
||||
expect(await screen.findByText('1.0.0')).toBeInTheDocument();
|
||||
});
|
||||
},
|
||||
{
|
||||
timeout: 7000,
|
||||
}
|
||||
);
|
||||
}, 7000);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { http, HttpResponse } from 'msw';
|
||||
|
||||
import { server } from '@/setup-tests/server';
|
||||
import PortainerError from '@/portainer/error';
|
||||
|
||||
import { getLicenses } from './license.service';
|
||||
import type { License } from './types';
|
||||
@@ -37,7 +38,9 @@ describe('getLicenses', () => {
|
||||
const promise = getLicenses();
|
||||
await promise.then(thenFn, catchFn);
|
||||
|
||||
expect(catchFn).toHaveBeenCalledWith(new Error(details));
|
||||
expect(catchFn).toHaveBeenCalledWith(
|
||||
new PortainerError(details, new Error(message))
|
||||
);
|
||||
expect(thenFn).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,6 +19,7 @@ import { kubernetesHandlers } from './setup-handlers/kubernetes';
|
||||
import { endpointsHandlers } from './setup-handlers/endpoints';
|
||||
import { settingsHandlers } from './setup-handlers/settings';
|
||||
import { templatesHandlers } from './setup-handlers/templates';
|
||||
import { edgeHandlers } from './setup-handlers/edge';
|
||||
|
||||
const tags: Tag[] = [
|
||||
{ ID: 1, Name: 'tag1', Endpoints: {} },
|
||||
@@ -54,13 +55,14 @@ export const handlers = [
|
||||
...dockerHandlers,
|
||||
...userHandlers,
|
||||
...kubernetesHandlers,
|
||||
...edgeHandlers,
|
||||
http.get('/api/stacks', () => HttpResponse.json([])),
|
||||
http.get('/api/licenses/info', () => HttpResponse.json(licenseInfo)),
|
||||
http.get('/api/status/nodes', () => HttpResponse.json({ nodes: 3 })),
|
||||
http.get('/api/backup/s3/status', () => HttpResponse.json({ Failed: false })),
|
||||
http.get('/api/endpoint_groups', () => HttpResponse.json([])),
|
||||
http.get('/api/endpoint_groups/:groupId', ({ params }) => {
|
||||
if (params.groupId instanceof Array) {
|
||||
if (!params.groupId || params.groupId instanceof Array) {
|
||||
throw new Error('should be string');
|
||||
}
|
||||
const id = parseInt(params.groupId, 10);
|
||||
@@ -82,6 +84,9 @@ export const handlers = [
|
||||
http.get<never, never, Partial<StatusResponse>>('/api/status', () =>
|
||||
HttpResponse.json({})
|
||||
),
|
||||
http.get<never, never, Partial<StatusResponse>>('/api/system/status', () =>
|
||||
HttpResponse.json({})
|
||||
),
|
||||
http.get<never, never, Partial<VersionResponse>>('/api/system/version', () =>
|
||||
HttpResponse.json({ ServerVersion: 'v2.10.0' })
|
||||
),
|
||||
@@ -104,4 +109,6 @@ export const handlers = [
|
||||
HttpResponse.json({ success: true })
|
||||
),
|
||||
http.get('/api/webhooks', () => HttpResponse.json([])),
|
||||
http.get('/api/policies', () => HttpResponse.json([])),
|
||||
http.get('/api/roles', () => HttpResponse.json([])),
|
||||
];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'vitest-dom/extend-expect';
|
||||
import '@testing-library/jest-dom/vitest';
|
||||
|
||||
import { mockCodeMirror } from './mock-codemirror';
|
||||
|
||||
|
||||
@@ -2,4 +2,7 @@ import { http, HttpResponse } from 'msw';
|
||||
|
||||
export const dockerImagesHandlers = [
|
||||
http.get('/api/docker/:envId/images', () => HttpResponse.json([])),
|
||||
http.get('/api/endpoints/:id/docker/images/json', () =>
|
||||
HttpResponse.json([])
|
||||
),
|
||||
];
|
||||
|
||||
24
app/setup-tests/setup-handlers/edge.ts
Normal file
24
app/setup-tests/setup-handlers/edge.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { http, HttpResponse } from 'msw';
|
||||
|
||||
export const edgeHandlers = [
|
||||
http.get('/api/edge_configurations', () => HttpResponse.json([])),
|
||||
http.get('/api/edge_configurations/:id', () => HttpResponse.json({})),
|
||||
http.get('/api/edge_update_schedules', () => HttpResponse.json([])),
|
||||
http.get('/api/edge_update_schedules/:id', () => HttpResponse.json({})),
|
||||
http.get('/api/edge_groups', () => HttpResponse.json([])),
|
||||
http.get('/api/edge_jobs', () => HttpResponse.json([])),
|
||||
http.get('/api/edge_jobs/:id', () => HttpResponse.json({})),
|
||||
http.get('/api/edge_jobs/:id/file', () =>
|
||||
HttpResponse.json({ FileContent: '' })
|
||||
),
|
||||
http.get('/api/edge_stacks', () => HttpResponse.json([])),
|
||||
http.get('/api/edge_stacks/:id', () => HttpResponse.json({})),
|
||||
http.get('/api/edge_stacks/:id/stagger/status', () =>
|
||||
HttpResponse.json({
|
||||
status: 'idle',
|
||||
})
|
||||
),
|
||||
http.get('/api/edge_stacks/:id/file', () =>
|
||||
HttpResponse.json({ StackFileContent: '' })
|
||||
),
|
||||
];
|
||||
@@ -1,3 +1,4 @@
|
||||
import { NodeList } from 'kubernetes-types/core/v1';
|
||||
import { http, HttpResponse } from 'msw';
|
||||
|
||||
export const kubernetesHandlers = [
|
||||
@@ -20,7 +21,27 @@ export const kubernetesHandlers = [
|
||||
http.get('/api/kubernetes/:endpointId/customresourcedefinitions', () =>
|
||||
HttpResponse.json({})
|
||||
),
|
||||
http.get('/api/kubernetes/:endpointId/rbac_enabled', () =>
|
||||
HttpResponse.json(false)
|
||||
),
|
||||
http.get('/api/kubernetes/:endpointId/customresourcedefinitions/:name', () =>
|
||||
HttpResponse.json({})
|
||||
),
|
||||
http.get(
|
||||
'/api/kubernetes/:endpointId/namespaces/portainer/configmaps/:name',
|
||||
() => HttpResponse.json({})
|
||||
),
|
||||
http.get('/api/kubernetes/:endpointId/max_resource_limits', () =>
|
||||
HttpResponse.json({})
|
||||
),
|
||||
http.get('/api/kubernetes/:endpointId/ingresscontrollers', () =>
|
||||
HttpResponse.json([])
|
||||
),
|
||||
http.get('/api/kubernetes/:id/namespaces/:ns/ingresscontrollers', () =>
|
||||
HttpResponse.json([])
|
||||
),
|
||||
|
||||
http.get('/api/endpoints/:endpointId/kubernetes/api/v1/nodes', () =>
|
||||
HttpResponse.json({ items: [] } satisfies NodeList)
|
||||
),
|
||||
];
|
||||
|
||||
@@ -5,9 +5,14 @@ import { PublicSettingsResponse } from '@/react/portainer/settings/types';
|
||||
export const settingsHandlers = [
|
||||
http.get('/api/ssl', () => HttpResponse.json({})),
|
||||
http.get('/api/settings', () => HttpResponse.json({})),
|
||||
http.get('/api/settings/edge/mtls_certificate', () => HttpResponse.json({})),
|
||||
http.get('/api/settings/edge/mtls_ca_certificate', () =>
|
||||
HttpResponse.json({})
|
||||
),
|
||||
http.get('/api/settings/additional_functionality', () =>
|
||||
HttpResponse.json({})
|
||||
),
|
||||
http.get('/api/support/debug_log', () => HttpResponse.json({})),
|
||||
http.get<never, never, Partial<PublicSettingsResponse>>(
|
||||
'/api/settings/public',
|
||||
() =>
|
||||
|
||||
9
app/setup-tests/setup-websocket.ts
Normal file
9
app/setup-tests/setup-websocket.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
// MSW 2.x requires WebSocket to be writable in the global scope
|
||||
// In JSDOM, WebSocket is read-only by default, so we need to make it configurable
|
||||
if (typeof global.WebSocket !== 'undefined') {
|
||||
Object.defineProperty(global, 'WebSocket', {
|
||||
writable: true,
|
||||
configurable: true,
|
||||
value: global.WebSocket,
|
||||
});
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
import 'vitest-dom/extend-expect';
|
||||
import '@testing-library/jest-dom/vitest';
|
||||
|
||||
15
package.json
15
package.json
@@ -157,6 +157,7 @@
|
||||
"@storybook/react-webpack5": "8.6.15",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@testing-library/dom": "^9.3.4",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^12",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
@@ -168,6 +169,7 @@
|
||||
"@types/json-schema": "^7.0.15",
|
||||
"@types/lodash": "^4.17.21",
|
||||
"@types/mustache": "^4.1.2",
|
||||
"@types/node": "^22.19.11",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/qs": "^6.9.17",
|
||||
"@types/react": "^17.0.37",
|
||||
@@ -179,7 +181,8 @@
|
||||
"@types/uuid": "^3.3.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
||||
"@typescript-eslint/parser": "^6.7.4",
|
||||
"@vitest/coverage-v8": "~2.1.9",
|
||||
"@vitest/coverage-v8": "^4",
|
||||
"@vitest/eslint-plugin": "^1.6.7",
|
||||
"auto-ngtemplate-loader": "^3.1.2",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"babel-loader": "^9.1.3",
|
||||
@@ -204,7 +207,6 @@
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-regex": "^1.10.0",
|
||||
"eslint-plugin-storybook": "^9",
|
||||
"eslint-plugin-vitest": "^0.3.20",
|
||||
"html-loader": "^0.5.5",
|
||||
"html-webpack-plugin": "^5.5.3",
|
||||
"husky": "^8.0.0",
|
||||
@@ -212,7 +214,7 @@
|
||||
"lint-staged": "^14.0.1",
|
||||
"lodash-webpack-plugin": "^0.11.6",
|
||||
"mini-css-extract-plugin": "^2.7.6",
|
||||
"msw": "^2.0.11",
|
||||
"msw": "^2.12.10",
|
||||
"msw-storybook-addon": "^2.0.6",
|
||||
"ngtemplate-loader": "^2.1.0",
|
||||
"postcss": "^8.5.6",
|
||||
@@ -231,8 +233,7 @@
|
||||
"typescript": "^5.5.2",
|
||||
"vite-plugin-svgr": "^4.5.0",
|
||||
"vite-tsconfig-paths": "^4.3.1",
|
||||
"vitest": "~2.1.9",
|
||||
"vitest-dom": "^0.1.1",
|
||||
"vitest": "^4",
|
||||
"webpack": "^5.105.0",
|
||||
"webpack-build-notifier": "^3.1.0",
|
||||
"webpack-bundle-analyzer": "^5.2.0",
|
||||
@@ -253,10 +254,10 @@
|
||||
"@uirouter/angularjs": "1.0.11",
|
||||
"moment": "^2.21.0",
|
||||
"markdown-it": "^12.3.2",
|
||||
"msw>wrap-ansi": "^7.0.0",
|
||||
"@types/react": "^17.0.37",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"@types/node": "^25"
|
||||
"@types/node": "^25",
|
||||
"@open-amt-cloud-toolkit/ui-toolkit>ws": "^7.5.10"
|
||||
},
|
||||
"configDependencies": {
|
||||
"@pnpm/plugin-types-fixer": "0.1.0+sha512-bLww63gRHi7siYTqFJb5qNdcXadU0jv20Et6z5AryMZ7FlLolbEJOrXLpg8+amQZNHHNW1dfFUBGVw/9ezQbFg=="
|
||||
|
||||
1576
pnpm-lock.yaml
generated
1576
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -40,7 +40,7 @@
|
||||
// https://github.com/jsonnext/codemirror-json-schema/issues/107#issuecomment-2144584296
|
||||
"yaml-schema": ["../node_modules/codemirror-json-schema/dist/yaml"]
|
||||
},
|
||||
"types": ["vitest/globals"]
|
||||
"types": ["vitest/globals", "@testing-library/jest-dom", "node"]
|
||||
},
|
||||
"exclude": ["api", "build", "dist", "distribution", "node_modules", "test", "webpack"],
|
||||
"include": ["app", ".storybook"]
|
||||
|
||||
@@ -3,10 +3,16 @@ import tsconfigPaths from 'vite-tsconfig-paths';
|
||||
import svgr from 'vite-plugin-svgr';
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
// force tests to import svg as url
|
||||
// TODO consider removing when moving from webpack
|
||||
assetsInlineLimit: 0,
|
||||
},
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
setupFiles: [
|
||||
'./app/setup-tests/setup-websocket.ts',
|
||||
'./app/setup-tests/setup-rtl.ts',
|
||||
'./app/setup-tests/setup-msw.ts',
|
||||
'./app/setup-tests/stub-modules.ts',
|
||||
|
||||
Reference in New Issue
Block a user