(
- initialDataFlowPaths,
- );
+ const [dataFlowPaths, setDataFlowPaths] = useState<
+ DataFlowPathsDomainModel | undefined
+ >(initialDataFlowPaths);
useEffect(() => {
const listener = (evt: MessageEvent) => {
@@ -20,6 +21,10 @@ export function DataFlowPathsView({
const msg: ToDataFlowPathsMessage = evt.data;
if (msg.t === "setDataFlowPaths") {
setDataFlowPaths(msg.dataFlowPaths);
+
+ // Scroll to the top of the page when we're rendering
+ // new data flow paths.
+ window.scrollTo(0, 0);
}
} else {
// sanitize origin
@@ -38,11 +43,5 @@ export function DataFlowPathsView({
return <>Loading data flow paths>;
}
- // For now, just render the data flows as JSON.
- return (
- <>
- Loaded
- {JSON.stringify(dataFlowPaths)}
- >
- );
+ return ;
}
diff --git a/extensions/ql-vscode/src/view/data-flow-paths/__tests__/DataFlowPaths.spec.tsx b/extensions/ql-vscode/src/view/data-flow-paths/__tests__/DataFlowPaths.spec.tsx
new file mode 100644
index 00000000000..02efd210590
--- /dev/null
+++ b/extensions/ql-vscode/src/view/data-flow-paths/__tests__/DataFlowPaths.spec.tsx
@@ -0,0 +1,31 @@
+import * as React from "react";
+import { render as reactRender, screen } from "@testing-library/react";
+import { DataFlowPaths, DataFlowPathsProps } from "../DataFlowPaths";
+import { createMockDataFlowPaths } from "../../../../test/factories/variant-analysis/shared/data-flow-paths";
+
+describe(DataFlowPaths.name, () => {
+ const render = (props: DataFlowPathsProps) =>
+ reactRender();
+
+ it("renders data flow paths", () => {
+ const dataFlowPaths = createMockDataFlowPaths();
+
+ render({ dataFlowPaths });
+
+ expect(screen.getByText(dataFlowPaths.ruleDescription)).toBeInTheDocument();
+ expect(
+ screen.getByText("1 paths available", { exact: false }),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByText("3 steps in", {
+ exact: false,
+ }),
+ ).toBeInTheDocument();
+
+ expect(
+ screen.getByText("This zip file may have a dangerous path", {
+ exact: false,
+ }),
+ ).toBeInTheDocument();
+ });
+});
diff --git a/extensions/ql-vscode/src/view/data-flow-paths/__tests__/DataFlowPathsView.spec.tsx b/extensions/ql-vscode/src/view/data-flow-paths/__tests__/DataFlowPathsView.spec.tsx
index da11f818f17..7baefc06cf6 100644
--- a/extensions/ql-vscode/src/view/data-flow-paths/__tests__/DataFlowPathsView.spec.tsx
+++ b/extensions/ql-vscode/src/view/data-flow-paths/__tests__/DataFlowPathsView.spec.tsx
@@ -4,6 +4,7 @@ import {
DataFlowPathsView,
DataFlowPathsViewProps,
} from "../DataFlowPathsView";
+import { createMockCodeFlows } from "../../../../test/factories/variant-analysis/shared/CodeFlow";
import { createMockDataFlowPaths } from "../../../../test/factories/variant-analysis/shared/data-flow-paths";
describe(DataFlowPathsView.name, () => {
@@ -17,8 +18,14 @@ describe(DataFlowPathsView.name, () => {
});
it("renders a data flow paths view", () => {
- render({ dataFlowPaths: createMockDataFlowPaths() });
+ const dataFlowPaths = createMockDataFlowPaths({
+ ruleDescription: "Rule description",
+ codeFlows: createMockCodeFlows(),
+ });
- expect(screen.getByText("Loaded")).toBeInTheDocument();
+ render({ dataFlowPaths });
+
+ expect(screen.queryByText("Code snippet text")).toBeInTheDocument();
+ expect(screen.getByText("Rule description")).toBeInTheDocument();
});
});
diff --git a/extensions/ql-vscode/test/factories/variant-analysis/shared/data-flow-paths.ts b/extensions/ql-vscode/test/factories/variant-analysis/shared/data-flow-paths.ts
index 18992421148..9f0ae98ac35 100644
--- a/extensions/ql-vscode/test/factories/variant-analysis/shared/data-flow-paths.ts
+++ b/extensions/ql-vscode/test/factories/variant-analysis/shared/data-flow-paths.ts
@@ -1,106 +1,122 @@
-import { CodeFlow } from "../../../../src/variant-analysis/shared/analysis-result";
+import {
+ AnalysisMessage,
+ CodeFlow,
+ ResultSeverity,
+} from "../../../../src/variant-analysis/shared/analysis-result";
import { DataFlowPaths } from "../../../../src/variant-analysis/shared/data-flow-paths";
-export function createMockDataFlowPaths(): DataFlowPaths {
- const codeFlows: CodeFlow[] = [
- {
- threadFlows: [
- {
- fileLink: {
- fileLinkPrefix:
- "https://github.com/PowerShell/PowerShell/blob/450d884668ca477c6581ce597958f021fac30bff",
- filePath:
- "src/System.Management.Automation/help/UpdatableHelpSystem.cs",
- },
- codeSnippet: {
- startLine: 1260,
- endLine: 1260,
- text: " string extractPath = Path.Combine(destination, entry.FullName);",
- },
- highlightedRegion: {
- startLine: 1260,
- startColumn: 72,
- endLine: 1260,
- endColumn: 86,
- },
- message: {
- tokens: [
- {
- t: "text",
- text: "access to property FullName : String",
- },
- ],
- },
+const defaultCodeFlows: CodeFlow[] = [
+ {
+ threadFlows: [
+ {
+ fileLink: {
+ fileLinkPrefix:
+ "https://github.com/PowerShell/PowerShell/blob/450d884668ca477c6581ce597958f021fac30bff",
+ filePath:
+ "src/System.Management.Automation/help/UpdatableHelpSystem.cs",
+ },
+ codeSnippet: {
+ startLine: 1260,
+ endLine: 1260,
+ text: " string extractPath = Path.Combine(destination, entry.FullName);",
+ },
+ highlightedRegion: {
+ startLine: 1260,
+ startColumn: 72,
+ endLine: 1260,
+ endColumn: 86,
+ },
+ message: {
+ tokens: [
+ {
+ t: "text",
+ text: "access to property FullName : String",
+ },
+ ],
+ },
+ },
+ {
+ fileLink: {
+ fileLinkPrefix:
+ "https://github.com/PowerShell/PowerShell/blob/450d884668ca477c6581ce597958f021fac30bff",
+ filePath:
+ "src/System.Management.Automation/help/UpdatableHelpSystem.cs",
+ },
+ codeSnippet: {
+ startLine: 1260,
+ endLine: 1260,
+ text: " string extractPath = Path.Combine(destination, entry.FullName);",
+ },
+ highlightedRegion: {
+ startLine: 1260,
+ startColumn: 46,
+ endLine: 1260,
+ endColumn: 87,
},
- {
- fileLink: {
- fileLinkPrefix:
- "https://github.com/PowerShell/PowerShell/blob/450d884668ca477c6581ce597958f021fac30bff",
- filePath:
- "src/System.Management.Automation/help/UpdatableHelpSystem.cs",
- },
- codeSnippet: {
- startLine: 1260,
- endLine: 1260,
- text: " string extractPath = Path.Combine(destination, entry.FullName);",
- },
- highlightedRegion: {
- startLine: 1260,
- startColumn: 46,
- endLine: 1260,
- endColumn: 87,
- },
- message: {
- tokens: [
- {
- t: "text",
- text: "call to method Combine : String",
- },
- ],
- },
+ message: {
+ tokens: [
+ {
+ t: "text",
+ text: "call to method Combine : String",
+ },
+ ],
},
- {
- fileLink: {
- fileLinkPrefix:
- "https://github.com/PowerShell/PowerShell/blob/450d884668ca477c6581ce597958f021fac30bff",
- filePath:
- "src/System.Management.Automation/help/UpdatableHelpSystem.cs",
- },
- codeSnippet: {
- startLine: 1261,
- endLine: 1261,
- text: " entry.ExtractToFile(extractPath);",
- },
- highlightedRegion: {
- startLine: 1261,
- startColumn: 45,
- endLine: 1261,
- endColumn: 56,
- },
- message: {
- tokens: [
- {
- t: "text",
- text: "access to local variable extractPath",
- },
- ],
- },
+ },
+ {
+ fileLink: {
+ fileLinkPrefix:
+ "https://github.com/PowerShell/PowerShell/blob/450d884668ca477c6581ce597958f021fac30bff",
+ filePath:
+ "src/System.Management.Automation/help/UpdatableHelpSystem.cs",
},
- ],
+ codeSnippet: {
+ startLine: 1261,
+ endLine: 1261,
+ text: " entry.ExtractToFile(extractPath);",
+ },
+ highlightedRegion: {
+ startLine: 1261,
+ startColumn: 45,
+ endLine: 1261,
+ endColumn: 56,
+ },
+ message: {
+ tokens: [
+ {
+ t: "text",
+ text: "access to local variable extractPath",
+ },
+ ],
+ },
+ },
+ ],
+ },
+];
+
+const defaultMessage: AnalysisMessage = {
+ tokens: [
+ {
+ t: "text",
+ text: "This zip file may have a dangerous path",
},
- ];
+ ],
+};
+export function createMockDataFlowPaths({
+ codeFlows = defaultCodeFlows,
+ ruleDescription = "ZipSlip vulnerability",
+ message = defaultMessage,
+ severity = "Warning",
+}: {
+ codeFlows?: CodeFlow[];
+ ruleDescription?: string;
+ message?: AnalysisMessage;
+ severity?: ResultSeverity;
+} = {}): DataFlowPaths {
return {
codeFlows,
- ruleDescription: "ZipSlip vulnerability",
- message: {
- tokens: [
- {
- t: "text",
- text: "This zip file may have a dangerous path",
- },
- ],
- },
- severity: "Warning",
+ ruleDescription,
+ message,
+ severity,
};
}