diff --git a/src/components/views/messages/DateSeparator.tsx b/src/components/views/messages/DateSeparator.tsx index a885806cf7..9edb5fb94e 100644 --- a/src/components/views/messages/DateSeparator.tsx +++ b/src/components/views/messages/DateSeparator.tsx @@ -320,7 +320,7 @@ export default class DateSeparator extends React.Component { const label = this.getLabel(); let dateHeaderContent: JSX.Element; - if (this.state.jumpToDateEnabled) { + if (this.state.jumpToDateEnabled && !this.props.forExport) { dateHeaderContent = this.renderJumpToDateMenu(); } else { dateHeaderContent = ( diff --git a/test/unit-tests/utils/exportUtils/HTMLExport-test.ts b/test/unit-tests/utils/exportUtils/HTMLExport-test.ts index 91c4c3febd..139ed83133 100644 --- a/test/unit-tests/utils/exportUtils/HTMLExport-test.ts +++ b/test/unit-tests/utils/exportUtils/HTMLExport-test.ts @@ -23,6 +23,7 @@ import { import fetchMock from "fetch-mock-jest"; import escapeHtml from "escape-html"; import { type RelationsContainer } from "matrix-js-sdk/src/models/relations-container"; +import { mocked } from "jest-mock"; import { filterConsole, mkReaction, mkStubRoom, REPEATABLE_DATE, stubClient } from "../../../test-utils"; import { ExportType, type IExportOptions } from "../../../../src/utils/exportUtils/exportUtils"; @@ -30,8 +31,10 @@ import SdkConfig from "../../../../src/SdkConfig"; import HTMLExporter from "../../../../src/utils/exportUtils/HtmlExport"; import DMRoomMap from "../../../../src/utils/DMRoomMap"; import { mediaFromMxc } from "../../../../src/customisations/Media"; +import SettingsStore from "../../../../src/settings/SettingsStore"; jest.mock("jszip"); +jest.mock("../../../../src/settings/SettingsStore"); const EVENT_MESSAGE: IRoomEvent = { event_id: "$1", @@ -88,6 +91,7 @@ describe("HTMLExport", () => { ); beforeEach(() => { + jest.clearAllMocks(); jest.useFakeTimers(); jest.setSystemTime(REPEATABLE_DATE); @@ -96,6 +100,13 @@ describe("HTMLExport", () => { room = new Room("!myroom:example.org", client, "@me:example.org"); client.getRoom.mockReturnValue(room); + + // Set up a default mock that uses the actual SettingsStore implementation + const actualSettingsStore = jest.requireActual("../../../../src/settings/SettingsStore").default; + mocked(SettingsStore).getValue.mockImplementation((name: any, roomId?: any, excludeDefault?: any): any => { + // Default to the real implementation + return actualSettingsStore.getValue(name, roomId, excludeDefault); + }); }); function mockMessages(...events: IRoomEvent[]): void { @@ -675,4 +686,34 @@ describe("HTMLExport", () => { const file = getMessageFile(exporter); expect(await file.text()).toContain(reaction.getContent()["m.relates_to"]?.key); }); + + it("should not crash when jump to date flag is enabled", async () => { + // Override just the feature flag for this specific test + const originalMock = mocked(SettingsStore).getValue.getMockImplementation(); + + mocked(SettingsStore).getValue.mockImplementation((name: any, roomId?: any, excludeDefault?: any): any => { + if (name === "feature_jump_to_date") { + return true; + } + // Fallback to the default mock implementation set in beforeEach + return originalMock!(name, roomId, excludeDefault); + }); + + mockMessages(EVENT_MESSAGE); + const exporter = new HTMLExporter( + room, + ExportType.LastNMessages, + { + attachmentsIncluded: false, + maxSize: 1_024 * 1_024, + numberOfMessages: 40, + }, + () => {}, + ); + + await exporter.export(); + + const file = getMessageFile(exporter); + expect(file).not.toBeUndefined(); + }); });