sliding-sync/sync3/tracker_test.go
David Robertson 4897acf3d6
Add the ability to reset the JoinedRoomsTracker
Not used yet; pulled out of #329.
2023-11-02 15:14:42 +00:00

209 lines
6.7 KiB
Go

package sync3
import (
"fmt"
"sort"
"testing"
)
func joinedUsersForRoom(jrt *JoinedRoomsTracker, roomID string) []string {
users, _ := jrt.JoinedUsersForRoom(roomID, nil)
return users
}
func TestTracker(t *testing.T) {
// basic usage
jrt := NewJoinedRoomsTracker()
jrt.UserJoinedRoom("alice", "room1")
jrt.UserJoinedRoom("alice", "room2")
jrt.UserJoinedRoom("bob", "room2")
jrt.UserJoinedRoom("bob", "room3")
assertEqualSlices(t, "", jrt.JoinedRoomsForUser("alice"), []string{"room1", "room2"})
assertEqualSlices(t, "", joinedUsersForRoom(jrt, "room1"), []string{"alice"})
jrt.UserLeftRoom("alice", "room1")
assertEqualSlices(t, "", jrt.JoinedRoomsForUser("alice"), []string{"room2"})
assertEqualSlices(t, "", joinedUsersForRoom(jrt, "room2"), []string{"alice", "bob"})
// test filters
fUsers, joinCount := jrt.JoinedUsersForRoom("room2", func(userID string) bool {
return userID == "alice"
})
assertInt(t, joinCount, 2)
assertEqualSlices(t, "filter_users wrong", fUsers, []string{"alice"})
fUsers, joinCount = jrt.JoinedUsersForRoom("room2", func(userID string) bool {
return userID == "unmatched"
})
assertInt(t, joinCount, 2)
assertEqualSlices(t, "wanted no filtered users", fUsers, nil)
// bogus values
assertEqualSlices(t, "", jrt.JoinedRoomsForUser("unknown"), nil)
assertEqualSlices(t, "", joinedUsersForRoom(jrt, "unknown"), nil)
// leaves before joins
jrt.UserLeftRoom("alice", "unknown")
jrt.UserLeftRoom("unknown", "unknown2")
assertEqualSlices(t, "", jrt.JoinedRoomsForUser("alice"), []string{"room2"})
jrt.UsersInvitedToRoom([]string{"alice"}, "room4")
assertNumEquals(t, jrt.NumInvitedUsersForRoom("room4"), 1)
jrt.UserJoinedRoom("alice", "room4")
assertNumEquals(t, jrt.NumInvitedUsersForRoom("room4"), 0)
jrt.UserJoinedRoom("alice", "room4") // dupe joins don't bother it
assertNumEquals(t, jrt.NumInvitedUsersForRoom("room4"), 0)
jrt.UsersInvitedToRoom([]string{"bob"}, "room4")
assertNumEquals(t, jrt.NumInvitedUsersForRoom("room4"), 1)
jrt.UsersInvitedToRoom([]string{"bob"}, "room4") // dupe invites don't bother it
assertNumEquals(t, jrt.NumInvitedUsersForRoom("room4"), 1)
jrt.UserLeftRoom("bob", "room4")
}
func TestTrackerStartup(t *testing.T) {
roomA := "!a"
roomB := "!b"
roomC := "!c"
alice := "@alice"
bob := "@bob"
jrt := NewJoinedRoomsTracker()
jrt.Startup(map[string][]string{
roomA: {alice, bob},
roomB: {bob},
roomC: {alice},
})
assertEqualSlices(t, "", jrt.JoinedRoomsForUser(alice), []string{roomA, roomC})
assertEqualSlices(t, "", jrt.JoinedRoomsForUser(bob), []string{roomA, roomB})
assertEqualSlices(t, "", jrt.JoinedRoomsForUser("@someone"), []string{})
assertBool(t, "alice should be joined", jrt.IsUserJoined(alice, roomA), true)
assertBool(t, "alice should not be joined", jrt.IsUserJoined(alice, roomB), false)
assertBool(t, "alice should be joined", jrt.IsUserJoined(alice, roomC), true)
assertBool(t, "bob should be joined", jrt.IsUserJoined(bob, roomA), true)
assertBool(t, "bob should be joined", jrt.IsUserJoined(bob, roomB), true)
assertBool(t, "bob should not be joined", jrt.IsUserJoined(bob, roomC), false)
assertInt(t, jrt.NumInvitedUsersForRoom(roomA), 0)
assertInt(t, jrt.NumInvitedUsersForRoom(roomB), 0)
assertInt(t, jrt.NumInvitedUsersForRoom(roomC), 0)
}
func TestTrackerReload(t *testing.T) {
roomA := "!a"
roomB := "!b"
roomC := "!c"
alice := "@alice"
bob := "@bob"
chris := "@chris"
jrt := NewJoinedRoomsTracker()
jrt.Startup(map[string][]string{
roomA: {alice, bob},
roomB: {bob},
roomC: {alice},
})
t.Log("Chris joins room C.")
jrt.ReloadMembershipsForRoom(roomC, []string{alice, chris}, nil)
members, _ := jrt.JoinedUsersForRoom(roomC, nil)
assertEqualSlices(t, "roomC joined members", members, []string{alice, chris})
assertEqualSlices(t, "alice's rooms", jrt.JoinedRoomsForUser(alice), []string{roomA, roomC})
assertEqualSlices(t, "chris's rooms", jrt.JoinedRoomsForUser(chris), []string{roomC})
assertInt(t, jrt.NumInvitedUsersForRoom(roomC), 0)
t.Log("Bob leaves room B.")
jrt.ReloadMembershipsForRoom(roomB, nil, nil)
members, _ = jrt.JoinedUsersForRoom(roomB, nil)
assertEqualSlices(t, "roomB joined members", members, nil)
assertEqualSlices(t, "bob's rooms", jrt.JoinedRoomsForUser(bob), []string{roomA})
assertInt(t, jrt.NumInvitedUsersForRoom(roomB), 0)
t.Log("Chris joins room A. Alice and Bob leave it, but Chris reinvites Bob.")
jrt.ReloadMembershipsForRoom(roomA, []string{chris}, []string{bob})
members, _ = jrt.JoinedUsersForRoom(roomA, nil)
assertEqualSlices(t, "roomA joined members", members, []string{chris})
assertEqualSlices(t, "alice's rooms", jrt.JoinedRoomsForUser(alice), []string{roomC})
assertEqualSlices(t, "bob's rooms", jrt.JoinedRoomsForUser(bob), nil)
assertEqualSlices(t, "chris's rooms", jrt.JoinedRoomsForUser(chris), []string{roomA, roomC})
assertInt(t, jrt.NumInvitedUsersForRoom(roomA), 1)
}
func TestJoinedRoomsTracker_UserLeftRoom_ReturnValue(t *testing.T) {
alice := "@alice"
bob := "@bob"
// Tell the tracker that alice left various rooms. Assert its return value is sensible.
tcs := []struct {
id string
joined []string
invited []string
expectedResult bool
}{
{
id: "!a",
joined: []string{alice, bob},
invited: nil,
expectedResult: true,
},
{
id: "!b",
joined: []string{alice},
invited: nil,
expectedResult: true,
},
{
id: "!c",
joined: []string{bob},
invited: nil,
expectedResult: false,
},
{
id: "!d",
joined: nil,
invited: nil,
expectedResult: false,
},
{
id: "!e",
joined: nil,
invited: []string{alice},
expectedResult: true,
},
}
jrt := NewJoinedRoomsTracker()
for _, tc := range tcs {
jrt.UsersJoinedRoom(tc.joined, tc.id)
jrt.UsersInvitedToRoom(tc.invited, tc.id)
}
// Tell the tracker that Alice left every room. Check the return value is sensible.
for _, tc := range tcs {
wasJoinedOrInvited := jrt.UserLeftRoom(alice, tc.id)
assertBool(t, fmt.Sprintf("wasJoinedOrInvited[%s]", tc.id), wasJoinedOrInvited, tc.expectedResult)
}
}
func assertBool(t *testing.T, msg string, got, want bool) {
t.Helper()
if got != want {
t.Errorf(msg)
}
}
func assertNumEquals(t *testing.T, got, want int) {
t.Helper()
if got != want {
t.Errorf("wrong number: got %v want %v", got, want)
}
}
func assertEqualSlices(t *testing.T, name string, got, want []string) {
t.Helper()
if len(got) != len(want) {
t.Fatalf("%s: slices not equal, length mismatch: got %v , want %v", name, got, want)
}
sort.Strings(got)
sort.Strings(want)
for i := 0; i < len(got); i++ {
if got[i] != want[i] {
t.Errorf("%s: slices not equal, got %v want %v", name, got, want)
}
}
}