This means you don't need to tack on `, nil` all the time, and can optionally specify when you want to allow unwanted items, obviating the need for `JSONCheckOffAllowUnwanted`. This composes better and supports adding additional functionality e.g allowing duplicate items.
248 lines
6.8 KiB
Go
248 lines
6.8 KiB
Go
package csapi_tests
|
|
|
|
import (
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/tidwall/gjson"
|
|
|
|
"github.com/matrix-org/complement"
|
|
"github.com/matrix-org/complement/b"
|
|
"github.com/matrix-org/complement/client"
|
|
"github.com/matrix-org/complement/helpers"
|
|
"github.com/matrix-org/complement/match"
|
|
"github.com/matrix-org/complement/must"
|
|
)
|
|
|
|
func TestLeftRoomFixture(t *testing.T) {
|
|
deployment := complement.Deploy(t, 1)
|
|
defer deployment.Destroy(t)
|
|
|
|
alice := deployment.Register(t, "hs1", helpers.RegistrationOpts{})
|
|
bob := deployment.Register(t, "hs1", helpers.RegistrationOpts{})
|
|
charlie := deployment.Register(t, "hs1", helpers.RegistrationOpts{
|
|
LocalpartSuffix: "charlie",
|
|
Password: "sufficiently_long_password_charlie",
|
|
})
|
|
|
|
roomID := alice.MustCreateRoom(t, map[string]interface{}{
|
|
"initial_state": []map[string]interface{}{
|
|
{
|
|
"content": map[string]interface{}{
|
|
"history_visibility": "joined",
|
|
},
|
|
"type": "m.room.history_visibility",
|
|
"state_key": "",
|
|
},
|
|
},
|
|
"preset": "public_chat",
|
|
})
|
|
|
|
bob.MustJoinRoom(t, roomID, nil)
|
|
|
|
alice.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(bob.UserID, roomID))
|
|
|
|
const madeUpStateKey = "madeup.test.state"
|
|
|
|
const (
|
|
beforeRoomName = "N1. B's room name before A left"
|
|
beforeMadeUpState = "S1. B's state before A left"
|
|
beforeMessageOne = "M1. B's message before A left"
|
|
beforeMessageTwo = "M2. B's message before A left"
|
|
)
|
|
|
|
const (
|
|
afterRoomName = "N2. B's room name after A left"
|
|
afterMadeUpState = "S2. B's state after A left"
|
|
afterMessage = "M3. B's message after A left"
|
|
)
|
|
|
|
alice.SendEventSynced(t, roomID, b.Event{
|
|
Type: "m.room.name",
|
|
StateKey: b.Ptr(""),
|
|
Content: map[string]interface{}{
|
|
"name": beforeRoomName,
|
|
},
|
|
})
|
|
|
|
alice.SendEventSynced(t, roomID, b.Event{
|
|
Type: madeUpStateKey,
|
|
StateKey: b.Ptr(""),
|
|
Content: map[string]interface{}{
|
|
"body": beforeMadeUpState,
|
|
},
|
|
})
|
|
|
|
alice.SendEventSynced(t, roomID, b.Event{
|
|
Type: "m.room.message",
|
|
Content: map[string]interface{}{
|
|
"msgtype": "m.text",
|
|
"body": beforeMessageOne,
|
|
},
|
|
})
|
|
|
|
alice.SendEventSynced(t, roomID, b.Event{
|
|
Type: "m.room.message",
|
|
Content: map[string]interface{}{
|
|
"msgtype": "m.text",
|
|
"body": beforeMessageTwo,
|
|
},
|
|
})
|
|
|
|
bob.MustLeaveRoom(t, roomID)
|
|
|
|
alice.MustSyncUntil(t, client.SyncReq{}, client.SyncLeftFrom(bob.UserID, roomID))
|
|
|
|
_, bobSinceToken := bob.MustSync(t, client.SyncReq{TimeoutMillis: "0"})
|
|
|
|
alice.SendEventSynced(t, roomID, b.Event{
|
|
Type: "m.room.name",
|
|
StateKey: b.Ptr(""),
|
|
Content: map[string]interface{}{
|
|
"name": afterRoomName,
|
|
},
|
|
})
|
|
|
|
alice.SendEventSynced(t, roomID, b.Event{
|
|
Type: madeUpStateKey,
|
|
StateKey: b.Ptr(""),
|
|
Content: map[string]interface{}{
|
|
"body": afterMadeUpState,
|
|
},
|
|
})
|
|
|
|
alice.SendEventSynced(t, roomID, b.Event{
|
|
Type: "m.room.message",
|
|
Content: map[string]interface{}{
|
|
"msgtype": "m.text",
|
|
"body": afterMessage,
|
|
},
|
|
})
|
|
|
|
// Have charlie join the room, to check against /members calls later
|
|
// (Bob should not see Charlie in /members after he leaves the room.)
|
|
charlie.MustJoinRoom(t, roomID, nil)
|
|
alice.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(charlie.UserID, roomID))
|
|
|
|
// sytest: Can get rooms/{roomId}/state for a departed room (SPEC-216)
|
|
t.Run("Can get rooms/{roomId}/state for a departed room", func(t *testing.T) {
|
|
// Bob gets the old state
|
|
resp := bob.MustDo(
|
|
t,
|
|
"GET",
|
|
[]string{"_matrix", "client", "v3", "rooms", roomID, "state", madeUpStateKey},
|
|
)
|
|
must.MatchResponse(t, resp, match.HTTPResponse{
|
|
JSON: []match.JSON{
|
|
match.JSONKeyEqual("body", beforeMadeUpState),
|
|
},
|
|
})
|
|
|
|
// ...While Alice gets the new state
|
|
resp = alice.MustDo(
|
|
t,
|
|
"GET",
|
|
[]string{"_matrix", "client", "v3", "rooms", roomID, "state", madeUpStateKey},
|
|
)
|
|
must.MatchResponse(t, resp, match.HTTPResponse{
|
|
JSON: []match.JSON{
|
|
match.JSONKeyEqual("body", afterMadeUpState),
|
|
},
|
|
})
|
|
})
|
|
|
|
// sytest: Can get rooms/{roomId}/members for a departed room (SPEC-216)
|
|
t.Run("Can get rooms/{roomId}/members for a departed room", func(t *testing.T) {
|
|
resp := bob.MustDo(
|
|
t,
|
|
"GET",
|
|
[]string{"_matrix", "client", "v3", "rooms", roomID, "members"},
|
|
)
|
|
|
|
must.MatchResponse(t, resp, match.HTTPResponse{
|
|
JSON: []match.JSON{
|
|
match.JSONCheckOff("chunk",
|
|
[]interface{}{
|
|
"m.room.member|" + alice.UserID + "|join",
|
|
"m.room.member|" + bob.UserID + "|leave",
|
|
}, match.CheckOffMapper(func(result gjson.Result) interface{} {
|
|
return strings.Join([]string{
|
|
result.Map()["type"].Str,
|
|
result.Map()["state_key"].Str,
|
|
result.Get("content.membership").Str,
|
|
}, "|")
|
|
})),
|
|
},
|
|
})
|
|
})
|
|
|
|
// sytest: Can get rooms/{roomId}/messages for a departed room (SPEC-216)
|
|
t.Run("Can get rooms/{roomId}/messages for a departed room", func(t *testing.T) {
|
|
resp := bob.MustDo(t, "GET", []string{"_matrix", "client", "v3", "rooms", roomID, "messages"}, client.WithQueries(url.Values{
|
|
"dir": []string{"b"},
|
|
"limit": []string{"3"},
|
|
"from": []string{bobSinceToken},
|
|
}))
|
|
|
|
must.MatchResponse(t, resp, match.HTTPResponse{
|
|
JSON: []match.JSON{
|
|
match.JSONCheckOff("chunk", []interface{}{
|
|
"m.room.message|" + beforeMessageOne + "|",
|
|
"m.room.message|" + beforeMessageTwo + "|",
|
|
"m.room.member||" + bob.UserID,
|
|
}, match.CheckOffMapper(func(result gjson.Result) interface{} {
|
|
return strings.Join([]string{
|
|
result.Map()["type"].Str,
|
|
result.Get("content.body").Str,
|
|
result.Map()["state_key"].Str,
|
|
}, "|")
|
|
})),
|
|
},
|
|
})
|
|
})
|
|
|
|
// sytest: Can get 'm.room.name' state for a departed room (SPEC-216)
|
|
t.Run("Can get 'm.room.name' state for a departed room", func(t *testing.T) {
|
|
// Bob gets the old name
|
|
resp := bob.MustDo(
|
|
t,
|
|
"GET",
|
|
[]string{"_matrix", "client", "v3", "rooms", roomID, "state", "m.room.name"},
|
|
)
|
|
must.MatchResponse(t, resp, match.HTTPResponse{
|
|
JSON: []match.JSON{
|
|
match.JSONKeyEqual("name", beforeRoomName),
|
|
},
|
|
})
|
|
|
|
// ...While Alice gets the new name
|
|
resp = alice.MustDo(
|
|
t,
|
|
"GET",
|
|
[]string{"_matrix", "client", "v3", "rooms", roomID, "state", "m.room.name"},
|
|
)
|
|
must.MatchResponse(t, resp, match.HTTPResponse{
|
|
JSON: []match.JSON{
|
|
match.JSONKeyEqual("name", afterRoomName),
|
|
},
|
|
})
|
|
})
|
|
|
|
// sytest: Getting messages going forward is limited for a departed room (SPEC-216)
|
|
t.Run("Getting messages going forward is limited for a departed room", func(t *testing.T) {
|
|
// TODO: try this with the most recent since token too
|
|
resp := bob.MustDo(t, "GET", []string{"_matrix", "client", "v3", "rooms", roomID, "messages"}, client.WithQueries(url.Values{
|
|
"dir": []string{"f"},
|
|
"limit": []string{"100"},
|
|
"from": []string{bobSinceToken},
|
|
}))
|
|
|
|
must.MatchResponse(t, resp, match.HTTPResponse{
|
|
JSON: []match.JSON{
|
|
match.JSONKeyArrayOfSize("chunk", 0),
|
|
},
|
|
})
|
|
})
|
|
|
|
}
|