mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
chore: migrate some tests from jest to vitest (#20568)
This commit is contained in:
+4
-1
@@ -8,5 +8,8 @@
|
||||
"@types/react-virtualized-auto-sizer",
|
||||
"jest_workaround",
|
||||
"ts-proto"
|
||||
]
|
||||
],
|
||||
"jest": {
|
||||
"entry": "./src/**/*.jest.{ts,tsx}"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ module.exports = {
|
||||
testEnvironmentOptions: {
|
||||
customExportConditions: [""],
|
||||
},
|
||||
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
|
||||
testRegex: "(/__tests__/.*|(\\.|/)(jest))\\.tsx?$",
|
||||
testPathIgnorePatterns: [
|
||||
"/node_modules/",
|
||||
"/e2e/",
|
||||
|
||||
+8
-6
@@ -27,10 +27,10 @@
|
||||
"storybook": "STORYBOOK=true storybook dev -p 6006",
|
||||
"storybook:build": "storybook build",
|
||||
"storybook:ci": "storybook build --test",
|
||||
"test": "jest",
|
||||
"test:ci": "jest --selectProjects test --silent",
|
||||
"test:coverage": "jest --selectProjects test --collectCoverage",
|
||||
"test:watch": "jest --selectProjects test --watch",
|
||||
"test": "vitest run && jest",
|
||||
"test:ci": "vitest run && jest --silent",
|
||||
"test:watch": "vitest",
|
||||
"test:watch-jest": "jest --watch",
|
||||
"stats": "STATS=true pnpm build && npx http-server ./stats -p 8081 -c-1",
|
||||
"update-emojis": "cp -rf ./node_modules/emoji-datasource-apple/img/apple/64/* ./static/emojis"
|
||||
},
|
||||
@@ -133,7 +133,7 @@
|
||||
"@swc/core": "1.3.38",
|
||||
"@swc/jest": "0.2.37",
|
||||
"@tailwindcss/typography": "0.5.16",
|
||||
"@testing-library/jest-dom": "6.6.3",
|
||||
"@testing-library/jest-dom": "6.9.1",
|
||||
"@testing-library/react": "14.3.1",
|
||||
"@testing-library/user-event": "14.6.1",
|
||||
"@types/chroma-js": "2.4.0",
|
||||
@@ -167,6 +167,7 @@
|
||||
"jest-location-mock": "2.0.0",
|
||||
"jest-websocket-mock": "2.5.0",
|
||||
"jest_workaround": "0.1.14",
|
||||
"jsdom": "27.0.1",
|
||||
"knip": "5.64.1",
|
||||
"msw": "2.4.8",
|
||||
"postcss": "8.5.6",
|
||||
@@ -180,7 +181,8 @@
|
||||
"ts-proto": "1.181.2",
|
||||
"typescript": "5.6.3",
|
||||
"vite": "7.1.11",
|
||||
"vite-plugin-checker": "0.11.0"
|
||||
"vite-plugin-checker": "0.11.0",
|
||||
"vitest": "4.0.5"
|
||||
},
|
||||
"browserslist": [
|
||||
"chrome 110",
|
||||
|
||||
Generated
+543
-15
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -2759,7 +2759,7 @@ function getConfiguredAxiosInstance(): AxiosInstance {
|
||||
}
|
||||
} else {
|
||||
// Do not write error logs if we are in a FE unit test.
|
||||
if (process.env.JEST_WORKER_ID === undefined) {
|
||||
if (!process.env.JEST_WORKER_ID && !process.env.VITEST) {
|
||||
console.error("CSRF token not found");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ConfirmDialog } from "./ConfirmDialog";
|
||||
describe("ConfirmDialog", () => {
|
||||
it("onClose is called when cancelled", () => {
|
||||
// Given
|
||||
const onCloseMock = jest.fn();
|
||||
const onCloseMock = vi.fn();
|
||||
const props = {
|
||||
cancelText: "CANCEL",
|
||||
hideCancel: false,
|
||||
@@ -24,8 +24,8 @@ describe("ConfirmDialog", () => {
|
||||
|
||||
it("onConfirm is called when confirmed", () => {
|
||||
// Given
|
||||
const onCloseMock = jest.fn();
|
||||
const onConfirmMock = jest.fn();
|
||||
const onCloseMock = vi.fn();
|
||||
const onConfirmMock = vi.fn();
|
||||
const props = {
|
||||
cancelText: "CANCEL",
|
||||
confirmText: "CONFIRM",
|
||||
|
||||
@@ -23,8 +23,8 @@ describe("DeleteDialog", () => {
|
||||
renderComponent(
|
||||
<DeleteDialog
|
||||
isOpen
|
||||
onConfirm={jest.fn()}
|
||||
onCancel={jest.fn()}
|
||||
onConfirm={vi.fn()}
|
||||
onCancel={vi.fn()}
|
||||
entity="template"
|
||||
name="MyTemplate"
|
||||
/>,
|
||||
@@ -38,8 +38,8 @@ describe("DeleteDialog", () => {
|
||||
renderComponent(
|
||||
<DeleteDialog
|
||||
isOpen
|
||||
onConfirm={jest.fn()}
|
||||
onCancel={jest.fn()}
|
||||
onConfirm={vi.fn()}
|
||||
onCancel={vi.fn()}
|
||||
entity="template"
|
||||
name="MyTemplate"
|
||||
/>,
|
||||
@@ -56,8 +56,8 @@ describe("DeleteDialog", () => {
|
||||
renderComponent(
|
||||
<DeleteDialog
|
||||
isOpen
|
||||
onConfirm={jest.fn()}
|
||||
onCancel={jest.fn()}
|
||||
onConfirm={vi.fn()}
|
||||
onCancel={vi.fn()}
|
||||
entity="template"
|
||||
name="MyTemplate"
|
||||
/>,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { fireEvent, screen } from "@testing-library/react";
|
||||
import { FileUpload } from "./FileUpload";
|
||||
|
||||
test("accepts files with the correct extension", async () => {
|
||||
const onUpload = jest.fn();
|
||||
const onUpload = vi.fn();
|
||||
|
||||
renderComponent(
|
||||
<FileUpload
|
||||
@@ -21,14 +21,14 @@ test("accepts files with the correct extension", async () => {
|
||||
fireEvent.drop(dropZone, {
|
||||
dataTransfer: { files: [tarFile] },
|
||||
});
|
||||
expect(onUpload).toBeCalledWith(tarFile);
|
||||
expect(onUpload).toHaveBeenCalledWith(tarFile);
|
||||
onUpload.mockClear();
|
||||
|
||||
const zipFile = new File([""], "file.zip");
|
||||
fireEvent.drop(dropZone, {
|
||||
dataTransfer: { files: [zipFile] },
|
||||
});
|
||||
expect(onUpload).toBeCalledWith(zipFile);
|
||||
expect(onUpload).toHaveBeenCalledWith(zipFile);
|
||||
onUpload.mockClear();
|
||||
|
||||
const unsupportedFile = new File([""], "file.mp4");
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { Mock } from "vitest";
|
||||
import {
|
||||
displayError,
|
||||
displaySuccess,
|
||||
@@ -48,7 +49,7 @@ describe("Snackbar", () => {
|
||||
|
||||
describe("displaySuccess", () => {
|
||||
const originalWindowDispatchEvent = window.dispatchEvent;
|
||||
type TDispatchEventMock = jest.MockedFunction<
|
||||
type TDispatchEventMock = Mock<
|
||||
(msg: CustomEvent<NotificationMsg>) => boolean
|
||||
>;
|
||||
let dispatchEventMock: TDispatchEventMock;
|
||||
@@ -67,7 +68,7 @@ describe("Snackbar", () => {
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
dispatchEventMock = jest.fn();
|
||||
dispatchEventMock = vi.fn();
|
||||
window.dispatchEvent =
|
||||
dispatchEventMock as unknown as typeof window.dispatchEvent;
|
||||
});
|
||||
@@ -114,16 +115,18 @@ describe("Snackbar", () => {
|
||||
});
|
||||
|
||||
describe("displayError", () => {
|
||||
it("shows the title and the message", (done) => {
|
||||
it("shows the title and the message", () => {
|
||||
const message = "Some error happened";
|
||||
|
||||
window.addEventListener(SnackbarEventType, (event) => {
|
||||
const notificationEvent = event as CustomEvent<NotificationMsg>;
|
||||
expect(notificationEvent.detail.msg).toEqual(message);
|
||||
done();
|
||||
});
|
||||
return new Promise<void>((resolve) => {
|
||||
window.addEventListener(SnackbarEventType, (event) => {
|
||||
const notificationEvent = event as CustomEvent<NotificationMsg>;
|
||||
expect(notificationEvent.detail.msg).toEqual(message);
|
||||
resolve();
|
||||
});
|
||||
|
||||
displayError(message);
|
||||
displayError(message);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import { createTestQueryClient } from "testHelpers/renderHelpers";
|
||||
import { renderHook } from "@testing-library/react";
|
||||
import type { FC, PropsWithChildren } from "react";
|
||||
import { QueryClientProvider } from "react-query";
|
||||
import { AuthProvider, useAuthContext } from "./AuthProvider";
|
||||
|
||||
const Wrapper: FC<PropsWithChildren> = ({ children }) => {
|
||||
return (
|
||||
<QueryClientProvider client={createTestQueryClient()}>
|
||||
<AuthProvider>{children}</AuthProvider>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
};
|
||||
|
||||
describe("useAuth", () => {
|
||||
it("throws an error if it is used outside of <AuthProvider />", () => {
|
||||
jest.spyOn(console, "error").mockImplementation(() => {});
|
||||
|
||||
expect(() => {
|
||||
renderHook(() => useAuthContext());
|
||||
}).toThrow("useAuth should be used inside of <AuthProvider />");
|
||||
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("returns AuthContextValue when used inside of <AuthProvider />", () => {
|
||||
expect(() => {
|
||||
renderHook(() => useAuthContext(), {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
@@ -4,14 +4,14 @@ import { useCustomEvent } from "./events";
|
||||
|
||||
describe(useCustomEvent.name, () => {
|
||||
it("Should receive custom events dispatched by the dispatchCustomEvent function", async () => {
|
||||
const mockCallback = jest.fn();
|
||||
const mockCallback = vi.fn();
|
||||
const eventType = "testEvent";
|
||||
const detail = { title: "We have a new event!" };
|
||||
|
||||
renderHook(() => useCustomEvent(eventType, mockCallback));
|
||||
dispatchCustomEvent(eventType, detail);
|
||||
|
||||
await waitFor(() => expect(mockCallback).toBeCalledTimes(1));
|
||||
await waitFor(() => expect(mockCallback).toHaveBeenCalledTimes(1));
|
||||
expect(mockCallback.mock.calls[0]?.[0]?.detail).toBe(detail);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ describe(useEffectEvent.name, () => {
|
||||
}
|
||||
|
||||
it("Should maintain a stable reference across all renders", () => {
|
||||
const callback = jest.fn();
|
||||
const callback = vi.fn();
|
||||
const { result, rerender } = renderEffectEvent(callback);
|
||||
|
||||
const firstResult = result.current;
|
||||
@@ -28,8 +28,8 @@ describe(useEffectEvent.name, () => {
|
||||
});
|
||||
|
||||
it("Should always call the most recent callback passed in", () => {
|
||||
const mockCallback1 = jest.fn();
|
||||
const mockCallback2 = jest.fn();
|
||||
const mockCallback1 = vi.fn();
|
||||
const mockCallback2 = vi.fn();
|
||||
|
||||
const { result, rerender } = renderEffectEvent(mockCallback1);
|
||||
rerender({ callback: mockCallback2 });
|
||||
|
||||
@@ -35,14 +35,14 @@ const NonNativeButton: FC<NonNativeButtonProps<HTMLElement>> = ({
|
||||
|
||||
describe(useClickable.name, () => {
|
||||
it("Always defaults to role 'button'", () => {
|
||||
render(<NonNativeButton onInteraction={jest.fn()} />);
|
||||
render(<NonNativeButton onInteraction={vi.fn()} />);
|
||||
expect(() => screen.getByRole("button")).not.toThrow();
|
||||
});
|
||||
|
||||
it("Overrides the native role of any element that receives the hook result (be very careful with this behavior)", () => {
|
||||
const anchorText = "I'm a button that's secretly a link!";
|
||||
render(
|
||||
<NonNativeButton as="a" role="button" onInteraction={jest.fn()}>
|
||||
<NonNativeButton as="a" role="button" onInteraction={vi.fn()}>
|
||||
{anchorText}
|
||||
</NonNativeButton>,
|
||||
);
|
||||
@@ -55,7 +55,7 @@ describe(useClickable.name, () => {
|
||||
});
|
||||
|
||||
it("Always returns out the same role override received via arguments", () => {
|
||||
const placeholderCallback = jest.fn();
|
||||
const placeholderCallback = vi.fn();
|
||||
const roles = [
|
||||
"button",
|
||||
"switch",
|
||||
@@ -73,7 +73,7 @@ describe(useClickable.name, () => {
|
||||
|
||||
it("Allows an element to receive keyboard focus", async () => {
|
||||
const user = userEvent.setup();
|
||||
const mockCallback = jest.fn();
|
||||
const mockCallback = vi.fn();
|
||||
|
||||
render(<NonNativeButton role="button" onInteraction={mockCallback} />, {
|
||||
wrapper: ({ children }) => (
|
||||
@@ -90,7 +90,7 @@ describe(useClickable.name, () => {
|
||||
});
|
||||
|
||||
it("Allows an element to respond to clicks and Space/Enter, following all rules for native Button element interactions", async () => {
|
||||
const mockCallback = jest.fn();
|
||||
const mockCallback = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
render(<NonNativeButton role="button" onInteraction={mockCallback} />);
|
||||
|
||||
@@ -107,7 +107,7 @@ describe(useClickable.name, () => {
|
||||
});
|
||||
|
||||
it("Will keep firing events if the Enter key is held down", async () => {
|
||||
const mockCallback = jest.fn();
|
||||
const mockCallback = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
render(<NonNativeButton role="button" onInteraction={mockCallback} />);
|
||||
|
||||
@@ -119,7 +119,7 @@ describe(useClickable.name, () => {
|
||||
});
|
||||
|
||||
it("Will NOT keep firing events if the Space key is held down", async () => {
|
||||
const mockCallback = jest.fn();
|
||||
const mockCallback = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
render(<NonNativeButton role="button" onInteraction={mockCallback} />);
|
||||
|
||||
@@ -133,7 +133,7 @@ describe(useClickable.name, () => {
|
||||
});
|
||||
|
||||
test("If focus is lost while Space is held down, then releasing the key will do nothing", async () => {
|
||||
const mockCallback = jest.fn();
|
||||
const mockCallback = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(<NonNativeButton role="button" onInteraction={mockCallback} />, {
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
// TODO: This test is timing out after upgrade a few Jest dependencies
|
||||
// and I was not able to figure out why. When running it specifically, I
|
||||
// can see many act warnings that may can help us to find the issue.
|
||||
// (Note: This comment was originally written by Bruno, and was relocated by
|
||||
// me. If you go poking at `git blame`, disabling these tests was not my idea.
|
||||
|
||||
import { renderHookWithAuth } from "testHelpers/hooks";
|
||||
import { waitFor } from "@testing-library/react";
|
||||
import {
|
||||
@@ -303,7 +309,7 @@ describe.skip(usePaginatedQuery.name, () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe(`${usePaginatedQuery.name} - Returned properties`, () => {
|
||||
describe.skip(`${usePaginatedQuery.name} - Returned properties`, () => {
|
||||
describe("Page change methods", () => {
|
||||
const mockQueryKey = jest.fn(() => ["mock"]);
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import { App } from "App";
|
||||
import {
|
||||
MockEntitlementsWithAuditLog,
|
||||
MockMemberPermissions,
|
||||
} from "testHelpers/entities";
|
||||
import { server } from "testHelpers/server";
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { HttpResponse, http } from "msw";
|
||||
|
||||
/**
|
||||
* The LicenseBanner, mounted above the AppRouter, fetches entitlements. Thus, to test their
|
||||
* effects, we must test at the App level and `waitFor` the fetch to be done.
|
||||
*/
|
||||
describe("Navbar", () => {
|
||||
it("shows Audit Log link when permitted and entitled", async () => {
|
||||
// set entitlements to allow audit log
|
||||
server.use(
|
||||
http.get("/api/v2/entitlements", () => {
|
||||
return HttpResponse.json(MockEntitlementsWithAuditLog);
|
||||
}),
|
||||
);
|
||||
render(<App />);
|
||||
const deploymentMenu = await screen.findByText("Admin settings");
|
||||
await userEvent.click(deploymentMenu);
|
||||
await screen.findByText("Audit Logs");
|
||||
});
|
||||
|
||||
it("does not show Audit Log link when not entitled", async () => {
|
||||
// by default, user is an Admin with permission to see the audit log,
|
||||
// but is unlicensed so not entitled to see the audit log
|
||||
render(<App />);
|
||||
const deploymentMenu = await screen.findByText("Admin settings");
|
||||
await userEvent.click(deploymentMenu);
|
||||
await waitFor(
|
||||
() => {
|
||||
expect(screen.queryByText("Audit Logs")).not.toBeInTheDocument();
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
);
|
||||
});
|
||||
|
||||
it("does not show Audit Log link when not permitted via role", async () => {
|
||||
// set permissions to Member (can't audit)
|
||||
server.use(
|
||||
http.post("/api/v2/authcheck", async () => {
|
||||
return HttpResponse.json(MockMemberPermissions);
|
||||
}),
|
||||
);
|
||||
// set entitlements to allow audit log
|
||||
server.use(
|
||||
http.get("/api/v2/entitlements", () => {
|
||||
return HttpResponse.json(MockEntitlementsWithAuditLog);
|
||||
}),
|
||||
);
|
||||
render(<App />);
|
||||
await waitFor(
|
||||
() => {
|
||||
expect(screen.queryByText("Deployment")).not.toBeInTheDocument();
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,104 +0,0 @@
|
||||
import { MockPrimaryWorkspaceProxy, MockUserOwner } from "testHelpers/entities";
|
||||
import { renderWithAuth } from "testHelpers/renderHelpers";
|
||||
import { screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import type { ProxyContextValue } from "contexts/ProxyContext";
|
||||
import { NavbarView } from "./NavbarView";
|
||||
|
||||
const proxyContextValue: ProxyContextValue = {
|
||||
latenciesLoaded: true,
|
||||
proxy: {
|
||||
preferredPathAppURL: "",
|
||||
preferredWildcardHostname: "",
|
||||
proxy: MockPrimaryWorkspaceProxy,
|
||||
},
|
||||
isLoading: false,
|
||||
isFetched: true,
|
||||
setProxy: jest.fn(),
|
||||
clearProxy: jest.fn(),
|
||||
refetchProxyLatencies: jest.fn(),
|
||||
proxyLatencies: {},
|
||||
};
|
||||
|
||||
describe("NavbarView", () => {
|
||||
const noop = jest.fn();
|
||||
|
||||
it("workspaces nav link has the correct href", async () => {
|
||||
renderWithAuth(
|
||||
<NavbarView
|
||||
proxyContextValue={proxyContextValue}
|
||||
user={MockUserOwner}
|
||||
onSignOut={noop}
|
||||
canViewDeployment
|
||||
canViewOrganizations
|
||||
canViewHealth
|
||||
canViewAuditLog
|
||||
canViewConnectionLog
|
||||
supportLinks={[]}
|
||||
/>,
|
||||
);
|
||||
const workspacesLink =
|
||||
await screen.findByText<HTMLAnchorElement>(/workspaces/i);
|
||||
expect(workspacesLink.href).toContain("/workspaces");
|
||||
});
|
||||
|
||||
it("templates nav link has the correct href", async () => {
|
||||
renderWithAuth(
|
||||
<NavbarView
|
||||
proxyContextValue={proxyContextValue}
|
||||
user={MockUserOwner}
|
||||
onSignOut={noop}
|
||||
canViewDeployment
|
||||
canViewOrganizations
|
||||
canViewHealth
|
||||
canViewAuditLog
|
||||
canViewConnectionLog
|
||||
supportLinks={[]}
|
||||
/>,
|
||||
);
|
||||
const templatesLink =
|
||||
await screen.findByText<HTMLAnchorElement>(/templates/i);
|
||||
expect(templatesLink.href).toContain("/templates");
|
||||
});
|
||||
|
||||
it("audit nav link has the correct href", async () => {
|
||||
renderWithAuth(
|
||||
<NavbarView
|
||||
proxyContextValue={proxyContextValue}
|
||||
user={MockUserOwner}
|
||||
onSignOut={noop}
|
||||
canViewDeployment
|
||||
canViewOrganizations
|
||||
canViewHealth
|
||||
canViewAuditLog
|
||||
canViewConnectionLog
|
||||
supportLinks={[]}
|
||||
/>,
|
||||
);
|
||||
const deploymentMenu = await screen.findByText("Admin settings");
|
||||
await userEvent.click(deploymentMenu);
|
||||
const auditLink = await screen.findByText<HTMLAnchorElement>(/audit logs/i);
|
||||
expect(auditLink.href).toContain("/audit");
|
||||
});
|
||||
|
||||
it("deployment nav link has the correct href", async () => {
|
||||
renderWithAuth(
|
||||
<NavbarView
|
||||
proxyContextValue={proxyContextValue}
|
||||
user={MockUserOwner}
|
||||
onSignOut={noop}
|
||||
canViewDeployment
|
||||
canViewOrganizations
|
||||
canViewHealth
|
||||
canViewAuditLog
|
||||
canViewConnectionLog
|
||||
supportLinks={[]}
|
||||
/>,
|
||||
);
|
||||
const deploymentMenu = await screen.findByText("Admin settings");
|
||||
await userEvent.click(deploymentMenu);
|
||||
const deploymentSettingsLink =
|
||||
await screen.findByText<HTMLAnchorElement>(/deployment/i);
|
||||
expect(deploymentSettingsLink.href).toContain("/deployment");
|
||||
});
|
||||
});
|
||||
@@ -10,7 +10,7 @@ describe("UserDropdownContent", () => {
|
||||
<Popover>
|
||||
<UserDropdownContent
|
||||
user={MockUserOwner}
|
||||
onSignOut={jest.fn()}
|
||||
onSignOut={vi.fn()}
|
||||
supportLinks={[]}
|
||||
/>
|
||||
</Popover>,
|
||||
@@ -26,7 +26,7 @@ describe("UserDropdownContent", () => {
|
||||
});
|
||||
|
||||
it("calls the onSignOut function", async () => {
|
||||
const onSignOut = jest.fn();
|
||||
const onSignOut = vi.fn();
|
||||
render(
|
||||
<Popover>
|
||||
<UserDropdownContent
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import {
|
||||
MockListeningPortsResponse,
|
||||
MockTemplate,
|
||||
MockWorkspace,
|
||||
MockWorkspaceAgent,
|
||||
} from "testHelpers/entities";
|
||||
import {
|
||||
createTestQueryClient,
|
||||
renderComponent,
|
||||
} from "testHelpers/renderHelpers";
|
||||
import { screen } from "@testing-library/react";
|
||||
import { QueryClientProvider } from "react-query";
|
||||
import { PortForwardPopoverView } from "./PortForwardButton";
|
||||
|
||||
describe("Port Forward Popover View", () => {
|
||||
it("renders component", async () => {
|
||||
renderComponent(
|
||||
<QueryClientProvider client={createTestQueryClient()}>
|
||||
<PortForwardPopoverView
|
||||
agent={MockWorkspaceAgent}
|
||||
template={MockTemplate}
|
||||
listeningPorts={MockListeningPortsResponse.ports}
|
||||
portSharingControlsEnabled
|
||||
host="host"
|
||||
workspace={MockWorkspace}
|
||||
sharedPorts={[]}
|
||||
refetchSharedPorts={jest.fn()}
|
||||
/>
|
||||
</QueryClientProvider>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByText(MockListeningPortsResponse.ports[0].port),
|
||||
).toBeInTheDocument();
|
||||
|
||||
expect(
|
||||
screen.getByText(MockListeningPortsResponse.ports[0].process_name),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -1,53 +0,0 @@
|
||||
import { AppProviders } from "App";
|
||||
import {
|
||||
MockTemplateExample,
|
||||
MockTemplateExample2,
|
||||
} from "testHelpers/entities";
|
||||
import { server } from "testHelpers/server";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { RequireAuth } from "contexts/auth/RequireAuth";
|
||||
import { HttpResponse, http } from "msw";
|
||||
import { createMemoryRouter, RouterProvider } from "react-router";
|
||||
import CreateTemplateGalleryPage from "./CreateTemplateGalleryPage";
|
||||
|
||||
test("displays the scratch template", async () => {
|
||||
server.use(
|
||||
http.get("api/v2/templates/examples", () => {
|
||||
return HttpResponse.json([
|
||||
MockTemplateExample,
|
||||
MockTemplateExample2,
|
||||
{
|
||||
...MockTemplateExample,
|
||||
id: "scratch",
|
||||
name: "Scratch",
|
||||
description: "Create a template from scratch",
|
||||
},
|
||||
]);
|
||||
}),
|
||||
);
|
||||
|
||||
render(
|
||||
<AppProviders>
|
||||
<RouterProvider
|
||||
router={createMemoryRouter(
|
||||
[
|
||||
{
|
||||
element: <RequireAuth />,
|
||||
children: [
|
||||
{
|
||||
path: "/starter-templates",
|
||||
element: <CreateTemplateGalleryPage />,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
{ initialEntries: ["/starter-templates"] },
|
||||
)}
|
||||
/>
|
||||
</AppProviders>,
|
||||
);
|
||||
|
||||
await screen.findByText(MockTemplateExample.name);
|
||||
screen.getByText(MockTemplateExample2.name);
|
||||
expect(screen.queryByText("Scratch")).toBeInTheDocument();
|
||||
});
|
||||
+4
-5
@@ -144,17 +144,16 @@ describe("validationSchema", () => {
|
||||
expect(validate).toThrow(Language.errorTimezone);
|
||||
});
|
||||
|
||||
it.each<[string]>(timeZones.map((zone) => [zone]))(
|
||||
"validation passes for tz=%p",
|
||||
(zone) => {
|
||||
it("validation passes for all timezones", () => {
|
||||
for (const zone of timeZones) {
|
||||
const values: WorkspaceScheduleFormValues = {
|
||||
...valid,
|
||||
timezone: zone,
|
||||
};
|
||||
const validate = () => validationSchema.validateSync(values);
|
||||
expect(validate).not.toThrow();
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("allows a ttl of 7 days", () => {
|
||||
const values: WorkspaceScheduleFormValues = {
|
||||
@@ -507,10 +507,6 @@ export const MockAssignableSiteRoles = [
|
||||
assignableRole(MockWorkspaceCreationBanRole, true),
|
||||
];
|
||||
|
||||
export const MockMemberPermissions = {
|
||||
viewAuditLog: false,
|
||||
};
|
||||
|
||||
export const MockUserOwner: TypesGen.User = {
|
||||
id: "test-user",
|
||||
username: "TestUser",
|
||||
|
||||
@@ -2,17 +2,19 @@ import { dispatchCustomEvent, isCustomEvent } from "./events";
|
||||
|
||||
describe("events", () => {
|
||||
describe("dispatchCustomEvent", () => {
|
||||
it("dispatch a custom event", (done) => {
|
||||
it("dispatch a custom event", () => {
|
||||
const eventDetail = { title: "Event title" };
|
||||
|
||||
window.addEventListener("eventType", (event) => {
|
||||
if (isCustomEvent(event)) {
|
||||
expect(event.detail).toEqual(eventDetail);
|
||||
done();
|
||||
}
|
||||
});
|
||||
return new Promise<void>((resolve) => {
|
||||
window.addEventListener("eventType", (event) => {
|
||||
if (isCustomEvent(event)) {
|
||||
expect(event.detail).toEqual(eventDetail);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
dispatchCustomEvent("eventType", eventDetail);
|
||||
dispatchCustomEvent("eventType", eventDetail);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -320,7 +320,7 @@ export class TarWriter {
|
||||
uid: 1000,
|
||||
gid: 1000,
|
||||
mode: fileType === TarFileTypeCodes.File ? 0o664 : 0o775,
|
||||
mtime: ~~(Date.now() / 1000),
|
||||
mtime: Math.trunc(Date.now() / 1000),
|
||||
user: "tarballjs",
|
||||
group: "tarballjs",
|
||||
...opts,
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"target": "es2020",
|
||||
"types": ["jest", "node", "react", "react-dom", "vite/client"],
|
||||
"types": ["node", "react", "react-dom", "vite/client", "vitest/globals"],
|
||||
"baseUrl": "src/"
|
||||
},
|
||||
"include": ["**/*.ts", "**/*.tsx"],
|
||||
|
||||
+10
-1
@@ -1,8 +1,9 @@
|
||||
import * as path from "node:path";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { visualizer } from "rollup-plugin-visualizer";
|
||||
import { defineConfig, type PluginOption } from "vite";
|
||||
import type { PluginOption } from "vite";
|
||||
import checker from "vite-plugin-checker";
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
const plugins: PluginOption[] = [
|
||||
react(),
|
||||
@@ -120,6 +121,7 @@ export default defineConfig({
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
App: path.resolve(__dirname, "./src/App"),
|
||||
api: path.resolve(__dirname, "./src/api"),
|
||||
components: path.resolve(__dirname, "./src/components"),
|
||||
contexts: path.resolve(__dirname, "./src/contexts"),
|
||||
@@ -131,4 +133,11 @@ export default defineConfig({
|
||||
utils: path.resolve(__dirname, "./src/utils"),
|
||||
},
|
||||
},
|
||||
test: {
|
||||
include: ["src/**/*.test.?(m)ts?(x)"],
|
||||
globals: true,
|
||||
environment: "jsdom",
|
||||
setupFiles: ["@testing-library/jest-dom/vitest"],
|
||||
silent: "passed-only",
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user