You've already forked matrix-react-sdk
mirror of
https://github.com/matrix-org/matrix-react-sdk.git
synced 2026-01-03 21:42:32 +03:00
Move from browser-request to fetch (#9345)
This commit is contained in:
committed by
GitHub
parent
ae883bb94b
commit
8b54be6f48
@@ -15,15 +15,31 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import { mocked } from "jest-mock";
|
||||
import { IImageInfo, ISendEventResponse, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { IImageInfo, ISendEventResponse, MatrixClient, RelationType, UploadResponse } from "matrix-js-sdk/src/matrix";
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
import encrypt, { IEncryptedFile } from "matrix-encrypt-attachment";
|
||||
|
||||
import ContentMessages from "../src/ContentMessages";
|
||||
import ContentMessages, { UploadCanceledError, uploadFile } from "../src/ContentMessages";
|
||||
import { doMaybeLocalRoomAction } from "../src/utils/local-room";
|
||||
import { createTestClient } from "./test-utils";
|
||||
import { BlurhashEncoder } from "../src/BlurhashEncoder";
|
||||
|
||||
jest.mock("matrix-encrypt-attachment", () => ({ encryptAttachment: jest.fn().mockResolvedValue({}) }));
|
||||
|
||||
jest.mock("../src/BlurhashEncoder", () => ({
|
||||
BlurhashEncoder: {
|
||||
instance: {
|
||||
getBlurhash: jest.fn(),
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock("../src/utils/local-room", () => ({
|
||||
doMaybeLocalRoomAction: jest.fn(),
|
||||
}));
|
||||
|
||||
const createElement = document.createElement.bind(document);
|
||||
|
||||
describe("ContentMessages", () => {
|
||||
const stickerUrl = "https://example.com/sticker";
|
||||
const roomId = "!room:example.com";
|
||||
@@ -36,6 +52,9 @@ describe("ContentMessages", () => {
|
||||
beforeEach(() => {
|
||||
client = {
|
||||
sendStickerMessage: jest.fn(),
|
||||
sendMessage: jest.fn(),
|
||||
isRoomEncrypted: jest.fn().mockReturnValue(false),
|
||||
uploadContent: jest.fn().mockResolvedValue({ content_uri: "mxc://server/file" }),
|
||||
} as unknown as MatrixClient;
|
||||
contentMessages = new ContentMessages();
|
||||
prom = Promise.resolve(null);
|
||||
@@ -65,4 +84,226 @@ describe("ContentMessages", () => {
|
||||
expect(client.sendStickerMessage).toHaveBeenCalledWith(roomId, null, stickerUrl, imageInfo, text);
|
||||
});
|
||||
});
|
||||
|
||||
describe("sendContentToRoom", () => {
|
||||
const roomId = "!roomId:server";
|
||||
beforeEach(() => {
|
||||
Object.defineProperty(global.Image.prototype, 'src', {
|
||||
// Define the property setter
|
||||
set(src) {
|
||||
setTimeout(() => this.onload());
|
||||
},
|
||||
});
|
||||
Object.defineProperty(global.Image.prototype, 'height', {
|
||||
get() { return 600; },
|
||||
});
|
||||
Object.defineProperty(global.Image.prototype, 'width', {
|
||||
get() { return 800; },
|
||||
});
|
||||
mocked(doMaybeLocalRoomAction).mockImplementation((
|
||||
roomId: string,
|
||||
fn: (actualRoomId: string) => Promise<ISendEventResponse>,
|
||||
) => fn(roomId));
|
||||
mocked(BlurhashEncoder.instance.getBlurhash).mockResolvedValue(undefined);
|
||||
});
|
||||
|
||||
it("should use m.image for image files", async () => {
|
||||
mocked(client.uploadContent).mockResolvedValue({ content_uri: "mxc://server/file" });
|
||||
const file = new File([], "fileName", { type: "image/jpeg" });
|
||||
await contentMessages.sendContentToRoom(file, roomId, undefined, client, undefined);
|
||||
expect(client.sendMessage).toHaveBeenCalledWith(roomId, null, expect.objectContaining({
|
||||
url: "mxc://server/file",
|
||||
msgtype: "m.image",
|
||||
}));
|
||||
});
|
||||
|
||||
it("should fall back to m.file for invalid image files", async () => {
|
||||
mocked(client.uploadContent).mockResolvedValue({ content_uri: "mxc://server/file" });
|
||||
const file = new File([], "fileName", { type: "image/png" });
|
||||
await contentMessages.sendContentToRoom(file, roomId, undefined, client, undefined);
|
||||
expect(client.sendMessage).toHaveBeenCalledWith(roomId, null, expect.objectContaining({
|
||||
url: "mxc://server/file",
|
||||
msgtype: "m.file",
|
||||
}));
|
||||
});
|
||||
|
||||
it("should use m.video for video files", async () => {
|
||||
jest.spyOn(document, "createElement").mockImplementation(tagName => {
|
||||
const element = createElement(tagName);
|
||||
if (tagName === "video") {
|
||||
element.load = jest.fn();
|
||||
element.play = () => element.onloadeddata(new Event("loadeddata"));
|
||||
element.pause = jest.fn();
|
||||
Object.defineProperty(element, 'videoHeight', {
|
||||
get() { return 600; },
|
||||
});
|
||||
Object.defineProperty(element, 'videoWidth', {
|
||||
get() { return 800; },
|
||||
});
|
||||
}
|
||||
return element;
|
||||
});
|
||||
|
||||
mocked(client.uploadContent).mockResolvedValue({ content_uri: "mxc://server/file" });
|
||||
const file = new File([], "fileName", { type: "video/mp4" });
|
||||
await contentMessages.sendContentToRoom(file, roomId, undefined, client, undefined);
|
||||
expect(client.sendMessage).toHaveBeenCalledWith(roomId, null, expect.objectContaining({
|
||||
url: "mxc://server/file",
|
||||
msgtype: "m.video",
|
||||
}));
|
||||
});
|
||||
|
||||
it("should use m.audio for audio files", async () => {
|
||||
mocked(client.uploadContent).mockResolvedValue({ content_uri: "mxc://server/file" });
|
||||
const file = new File([], "fileName", { type: "audio/mp3" });
|
||||
await contentMessages.sendContentToRoom(file, roomId, undefined, client, undefined);
|
||||
expect(client.sendMessage).toHaveBeenCalledWith(roomId, null, expect.objectContaining({
|
||||
url: "mxc://server/file",
|
||||
msgtype: "m.audio",
|
||||
}));
|
||||
});
|
||||
|
||||
it("should default to name 'Attachment' if file doesn't have a name", async () => {
|
||||
mocked(client.uploadContent).mockResolvedValue({ content_uri: "mxc://server/file" });
|
||||
const file = new File([], "", { type: "text/plain" });
|
||||
await contentMessages.sendContentToRoom(file, roomId, undefined, client, undefined);
|
||||
expect(client.sendMessage).toHaveBeenCalledWith(roomId, null, expect.objectContaining({
|
||||
url: "mxc://server/file",
|
||||
msgtype: "m.file",
|
||||
body: "Attachment",
|
||||
}));
|
||||
});
|
||||
|
||||
it("should keep RoomUpload's total and loaded values up to date", async () => {
|
||||
mocked(client.uploadContent).mockResolvedValue({ content_uri: "mxc://server/file" });
|
||||
const file = new File([], "", { type: "text/plain" });
|
||||
const prom = contentMessages.sendContentToRoom(file, roomId, undefined, client, undefined);
|
||||
const [upload] = contentMessages.getCurrentUploads();
|
||||
|
||||
expect(upload.loaded).toBe(0);
|
||||
expect(upload.total).toBe(file.size);
|
||||
const { progressHandler } = mocked(client.uploadContent).mock.calls[0][1];
|
||||
progressHandler({ loaded: 123, total: 1234 });
|
||||
expect(upload.loaded).toBe(123);
|
||||
expect(upload.total).toBe(1234);
|
||||
await prom;
|
||||
});
|
||||
});
|
||||
|
||||
describe("getCurrentUploads", () => {
|
||||
const file1 = new File([], "file1");
|
||||
const file2 = new File([], "file2");
|
||||
const roomId = "!roomId:server";
|
||||
|
||||
beforeEach(() => {
|
||||
mocked(doMaybeLocalRoomAction).mockImplementation((
|
||||
roomId: string,
|
||||
fn: (actualRoomId: string) => Promise<ISendEventResponse>,
|
||||
) => fn(roomId));
|
||||
});
|
||||
|
||||
it("should return only uploads for the given relation", async () => {
|
||||
const relation = {
|
||||
rel_type: RelationType.Thread,
|
||||
event_id: "!threadId:server",
|
||||
};
|
||||
const p1 = contentMessages.sendContentToRoom(file1, roomId, relation, client, undefined);
|
||||
const p2 = contentMessages.sendContentToRoom(file2, roomId, undefined, client, undefined);
|
||||
|
||||
const uploads = contentMessages.getCurrentUploads(relation);
|
||||
expect(uploads).toHaveLength(1);
|
||||
expect(uploads[0].relation).toEqual(relation);
|
||||
expect(uploads[0].fileName).toEqual("file1");
|
||||
await Promise.all([p1, p2]);
|
||||
});
|
||||
|
||||
it("should return only uploads for no relation when not passed one", async () => {
|
||||
const relation = {
|
||||
rel_type: RelationType.Thread,
|
||||
event_id: "!threadId:server",
|
||||
};
|
||||
const p1 = contentMessages.sendContentToRoom(file1, roomId, relation, client, undefined);
|
||||
const p2 = contentMessages.sendContentToRoom(file2, roomId, undefined, client, undefined);
|
||||
|
||||
const uploads = contentMessages.getCurrentUploads();
|
||||
expect(uploads).toHaveLength(1);
|
||||
expect(uploads[0].relation).toEqual(undefined);
|
||||
expect(uploads[0].fileName).toEqual("file2");
|
||||
await Promise.all([p1, p2]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("cancelUpload", () => {
|
||||
it("should cancel in-flight upload", async () => {
|
||||
const deferred = defer<UploadResponse>();
|
||||
mocked(client.uploadContent).mockReturnValue(deferred.promise);
|
||||
const file1 = new File([], "file1");
|
||||
const prom = contentMessages.sendContentToRoom(file1, roomId, undefined, client, undefined);
|
||||
const { abortController } = mocked(client.uploadContent).mock.calls[0][1];
|
||||
expect(abortController.signal.aborted).toBeFalsy();
|
||||
const [upload] = contentMessages.getCurrentUploads();
|
||||
contentMessages.cancelUpload(upload);
|
||||
expect(abortController.signal.aborted).toBeTruthy();
|
||||
deferred.resolve({} as UploadResponse);
|
||||
await prom;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("uploadFile", () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
const client = createTestClient();
|
||||
|
||||
it("should not encrypt the file if the room isn't encrypted", async () => {
|
||||
mocked(client.isRoomEncrypted).mockReturnValue(false);
|
||||
mocked(client.uploadContent).mockResolvedValue({ content_uri: "mxc://server/file" });
|
||||
const progressHandler = jest.fn();
|
||||
const file = new Blob([]);
|
||||
|
||||
const res = await uploadFile(client, "!roomId:server", file, progressHandler);
|
||||
|
||||
expect(res.url).toBe("mxc://server/file");
|
||||
expect(res.file).toBeFalsy();
|
||||
expect(encrypt.encryptAttachment).not.toHaveBeenCalled();
|
||||
expect(client.uploadContent).toHaveBeenCalledWith(file, expect.objectContaining({ progressHandler }));
|
||||
});
|
||||
|
||||
it("should encrypt the file if the room is encrypted", async () => {
|
||||
mocked(client.isRoomEncrypted).mockReturnValue(true);
|
||||
mocked(client.uploadContent).mockResolvedValue({ content_uri: "mxc://server/file" });
|
||||
mocked(encrypt.encryptAttachment).mockResolvedValue({
|
||||
data: new ArrayBuffer(123),
|
||||
info: {} as IEncryptedFile,
|
||||
});
|
||||
const progressHandler = jest.fn();
|
||||
const file = new Blob(["123"]);
|
||||
|
||||
const res = await uploadFile(client, "!roomId:server", file, progressHandler);
|
||||
|
||||
expect(res.url).toBeFalsy();
|
||||
expect(res.file).toEqual(expect.objectContaining({
|
||||
url: "mxc://server/file",
|
||||
}));
|
||||
expect(encrypt.encryptAttachment).toHaveBeenCalled();
|
||||
expect(client.uploadContent).toHaveBeenCalledWith(expect.any(Blob), expect.objectContaining({
|
||||
progressHandler,
|
||||
includeFilename: false,
|
||||
}));
|
||||
expect(mocked(client.uploadContent).mock.calls[0][0]).not.toBe(file);
|
||||
});
|
||||
|
||||
it("should throw UploadCanceledError upon aborting the upload", async () => {
|
||||
mocked(client.isRoomEncrypted).mockReturnValue(false);
|
||||
const deferred = defer<UploadResponse>();
|
||||
mocked(client.uploadContent).mockReturnValue(deferred.promise);
|
||||
const file = new Blob([]);
|
||||
|
||||
const prom = uploadFile(client, "!roomId:server", file);
|
||||
mocked(client.uploadContent).mock.calls[0][1].abortController.abort();
|
||||
deferred.resolve({ content_uri: "mxc://foo/bar" });
|
||||
await expect(prom).rejects.toThrowError(UploadCanceledError);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,47 +14,199 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { mocked } from "jest-mock";
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
|
||||
import ScalarAuthClient from '../src/ScalarAuthClient';
|
||||
import { MatrixClientPeg } from '../src/MatrixClientPeg';
|
||||
import { stubClient } from './test-utils';
|
||||
import SdkConfig from "../src/SdkConfig";
|
||||
import { WidgetType } from "../src/widgets/WidgetType";
|
||||
|
||||
describe('ScalarAuthClient', function() {
|
||||
const apiUrl = 'test.com/api';
|
||||
const uiUrl = 'test.com/app';
|
||||
const apiUrl = 'https://test.com/api';
|
||||
const uiUrl = 'https:/test.com/app';
|
||||
const tokenObject = {
|
||||
access_token: "token",
|
||||
token_type: "Bearer",
|
||||
matrix_server_name: "localhost",
|
||||
expires_in: 999,
|
||||
};
|
||||
|
||||
let client;
|
||||
beforeEach(function() {
|
||||
window.localStorage.getItem = jest.fn((arg) => {
|
||||
if (arg === "mx_scalar_token") return "brokentoken";
|
||||
});
|
||||
stubClient();
|
||||
jest.clearAllMocks();
|
||||
client = stubClient();
|
||||
});
|
||||
|
||||
it('should request a new token if the old one fails', async function() {
|
||||
const sac = new ScalarAuthClient(apiUrl, uiUrl);
|
||||
const sac = new ScalarAuthClient(apiUrl + 0, uiUrl);
|
||||
|
||||
// @ts-ignore unhappy with Promise calls
|
||||
jest.spyOn(sac, 'getAccountName').mockImplementation((arg: string) => {
|
||||
switch (arg) {
|
||||
case "brokentoken":
|
||||
return Promise.reject({
|
||||
message: "Invalid token",
|
||||
});
|
||||
case "wokentoken":
|
||||
default:
|
||||
return Promise.resolve(MatrixClientPeg.get().getUserId());
|
||||
}
|
||||
fetchMock.get("https://test.com/api0/account?scalar_token=brokentoken&v=1.1", {
|
||||
body: { message: "Invalid token" },
|
||||
});
|
||||
|
||||
MatrixClientPeg.get().getOpenIdToken = jest.fn().mockResolvedValue('this is your openid token');
|
||||
fetchMock.get("https://test.com/api0/account?scalar_token=wokentoken&v=1.1", {
|
||||
body: { user_id: client.getUserId() },
|
||||
});
|
||||
|
||||
client.getOpenIdToken = jest.fn().mockResolvedValue(tokenObject);
|
||||
|
||||
sac.exchangeForScalarToken = jest.fn((arg) => {
|
||||
if (arg === "this is your openid token") return Promise.resolve("wokentoken");
|
||||
if (arg === tokenObject) return Promise.resolve("wokentoken");
|
||||
});
|
||||
|
||||
await sac.connect();
|
||||
|
||||
expect(sac.exchangeForScalarToken).toBeCalledWith('this is your openid token');
|
||||
expect(sac.exchangeForScalarToken).toBeCalledWith(tokenObject);
|
||||
expect(sac.hasCredentials).toBeTruthy();
|
||||
// @ts-ignore private property
|
||||
expect(sac.scalarToken).toEqual('wokentoken');
|
||||
});
|
||||
|
||||
describe("exchangeForScalarToken", () => {
|
||||
it("should return `scalar_token` from API /register", async () => {
|
||||
const sac = new ScalarAuthClient(apiUrl + 1, uiUrl);
|
||||
|
||||
fetchMock.postOnce("https://test.com/api1/register?v=1.1", {
|
||||
body: { scalar_token: "stoken" },
|
||||
});
|
||||
|
||||
await expect(sac.exchangeForScalarToken(tokenObject)).resolves.toBe("stoken");
|
||||
});
|
||||
|
||||
it("should throw upon non-20x code", async () => {
|
||||
const sac = new ScalarAuthClient(apiUrl + 2, uiUrl);
|
||||
|
||||
fetchMock.postOnce("https://test.com/api2/register?v=1.1", {
|
||||
status: 500,
|
||||
});
|
||||
|
||||
await expect(sac.exchangeForScalarToken(tokenObject)).rejects.toThrow("Scalar request failed: 500");
|
||||
});
|
||||
|
||||
it("should throw if scalar_token is missing in response", async () => {
|
||||
const sac = new ScalarAuthClient(apiUrl + 3, uiUrl);
|
||||
|
||||
fetchMock.postOnce("https://test.com/api3/register?v=1.1", {
|
||||
body: {},
|
||||
});
|
||||
|
||||
await expect(sac.exchangeForScalarToken(tokenObject)).rejects.toThrow("Missing scalar_token in response");
|
||||
});
|
||||
});
|
||||
|
||||
describe("registerForToken", () => {
|
||||
it("should call `termsInteractionCallback` upon M_TERMS_NOT_SIGNED error", async () => {
|
||||
const sac = new ScalarAuthClient(apiUrl + 4, uiUrl);
|
||||
const termsInteractionCallback = jest.fn();
|
||||
sac.setTermsInteractionCallback(termsInteractionCallback);
|
||||
fetchMock.get("https://test.com/api4/account?scalar_token=testtoken1&v=1.1", {
|
||||
body: { errcode: "M_TERMS_NOT_SIGNED" },
|
||||
});
|
||||
sac.exchangeForScalarToken = jest.fn(() => Promise.resolve("testtoken1"));
|
||||
mocked(client.getTerms).mockResolvedValue({ policies: [] });
|
||||
|
||||
await expect(sac.registerForToken()).resolves.toBe("testtoken1");
|
||||
});
|
||||
|
||||
it("should throw upon non-20x code", async () => {
|
||||
const sac = new ScalarAuthClient(apiUrl + 5, uiUrl);
|
||||
fetchMock.get("https://test.com/api5/account?scalar_token=testtoken2&v=1.1", {
|
||||
body: { errcode: "SERVER_IS_SAD" },
|
||||
status: 500,
|
||||
});
|
||||
sac.exchangeForScalarToken = jest.fn(() => Promise.resolve("testtoken2"));
|
||||
|
||||
await expect(sac.registerForToken()).rejects.toBeTruthy();
|
||||
});
|
||||
|
||||
it("should throw if user_id is missing from response", async () => {
|
||||
const sac = new ScalarAuthClient(apiUrl + 6, uiUrl);
|
||||
fetchMock.get("https://test.com/api6/account?scalar_token=testtoken3&v=1.1", {
|
||||
body: {},
|
||||
});
|
||||
sac.exchangeForScalarToken = jest.fn(() => Promise.resolve("testtoken3"));
|
||||
|
||||
await expect(sac.registerForToken()).rejects.toThrow("Missing user_id in response");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getScalarPageTitle", () => {
|
||||
let sac: ScalarAuthClient;
|
||||
|
||||
beforeEach(async () => {
|
||||
SdkConfig.put({
|
||||
integrations_rest_url: apiUrl + 7,
|
||||
integrations_ui_url: uiUrl,
|
||||
});
|
||||
|
||||
window.localStorage.setItem("mx_scalar_token_at_https://test.com/api7", "wokentoken1");
|
||||
fetchMock.get("https://test.com/api7/account?scalar_token=wokentoken1&v=1.1", {
|
||||
body: { user_id: client.getUserId() },
|
||||
});
|
||||
|
||||
sac = new ScalarAuthClient(apiUrl + 7, uiUrl);
|
||||
await sac.connect();
|
||||
});
|
||||
|
||||
it("should return `cached_title` from API /widgets/title_lookup", async () => {
|
||||
const url = "google.com";
|
||||
fetchMock.get("https://test.com/api7/widgets/title_lookup?scalar_token=wokentoken1&curl=" + url, {
|
||||
body: {
|
||||
page_title_cache_item: {
|
||||
cached_title: "Google",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await expect(sac.getScalarPageTitle(url)).resolves.toBe("Google");
|
||||
});
|
||||
|
||||
it("should throw upon non-20x code", async () => {
|
||||
const url = "yahoo.com";
|
||||
fetchMock.get("https://test.com/api7/widgets/title_lookup?scalar_token=wokentoken1&curl=" + url, {
|
||||
status: 500,
|
||||
});
|
||||
|
||||
await expect(sac.getScalarPageTitle(url)).rejects.toThrow("Scalar request failed: 500");
|
||||
});
|
||||
});
|
||||
|
||||
describe("disableWidgetAssets", () => {
|
||||
let sac: ScalarAuthClient;
|
||||
|
||||
beforeEach(async () => {
|
||||
SdkConfig.put({
|
||||
integrations_rest_url: apiUrl + 8,
|
||||
integrations_ui_url: uiUrl,
|
||||
});
|
||||
|
||||
window.localStorage.setItem("mx_scalar_token_at_https://test.com/api8", "wokentoken1");
|
||||
fetchMock.get("https://test.com/api8/account?scalar_token=wokentoken1&v=1.1", {
|
||||
body: { user_id: client.getUserId() },
|
||||
});
|
||||
|
||||
sac = new ScalarAuthClient(apiUrl + 8, uiUrl);
|
||||
await sac.connect();
|
||||
});
|
||||
|
||||
it("should send state=disable to API /widgets/set_assets_state", async () => {
|
||||
fetchMock.get("https://test.com/api8/widgets/set_assets_state?scalar_token=wokentoken1" +
|
||||
"&widget_type=m.custom&widget_id=id1&state=disable", {
|
||||
body: "OK",
|
||||
});
|
||||
|
||||
await expect(sac.disableWidgetAssets(WidgetType.CUSTOM, "id1")).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it("should throw upon non-20x code", async () => {
|
||||
fetchMock.get("https://test.com/api8/widgets/set_assets_state?scalar_token=wokentoken1" +
|
||||
"&widget_type=m.custom&widget_id=id2&state=disable", {
|
||||
status: 500,
|
||||
});
|
||||
|
||||
await expect(sac.disableWidgetAssets(WidgetType.CUSTOM, "id2"))
|
||||
.rejects.toThrow("Scalar request failed: 500");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import { mocked } from "jest-mock";
|
||||
import { IAbortablePromise, IEncryptedFile, IUploadOpts, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { IEncryptedFile, UploadOpts, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { createVoiceMessageRecording, VoiceMessageRecording } from "../../src/audio/VoiceMessageRecording";
|
||||
import { RecordingState, VoiceRecording } from "../../src/audio/VoiceRecording";
|
||||
@@ -161,8 +161,8 @@ describe("VoiceMessageRecording", () => {
|
||||
matrixClient: MatrixClient,
|
||||
roomId: string,
|
||||
file: File | Blob,
|
||||
_progressHandler?: IUploadOpts["progressHandler"],
|
||||
): IAbortablePromise<{ url?: string, file?: IEncryptedFile }> => {
|
||||
_progressHandler?: UploadOpts["progressHandler"],
|
||||
): Promise<{ url?: string, file?: IEncryptedFile }> => {
|
||||
uploadFileClient = matrixClient;
|
||||
uploadFileRoomId = roomId;
|
||||
uploadBlob = file;
|
||||
|
||||
58
test/components/views/context_menus/EmbeddedPage-test.tsx
Normal file
58
test/components/views/context_menus/EmbeddedPage-test.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 2022 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 React from "react";
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { mocked } from "jest-mock";
|
||||
|
||||
import { _t } from "../../../../src/languageHandler";
|
||||
import EmbeddedPage from "../../../../src/components/structures/EmbeddedPage";
|
||||
|
||||
jest.mock("../../../../src/languageHandler", () => ({
|
||||
_t: jest.fn(),
|
||||
}));
|
||||
|
||||
describe("<EmbeddedPage />", () => {
|
||||
it("should translate _t strings", async () => {
|
||||
mocked(_t).mockReturnValue("Przeglądaj pokoje");
|
||||
fetchMock.get("https://home.page", {
|
||||
body: '<h1>_t("Explore rooms")</h1>',
|
||||
});
|
||||
|
||||
const { asFragment } = render(<EmbeddedPage url="https://home.page" />);
|
||||
await screen.findByText("Przeglądaj pokoje");
|
||||
expect(_t).toHaveBeenCalledWith("Explore rooms");
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should show error if unable to load", async () => {
|
||||
mocked(_t).mockReturnValue("Couldn't load page");
|
||||
fetchMock.get("https://other.page", {
|
||||
status: 404,
|
||||
});
|
||||
|
||||
const { asFragment } = render(<EmbeddedPage url="https://other.page" />);
|
||||
await screen.findByText("Couldn't load page");
|
||||
expect(_t).toHaveBeenCalledWith("Couldn't load page");
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should render nothing if no url given", () => {
|
||||
const { asFragment } = render(<EmbeddedPage />);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<EmbeddedPage /> should render nothing if no url given 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="undefined undefined_guest"
|
||||
>
|
||||
<div
|
||||
class="undefined_body"
|
||||
/>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<EmbeddedPage /> should show error if unable to load 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="undefined undefined_guest"
|
||||
>
|
||||
<div
|
||||
class="undefined_body"
|
||||
>
|
||||
Couldn't load page
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<EmbeddedPage /> should translate _t strings 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="undefined undefined_guest"
|
||||
>
|
||||
<div
|
||||
class="undefined_body"
|
||||
>
|
||||
<h1>
|
||||
Przeglądaj pokoje
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
104
test/components/views/dialogs/ChangelogDialog-test.tsx
Normal file
104
test/components/views/dialogs/ChangelogDialog-test.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright 2022 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 React from "react";
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
import { render, screen, waitForElementToBeRemoved } from "@testing-library/react";
|
||||
|
||||
import ChangelogDialog from "../../../../src/components/views/dialogs/ChangelogDialog";
|
||||
|
||||
describe("<ChangelogDialog />", () => {
|
||||
it("should fetch github proxy url for each repo with old and new version strings", async () => {
|
||||
const webUrl = "https://riot.im/github/repos/vector-im/element-web/compare/oldsha1...newsha1";
|
||||
fetchMock.get(webUrl, {
|
||||
url: "https://api.github.com/repos/vector-im/element-web/compare/master...develop",
|
||||
html_url: "https://github.com/vector-im/element-web/compare/master...develop",
|
||||
permalink_url: "https://github.com/vector-im/element-web/compare/vector-im:72ca95e...vector-im:8891698",
|
||||
diff_url: "https://github.com/vector-im/element-web/compare/master...develop.diff",
|
||||
patch_url: "https://github.com/vector-im/element-web/compare/master...develop.patch",
|
||||
base_commit: {},
|
||||
merge_base_commit: {},
|
||||
status: "ahead",
|
||||
ahead_by: 24,
|
||||
behind_by: 0,
|
||||
total_commits: 24,
|
||||
commits: [{
|
||||
sha: "commit-sha",
|
||||
html_url: "https://api.github.com/repos/vector-im/element-web/commit/commit-sha",
|
||||
commit: { message: "This is the first commit message" },
|
||||
}],
|
||||
files: [],
|
||||
});
|
||||
const reactUrl = "https://riot.im/github/repos/matrix-org/matrix-react-sdk/compare/oldsha2...newsha2";
|
||||
fetchMock.get(reactUrl, {
|
||||
url: "https://api.github.com/repos/matrix-org/matrix-react-sdk/compare/master...develop",
|
||||
html_url: "https://github.com/matrix-org/matrix-react-sdk/compare/master...develop",
|
||||
permalink_url: "https://github.com/matrix-org/matrix-react-sdk/compare/matrix-org:cdb00...matrix-org:4a926",
|
||||
diff_url: "https://github.com/matrix-org/matrix-react-sdk/compare/master...develop.diff",
|
||||
patch_url: "https://github.com/matrix-org/matrix-react-sdk/compare/master...develop.patch",
|
||||
base_commit: {},
|
||||
merge_base_commit: {},
|
||||
status: "ahead",
|
||||
ahead_by: 83,
|
||||
behind_by: 0,
|
||||
total_commits: 83,
|
||||
commits: [{
|
||||
sha: "commit-sha0",
|
||||
html_url: "https://api.github.com/repos/matrix-org/matrix-react-sdk/commit/commit-sha",
|
||||
commit: { message: "This is a commit message" },
|
||||
}],
|
||||
files: [],
|
||||
});
|
||||
const jsUrl = "https://riot.im/github/repos/matrix-org/matrix-js-sdk/compare/oldsha3...newsha3";
|
||||
fetchMock.get(jsUrl, {
|
||||
url: "https://api.github.com/repos/matrix-org/matrix-js-sdk/compare/master...develop",
|
||||
html_url: "https://github.com/matrix-org/matrix-js-sdk/compare/master...develop",
|
||||
permalink_url: "https://github.com/matrix-org/matrix-js-sdk/compare/matrix-org:6166a8f...matrix-org:fec350",
|
||||
diff_url: "https://github.com/matrix-org/matrix-js-sdk/compare/master...develop.diff",
|
||||
patch_url: "https://github.com/matrix-org/matrix-js-sdk/compare/master...develop.patch",
|
||||
base_commit: {},
|
||||
merge_base_commit: {},
|
||||
status: "ahead",
|
||||
ahead_by: 48,
|
||||
behind_by: 0,
|
||||
total_commits: 48,
|
||||
commits: [{
|
||||
sha: "commit-sha1",
|
||||
html_url: "https://api.github.com/repos/matrix-org/matrix-js-sdk/commit/commit-sha1",
|
||||
commit: { message: "This is a commit message" },
|
||||
}, {
|
||||
sha: "commit-sha2",
|
||||
html_url: "https://api.github.com/repos/matrix-org/matrix-js-sdk/commit/commit-sha2",
|
||||
commit: { message: "This is another commit message" },
|
||||
}],
|
||||
files: [],
|
||||
});
|
||||
|
||||
const newVersion = "newsha1-react-newsha2-js-newsha3";
|
||||
const oldVersion = "oldsha1-react-oldsha2-js-oldsha3";
|
||||
const { asFragment } = render((
|
||||
<ChangelogDialog newVersion={newVersion} version={oldVersion} onFinished={jest.fn()} />
|
||||
));
|
||||
|
||||
// Wait for spinners to go away
|
||||
await waitForElementToBeRemoved(screen.getAllByRole("progressbar"));
|
||||
|
||||
expect(fetchMock).toHaveFetched(webUrl);
|
||||
expect(fetchMock).toHaveFetched(reactUrl);
|
||||
expect(fetchMock).toHaveFetched(jsUrl);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -26,6 +26,11 @@ import SdkConfig from "../../../../src/SdkConfig";
|
||||
import { ValidatedServerConfig } from "../../../../src/utils/ValidatedServerConfig";
|
||||
import { IConfigOptions } from "../../../../src/IConfigOptions";
|
||||
|
||||
const mockGetAccessToken = jest.fn().mockResolvedValue("getAccessToken");
|
||||
jest.mock("../../../../src/IdentityAuthClient", () => jest.fn().mockImplementation(() => ({
|
||||
getAccessToken: mockGetAccessToken,
|
||||
})));
|
||||
|
||||
describe("InviteDialog", () => {
|
||||
const roomId = "!111111111111111111:example.org";
|
||||
const aliceId = "@alice:example.org";
|
||||
@@ -42,6 +47,14 @@ describe("InviteDialog", () => {
|
||||
getProfileInfo: jest.fn().mockRejectedValue({ errcode: "" }),
|
||||
getIdentityServerUrl: jest.fn(),
|
||||
searchUserDirectory: jest.fn().mockResolvedValue({}),
|
||||
lookupThreePid: jest.fn(),
|
||||
registerWithIdentityServer: jest.fn().mockResolvedValue({
|
||||
access_token: "access_token",
|
||||
token: "token",
|
||||
}),
|
||||
getOpenIdToken: jest.fn().mockResolvedValue({}),
|
||||
getIdentityAccount: jest.fn().mockResolvedValue({}),
|
||||
getTerms: jest.fn().mockResolvedValue({ policies: [] }),
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -85,7 +98,7 @@ describe("InviteDialog", () => {
|
||||
expect(screen.queryByText("Invite to Room")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should suggest valid MXIDs even if unknown", () => {
|
||||
it("should suggest valid MXIDs even if unknown", async () => {
|
||||
render((
|
||||
<InviteDialog
|
||||
kind={KIND_INVITE}
|
||||
@@ -95,7 +108,7 @@ describe("InviteDialog", () => {
|
||||
/>
|
||||
));
|
||||
|
||||
expect(screen.queryByText("@localpart:server.tld")).toBeFalsy();
|
||||
await screen.findAllByText("@localpart:server.tld"); // Using findAllByText as the MXID is used for name too
|
||||
});
|
||||
|
||||
it("should not suggest invalid MXIDs", () => {
|
||||
@@ -110,4 +123,48 @@ describe("InviteDialog", () => {
|
||||
|
||||
expect(screen.queryByText("@localpart:server:tld")).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should lookup inputs which look like email addresses", async () => {
|
||||
mockClient.getIdentityServerUrl.mockReturnValue("https://identity-server");
|
||||
mockClient.lookupThreePid.mockResolvedValue({
|
||||
address: "foobar@email.com",
|
||||
medium: "email",
|
||||
mxid: "@foobar:server",
|
||||
});
|
||||
mockClient.getProfileInfo.mockResolvedValue({
|
||||
displayname: "Mr. Foo",
|
||||
avatar_url: "mxc://foo/bar",
|
||||
});
|
||||
|
||||
render((
|
||||
<InviteDialog
|
||||
kind={KIND_INVITE}
|
||||
roomId={roomId}
|
||||
onFinished={jest.fn()}
|
||||
initialText="foobar@email.com"
|
||||
/>
|
||||
));
|
||||
|
||||
await screen.findByText("Mr. Foo");
|
||||
await screen.findByText("@foobar:server");
|
||||
expect(mockClient.lookupThreePid).toHaveBeenCalledWith("email", "foobar@email.com", expect.anything());
|
||||
expect(mockClient.getProfileInfo).toHaveBeenCalledWith("@foobar:server");
|
||||
});
|
||||
|
||||
it("should suggest e-mail even if lookup fails", async () => {
|
||||
mockClient.getIdentityServerUrl.mockReturnValue("https://identity-server");
|
||||
mockClient.lookupThreePid.mockResolvedValue({});
|
||||
|
||||
render((
|
||||
<InviteDialog
|
||||
kind={KIND_INVITE}
|
||||
roomId={roomId}
|
||||
onFinished={jest.fn()}
|
||||
initialText="foobar@email.com"
|
||||
/>
|
||||
));
|
||||
|
||||
await screen.findByText("foobar@email.com");
|
||||
await screen.findByText("Invite by email");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<ChangelogDialog /> should fetch github proxy url for each repo with old and new version strings 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-describedby="mx_Dialog_content"
|
||||
aria-labelledby="mx_BaseDialog_title"
|
||||
class="mx_QuestionDialog mx_Dialog_fixedWidth"
|
||||
data-focus-lock-disabled="false"
|
||||
role="dialog"
|
||||
>
|
||||
<div
|
||||
class="mx_Dialog_header mx_Dialog_headerWithCancel"
|
||||
>
|
||||
<h2
|
||||
class="mx_Heading_h2 mx_Dialog_title"
|
||||
id="mx_BaseDialog_title"
|
||||
>
|
||||
Changelog
|
||||
</h2>
|
||||
<div
|
||||
aria-label="Close dialog"
|
||||
class="mx_AccessibleButton mx_Dialog_cancelButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="mx_Dialog_content"
|
||||
id="mx_Dialog_content"
|
||||
>
|
||||
<div
|
||||
class="mx_ChangelogDialog_content"
|
||||
>
|
||||
<div>
|
||||
<h2>
|
||||
vector-im/element-web
|
||||
</h2>
|
||||
<ul>
|
||||
<li
|
||||
class="mx_ChangelogDialog_li"
|
||||
>
|
||||
<a
|
||||
href="https://api.github.com/repos/vector-im/element-web/commit/commit-sha"
|
||||
rel="noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
This is the first commit message
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h2>
|
||||
matrix-org/matrix-react-sdk
|
||||
</h2>
|
||||
<ul>
|
||||
<li
|
||||
class="mx_ChangelogDialog_li"
|
||||
>
|
||||
<a
|
||||
href="https://api.github.com/repos/matrix-org/matrix-react-sdk/commit/commit-sha"
|
||||
rel="noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
This is a commit message
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h2>
|
||||
matrix-org/matrix-js-sdk
|
||||
</h2>
|
||||
<ul>
|
||||
<li
|
||||
class="mx_ChangelogDialog_li"
|
||||
>
|
||||
<a
|
||||
href="https://api.github.com/repos/matrix-org/matrix-js-sdk/commit/commit-sha1"
|
||||
rel="noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
This is a commit message
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class="mx_ChangelogDialog_li"
|
||||
>
|
||||
<a
|
||||
href="https://api.github.com/repos/matrix-org/matrix-js-sdk/commit/commit-sha2"
|
||||
rel="noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
This is another commit message
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_Dialog_buttons"
|
||||
>
|
||||
<span
|
||||
class="mx_Dialog_buttons_row"
|
||||
>
|
||||
<button
|
||||
data-test-id="dialog-cancel-button"
|
||||
type="button"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
class="mx_Dialog_primary"
|
||||
data-test-id="dialog-primary-button"
|
||||
type="button"
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
@@ -364,7 +364,7 @@ describe('<RoomPreviewBar />', () => {
|
||||
|
||||
expect(getMessage(component)).toMatchSnapshot();
|
||||
expect(MatrixClientPeg.get().lookupThreePid).toHaveBeenCalledWith(
|
||||
'email', invitedEmail, undefined, 'mock-token',
|
||||
'email', invitedEmail, 'mock-token',
|
||||
);
|
||||
await testJoinButton({ inviterName, invitedEmail })();
|
||||
});
|
||||
|
||||
@@ -130,6 +130,20 @@ describe("createRoom", () => {
|
||||
expect(callPower).toBe(100);
|
||||
expect(callMemberPower).toBe(100);
|
||||
});
|
||||
|
||||
it("should upload avatar if one is passed", async () => {
|
||||
client.uploadContent.mockResolvedValue({ content_uri: "mxc://foobar" });
|
||||
const avatar = new File([], "avatar.png");
|
||||
await createRoom({ avatar });
|
||||
expect(client.createRoom).toHaveBeenCalledWith(expect.objectContaining({
|
||||
initial_state: expect.arrayContaining([{
|
||||
content: {
|
||||
url: "mxc://foobar",
|
||||
},
|
||||
type: "m.room.avatar",
|
||||
}]),
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe("canEncryptToAllUsers", () => {
|
||||
|
||||
@@ -27,10 +27,7 @@ import {
|
||||
import { stubClient } from '../test-utils';
|
||||
|
||||
describe('languageHandler', function() {
|
||||
/*
|
||||
See /__mocks__/browser-request.js/ for how we are stubbing out translations
|
||||
to provide fixture data for these tests
|
||||
*/
|
||||
// See setupLanguage.ts for how we are stubbing out translations to provide fixture data for these tests
|
||||
const basicString = 'Rooms';
|
||||
const selfClosingTagSub = 'Accept <policyLink /> to continue:';
|
||||
const textInTagSub = '<a>Upgrade</a> to your own domain';
|
||||
|
||||
@@ -14,7 +14,70 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
|
||||
import * as languageHandler from "../../src/languageHandler";
|
||||
import en from "../../src/i18n/strings/en_EN.json";
|
||||
import de from "../../src/i18n/strings/de_DE.json";
|
||||
|
||||
fetchMock.config.overwriteRoutes = false;
|
||||
fetchMock.catch("");
|
||||
window.fetch = fetchMock.sandbox();
|
||||
|
||||
const lv = {
|
||||
"Save": "Saglabāt",
|
||||
"Uploading %(filename)s and %(count)s others|one": "Качване на %(filename)s и %(count)s друг",
|
||||
};
|
||||
|
||||
// Fake languages.json containing references to en_EN, de_DE and lv
|
||||
// en_EN.json
|
||||
// de_DE.json
|
||||
// lv.json - mock version with few translations, used to test fallback translation
|
||||
|
||||
function weblateToCounterpart(inTrs: object): object {
|
||||
const outTrs = {};
|
||||
|
||||
for (const key of Object.keys(inTrs)) {
|
||||
const keyParts = key.split('|', 2);
|
||||
if (keyParts.length === 2) {
|
||||
let obj = outTrs[keyParts[0]];
|
||||
if (obj === undefined) {
|
||||
obj = outTrs[keyParts[0]] = {};
|
||||
} else if (typeof obj === "string") {
|
||||
// This is a transitional edge case if a string went from singular to pluralised and both still remain
|
||||
// in the translation json file. Use the singular translation as `other` and merge pluralisation atop.
|
||||
obj = outTrs[keyParts[0]] = {
|
||||
"other": inTrs[key],
|
||||
};
|
||||
console.warn("Found entry in i18n file in both singular and pluralised form", keyParts[0]);
|
||||
}
|
||||
obj[keyParts[1]] = inTrs[key];
|
||||
} else {
|
||||
outTrs[key] = inTrs[key];
|
||||
}
|
||||
}
|
||||
|
||||
return outTrs;
|
||||
}
|
||||
|
||||
fetchMock
|
||||
.get("/i18n/languages.json", {
|
||||
"en": {
|
||||
"fileName": "en_EN.json",
|
||||
"label": "English",
|
||||
},
|
||||
"de": {
|
||||
"fileName": "de_DE.json",
|
||||
"label": "German",
|
||||
},
|
||||
"lv": {
|
||||
"fileName": "lv.json",
|
||||
"label": "Latvian",
|
||||
},
|
||||
})
|
||||
.get("end:en_EN.json", weblateToCounterpart(en))
|
||||
.get("end:de_DE.json", weblateToCounterpart(de))
|
||||
.get("end:lv.json", weblateToCounterpart(lv));
|
||||
|
||||
languageHandler.setLanguage('en');
|
||||
languageHandler.setMissingEntryGenerator(key => key.split("|", 2)[1]);
|
||||
|
||||
@@ -45,6 +45,7 @@ global.matchMedia = mockMatchMedia;
|
||||
|
||||
// maplibre requires a createObjectURL mock
|
||||
global.URL.createObjectURL = jest.fn();
|
||||
global.URL.revokeObjectURL = jest.fn();
|
||||
|
||||
// polyfilling TextEncoder as it is not available on JSDOM
|
||||
// view https://github.com/facebook/jest/issues/9983
|
||||
|
||||
@@ -20,8 +20,7 @@ import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
|
||||
import { configure } from "enzyme";
|
||||
import "blob-polyfill"; // https://github.com/jsdom/jsdom/issues/2555
|
||||
|
||||
// Enable the jest & enzyme mocks
|
||||
require('jest-fetch-mock').enableMocks();
|
||||
// Enable the enzyme mocks
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
// Very carefully enable the mocks for everything else in
|
||||
|
||||
@@ -158,7 +158,7 @@ export function createTestClient(): MatrixClient {
|
||||
getOpenIdToken: jest.fn().mockResolvedValue(undefined),
|
||||
registerWithIdentityServer: jest.fn().mockResolvedValue({}),
|
||||
getIdentityAccount: jest.fn().mockResolvedValue({}),
|
||||
getTerms: jest.fn().mockResolvedValueOnce(undefined),
|
||||
getTerms: jest.fn().mockResolvedValue({ policies: [] }),
|
||||
doesServerSupportUnstableFeature: jest.fn().mockResolvedValue(undefined),
|
||||
isVersionSupported: jest.fn().mockResolvedValue(undefined),
|
||||
getPushRules: jest.fn().mockResolvedValue(undefined),
|
||||
@@ -182,6 +182,7 @@ export function createTestClient(): MatrixClient {
|
||||
setVideoInput: jest.fn(),
|
||||
setAudioInput: jest.fn(),
|
||||
} as unknown as MediaHandler),
|
||||
uploadContent: jest.fn(),
|
||||
} as unknown as MatrixClient;
|
||||
|
||||
client.reEmitter = new ReEmitter(client);
|
||||
|
||||
@@ -98,9 +98,9 @@ describe('MultiInviter', () => {
|
||||
const result = await inviter.invite([MXID1, MXID2, MXID3]);
|
||||
|
||||
expect(client.invite).toHaveBeenCalledTimes(3);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, undefined, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, undefined, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, undefined, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, undefined);
|
||||
|
||||
expectAllInvitedResult(result);
|
||||
});
|
||||
@@ -116,9 +116,9 @@ describe('MultiInviter', () => {
|
||||
const result = await inviter.invite([MXID1, MXID2, MXID3]);
|
||||
|
||||
expect(client.invite).toHaveBeenCalledTimes(3);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, undefined, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, undefined, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, undefined, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, undefined);
|
||||
|
||||
expectAllInvitedResult(result);
|
||||
});
|
||||
@@ -131,7 +131,7 @@ describe('MultiInviter', () => {
|
||||
const result = await inviter.invite([MXID1, MXID2, MXID3]);
|
||||
|
||||
expect(client.invite).toHaveBeenCalledTimes(1);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, undefined, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, undefined);
|
||||
|
||||
// The resolved state is 'invited' for all users.
|
||||
// With the above client expectations, the test ensures that only the first user is invited.
|
||||
|
||||
Reference in New Issue
Block a user