Skip to content

Commit 72faf86

Browse files
committed
Add some simple model editor React unit tests
1 parent 9175449 commit 72faf86

5 files changed

Lines changed: 152 additions & 0 deletions

File tree

extensions/ql-vscode/src/model-editor/method.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ export interface MethodSignature {
3030
* e.g. `org.sql2o.Connection#createQuery(String)`
3131
*/
3232
signature: string;
33+
/**
34+
* The package name in Java, or the namespace in C#, e.g. `org.sql2o` or `System.Net.Http.Headers`.
35+
*
36+
* If the class is not in a package, the value should be an empty string.
37+
*/
3338
packageName: string;
3439
typeName: string;
3540
methodName: string;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import * as React from "react";
2+
import { render, screen } from "@testing-library/react";
3+
import { HiddenMethodsRow } from "../HiddenMethodsRow";
4+
5+
describe(HiddenMethodsRow.name, () => {
6+
it("does not render with 0 hidden methods", () => {
7+
const { container } = render(
8+
<HiddenMethodsRow numHiddenMethods={0} someMethodsAreVisible={true} />,
9+
);
10+
11+
expect(container).toBeEmptyDOMElement();
12+
});
13+
14+
it("renders with 1 hidden methods and no visible methods", () => {
15+
render(
16+
<HiddenMethodsRow numHiddenMethods={1} someMethodsAreVisible={false} />,
17+
);
18+
19+
expect(
20+
screen.getByText("1 method modeled in other CodeQL packs"),
21+
).toBeVisible();
22+
});
23+
24+
it("renders with 1 hidden methods and visible methods", () => {
25+
render(
26+
<HiddenMethodsRow numHiddenMethods={1} someMethodsAreVisible={true} />,
27+
);
28+
29+
expect(
30+
screen.getByText("And 1 method modeled in other CodeQL packs"),
31+
).toBeVisible();
32+
});
33+
34+
it("renders with 3 hidden methods and no visible methods", () => {
35+
render(
36+
<HiddenMethodsRow numHiddenMethods={3} someMethodsAreVisible={false} />,
37+
);
38+
39+
expect(
40+
screen.getByText("3 methods modeled in other CodeQL packs"),
41+
).toBeVisible();
42+
});
43+
44+
it("renders with 3 hidden methods and visible methods", () => {
45+
render(
46+
<HiddenMethodsRow numHiddenMethods={3} someMethodsAreVisible={true} />,
47+
);
48+
49+
expect(
50+
screen.getByText("And 3 methods modeled in other CodeQL packs"),
51+
).toBeVisible();
52+
});
53+
});
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import * as React from "react";
2+
import { render, screen } from "@testing-library/react";
3+
import { KindInput } from "../KindInput";
4+
import userEvent from "@testing-library/user-event";
5+
6+
describe(KindInput.name, () => {
7+
const onChange = jest.fn();
8+
9+
beforeEach(() => {
10+
onChange.mockReset();
11+
});
12+
13+
it("allows changing the kind", async () => {
14+
render(
15+
<KindInput
16+
kinds={["local", "remote"]}
17+
value="local"
18+
onChange={onChange}
19+
/>,
20+
);
21+
22+
expect(screen.getByRole("combobox")).toHaveValue("local");
23+
await userEvent.selectOptions(screen.getByRole("combobox"), "remote");
24+
expect(onChange).toHaveBeenCalledWith("remote");
25+
});
26+
27+
it("resets the kind when changing the supported kinds", () => {
28+
const { rerender } = render(
29+
<KindInput
30+
kinds={["local", "remote"]}
31+
value={"local"}
32+
onChange={onChange}
33+
/>,
34+
);
35+
36+
expect(screen.getByRole("combobox")).toHaveValue("local");
37+
expect(onChange).not.toHaveBeenCalled();
38+
39+
rerender(
40+
<KindInput
41+
kinds={["sql-injection", "log-injection", "url-redirection"]}
42+
value="local"
43+
onChange={onChange}
44+
/>,
45+
);
46+
expect(screen.getByRole("combobox")).toHaveValue("sql-injection");
47+
expect(onChange).toHaveBeenCalledWith("sql-injection");
48+
});
49+
50+
it("sets the kind when value is undefined", () => {
51+
render(
52+
<KindInput
53+
kinds={["local", "remote"]}
54+
value={undefined}
55+
onChange={onChange}
56+
/>,
57+
);
58+
59+
expect(screen.getByRole("combobox")).toHaveValue("local");
60+
expect(onChange).toHaveBeenCalledWith("local");
61+
});
62+
});

extensions/ql-vscode/src/view/model-editor/__tests__/MethodName.spec.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,13 @@ describe(MethodName.name, () => {
1414
const name = `${method.packageName}.${method.typeName}.${method.methodName}${method.methodParameters}`;
1515
expect(screen.getByText(name)).toBeInTheDocument();
1616
});
17+
18+
it("renders method name without package name", () => {
19+
const method = createMethod();
20+
method.packageName = "";
21+
render(method);
22+
23+
const name = `${method.typeName}.${method.methodName}${method.methodParameters}`;
24+
expect(screen.getByText(name)).toBeInTheDocument();
25+
});
1726
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import * as React from "react";
2+
import { render, screen } from "@testing-library/react";
3+
import { ModelingStatusIndicator } from "../ModelingStatusIndicator";
4+
5+
describe(ModelingStatusIndicator.name, () => {
6+
test.each([
7+
{
8+
status: "unmodeled",
9+
text: "Method not modeled",
10+
},
11+
{
12+
status: "unsaved",
13+
text: "Changes have not been saved",
14+
},
15+
{
16+
status: "saved",
17+
text: "Method modeled",
18+
},
19+
] as const)("renders %s status indicator", ({ status, text }) => {
20+
render(<ModelingStatusIndicator status={status} />);
21+
expect(screen.getByLabelText(text)).toBeVisible();
22+
});
23+
});

0 commit comments

Comments
 (0)