Copilot commented on code in PR #708:
URL: https://github.com/apache/shenyu-dashboard/pull/708#discussion_r4229372259


##########
src/routes/Document/components/ApiDebug.test.js:
##########
@@ -131,3 +131,34 @@ it("validates HTTP(S) URLs with or without an explicit 
port", () => {
   expect(isValidHttpUrl("http://api.example.test:8080/orders";)).toBe(true);
   expect(isValidHttpUrl("ftp://api.example.test/orders";)).toBe(false);
 });
+
+it("renders a non-JSON response body as literal text instead of HTML", async 
() => {
+  const body =
+    '<img id="injected" src="x"><b>upstream</b>\n  <form id="fake"></form>';
+  fetch.mockResolvedValue({
+    text: async () => body,
+    headers: { get: () => null },
+  });
+  jest.spyOn(console, "error").mockImplementation(() => {});
+
+  const requestUrl = "https://api.example.test/orders";;
+  const { container } = render(
+    <ApiContext.Provider
+      value={{
+        ...contextValue,
+        apiDetail: { ...contextValue.apiDetail, apiPath: requestUrl },
+      }}
+    >
+      <ApiDebug />
+    </ApiContext.Provider>,
+  );
+
+  fireEvent.submit(container.querySelector("form"));
+
+  await waitFor(() => expect(container.querySelector("pre")).not.toBeNull());
+  const pre = container.querySelector("pre");
+  expect(pre.textContent).toBe(body);
+  expect(pre.children).toHaveLength(0);
+  expect(container.querySelector("#injected")).toBeNull();
+  expect(container.querySelector("#fake")).toBeNull();

Review Comment:
   The test replaces `console.error` but never restores it. This can leak into 
later tests and hide failures. Store the spy and call `mockRestore()` (or 
`jest.restoreAllMocks()`) in a cleanup step (e.g., `afterEach`) or in a 
`try/finally` around the assertions.



##########
src/routes/Document/components/ApiDebug.js:
##########
@@ -501,7 +500,10 @@ function ApiDebug() {
           Object.keys(responseInfo).length ? (
             <ReactJson src={responseInfo.body} name={false} />
           ) : responseInfo.body ? (
-            ReactHtmlParser(responseInfo.body)
+            // Non-JSON upstream bodies are untrusted: show them as text only.
+            <pre style={{ whiteSpace: "pre-wrap", wordWrap: "break-word" }}>

Review Comment:
   `wordWrap` is a legacy alias and is less consistently used than 
`overflowWrap`. Consider switching to `overflowWrap: "break-word"` (optionally 
with `wordBreak: "break-word"` if you need broader behavior) to better align 
with modern CSS and avoid relying on legacy properties.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to