Module API for adding new file upload mechanisms (#33355)
* Initial reword of upload to MVVM. * Update tests * More incremental improvements * Refactor tests to use helper method for composer uploads. * Add drag and drop tests * lint * Add commentary * fixup test * More precise selector * Retarget uploads * lint * fixup * one more type * update snap * Fixup composerUploadFiles * fix import * lint * Copy and paste fixes too * Add tests for pasting * Add tests for pasting files. * Remove redundant fn * rm comment * tidy up * Test cleanup * More clean up * another fix * Begin fleshing out * Park changes * More stuff * Use condensed version * Cleanup tests * more cleaning * last bity * Add a test for the composer * Park up changes * Rewrite Measured to be a functional component * Add tests to cover narrow viewports * lint * breakpoint is optional * Cleanup * Support narrow mode * fixup * begone * Provide default value * add label * fixup test * update copyright * cleanup * Be a bit more lazy with FileDropTarget * remove a debug statement * Fixup * fix two snaps * Update screenshot * and the other one * Update snaps * unfake CIDER * update screens again * remove extra test * Undo accidental snapshots * Bit of tidyup * fixup * even more tidyup * may drag and drop file * tidy up again * snap snap snap * Use load to make sonarQube happy * Bunch of refactors * More cleanup * cleanup debug code * tweaks * remove a test we no longer need * make it happy * fix import * fixup * Update snaps * typo * one off * Add tests * lint * remove only * Reduce screenshot scope * fix snapshot usage * cleanup
This commit is contained in:
+86
-7
@@ -4,15 +4,21 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { type IEventRelation, type MatrixClient, type Room, RoomEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { render } from "jest-matrix-react";
|
||||
|
||||
import type { MockedObject } from "jest-mock";
|
||||
import { RoomUploadViewModel } from "../../../src/viewmodels/room/RoomUploadViewModel";
|
||||
import { mkEvent, mkStubRoom, stubClient } from "../../test-utils";
|
||||
import { RoomUploadContextProvider, RoomUploadViewModel } from "../../../src/viewmodels/room/RoomUploadViewModel";
|
||||
import { getRoomContext, mkEvent, mkStubRoom, stubClient } from "../../test-utils";
|
||||
import { TimelineRenderingType } from "../../../src/contexts/RoomContext";
|
||||
import type { MatrixDispatcher } from "../../../src/dispatcher/dispatcher";
|
||||
import defaultDispatcher, { MatrixDispatcher } from "../../../src/dispatcher/dispatcher";
|
||||
import ContentMessages from "../../../src/ContentMessages";
|
||||
import { ComposerApi } from "../../../src/modules/ComposerApi";
|
||||
import type { ComposerInsertFilesPayload } from "../../../src/dispatcher/payloads/ComposerInsertFilePayload";
|
||||
import { ScopedRoomContextProvider } from "../../../src/contexts/ScopedRoomContext";
|
||||
import { Action } from "../../../src/dispatcher/actions";
|
||||
import MatrixClientContext from "../../../src/contexts/MatrixClientContext";
|
||||
const sendContentListToRoomSpy = jest.spyOn(ContentMessages.sharedInstance(), "sendContentListToRoom");
|
||||
|
||||
describe("RoomUploadViewModel", () => {
|
||||
@@ -31,7 +37,7 @@ describe("RoomUploadViewModel", () => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it.each([true, false])("handles state of mayUpload when room.maySendMessage = %s", (maySendMessage) => {
|
||||
it.each([true, false])("handles state when room.maySendMessage = %s", (maySendMessage) => {
|
||||
room.maySendMessage.mockReturnValue(maySendMessage);
|
||||
const vm = new RoomUploadViewModel(
|
||||
room,
|
||||
@@ -42,10 +48,45 @@ describe("RoomUploadViewModel", () => {
|
||||
undefined,
|
||||
() => {},
|
||||
);
|
||||
expect(vm.getSnapshot().mayUpload).toEqual(maySendMessage);
|
||||
expect(vm.getSnapshot().options).toHaveLength(maySendMessage ? 1 : 0);
|
||||
room.maySendMessage.mockReturnValue(!maySendMessage);
|
||||
room.emit(RoomEvent.CurrentStateUpdated, room, null as any, null as any);
|
||||
expect(vm.getSnapshot().mayUpload).toEqual(!maySendMessage);
|
||||
expect(vm.getSnapshot().options).toHaveLength(maySendMessage ? 0 : 1);
|
||||
});
|
||||
|
||||
it("handles custom upload option", async () => {
|
||||
const compApi = new ComposerApi(new MatrixDispatcher());
|
||||
const replyEv = mkEvent({ type: "fake", content: {}, user: "any", event: true });
|
||||
const vm = new RoomUploadViewModel(
|
||||
room,
|
||||
client,
|
||||
TimelineRenderingType.Room,
|
||||
dis,
|
||||
replyEv,
|
||||
{
|
||||
rel_type: "any_type",
|
||||
},
|
||||
() => {},
|
||||
compApi,
|
||||
);
|
||||
const onSelected = jest.fn();
|
||||
const icon = { myicon: 5 } as any;
|
||||
compApi.addFileUploadOption({
|
||||
type: "org.example.test",
|
||||
label: "My uploader",
|
||||
icon,
|
||||
onSelected,
|
||||
});
|
||||
expect(vm.getSnapshot().options).toContainEqual({ type: "org.example.test", label: "My uploader", icon });
|
||||
vm.onUploadOptionSelected("org.example.test");
|
||||
expect(onSelected).toHaveBeenCalledWith(
|
||||
room.roomId,
|
||||
{ view: "room" },
|
||||
{
|
||||
inReplyToEventId: replyEv.getId(),
|
||||
relType: "any_type",
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe("uploads via input", () => {
|
||||
@@ -171,4 +212,42 @@ describe("RoomUploadViewModel", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("RoomUploadContextProvider", () => {
|
||||
it("uploads when called via module API", async () => {
|
||||
sendContentListToRoomSpy.mockResolvedValue(undefined);
|
||||
render(
|
||||
<MatrixClientContext.Provider value={client}>
|
||||
<ScopedRoomContextProvider {...getRoomContext(room, {})}>
|
||||
<RoomUploadContextProvider>
|
||||
<p>Any child</p>
|
||||
</RoomUploadContextProvider>
|
||||
</ScopedRoomContextProvider>
|
||||
</MatrixClientContext.Provider>,
|
||||
);
|
||||
const files = [
|
||||
{
|
||||
name: "fake.png",
|
||||
size: 1024,
|
||||
type: "image/png",
|
||||
},
|
||||
] as File[];
|
||||
defaultDispatcher.dispatch(
|
||||
{
|
||||
action: Action.ComposerFileInsert,
|
||||
files,
|
||||
timelineRenderingType: TimelineRenderingType.Room,
|
||||
} satisfies ComposerInsertFilesPayload,
|
||||
true,
|
||||
);
|
||||
expect(sendContentListToRoomSpy).toHaveBeenCalledWith(
|
||||
files,
|
||||
room.roomId,
|
||||
undefined,
|
||||
undefined,
|
||||
client,
|
||||
TimelineRenderingType.Room,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user