Skip to content

Commit

Permalink
Merge tag 'v23.5.0' into sc
Browse files Browse the repository at this point in the history
* Implement MSC3758: a push rule condition to match event properties exactly ([\matrix-org#3179](matrix-org#3179)).
* Enable group calls without video and audio track by configuration of MatrixClient ([\matrix-org#3162](matrix-org#3162)). Contributed by @EnricoSchw.
* Updates to protocol used for Sign in with QR code ([\matrix-org#3155](matrix-org#3155)). Contributed by @hughns.
* Implement MSC3873 to handle escaped dots in push rule keys ([\matrix-org#3134](matrix-org#3134)). Fixes undefined/matrix-js-sdk#1454.
* Fix spec compliance issue around encrypted `m.relates_to` ([\matrix-org#3178](matrix-org#3178)).
* Fix reactions in threads sometimes causing stuck notifications ([\matrix-org#3146](matrix-org#3146)). Fixes element-hq/element-web#24000. Contributed by @justjanne.
  • Loading branch information
su-ex committed Mar 15, 2023
2 parents 0c0854b + 26663e6 commit 589938f
Show file tree
Hide file tree
Showing 31 changed files with 1,923 additions and 793 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docs-pr-netlify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
# There's a 'download artifact' action, but it hasn't been updated for the workflow_run action
# (https://github.com/actions/download-artifact/issues/60) so instead we get this mess:
- name: 📥 Download artifact
uses: dawidd6/action-download-artifact@bd10f381a96414ce2b13a11bfa89902ba7cea07f # v2.24.3
uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 # v2.26.0
with:
workflow: static_analysis.yml
run_id: ${{ github.event.workflow_run.id }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ out

.vscode
.vscode/
.idea/
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
Changes in [23.5.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v23.5.0) (2023-03-15)
==================================================================================================

## ✨ Features
* Implement MSC3758: a push rule condition to match event properties exactly ([\#3179](https://github.com/matrix-org/matrix-js-sdk/pull/3179)).
* Enable group calls without video and audio track by configuration of MatrixClient ([\#3162](https://github.com/matrix-org/matrix-js-sdk/pull/3162)). Contributed by @EnricoSchw.
* Updates to protocol used for Sign in with QR code ([\#3155](https://github.com/matrix-org/matrix-js-sdk/pull/3155)). Contributed by @hughns.
* Implement MSC3873 to handle escaped dots in push rule keys ([\#3134](https://github.com/matrix-org/matrix-js-sdk/pull/3134)). Fixes undefined/matrix-js-sdk#1454.

## 🐛 Bug Fixes
* Fix spec compliance issue around encrypted `m.relates_to` ([\#3178](https://github.com/matrix-org/matrix-js-sdk/pull/3178)).
* Fix reactions in threads sometimes causing stuck notifications ([\#3146](https://github.com/matrix-org/matrix-js-sdk/pull/3146)). Fixes vector-im/element-web#24000. Contributed by @justjanne.

Changes in [23.4.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v23.4.0) (2023-02-28)
==================================================================================================

Expand All @@ -7,8 +20,6 @@ Changes in [23.4.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v23
* Polls: count undecryptable poll relations ([\#3163](https://github.com/matrix-org/matrix-js-sdk/pull/3163)). Contributed by @kerryarchibald.

## 🐛 Bug Fixes
* Fix spec compliance issue around encrypted `m.relates_to` ([\#3178](https://github.com/matrix-org/matrix-js-sdk/pull/3178)).
* Fix reactions in threads sometimes causing stuck notifications ([\#3146](https://github.com/matrix-org/matrix-js-sdk/pull/3146)). Fixes vector-im/element-web#24000. Contributed by @justjanne.
* Better type guard parseTopicContent ([\#3165](https://github.com/matrix-org/matrix-js-sdk/pull/3165)). Fixes matrix-org/element-web-rageshakes#20177 and matrix-org/element-web-rageshakes#20178.
* Fix a bug where events in encrypted rooms would sometimes erroneously increment the total unread counter after being processed locally. ([\#3130](https://github.com/matrix-org/matrix-js-sdk/pull/3130)). Fixes vector-im/element-web#24448. Contributed by @Half-Shot.
* Stop the ICE disconnected timer on call terminate ([\#3147](https://github.com/matrix-org/matrix-js-sdk/pull/3147)).
Expand Down
31 changes: 26 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "matrix-js-sdk",
"version": "23.4.0",
"version": "23.5.0",
"description": "Matrix Client-Server SDK for Javascript",
"engines": {
"node": ">=16.0.0"
Expand All @@ -14,7 +14,7 @@
"build:dev": "yarn clean && git rev-parse HEAD > git-revision.txt && yarn build:compile && yarn build:types",
"build:types": "tsc -p tsconfig-build.json --emitDeclarationOnly",
"build:compile": "babel -d lib --verbose --extensions \".ts,.js\" src",
"build:compile-browser": "mkdir dist && browserify -d src/browser-index.ts -p [ tsify -p ./tsconfig-build.json ] -t [ babelify --sourceMaps=inline --presets [ @babel/preset-env @babel/preset-typescript ] ] | exorcist dist/browser-matrix.js.map > dist/browser-matrix.js",
"build:compile-browser": "mkdir dist && BROWSERIFYSWAP_ENV='no-rust-crypto' browserify -d src/browser-index.ts -p [ tsify -p ./tsconfig-build.json ] | exorcist dist/browser-matrix.js.map > dist/browser-matrix.js",
"build:minify-browser": "terser dist/browser-matrix.js --compress --mangle --source-map --output dist/browser-matrix.min.js",
"gendoc": "typedoc",
"lint": "yarn lint:types && yarn lint:js",
Expand Down Expand Up @@ -97,16 +97,17 @@
"babelify": "^10.0.0",
"better-docs": "^2.4.0-beta.9",
"browserify": "^17.0.0",
"browserify-swap": "^0.2.2",
"debug": "^4.3.4",
"docdash": "^2.0.0",
"domexception": "^4.0.0",
"eslint": "8.33.0",
"eslint": "8.34.0",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^3.5.1",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jest": "^27.1.6",
"eslint-plugin-jsdoc": "^39.6.4",
"eslint-plugin-jsdoc": "^40.0.0",
"eslint-plugin-matrix-org": "^1.0.0",
"eslint-plugin-tsdoc": "^0.2.17",
"eslint-plugin-unicorn": "^45.0.0",
Expand All @@ -118,7 +119,7 @@
"jest-localstorage-mock": "^2.4.6",
"jest-mock": "^29.0.0",
"matrix-mock-request": "^2.5.0",
"prettier": "2.8.3",
"prettier": "2.8.4",
"rimraf": "^4.0.0",
"terser": "^5.5.1",
"tsify": "^5.0.2",
Expand Down Expand Up @@ -148,5 +149,25 @@
"outputName": "jest-sonar-report.xml",
"relativePaths": true
},
"browserify": {
"transform": [
"browserify-swap",
[
"babelify",
{
"sourceMaps": "inline",
"presets": [
"@babel/preset-env",
"@babel/preset-typescript"
]
}
]
]
},
"browserify-swap": {
"no-rust-crypto": {
"src/rust-crypto/index.ts$": "./src/rust-crypto/browserify-index.ts"
}
},
"typings": "./lib/index.d.ts"
}
11 changes: 9 additions & 2 deletions spec/integ/matrix-client-methods.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1336,18 +1336,25 @@ describe("MatrixClient", function () {
it.each([
{
userId: "alice@localhost",
powerLevel: 100,
expectation: {
"alice@localhost": 100,
},
},
{
userId: ["alice@localhost", "bob@localhost"],
powerLevel: 100,
expectation: {
"alice@localhost": 100,
"bob@localhost": 100,
},
},
])("should modify power levels of $userId correctly", async ({ userId, expectation }) => {
{
userId: "alice@localhost",
powerLevel: undefined,
expectation: {},
},
])("should modify power levels of $userId correctly", async ({ userId, powerLevel, expectation }) => {
const event = {
getType: () => "m.room.power_levels",
getContent: () => ({
Expand All @@ -1364,7 +1371,7 @@ describe("MatrixClient", function () {
})
.respond(200, {});

const prom = client!.setPowerLevel("!room_id:server", userId, 100, event);
const prom = client!.setPowerLevel("!room_id:server", userId, powerLevel, event);
await httpBackend!.flushAllExpected();
await prom;
});
Expand Down
95 changes: 94 additions & 1 deletion spec/integ/matrix-client-unread-notifications.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,21 @@ import "fake-indexeddb/auto";

import HttpBackend from "matrix-mock-request";

import { Category, ISyncResponse, MatrixClient, NotificationCountType, Room } from "../../src";
import {
Category,
ClientEvent,
EventType,
ISyncResponse,
MatrixClient,
MatrixEvent,
NotificationCountType,
RelationType,
Room,
} from "../../src";
import { TestClient } from "../TestClient";
import { ReceiptType } from "../../src/@types/read_receipts";
import { mkThread } from "../test-utils/thread";
import { SyncState } from "../../src/sync";

describe("MatrixClient syncing", () => {
const userA = "@alice:localhost";
Expand Down Expand Up @@ -51,6 +64,86 @@ describe("MatrixClient syncing", () => {
return httpBackend!.stop();
});

it("reactions in thread set the correct timeline to unread", async () => {
const roomId = "!room:localhost";

// start the client, and wait for it to initialise
httpBackend!.when("GET", "/sync").respond(200, {
next_batch: "s_5_3",
rooms: {
[Category.Join]: {},
[Category.Leave]: {},
[Category.Invite]: {},
},
});
client!.startClient({ threadSupport: true });
await Promise.all([
httpBackend?.flushAllExpected(),
new Promise<void>((resolve) => {
client!.on(ClientEvent.Sync, (state) => state === SyncState.Syncing && resolve());
}),
]);

const room = new Room(roomId, client!, selfUserId);
jest.spyOn(client!, "getRoom").mockImplementation((id) => (id === roomId ? room : null));

const thread = mkThread({ room, client: client!, authorId: selfUserId, participantUserIds: [selfUserId] });
const threadReply = thread.events.at(-1)!;
room.addLiveEvents([thread.rootEvent]);

// Initialize read receipt datastructure before testing the reaction
room.addReceiptToStructure(thread.rootEvent.getId()!, ReceiptType.Read, selfUserId, { ts: 1 }, false);
thread.thread.addReceiptToStructure(
threadReply.getId()!,
ReceiptType.Read,
selfUserId,
{ thread_id: thread.thread.id, ts: 1 },
false,
);
expect(room.getReadReceiptForUserId(selfUserId, false)?.eventId).toEqual(thread.rootEvent.getId());
expect(thread.thread.getReadReceiptForUserId(selfUserId, false)?.eventId).toEqual(threadReply.getId());

const reactionEventId = `$9-${Math.random()}-${Math.random()}`;
let lastEvent: MatrixEvent | null = null;
jest.spyOn(client! as any, "sendEventHttpRequest").mockImplementation((event) => {
lastEvent = event as MatrixEvent;
return { event_id: reactionEventId };
});

await client!.sendEvent(roomId, EventType.Reaction, {
"m.relates_to": {
rel_type: RelationType.Annotation,
event_id: threadReply.getId(),
key: "",
},
});

expect(lastEvent!.getId()).toEqual(reactionEventId);
room.handleRemoteEcho(new MatrixEvent(lastEvent!.event), lastEvent!);

// Our ideal state after this is the following:
//
// Room: [synthetic: threadroot, actual: threadroot]
// Thread: [synthetic: threadreaction, actual: threadreply]
//
// The reaction and reply are both in the thread, and their receipts should be isolated to the thread.
// The reaction has not been acknowledged in a dedicated read receipt message, so only the synthetic receipt
// should be updated.

// Ensure the synthetic receipt for the room has not been updated
expect(room.getReadReceiptForUserId(selfUserId, false)?.eventId).toEqual(thread.rootEvent.getId());
expect(room.getEventReadUpTo(selfUserId, false)).toEqual(thread.rootEvent.getId());
// Ensure the actual receipt for the room has not been updated
expect(room.getReadReceiptForUserId(selfUserId, true)?.eventId).toEqual(thread.rootEvent.getId());
expect(room.getEventReadUpTo(selfUserId, true)).toEqual(thread.rootEvent.getId());
// Ensure the synthetic receipt for the thread has been updated
expect(thread.thread.getReadReceiptForUserId(selfUserId, false)?.eventId).toEqual(reactionEventId);
expect(thread.thread.getEventReadUpTo(selfUserId, false)).toEqual(reactionEventId);
// Ensure the actual receipt for the thread has not been updated
expect(thread.thread.getReadReceiptForUserId(selfUserId, true)?.eventId).toEqual(threadReply.getId());
expect(thread.thread.getEventReadUpTo(selfUserId, true)).toEqual(threadReply.getId());
});

describe("Stuck unread notifications integration tests", () => {
const ROOM_ID = "!room:localhost";

Expand Down
Loading

0 comments on commit 589938f

Please sign in to comment.