{
public render(): JSX.Element {
const { children: content, language } = this.props;
- const highlighted = language ? hljs.highlight(language, content) : hljs.highlightAuto(content);
+ const highlighted = language ? hljs.highlight(content, { language }) : hljs.highlightAuto(content);
return (
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 4da12e366b..54272b871c 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -3452,6 +3452,7 @@
"User menu": "User menu",
"Could not load user profile": "Could not load user profile",
"Decrypted event source": "Decrypted event source",
+ "Decrypted source unavailable": "Decrypted source unavailable",
"Original event source": "Original event source",
"Event ID: %(eventId)s": "Event ID: %(eventId)s",
"Thread root ID: %(threadRootId)s": "Thread root ID: %(threadRootId)s",
diff --git a/test/components/structures/ViewSource-test.tsx b/test/components/structures/ViewSource-test.tsx
new file mode 100644
index 0000000000..a4bc8b1eca
--- /dev/null
+++ b/test/components/structures/ViewSource-test.tsx
@@ -0,0 +1,59 @@
+/*
+Copyright 2023 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import { render } from "@testing-library/react";
+import { EventType, MatrixEvent } from "matrix-js-sdk/src/matrix";
+import React from "react";
+
+import ViewSource from "../../../src/components/structures/ViewSource";
+import { mkEvent, stubClient } from "../../test-utils/test-utils";
+
+describe("ThreadView", () => {
+ const ROOM_ID = "!roomId:example.org";
+ const SENDER = "@alice:example.org";
+
+ let messageEvent: MatrixEvent;
+
+ const redactionEvent = mkEvent({
+ user: SENDER,
+ event: true,
+ type: EventType.RoomRedaction,
+ content: {},
+ });
+
+ beforeEach(() => {
+ messageEvent = new MatrixEvent({
+ type: EventType.RoomMessageEncrypted,
+ room_id: ROOM_ID,
+ sender: SENDER,
+ content: {},
+ state_key: undefined,
+ });
+ messageEvent.makeRedacted(redactionEvent);
+ });
+
+ beforeEach(stubClient);
+
+ // See https://github.com/vector-im/element-web/issues/24165
+ it("doesn't error when viewing redacted encrypted messages", () => {
+ // Sanity checks
+ expect(messageEvent.isEncrypted()).toBeTruthy();
+ // @ts-ignore clearEvent is private, but it's being used directly
+ expect(messageEvent.clearEvent).toBe(undefined);
+
+ expect(() => render( {}} />)).not.toThrow();
+ });
+});
diff --git a/test/components/views/elements/SyntaxHighlight-test.tsx b/test/components/views/elements/SyntaxHighlight-test.tsx
new file mode 100644
index 0000000000..bdd3e50cf0
--- /dev/null
+++ b/test/components/views/elements/SyntaxHighlight-test.tsx
@@ -0,0 +1,38 @@
+/* eslint @typescript-eslint/no-unused-vars: ["error", { "varsIgnorePattern": "^_" }] */
+/*
+Copyright 2023 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import { render } from "@testing-library/react";
+import hljs, { type HighlightOptions } from "highlight.js";
+import React from "react";
+
+import SyntaxHighlight from "../../../../src/components/views/elements/SyntaxHighlight";
+
+describe("", () => {
+ it("renders", () => {
+ const { container } = render(console.log("Hello, World!"););
+ expect(container).toMatchSnapshot();
+ });
+
+ it.each(["json", "javascript", "css"])("uses the provided language", (lang) => {
+ const mock = jest.spyOn(hljs, "highlight");
+
+ render(// Hello, World);
+
+ const [_lang, opts] = mock.mock.lastCall!;
+ expect((opts as HighlightOptions)["language"]).toBe(lang);
+ });
+});
diff --git a/test/components/views/elements/__snapshots__/SyntaxHighlight-test.tsx.snap b/test/components/views/elements/__snapshots__/SyntaxHighlight-test.tsx.snap
new file mode 100644
index 0000000000..e7ad9c057b
--- /dev/null
+++ b/test/components/views/elements/__snapshots__/SyntaxHighlight-test.tsx.snap
@@ -0,0 +1,30 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` renders 1`] = `
+
+
+
+
+ console
+
+ .
+
+ log
+
+ (
+
+ "Hello, World!"
+
+ );
+
+
+
+`;