You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-31 15:24:23 +03:00
Improve compliance with MSC3266 (#4155)
* Fix fields of MSC 3266 summary object Also remove redundant room_type field which is inherited from elsewhere * Export the MSC 3266 summary type * Use proper endpoint for MSC 3266 summary lookup Use the endpoint recommended by the MSC * Rename newly-exported symbol to not start with I * Use "export type" * Lint * Fix type of "encryption" field * Add TSDoc documentation * Add basic integration test for getRoomSummary * Lint * Use fallback endpoint for MSC3266 * Improve test coverage * Lint * Refactor async catch to satisfy linter * Increase test coverage
This commit is contained in:
committed by
GitHub
parent
6fedda91f9
commit
e874468ba3
@ -19,7 +19,16 @@ import { Mocked } from "jest-mock";
|
|||||||
import * as utils from "../test-utils/test-utils";
|
import * as utils from "../test-utils/test-utils";
|
||||||
import { CRYPTO_ENABLED, IStoredClientOpts, MatrixClient } from "../../src/client";
|
import { CRYPTO_ENABLED, IStoredClientOpts, MatrixClient } from "../../src/client";
|
||||||
import { MatrixEvent } from "../../src/models/event";
|
import { MatrixEvent } from "../../src/models/event";
|
||||||
import { Filter, KnockRoomOpts, MemoryStore, Method, Room, SERVICE_TYPES } from "../../src/matrix";
|
import {
|
||||||
|
Filter,
|
||||||
|
JoinRule,
|
||||||
|
KnockRoomOpts,
|
||||||
|
MemoryStore,
|
||||||
|
Method,
|
||||||
|
Room,
|
||||||
|
RoomSummary,
|
||||||
|
SERVICE_TYPES,
|
||||||
|
} from "../../src/matrix";
|
||||||
import { TestClient } from "../TestClient";
|
import { TestClient } from "../TestClient";
|
||||||
import { THREAD_RELATION_TYPE } from "../../src/models/thread";
|
import { THREAD_RELATION_TYPE } from "../../src/models/thread";
|
||||||
import { IFilterDefinition } from "../../src/filter";
|
import { IFilterDefinition } from "../../src/filter";
|
||||||
@ -1710,6 +1719,102 @@ describe("MatrixClient", function () {
|
|||||||
await Promise.all([client.unbindThreePid("email", "alice@server.com"), httpBackend.flushAllExpected()]);
|
await Promise.all([client.unbindThreePid("email", "alice@server.com"), httpBackend.flushAllExpected()]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("getRoomSummary", () => {
|
||||||
|
const roomId = "!foo:bar";
|
||||||
|
const encodedRoomId = encodeURIComponent(roomId);
|
||||||
|
|
||||||
|
const roomSummary: RoomSummary = {
|
||||||
|
"room_id": roomId,
|
||||||
|
"name": "My Room",
|
||||||
|
"avatar_url": "",
|
||||||
|
"topic": "My room topic",
|
||||||
|
"world_readable": false,
|
||||||
|
"guest_can_join": false,
|
||||||
|
"num_joined_members": 1,
|
||||||
|
"room_type": "",
|
||||||
|
"join_rule": JoinRule.Public,
|
||||||
|
"membership": "leave",
|
||||||
|
"im.nheko.summary.room_version": "6",
|
||||||
|
"im.nheko.summary.encryption": "algo",
|
||||||
|
};
|
||||||
|
|
||||||
|
const prefix = "/_matrix/client/unstable/im.nheko.summary/";
|
||||||
|
const suffix = `summary/${encodedRoomId}`;
|
||||||
|
const deprecatedSuffix = `rooms/${encodedRoomId}/summary`;
|
||||||
|
|
||||||
|
const errorUnrecogStatus = 404;
|
||||||
|
const errorUnrecogBody = {
|
||||||
|
errcode: "M_UNRECOGNIZED",
|
||||||
|
error: "Unsupported endpoint",
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorBadreqStatus = 400;
|
||||||
|
const errorBadreqBody = {
|
||||||
|
errcode: "M_UNKNOWN",
|
||||||
|
error: "Invalid request",
|
||||||
|
};
|
||||||
|
|
||||||
|
it("should respond with a valid room summary object", () => {
|
||||||
|
httpBackend.when("GET", prefix + suffix).respond(200, roomSummary);
|
||||||
|
|
||||||
|
const prom = client.getRoomSummary(roomId).then((response) => {
|
||||||
|
expect(response).toEqual(roomSummary);
|
||||||
|
});
|
||||||
|
|
||||||
|
httpBackend.flush("");
|
||||||
|
return prom;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should allow fallback to the deprecated endpoint", () => {
|
||||||
|
httpBackend.when("GET", prefix + suffix).respond(errorUnrecogStatus, errorUnrecogBody);
|
||||||
|
httpBackend.when("GET", prefix + deprecatedSuffix).respond(200, roomSummary);
|
||||||
|
|
||||||
|
const prom = client.getRoomSummary(roomId).then((response) => {
|
||||||
|
expect(response).toEqual(roomSummary);
|
||||||
|
});
|
||||||
|
|
||||||
|
httpBackend.flush("");
|
||||||
|
return prom;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should respond to unsupported path with error", () => {
|
||||||
|
httpBackend.when("GET", prefix + suffix).respond(errorUnrecogStatus, errorUnrecogBody);
|
||||||
|
httpBackend.when("GET", prefix + deprecatedSuffix).respond(errorUnrecogStatus, errorUnrecogBody);
|
||||||
|
|
||||||
|
const prom = client.getRoomSummary(roomId).then(
|
||||||
|
function (response) {
|
||||||
|
throw Error("request not failed");
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
expect(error.httpStatus).toEqual(errorUnrecogStatus);
|
||||||
|
expect(error.errcode).toEqual(errorUnrecogBody.errcode);
|
||||||
|
expect(error.message).toEqual(`MatrixError: [${errorUnrecogStatus}] ${errorUnrecogBody.error}`);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
httpBackend.flush("");
|
||||||
|
return prom;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should respond to invalid path arguments with error", () => {
|
||||||
|
httpBackend.when("GET", prefix).respond(errorBadreqStatus, errorBadreqBody);
|
||||||
|
|
||||||
|
const prom = client.getRoomSummary("notAroom").then(
|
||||||
|
function (response) {
|
||||||
|
throw Error("request not failed");
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
expect(error.httpStatus).toEqual(errorBadreqStatus);
|
||||||
|
expect(error.errcode).toEqual(errorBadreqBody.errcode);
|
||||||
|
expect(error.message).toEqual(`MatrixError: [${errorBadreqStatus}] ${errorBadreqBody.error}`);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
httpBackend.flush("");
|
||||||
|
return prom;
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function withThreadId(event: MatrixEvent, newThreadId: string): MatrixEvent {
|
function withThreadId(event: MatrixEvent, newThreadId: string): MatrixEvent {
|
||||||
|
@ -865,10 +865,24 @@ interface IThirdPartyUser {
|
|||||||
fields: object;
|
fields: object;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IRoomSummary extends Omit<IPublicRoomsChunkRoom, "canonical_alias" | "aliases"> {
|
/**
|
||||||
room_type?: RoomType;
|
* The summary of a room as defined by an initial version of MSC3266 and implemented in Synapse
|
||||||
membership?: Membership;
|
* Proposed at https://github.com/matrix-org/matrix-doc/pull/3266
|
||||||
is_encrypted: boolean;
|
*/
|
||||||
|
export interface RoomSummary extends Omit<IPublicRoomsChunkRoom, "canonical_alias" | "aliases"> {
|
||||||
|
/**
|
||||||
|
* The current membership of this user in the room.
|
||||||
|
* Usually "leave" if the room is fetched over federation.
|
||||||
|
*/
|
||||||
|
"membership"?: Membership;
|
||||||
|
/**
|
||||||
|
* Version of the room.
|
||||||
|
*/
|
||||||
|
"im.nheko.summary.room_version"?: string;
|
||||||
|
/**
|
||||||
|
* The encryption algorithm used for this room, if the room is encrypted.
|
||||||
|
*/
|
||||||
|
"im.nheko.summary.encryption"?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IRoomKeysResponse {
|
interface IRoomKeysResponse {
|
||||||
@ -9786,11 +9800,21 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
* @param roomIdOrAlias - The ID or alias of the room to get the summary of.
|
* @param roomIdOrAlias - The ID or alias of the room to get the summary of.
|
||||||
* @param via - The list of servers which know about the room if only an ID was provided.
|
* @param via - The list of servers which know about the room if only an ID was provided.
|
||||||
*/
|
*/
|
||||||
public async getRoomSummary(roomIdOrAlias: string, via?: string[]): Promise<IRoomSummary> {
|
public async getRoomSummary(roomIdOrAlias: string, via?: string[]): Promise<RoomSummary> {
|
||||||
const path = utils.encodeUri("/rooms/$roomid/summary", { $roomid: roomIdOrAlias });
|
const paramOpts = {
|
||||||
return this.http.authedRequest(Method.Get, path, { via }, undefined, {
|
|
||||||
prefix: "/_matrix/client/unstable/im.nheko.summary",
|
prefix: "/_matrix/client/unstable/im.nheko.summary",
|
||||||
});
|
};
|
||||||
|
try {
|
||||||
|
const path = utils.encodeUri("/summary/$roomid", { $roomid: roomIdOrAlias });
|
||||||
|
return await this.http.authedRequest(Method.Get, path, { via }, undefined, paramOpts);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof MatrixError && e.errcode === "M_UNRECOGNIZED") {
|
||||||
|
const path = utils.encodeUri("/rooms/$roomid/summary", { $roomid: roomIdOrAlias });
|
||||||
|
return await this.http.authedRequest(Method.Get, path, { via }, undefined, paramOpts);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,6 +77,7 @@ export * from "./@types/extensible_events";
|
|||||||
export * from "./@types/IIdentityServerProvider";
|
export * from "./@types/IIdentityServerProvider";
|
||||||
export * from "./models/room-summary";
|
export * from "./models/room-summary";
|
||||||
export * from "./models/event-status";
|
export * from "./models/event-status";
|
||||||
|
export type { RoomSummary } from "./client";
|
||||||
export * as ContentHelpers from "./content-helpers";
|
export * as ContentHelpers from "./content-helpers";
|
||||||
export * as SecretStorage from "./secret-storage";
|
export * as SecretStorage from "./secret-storage";
|
||||||
export type { ICryptoCallbacks } from "./crypto"; // used to be located here
|
export type { ICryptoCallbacks } from "./crypto"; // used to be located here
|
||||||
|
Reference in New Issue
Block a user