From e9e5143269ba511001c99cde2ba25c1a92f6cd75 Mon Sep 17 00:00:00 2001 From: "J.C" <73438877+1hiking@users.noreply.github.com.> Date: Sat, 8 Aug 2026 22:10:55 -0600 Subject: [PATCH 1/5] Fix UserID toString identifier --- .../io/github/hikingc/matrixsdk/api/identifiers/UserID.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/UserID.java b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/UserID.java index 8616393..ba946aa 100644 --- a/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/UserID.java +++ b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/UserID.java @@ -62,6 +62,6 @@ public boolean equals(Object obj) { @Override public String toString() { - return "!" + localpart + ":" + domain; + return "@" + localpart + ":" + domain; } } From f9558b2dcf89bf802f896c4f1602a031eb3c9835 Mon Sep 17 00:00:00 2001 From: "J.C" <73438877+1hiking@users.noreply.github.com.> Date: Sat, 8 Aug 2026 23:31:47 -0600 Subject: [PATCH 2/5] Add EventID - Unlike other IDs, this one has lax verification to not mess up with early room specs. --- .../matrixsdk/api/identifiers/EventID.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/main/java/io/github/hikingc/matrixsdk/api/identifiers/EventID.java diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/EventID.java b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/EventID.java new file mode 100644 index 0000000..2978bf7 --- /dev/null +++ b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/EventID.java @@ -0,0 +1,67 @@ +package io.github.hikingc.matrixsdk.api.identifiers; + +import java.nio.charset.StandardCharsets; +import java.util.Objects; + +/// This class allows for the representation and validation of an Event ID in Matrix. +/// +/// Their form is as follows: `$opaque_id`, some room versions include a `domain` component, whereas +/// more recent room versions omit the domain and use a base64-encoded hash instead. +/// +/// The length of a [EventID], including the `$` sigil, **MUST NOT** exceed 255 bytes. +/// +/// @see Event Identifiers as defined +/// in the specification +public final class EventID implements Validator { + private final String opaqueId; + + private EventID(String opaqueId) { + this.opaqueId = opaqueId; + } + + /// Builds and validates a [RoomID] + /// + /// @param rawRoomId the [String] to validate. + /// @return a [RoomID]. + /// @throws IllegalArgumentException if the [String] has broken a rule from the spec. + /// @throws NullPointerException if the [String] is null. + public static EventID parse(String rawRoomId) { + Objects.requireNonNull(rawRoomId, "Room ID" + " must not be null"); + + if (rawRoomId.getBytes(StandardCharsets.UTF_8).length > MAX_BYTES) { + throw new IllegalArgumentException("Event ID exceeds " + MAX_BYTES + " bytes"); + } + + if (rawRoomId.isEmpty()) { + throw new IllegalArgumentException("Event ID must not be empty"); + } + + if (rawRoomId.charAt(0) != '$') { + throw new IllegalArgumentException("Event ID must start with \'$\'"); + } + + if (rawRoomId.contentEquals("$")) { + throw new IllegalArgumentException("Event ID must not only contain \'$\'"); + } + + return new EventID(rawRoomId); + } + + @Override + public int hashCode() { + return Objects.hash(opaqueId); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (EventID) obj; + return Objects.equals(this.opaqueId, that.opaqueId); + } + + @Override + public String toString() { + return "$" + opaqueId; + } +} From a5b3bbc1b747d7b20bd3322a2db8363ec278fc1c Mon Sep 17 00:00:00 2001 From: "J.C" <73438877+1hiking@users.noreply.github.com.> Date: Sat, 8 Aug 2026 23:32:08 -0600 Subject: [PATCH 3/5] Remove unnecesary escapes --- .../io/github/hikingc/matrixsdk/api/Event.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/Event.java b/src/main/java/io/github/hikingc/matrixsdk/api/Event.java index f80486a..e439592 100644 --- a/src/main/java/io/github/hikingc/matrixsdk/api/Event.java +++ b/src/main/java/io/github/hikingc/matrixsdk/api/Event.java @@ -3,7 +3,6 @@ import io.github.hikingc.matrixsdk.api.events.*; import io.github.hikingc.matrixsdk.api.events.content.MessageEventContent; import io.github.hikingc.matrixsdk.api.events.content.StateEventContent; -import io.github.hikingc.matrixsdk.api.events.model.RoomMemberEvent; import io.github.hikingc.matrixsdk.api.events.queries.ChronologicalDirection; import io.github.hikingc.matrixsdk.api.events.queries.Membership; import io.github.hikingc.matrixsdk.api.events.queries.QueryParametersMessages; @@ -12,6 +11,7 @@ import io.github.hikingc.matrixsdk.api.identifiers.RoomID; import io.github.hikingc.matrixsdk.exceptions.MatrixIOException; import io.github.hikingc.matrixsdk.exceptions.MatrixNetworkException; +import io.github.hikingc.matrixsdk.api.events.model.RoomMemberEvent; import java.nio.file.Path; import java.util.List; @@ -29,7 +29,8 @@ public interface Event { /// @param roomId the room ID where the event is. /// @param eventId the event ID to retrieve. /// @return the full event. - ClientEvent getEvent(RoomID roomId, String eventId); + @SuppressWarnings("java:S1452") + ClientEvent getEvent(RoomID roomId, String eventId); /// Returns currently-joined members /// @@ -54,7 +55,7 @@ List getMembers( /// /// @param roomId the room ID to fetch data from. /// @return the current state of the room - List> getStateEvents(RoomID roomId); + List> getStateEvents(RoomID roomId); /// Looks up the contents of a state event in a room. If the user is joined to the room then the /// state is taken from the current state of the room. If the user has left the room then the @@ -65,9 +66,7 @@ List getMembers( /// @param stateKey the room to look up the state in. /// @return the content of the event, including all additional metadata fields. @SuppressWarnings("java:S1452") - // Caller doesn't know content type ahead of time; polymorphic dispatch via @JsonTypeInfo resolves - // it - ClientEvent getStateEvent(RoomID roomId, String eventType, String stateKey); + StateEvent getStateEvent(RoomID roomId, String eventType, String stateKey); /// Returns a list of message and state events for a room. It uses pagination query parameters to /// paginate history in the room. The content is not parsed or escaped which means newlines (`\n`) @@ -110,8 +109,8 @@ EventMetadata getEventClosestToTimestamp( /// Sends a message event. /// - /// @param roomId the room ID where to send the event. - /// @param txnId for this event. Clients should generate an ID unique across requests with the + /// @param roomId the room ID where to send the event. + /// @param txnId for this event. Clients should generate an ID unique across requests with the /// same access token; it will be used by the server to ensure idempotency of requests. /// @param content of any type of message event. /// @return a [String] representing a unique identifier of the event. From 078835b6c3b7c3c7404a3420044640cff16f5286 Mon Sep 17 00:00:00 2001 From: "J.C" <73438877+1hiking@users.noreply.github.com.> Date: Sat, 8 Aug 2026 23:32:30 -0600 Subject: [PATCH 4/5] Add tests --- .../api/identifiers/EventIDTest.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/test/java/io/github/hikingc/matrixsdk/api/identifiers/EventIDTest.java diff --git a/src/test/java/io/github/hikingc/matrixsdk/api/identifiers/EventIDTest.java b/src/test/java/io/github/hikingc/matrixsdk/api/identifiers/EventIDTest.java new file mode 100644 index 0000000..8f54e25 --- /dev/null +++ b/src/test/java/io/github/hikingc/matrixsdk/api/identifiers/EventIDTest.java @@ -0,0 +1,67 @@ +package io.github.hikingc.matrixsdk.api.identifiers; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EmptySource; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; + +class EventIDTest { + + @ParameterizedTest(name = "[{index}] \"{0}\"") + @ValueSource( + strings = { + // v3+ reference-hash shape + "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI9dSaz3jRoiQ-fXE", + "$acR1l0raRc2h8DzKlR4E9RAxwbrIY8v_4V-1kfBGCiA", + "$LWXstUyAjMr8vBiVjTMH_hEcnKMhc0zVi52gxHYzc-4", + "$1c-AYXvOG3AH0z9OTfHktZ4b6l3f1uK1Wv4h5CkQY9U", + // legacy v1/v2 shape + "$acR1l0raRc2h8DzKlR4E9RAxwbrIY8v_4V-1kfBGCiA:matrix.org", + "$event1:example.com", + "$143273582443PhrSn:example.org", + // opaque content is allowed to contain "unusual" characters per spec — + // clients must not impose structure beyond the sigil + "$acR1l0raRc2h8DzKlR4E9RAxwbrIY8v/4V+1kfBGCiA", // non-base64url chars, still opaque + "$has spaces in it", + "$has\nnewline", + "$emoji🎉event", + "$has\"quote", + "$ " // single space after sigil is still non-empty content + }) + void withValidStrings_ReturnEventID(String id) { + assertDoesNotThrow(() -> EventID.parse(id), "Exception not expected for input: " + id); + } + + @ParameterizedTest(name = "[{index}] \"{0}\"") + @ValueSource( + strings = { + "acR1l0raRc2h8DzKlR4E9RAxwbrIY8v_4V-1kfBGCiA", // missing sigil + "@acR1l0raRc2h8DzKlR4E9RAxwbrIY8v_4V-1kfBGCiA", // wrong sigil (User ID) + "!acR1l0raRc2h8DzKlR4E9RAxwbrIY8v_4V-1kfBGCiA", // wrong sigil (Room ID) + "#acR1l0raRc2h8DzKlR4E9RAxwbrIY8v_4V-1kfBGCiA", // wrong sigil (Room Alias) + " ", // no sigil at all, just whitespace + "$" // sigil present but zero content after it + }) + void withInvalidStrings_ThrowsException(String id) { + assertThrows( + IllegalArgumentException.class, + () -> EventID.parse(id), + "Exception expected for input: " + id); + } + + @ParameterizedTest + @NullSource + void withNull_ThrowsException(String id) { + assertThrows(NullPointerException.class, () -> EventID.parse(id)); + } + + @ParameterizedTest + @EmptySource + void withEmpty_ThrowsException(String id) { + assertThrows(IllegalArgumentException.class, () -> EventID.parse(id)); + } +} From 7dec7f869bedd5b2b00a18650adc628e4404aacc Mon Sep 17 00:00:00 2001 From: "J.C" <73438877+1hiking@users.noreply.github.com.> Date: Sun, 9 Aug 2026 09:53:28 -0600 Subject: [PATCH 5/5] Add ID classes into existing records. - Add JsonCreator and JsonValue to bring serialization into the class - Patch tests to match correct class type --- .../matrixsdk/api/identifiers/EventID.java | 4 +- .../matrixsdk/api/identifiers/RoomAlias.java | 4 + .../matrixsdk/api/identifiers/RoomID.java | 4 + .../matrixsdk/api/identifiers/UserID.java | 4 + .../api/rooms/RoomMembershipRequest.java | 4 +- .../matrixsdk/api/rooms/ThirdPartySigned.java | 6 +- .../api/rooms/models/PublishedRoomsChunk.java | 6 +- .../api/rooms/models/ResolvedAlias.java | 3 +- .../services/events/EventServiceTest.java | 6 +- .../services/rooms/RoomServiceTest.java | 81 +++++++++---------- .../userdata/UserDataServiceTest.java | 17 ++-- 11 files changed, 78 insertions(+), 61 deletions(-) diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/EventID.java b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/EventID.java index 2978bf7..f2d62cc 100644 --- a/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/EventID.java +++ b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/EventID.java @@ -37,11 +37,11 @@ public static EventID parse(String rawRoomId) { } if (rawRoomId.charAt(0) != '$') { - throw new IllegalArgumentException("Event ID must start with \'$\'"); + throw new IllegalArgumentException("Event ID must start with '$'"); } if (rawRoomId.contentEquals("$")) { - throw new IllegalArgumentException("Event ID must not only contain \'$\'"); + throw new IllegalArgumentException("Event ID must not only contain '$'"); } return new EventID(rawRoomId); diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/RoomAlias.java b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/RoomAlias.java index abccee4..4180e73 100644 --- a/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/RoomAlias.java +++ b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/RoomAlias.java @@ -1,5 +1,7 @@ package io.github.hikingc.matrixsdk.api.identifiers; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; import java.util.Objects; /// This class allows for the representation and validation of a Room Alias in Matrix. @@ -32,6 +34,7 @@ private RoomAlias(String opaqueId, String domain) { /// @return a [RoomAlias]. /// @throws IllegalArgumentException if the [String] has broken a rule from the spec. /// @throws NullPointerException if the [String] is null. + @JsonCreator public static RoomAlias parse(String rawAliasId) { Objects.requireNonNull(rawAliasId, "Alias ID" + " must not be null"); @@ -58,6 +61,7 @@ public boolean equals(Object obj) { } @Override + @JsonValue public String toString() { return "#" + opaqueId + ":" + domain; } diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/RoomID.java b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/RoomID.java index c623a01..015031f 100644 --- a/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/RoomID.java +++ b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/RoomID.java @@ -1,5 +1,7 @@ package io.github.hikingc.matrixsdk.api.identifiers; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; import java.util.Objects; /// This class allows for the representation and validation of a Room Identifier in Matrix. @@ -32,6 +34,7 @@ private RoomID(String opaqueId, String domain) { /// @return a [RoomID]. /// @throws IllegalArgumentException if the [String] has broken a rule from the spec. /// @throws NullPointerException if the [String] is null. + @JsonCreator public static RoomID parse(String rawRoomId) { Objects.requireNonNull(rawRoomId, "Room ID" + " must not be null"); @@ -58,6 +61,7 @@ public boolean equals(Object obj) { } @Override + @JsonValue public String toString() { return "!" + opaqueId + ":" + domain; } diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/UserID.java b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/UserID.java index ba946aa..2a3c2d2 100644 --- a/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/UserID.java +++ b/src/main/java/io/github/hikingc/matrixsdk/api/identifiers/UserID.java @@ -1,5 +1,7 @@ package io.github.hikingc.matrixsdk.api.identifiers; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; import java.util.Objects; /// This class allows for the representation and validation of a User Identifier in Matrix. @@ -30,6 +32,7 @@ private UserID(String opaqueId, String domain) { /// @return a [UserID]. /// @throws IllegalArgumentException if the [String] has broken a rule from the spec. /// @throws NullPointerException if the [String] is null. + @JsonCreator public static UserID parse(String rawUserId) { Objects.requireNonNull(rawUserId, "User ID" + " must not be null"); @@ -61,6 +64,7 @@ public boolean equals(Object obj) { } @Override + @JsonValue public String toString() { return "@" + localpart + ":" + domain; } diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/rooms/RoomMembershipRequest.java b/src/main/java/io/github/hikingc/matrixsdk/api/rooms/RoomMembershipRequest.java index 03c76d8..ab83de0 100644 --- a/src/main/java/io/github/hikingc/matrixsdk/api/rooms/RoomMembershipRequest.java +++ b/src/main/java/io/github/hikingc/matrixsdk/api/rooms/RoomMembershipRequest.java @@ -1,12 +1,14 @@ package io.github.hikingc.matrixsdk.api.rooms; +import io.github.hikingc.matrixsdk.api.identifiers.UserID; + import java.util.Objects; /// This record represents the required values to be supplied to actions like banning or kicking. /// /// @param reason The reason of the expulsion, the target will receive this message. /// @param userId The id of the target to expel. -public record RoomMembershipRequest(String reason, String userId) { +public record RoomMembershipRequest(String reason, UserID userId) { /// Compact constructor designed to validate nullity. /// diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/rooms/ThirdPartySigned.java b/src/main/java/io/github/hikingc/matrixsdk/api/rooms/ThirdPartySigned.java index 84f1d43..cf9e7c8 100644 --- a/src/main/java/io/github/hikingc/matrixsdk/api/rooms/ThirdPartySigned.java +++ b/src/main/java/io/github/hikingc/matrixsdk/api/rooms/ThirdPartySigned.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Map; + +import io.github.hikingc.matrixsdk.api.identifiers.UserID; import org.jspecify.annotations.NullMarked; /// Holds information to supply the server and verify a `m.room.third_party_invite` event. @@ -12,7 +14,7 @@ /// @param token the state key of the `m.third_party_invite` event. @NullMarked public record ThirdPartySigned( - @JsonProperty(required = true) String mxid, - @JsonProperty(required = true) String sender, + @JsonProperty(required = true) UserID mxid, + @JsonProperty(required = true) UserID sender, @JsonProperty(required = true) Map> signatures, @JsonProperty(required = true) String token) {} diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/rooms/models/PublishedRoomsChunk.java b/src/main/java/io/github/hikingc/matrixsdk/api/rooms/models/PublishedRoomsChunk.java index 210e900..696bbd3 100644 --- a/src/main/java/io/github/hikingc/matrixsdk/api/rooms/models/PublishedRoomsChunk.java +++ b/src/main/java/io/github/hikingc/matrixsdk/api/rooms/models/PublishedRoomsChunk.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.github.hikingc.matrixsdk.api.Room; +import io.github.hikingc.matrixsdk.api.identifiers.RoomAlias; +import io.github.hikingc.matrixsdk.api.identifiers.RoomID; import io.github.hikingc.matrixsdk.api.identifiers.Validator; import java.net.URI; import java.util.List; @@ -25,12 +27,12 @@ /// additional values for a determinate room public record PublishedRoomsChunk( URI avatarUrl, - String canonicalAlias, + RoomAlias canonicalAlias, @JsonProperty(required = true) boolean guestCanJoin, String joinRule, String name, @JsonProperty(required = true) int numJoinedMembers, - @NonNull @JsonProperty(required = true) String roomId, + @NonNull @JsonProperty(required = true) RoomID roomId, String roomType, String topic, @JsonProperty(required = true) boolean worldReadable) {} diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/rooms/models/ResolvedAlias.java b/src/main/java/io/github/hikingc/matrixsdk/api/rooms/models/ResolvedAlias.java index fc3d31e..fdc5610 100644 --- a/src/main/java/io/github/hikingc/matrixsdk/api/rooms/models/ResolvedAlias.java +++ b/src/main/java/io/github/hikingc/matrixsdk/api/rooms/models/ResolvedAlias.java @@ -1,9 +1,10 @@ package io.github.hikingc.matrixsdk.api.rooms.models; +import io.github.hikingc.matrixsdk.api.identifiers.RoomID; import java.util.List; /// This record contains data when resolving a room alias. /// /// @param roomId the room id for the room alias. /// @param servers a list of servers aware of said alias. -public record ResolvedAlias(String roomId, List servers) {} +public record ResolvedAlias(RoomID roomId, List servers) {} diff --git a/src/test/java/io/github/hikingc/matrixsdk/services/events/EventServiceTest.java b/src/test/java/io/github/hikingc/matrixsdk/services/events/EventServiceTest.java index 970219b..7d59e23 100644 --- a/src/test/java/io/github/hikingc/matrixsdk/services/events/EventServiceTest.java +++ b/src/test/java/io/github/hikingc/matrixsdk/services/events/EventServiceTest.java @@ -9,7 +9,9 @@ import com.github.tomakehurst.wiremock.junit5.WireMockTest; import io.github.hikingc.matrixsdk.api.MatrixClient; import io.github.hikingc.matrixsdk.api.events.*; +import io.github.hikingc.matrixsdk.api.events.content.RoomJoinRules; import io.github.hikingc.matrixsdk.api.events.content.RoomMessage; +import io.github.hikingc.matrixsdk.api.events.content.StateEventContent; import io.github.hikingc.matrixsdk.api.events.content.roommessages.FileContent; import io.github.hikingc.matrixsdk.api.events.content.roommessages.TextContent; import io.github.hikingc.matrixsdk.api.events.queries.ChronologicalDirection; @@ -538,7 +540,9 @@ void getInitialSync_WithACorrectPayload_ThenReturnRoomInfo() { @Test void sendStateEvent_WithACorrectPayload_ThenReturnAString() { - // TODO pending interface to confirm fields to assert + StateEventContent content = new RoomJoinRules(new RoomJoinRules.AllowCondition("EXAMPLE","TYPE"),"JOINRULE"); + var response = client.events().sendStateEvent(ROOM_ID,"",content); + assertThat(response).isNotNull(); } @Test diff --git a/src/test/java/io/github/hikingc/matrixsdk/services/rooms/RoomServiceTest.java b/src/test/java/io/github/hikingc/matrixsdk/services/rooms/RoomServiceTest.java index d0a4762..e303c83 100644 --- a/src/test/java/io/github/hikingc/matrixsdk/services/rooms/RoomServiceTest.java +++ b/src/test/java/io/github/hikingc/matrixsdk/services/rooms/RoomServiceTest.java @@ -9,6 +9,7 @@ import io.github.hikingc.matrixsdk.api.events.content.RoomPowerLevels; import io.github.hikingc.matrixsdk.api.identifiers.RoomAlias; import io.github.hikingc.matrixsdk.api.identifiers.RoomID; +import io.github.hikingc.matrixsdk.api.identifiers.UserID; import io.github.hikingc.matrixsdk.api.identifiers.Validator; import io.github.hikingc.matrixsdk.api.rooms.*; import io.github.hikingc.matrixsdk.api.rooms.queries.CreationRoomType; @@ -17,7 +18,6 @@ import io.github.hikingc.matrixsdk.context.DiscoveryResponse; import java.util.List; import java.util.Map; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,6 +26,7 @@ class RoomServiceTest { private static final RoomID ROOM_ID = RoomID.parse("!ekkTuJPNWnbuCJHvYB:kde.org"); + private static final UserID USER_ID = UserID.parse("@example:example.com"); private static final String AUTH_TOKEN = "1234"; private static MatrixClient client; private static DiscoveryResponse DISCOVERY_RESPONSE; @@ -116,51 +117,40 @@ void sendCreateRequest_WithACorrectPayload_thenReturnARoomId() { { "room_id": "%s" } """ .formatted(expectedRoomId)))); - InitialRoomConfiguration config = new InitialRoomConfiguration( + InitialRoomConfiguration config = + new InitialRoomConfiguration( new InitialRoomConfiguration.CreationContent(false), // m.federate: false List.of( - new InitialRoomConfiguration.StateEvent( - Map.of("join_rule", "public"), - "", - "m.room.join_rules"), - new InitialRoomConfiguration.StateEvent( - Map.of("history_visibility", "shared"), - "", - "m.room.history_visibility") - ), + new InitialRoomConfiguration.StateEvent( + Map.of("join_rule", "public"), "", "m.room.join_rules"), + new InitialRoomConfiguration.StateEvent( + Map.of("history_visibility", "shared"), "", "m.room.history_visibility")), List.of("@alice:example.com", "@bob:example.com"), List.of( - new InitialRoomConfiguration.Invite3pid( - "alice@example.com", - "abc123_OpaqueString", - "identity.example.com", - "email") - ), + new InitialRoomConfiguration.Invite3pid( + "alice@example.com", "abc123_OpaqueString", "identity.example.com", "email")), false, // is_direct "The Grand Duke Pub", new RoomPowerLevels( - 50, // ban - Map.of( - "m.room.name", 50, - "m.room.power_levels", 100 - ), // events - 0, // eventsDefault - 0, // invite - 50, // kick - null, // notifications — not present in source JSON - 50, // redact - 50, // stateDefault - Map.of("@alice:example.com", 100), // users - 0 // users_default - ), + 50, // ban + Map.of( + "m.room.name", 50, + "m.room.power_levels", 100), // events + 0, // eventsDefault + 0, // invite + 50, // kick + null, // notifications — not present in source JSON + 50, // redact + 50, // stateDefault + Map.of("@alice:example.com", 100), // users + 0 // users_default + ), CreationRoomType.PRIVATE_CHAT, "thepub", "11", "All about happy hour", - VisibilityRoomType.PRIVATE - ); - var response = - client.room().create(config); + VisibilityRoomType.PRIVATE); + var response = client.room().create(config); assertEquals(expectedRoomId, response); } @@ -209,7 +199,7 @@ void sendResolveAliasRequest_WithCorrectPayload_thenReturnResolvedAlias() { var response = client.room().resolveAlias(alias); assertNotNull(response); - assertEquals(ROOM_ID.toString(), response.roomId()); + assertEquals(ROOM_ID, response.roomId()); assertFalse(response.servers().isEmpty()); } @@ -286,7 +276,8 @@ void sendInviteRequest_WithCorrectPayload_thenHitCorrectEndpoint() { true)) .willReturn(okJson("{}"))); - client.room().inviteUser(ROOM_ID, new RoomMembershipRequest("Welcome!", "@alice:example.com")); + client.room().inviteUser( + ROOM_ID, new RoomMembershipRequest("Welcome!", UserID.parse("@alice:example.com"))); verify(postRequestedFor(urlEqualTo("/_matrix/client/v3/rooms/" + ROOM_ID + "/invite"))); } @@ -373,14 +364,14 @@ void sendKickRequest_WithCorrectPayload_thenHitCorrectEndpoint() { """ { "reason": "Test reason", - "user_id": "user" + "user_id": "@example:example.com" } """, true, true)) .willReturn(okJson("{}"))); - client.room().kick(ROOM_ID, new RoomMembershipRequest("Test reason", "user")); + client.room().kick(ROOM_ID, new RoomMembershipRequest("Test reason", USER_ID)); verify(postRequestedFor(urlEqualTo("/_matrix/client/v3/rooms/" + ROOM_ID + "/kick"))); } @@ -394,14 +385,14 @@ void sendBanRequest_WithCorrectPayload_thenHitCorrectEndpoint() { """ { "reason": "Test reason", - "user_id": "user" + "user_id": "@example:example.com" } """, true, true)) .willReturn(okJson("{}"))); - client.room().ban(ROOM_ID, new RoomMembershipRequest("Test reason", "user")); + client.room().ban(ROOM_ID, new RoomMembershipRequest("Test reason", USER_ID)); verify(postRequestedFor(urlEqualTo("/_matrix/client/v3/rooms/" + ROOM_ID + "/ban"))); } @@ -415,14 +406,14 @@ void sendUnbanRequest_WithCorrectPayload_thenHitCorrectEndpoint() { """ { "reason": "Test reason", - "user_id": "user" + "user_id": "@example:example.com" } """, true, true)) .willReturn(okJson("{}"))); - client.room().unban(ROOM_ID, new RoomMembershipRequest("Test reason", "user")); + client.room().unban(ROOM_ID, new RoomMembershipRequest("Test reason", USER_ID)); verify(postRequestedFor(urlEqualTo("/_matrix/client/v3/rooms/" + ROOM_ID + "/unban"))); } @@ -488,7 +479,7 @@ void sendGetPublicRoomDirRequest_WithQueryParams_thenReturnDirectory() { assertNotNull(response); assertNotNull(response.chunk()); - assertEquals("!abc123:example.com", response.chunk().getFirst().roomId()); + assertEquals(RoomID.parse("!abc123:example.com"), response.chunk().getFirst().roomId()); assertEquals("General", response.chunk().getFirst().name()); assertEquals(1, response.totalRoomCountEstimate()); } @@ -520,7 +511,7 @@ void sendGetPublicRoomDirPostRequest_WithBody_thenReturnDirectory() { assertNotNull(response); assertFalse(response.chunk().isEmpty()); - assertEquals("!abc123:example.com", response.chunk().getFirst().roomId()); + assertEquals(RoomID.parse("!abc123:example.com"), response.chunk().getFirst().roomId()); } @Test diff --git a/src/test/java/io/github/hikingc/matrixsdk/services/userdata/UserDataServiceTest.java b/src/test/java/io/github/hikingc/matrixsdk/services/userdata/UserDataServiceTest.java index bf0e8d2..bafe5ce 100644 --- a/src/test/java/io/github/hikingc/matrixsdk/services/userdata/UserDataServiceTest.java +++ b/src/test/java/io/github/hikingc/matrixsdk/services/userdata/UserDataServiceTest.java @@ -40,18 +40,21 @@ void searchUsersByTerm() { .willReturn( okJson( """ - { - "results": [ - {"user_id": "@searchterm:matrix.org", "display_name": "Search Term"} - ], - "limited": false - } - """))); + { + "results": [ + {"user_id": "@user:example.com", "display_name": "Search Term"} + ], + "limited": false + } + """))); var results = client.userData().searchUsersByTerm(10, "searchterm"); assertThat(results).isNotNull(); assertThat(results.results()).hasSize(1); + assertThat(results.results().getFirst().userId()).isEqualTo(USER_ID); + assertThat(results.results().getFirst().displayName()).isEqualTo("Search Term"); + assertThat(results.limited()).isFalse(); } @Test