mirror of
https://github.com/matrix-org/sliding-sync.git
synced 2025-03-10 13:37:11 +00:00
Define avatar
field on sync3.Room
This commit is contained in:
parent
64183a3b99
commit
59a6554615
42
sync3/avatar.go
Normal file
42
sync3/avatar.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package sync3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// An AvatarChange represents a change to a room's avatar. There are three cases:
|
||||||
|
// - an empty string represents no change, and should be omitted when JSON-serialised;
|
||||||
|
// - the sentinel `<no-avatar>` represents a room that has never had an avatar,
|
||||||
|
// or a room whose avatar has been removed. It is JSON-serialised as null.
|
||||||
|
// - All other strings represent the current avatar of the room and JSON-serialise as
|
||||||
|
// normal.
|
||||||
|
type AvatarChange string
|
||||||
|
|
||||||
|
const DeletedAvatar = AvatarChange("<no-avatar>")
|
||||||
|
const UnchangedAvatar AvatarChange = ""
|
||||||
|
|
||||||
|
// NewAvatarChange interprets an optional avatar string as an AvatarChange.
|
||||||
|
func NewAvatarChange(avatar string) AvatarChange {
|
||||||
|
if avatar == "" {
|
||||||
|
return DeletedAvatar
|
||||||
|
}
|
||||||
|
return AvatarChange(avatar)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AvatarChange) MarshalJSON() ([]byte, error) {
|
||||||
|
if a == DeletedAvatar {
|
||||||
|
return []byte(`null`), nil
|
||||||
|
} else {
|
||||||
|
return json.Marshal(string(a))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: the unmarshalling is only used in tests.
|
||||||
|
func (a *AvatarChange) UnmarshalJSON(data []byte) error {
|
||||||
|
if bytes.Equal(data, []byte("null")) {
|
||||||
|
*a = DeletedAvatar
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return json.Unmarshal(data, (*string)(a))
|
||||||
|
}
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
type Room struct {
|
type Room struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
AvatarChange AvatarChange `json:"avatar,omitempty"`
|
||||||
RequiredState []json.RawMessage `json:"required_state,omitempty"`
|
RequiredState []json.RawMessage `json:"required_state,omitempty"`
|
||||||
Timeline []json.RawMessage `json:"timeline,omitempty"`
|
Timeline []json.RawMessage `json:"timeline,omitempty"`
|
||||||
InviteState []json.RawMessage `json:"invite_state,omitempty"`
|
InviteState []json.RawMessage `json:"invite_state,omitempty"`
|
||||||
|
74
sync3/room_test.go
Normal file
74
sync3/room_test.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package sync3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAvatarChangeMarshalling(t *testing.T) {
|
||||||
|
var url = "mxc://..."
|
||||||
|
testCases := []struct {
|
||||||
|
Name string
|
||||||
|
AvatarChange AvatarChange
|
||||||
|
Check func(avatar gjson.Result) error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "Avatar exists",
|
||||||
|
AvatarChange: NewAvatarChange(url),
|
||||||
|
Check: func(avatar gjson.Result) error {
|
||||||
|
if !(avatar.Exists() && avatar.Type == gjson.String && avatar.Str == url) {
|
||||||
|
return fmt.Errorf("unexpected marshalled avatar: got %#v want %s", avatar, url)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Avatar doesn't exist",
|
||||||
|
AvatarChange: DeletedAvatar,
|
||||||
|
Check: func(avatar gjson.Result) error {
|
||||||
|
if !(avatar.Exists() && avatar.Type == gjson.Null) {
|
||||||
|
return fmt.Errorf("unexpected marshalled Avatar: got %#v want null", avatar)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Avatar unchanged",
|
||||||
|
AvatarChange: UnchangedAvatar,
|
||||||
|
Check: func(avatar gjson.Result) error {
|
||||||
|
if avatar.Exists() {
|
||||||
|
return fmt.Errorf("unexpected marshalled Avatar: got %#v want omitted", avatar)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.Name, func(t *testing.T) {
|
||||||
|
room := Room{AvatarChange: tc.AvatarChange}
|
||||||
|
marshalled, err := json.Marshal(room)
|
||||||
|
t.Logf("Marshalled to %s", string(marshalled))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
avatar := gjson.GetBytes(marshalled, "avatar")
|
||||||
|
if err = tc.Check(avatar); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var unmarshalled Room
|
||||||
|
err = json.Unmarshal(marshalled, &unmarshalled)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Logf("Unmarshalled to %#v", unmarshalled.AvatarChange)
|
||||||
|
if !reflect.DeepEqual(unmarshalled, room) {
|
||||||
|
t.Fatalf("Unmarshalled struct is different from original")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -39,6 +39,39 @@ func MatchRoomName(name string) RoomMatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MatchRoomAvatar builds a RoomMatcher which checks that the given room response has
|
||||||
|
// set the room's avatar to the given value.
|
||||||
|
func MatchRoomAvatar(wantAvatar string) RoomMatcher {
|
||||||
|
return func(r sync3.Room) error {
|
||||||
|
if string(r.AvatarChange) != wantAvatar {
|
||||||
|
return fmt.Errorf("MatchRoomAvatar: got \"%s\" want \"%s\"", r.AvatarChange, wantAvatar)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchRoomUnsetAvatar builds a RoomMatcher which checks that the given room has no
|
||||||
|
// avatar, or has had its avatar deleted.
|
||||||
|
func MatchRoomUnsetAvatar() RoomMatcher {
|
||||||
|
return func(r sync3.Room) error {
|
||||||
|
if r.AvatarChange != sync3.DeletedAvatar {
|
||||||
|
return fmt.Errorf("MatchRoomAvatar: got \"%s\" want \"%s\"", r.AvatarChange, sync3.DeletedAvatar)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchRoomUnchangedAvatar builds a RoomMatcher which checks that the given room has no
|
||||||
|
// change to its avatar, or has had its avatar deleted.
|
||||||
|
func MatchRoomUnchangedAvatar() RoomMatcher {
|
||||||
|
return func(r sync3.Room) error {
|
||||||
|
if r.AvatarChange != sync3.UnchangedAvatar {
|
||||||
|
return fmt.Errorf("MatchRoomAvatar: got \"%s\" want \"%s\"", r.AvatarChange, sync3.UnchangedAvatar)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func MatchJoinCount(count int) RoomMatcher {
|
func MatchJoinCount(count int) RoomMatcher {
|
||||||
return func(r sync3.Room) error {
|
return func(r sync3.Room) error {
|
||||||
if r.JoinedCount != count {
|
if r.JoinedCount != count {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user