client

package
v0.0.0-...-fc63446 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 26, 2024 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CtxKeyWithRetryUntil ctxKey = "complement_retry_until" // contains *retryUntilParams
)
View Source
const (
	SharedSecret = "complement"
)

Variables

This section is empty.

Functions

func GetJSONFieldStr

func GetJSONFieldStr(t ct.TestLike, body []byte, wantKey string) string

GetJSONFieldStr extracts a value from a byte-encoded JSON body given a search key

func GetJSONFieldStringArray

func GetJSONFieldStringArray(t ct.TestLike, body []byte, wantKey string) []string

func GjsonEscape

func GjsonEscape(in string) string

GjsonEscape escapes . and * from the input so it can be used with gjson.Get

func NewLoggedClient

func NewLoggedClient(t ct.TestLike, hsName string, cli *http.Client) *http.Client

NewLoggedClient returns an http.Client which logs requests/responses

func ParseJSON

func ParseJSON(t ct.TestLike, res *http.Response) []byte

ParseJSON parses a JSON-encoded HTTP Response body into a byte slice

func SplitMxc

func SplitMxc(mxcUri string) (string, string)

Splits an MXC URI into its origin and media ID parts

Types

type CSAPI

type CSAPI struct {
	UserID      string
	AccessToken string
	DeviceID    string
	Password    string // if provided
	BaseURL     string
	Client      *http.Client
	// how long are we willing to wait for MustSyncUntil.... calls
	SyncUntilTimeout time.Duration
	// True to enable verbose logging
	Debug bool
	// contains filtered or unexported fields
}

func (*CSAPI) ConsumeRefreshToken

func (c *CSAPI) ConsumeRefreshToken(t ct.TestLike, refreshToken string) (newAccessToken, newRefreshToken string, expiresInMs int64)

RefreshToken will consume a refresh token and return a new access token and refresh token.

func (*CSAPI) CreateMedia

func (c *CSAPI) CreateMedia(t ct.TestLike) string

CreateMedia creates an MXC URI for asynchronous media uploads.

func (*CSAPI) CreateRoom

func (c *CSAPI) CreateRoom(t ct.TestLike, body map[string]interface{}) *http.Response

CreateRoom creates a room with an optional HTTP request body.

func (*CSAPI) Do

func (c *CSAPI) Do(t ct.TestLike, method string, paths []string, opts ...RequestOpt) *http.Response

Do performs an arbitrary HTTP request to the server. This function supports RequestOpts to set extra information on the request such as an HTTP request body, query parameters and content-type. See all functions in this package starting with `With...`.

Fails the test if an HTTP request could not be made or if there was a network error talking to the server. To do assertions on the HTTP response, see the `must` package. For example:

must.MatchResponse(t, res, match.HTTPResponse{
	StatusCode: 400,
	JSON: []match.JSON{
		match.JSONKeyEqual("errcode", "M_INVALID_USERNAME"),
	},
})

func (*CSAPI) DownloadContent

func (c *CSAPI) DownloadContent(t ct.TestLike, mxcUri string) ([]byte, string)

DownloadContent downloads media from the server, returning the raw bytes and the Content-Type. Fails the test on error.

func (*CSAPI) DownloadContentAuthenticated

func (c *CSAPI) DownloadContentAuthenticated(t ct.TestLike, mxcUri string) ([]byte, string)

DownloadContentAuthenticated downloads media from _matrix/client/v1/media resource, returning the raw bytes and the Content-Type. Fails the test on error.

func (*CSAPI) GetAllPushRules

func (c *CSAPI) GetAllPushRules(t ct.TestLike) gjson.Result

GetAllPushRules fetches all configured push rules for a user from the homeserver. Push rules are returned as a parsed gjson result

Example of printing the IDs of all underride rules of the current user:

allPushRules := c.GetAllPushRules(t)
globalUnderridePushRules := allPushRules.Get("global").Get("underride").Array()

for index, rule := range globalUnderridePushRules {
  fmt.Printf("This rule's ID is: %s\n", rule.Get("rule_id").Str)
}

Push rules are returned in the same order received from the homeserver.

func (*CSAPI) GetCapabilities

func (c *CSAPI) GetCapabilities(t ct.TestLike) []byte

GetCapbabilities queries the server's capabilities

func (*CSAPI) GetDefaultRoomVersion

func (c *CSAPI) GetDefaultRoomVersion(t ct.TestLike) gomatrixserverlib.RoomVersion

GetDefaultRoomVersion returns the server's default room version

func (*CSAPI) GetGlobalAccountData

func (c *CSAPI) GetGlobalAccountData(t ct.TestLike, eventType string) *http.Response

func (*CSAPI) GetPushRule

func (c *CSAPI) GetPushRule(t ct.TestLike, scope string, kind string, ruleID string) gjson.Result

GetPushRule queries the contents of a client's push rule by scope, kind and rule ID. A parsed gjson result is returned. Fails the test if the query to server returns a non-2xx status code.

Example of checking that a global underride rule contains the expected actions:

containsDisplayNameRule := c.GetPushRule(t, "global", "underride", ".m.rule.contains_display_name")
must.MatchGJSON(
  t,
  containsDisplayNameRule,
  match.JSONKeyEqual("actions", []interface{}{
    "notify",
    map[string]interface{}{"set_tweak": "sound", "value": "default"},
    map[string]interface{}{"set_tweak": "highlight"},
  }),
)

func (*CSAPI) GetRoomAccountData

func (c *CSAPI) GetRoomAccountData(t ct.TestLike, roomID string, eventType string) *http.Response

func (*CSAPI) InviteRoom

func (c *CSAPI) InviteRoom(t ct.TestLike, roomID string, userID string) *http.Response

InviteRoom invites userID to the room ID, else fails the test.

func (*CSAPI) JoinRoom

func (c *CSAPI) JoinRoom(t ct.TestLike, roomIDOrAlias string, serverNames []string) *http.Response

JoinRoom joins the room ID or alias given. Returns the raw http response

func (*CSAPI) LeaveRoom

func (c *CSAPI) LeaveRoom(t ct.TestLike, roomID string) *http.Response

LeaveRoom leaves the room ID.

func (*CSAPI) LoginUser

func (c *CSAPI) LoginUser(t ct.TestLike, localpart, password string, opts ...LoginOpt) (userID, accessToken, deviceID string)

LoginUser will log in to a homeserver and create a new device on an existing user.

func (*CSAPI) LoginUserWithRefreshToken

func (c *CSAPI) LoginUserWithRefreshToken(t ct.TestLike, localpart, password string) (userID, accessToken, refreshToken, deviceID string, expiresInMs int64)

LoginUserWithRefreshToken will log in to a homeserver, with refresh token enabled, and create a new device on an existing user.

func (*CSAPI) MustCreateRoom

func (c *CSAPI) MustCreateRoom(t ct.TestLike, reqBody map[string]interface{}) string

MustCreateRoom creates a room with an optional HTTP request body. Fails the test on error. Returns the room ID.

func (*CSAPI) MustDo

func (c *CSAPI) MustDo(t ct.TestLike, method string, paths []string, opts ...RequestOpt) *http.Response

MustDo is the same as Do but fails the test if the returned HTTP response code is not 2xx.

func (*CSAPI) MustGenerateOneTimeKeys

func (c *CSAPI) MustGenerateOneTimeKeys(t ct.TestLike, otkCount uint) (deviceKeys map[string]interface{}, oneTimeKeys map[string]interface{})

Generate realistic looking device keys and OTKs. They are not guaranteed to be 100% valid, but should pass most server-side checks. Critically, these keys are generated using a Pseudo-Random Number Generator (PRNG) for determinism and hence ARE NOT SECURE. DO NOT USE THIS OUTSIDE OF TESTS.

func (*CSAPI) MustGetGlobalAccountData

func (c *CSAPI) MustGetGlobalAccountData(t ct.TestLike, eventType string) *http.Response

func (*CSAPI) MustGetRoomAccountData

func (c *CSAPI) MustGetRoomAccountData(t ct.TestLike, roomID string, eventType string) *http.Response

func (*CSAPI) MustInviteRoom

func (c *CSAPI) MustInviteRoom(t ct.TestLike, roomID string, userID string)

InviteRoom invites userID to the room ID, else fails the test.

func (*CSAPI) MustJoinRoom

func (c *CSAPI) MustJoinRoom(t ct.TestLike, roomIDOrAlias string, serverNames []string) string

MustJoinRoom joins the room ID or alias given, else fails the test. Returns the room ID.

func (*CSAPI) MustLeaveRoom

func (c *CSAPI) MustLeaveRoom(t ct.TestLike, roomID string)

MustLeaveRoom leaves the room ID, else fails the test.

func (*CSAPI) MustSendRedaction

func (c *CSAPI) MustSendRedaction(t ct.TestLike, roomID string, content map[string]interface{}, eventID string) string

SendRedaction sends a redaction request. Will fail if the returned HTTP request code is not 200. Returns the event ID of the redaction event.

func (*CSAPI) MustSendToDeviceMessages

func (c *CSAPI) MustSendToDeviceMessages(t ct.TestLike, evType string, messages map[string]map[string]map[string]interface{})

SendToDeviceMessages sends to-device messages over /sendToDevice/.

The messages parameter is nested as follows: user_id -> device_id -> content (map[string]interface{})

func (*CSAPI) MustSendTyping

func (c *CSAPI) MustSendTyping(t ct.TestLike, roomID string, isTyping bool, timeoutMillis int)

MustSendTyping marks this user as typing until the timeout is reached. If isTyping is false, timeout is ignored.

func (*CSAPI) MustSetGlobalAccountData

func (c *CSAPI) MustSetGlobalAccountData(t ct.TestLike, eventType string, content map[string]interface{}) *http.Response

func (*CSAPI) MustSetRoomAccountData

func (c *CSAPI) MustSetRoomAccountData(t ct.TestLike, roomID string, eventType string, content map[string]interface{}) *http.Response

func (*CSAPI) MustSync

func (c *CSAPI) MustSync(t ct.TestLike, syncReq SyncReq) (gjson.Result, string)

Perform a single /sync request with the given request options. To sync until something happens, see `MustSyncUntil`.

Fails the test if the /sync request does not return 200 OK. Returns the top-level parsed /sync response JSON as well as the next_batch token from the response.

func (*CSAPI) MustSyncUntil

func (c *CSAPI) MustSyncUntil(t ct.TestLike, syncReq SyncReq, checks ...SyncCheckOpt) string

MustSyncUntil blocks and continually calls /sync (advancing the since token) until all the check functions return no error. Returns the final/latest since token.

Initial /sync example: (no since token)

bob.InviteRoom(t, roomID, alice.UserID)
alice.JoinRoom(t, roomID, nil)
alice.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(alice.UserID, roomID))

Incremental /sync example: (test controls since token)

since := alice.MustSyncUntil(t, client.SyncReq{TimeoutMillis: "0"}) // get a since token
bob.InviteRoom(t, roomID, alice.UserID)
since = alice.MustSyncUntil(t, client.SyncReq{Since: since}, client.SyncInvitedTo(alice.UserID, roomID))
alice.JoinRoom(t, roomID, nil)
alice.MustSyncUntil(t, client.SyncReq{Since: since}, client.SyncJoinedTo(alice.UserID, roomID))

Checking multiple parts of /sync:

alice.MustSyncUntil(
    t, client.SyncReq{},
    client.SyncJoinedTo(alice.UserID, roomID),
    client.SyncJoinedTo(alice.UserID, roomID2),
    client.SyncJoinedTo(alice.UserID, roomID3),
)

Check functions are unordered and independent. Once a check function returns true it is removed from the list of checks and won't be called again.

In the unlikely event that you want all the checkers to pass *explicitly* in a single /sync response (e.g to assert some form of atomic update which updates multiple parts of the /sync response at once) then make your own checker function which does this.

In the unlikely event that you need ordering on your checks, call MustSyncUntil multiple times with a single checker, and reuse the returned since token, as in the "Incremental sync" example.

Will time out after CSAPI.SyncUntilTimeout. Returns the `next_batch` token from the final response.

func (*CSAPI) MustUploadKeys

func (c *CSAPI) MustUploadKeys(t ct.TestLike, deviceKeys map[string]interface{}, oneTimeKeys map[string]interface{}) (otkCounts map[string]int)

func (*CSAPI) RegisterSharedSecret

func (c *CSAPI) RegisterSharedSecret(t ct.TestLike, user, pass string, isAdmin bool) (userID, accessToken, deviceID string)

RegisterSharedSecret registers a new account with a shared secret via HMAC See https://github.com/matrix-org/synapse/blob/e550ab17adc8dd3c48daf7fedcd09418a73f524b/synapse/_scripts/register_new_matrix_user.py#L40

func (*CSAPI) RegisterUser

func (c *CSAPI) RegisterUser(t ct.TestLike, localpart, password string) (userID, accessToken, deviceID string)

RegisterUser will register the user with given parameters and return user ID, access token and device ID. It fails the test on network error.

func (*CSAPI) SendEventSynced

func (c *CSAPI) SendEventSynced(t ct.TestLike, roomID string, e b.Event) string

SendEventSynced sends `e` into the room and waits for its event ID to come down /sync. Returns the event ID of the sent event.

func (*CSAPI) SendRedaction

func (c *CSAPI) SendRedaction(t ct.TestLike, roomID string, content map[string]interface{}, eventID string) *http.Response

SendRedaction sends a redaction request.

func (*CSAPI) SendToDeviceMessages

func (c *CSAPI) SendToDeviceMessages(t ct.TestLike, evType string, messages map[string]map[string]map[string]interface{}) (errRes *http.Response)

SendToDeviceMessages sends to-device messages over /sendToDevice/.

The messages parameter is nested as follows: user_id -> device_id -> content (map[string]interface{})

func (*CSAPI) SendTyping

func (c *CSAPI) SendTyping(t ct.TestLike, roomID string, isTyping bool, timeoutMillis int) *http.Response

SendTyping marks this user as typing until the timeout is reached. If isTyping is false, timeout is ignored.

func (*CSAPI) SetPushRule

func (c *CSAPI) SetPushRule(t ct.TestLike, scope string, kind string, ruleID string, body map[string]interface{}, before string, after string) *http.Response

SetPushRule creates a new push rule on the user, or modifies an existing one. If `before` or `after` parameters are not set to an empty string, their values will be set as the `before` and `after` query parameters respectively on the "set push rules" client endpoint: https://spec.matrix.org/v1.5/client-server-api/#put_matrixclientv3pushrulesscopekindruleid

Example of setting a push rule with ID 'com.example.rule2' that must come after 'com.example.rule1':

c.SetPushRule(t, "global", "underride", "com.example.rule2", map[string]interface{}{
  "actions": []string{"dont_notify"},
}, nil, "com.example.rule1")

func (*CSAPI) Sync

func (c *CSAPI) Sync(t ct.TestLike, syncReq SyncReq) (gjson.Result, *http.Response)

Perform a single /sync request with the given request options. To sync until something happens, see `MustSyncUntil`.

Always returns the HTTP response, even on non-2xx. Returns the top-level parsed /sync response JSON on 2xx.

func (*CSAPI) Unsafe_SendEventUnsynced

func (c *CSAPI) Unsafe_SendEventUnsynced(t ct.TestLike, roomID string, e b.Event) string

Unsafe_SendEventUnsynced sends `e` into the room. This function is UNSAFE as it does not wait for the event to be fully processed. This can cause flakey tests. Prefer `SendEventSynced`. Returns the event ID of the sent event.

func (*CSAPI) Unsafe_SendEventUnsyncedWithTxnID

func (c *CSAPI) Unsafe_SendEventUnsyncedWithTxnID(t ct.TestLike, roomID string, e b.Event, txnID string) string

SendEventUnsyncedWithTxnID sends `e` into the room with a prescribed transaction ID. This is useful for writing tests that interrogate transaction semantics. This function is UNSAFE as it does not wait for the event to be fully processed. This can cause flakey tests. Prefer `SendEventSynced`. Returns the event ID of the sent event.

func (*CSAPI) UploadContent

func (c *CSAPI) UploadContent(t ct.TestLike, fileBody []byte, fileName string, contentType string) string

UploadContent uploads the provided content with an optional file name. Fails the test on error. Returns the MXC URI.

func (*CSAPI) UploadMediaAsync

func (c *CSAPI) UploadMediaAsync(t ct.TestLike, serverName, mediaID string, fileBody []byte, fileName string, contentType string)

UploadMediaAsync uploads the provided content to the given server and media ID. Fails the test on error.

type LoginOpt

type LoginOpt func(map[string]interface{})

func WithDeviceID

func WithDeviceID(deviceID string) LoginOpt

type RequestOpt

type RequestOpt func(req *http.Request)

RequestOpt is a functional option which will modify an outgoing HTTP request. See functions starting with `With...` in this package for more info.

func WithContentType

func WithContentType(cType string) RequestOpt

WithContentType sets the HTTP request Content-Type header to `cType`

func WithJSONBody

func WithJSONBody(t ct.TestLike, obj interface{}) RequestOpt

WithJSONBody sets the HTTP request body to the JSON serialised form of `obj`

func WithQueries

func WithQueries(q url.Values) RequestOpt

WithQueries sets the query parameters on the request. This function should not be used to set an "access_token" parameter for Matrix authentication. Instead, set CSAPI.AccessToken.

func WithRawBody

func WithRawBody(body []byte) RequestOpt

WithRawBody sets the HTTP request body to `body`

func WithRetryUntil

func WithRetryUntil(timeout time.Duration, untilFn func(res *http.Response) bool) RequestOpt

WithRetryUntil will retry the request until the provided function returns true. Times out after `timeout`, which will then fail the test.

type SyncCheckOpt

type SyncCheckOpt func(clientUserID string, topLevelSyncJSON gjson.Result) error

SyncCheckOpt is a functional option for use with MustSyncUntil which should return <nil> if the response satisfies the check, else return a human friendly error. The result object is the entire /sync response from this request.

func SyncEphemeralHas

func SyncEphemeralHas(roomID string, check func(gjson.Result) bool) SyncCheckOpt

func SyncGlobalAccountDataHas

func SyncGlobalAccountDataHas(check func(gjson.Result) bool) SyncCheckOpt

Calls the `check` function for each global account data event, and returns with success if the `check` function returns true for at least one event.

func SyncInvitedTo

func SyncInvitedTo(userID, roomID string) SyncCheckOpt

Checks that `userID` gets invited to `roomID`.

This checks different parts of the /sync response depending on the client making the request. If the client is also the person being invited to the room then the 'invite' block will be inspected. If the client is different to the person being invited then the 'join' block will be inspected.

func SyncJoinedTo

func SyncJoinedTo(userID, roomID string, checks ...func(gjson.Result) bool) SyncCheckOpt

Check that `userID` gets joined to `roomID` by inspecting the join timeline for a membership event.

Additional checks can be passed to narrow down the check, all must pass.

func SyncLeftFrom

func SyncLeftFrom(userID, roomID string) SyncCheckOpt

Check that `userID` is leaving `roomID` by inspecting the timeline for a membership event, or witnessing `roomID` in `rooms.leave` Note: This will not work properly with initial syncs, see https://github.com/matrix-org/matrix-doc/issues/3537

func SyncPresenceHas

func SyncPresenceHas(fromUser string, expectedPresence *string, checks ...func(gjson.Result) bool) SyncCheckOpt

Check that the sync contains presence from a user, optionally with an expected presence (set to nil to not check), and optionally with extra checks.

func SyncRoomAccountDataHas

func SyncRoomAccountDataHas(roomID string, check func(gjson.Result) bool) SyncCheckOpt

Calls the `check` function for each account data event for the given room, and returns with success if the `check` function returns true for at least one event.

func SyncStateHas

func SyncStateHas(roomID string, check func(gjson.Result) bool) SyncCheckOpt

Check that the state section for `roomID` has an event which passes the check function. Note that the state section of a sync response only contains the change in state up to the start of the timeline and will not contain the entire state of the room for incremental or `lazy_load_members` syncs.

func SyncTimelineHas

func SyncTimelineHas(roomID string, check func(gjson.Result) bool) SyncCheckOpt

Check that the timeline for `roomID` has an event which passes the check function.

func SyncTimelineHasEventID

func SyncTimelineHasEventID(roomID string, eventID string) SyncCheckOpt

Check that the timeline for `roomID` has an event which matches the event ID.

func SyncToDeviceHas

func SyncToDeviceHas(fromUser string, check func(gjson.Result) bool) SyncCheckOpt

Check that sync has received a to-device message, with optional user filtering.

If fromUser == "", all messages will be passed through to the check function. `check` will be called for all messages that have passed the filter.

`check` gets passed the full event, including sender and type.

func SyncUsersTyping

func SyncUsersTyping(roomID string, userIDs []string) SyncCheckOpt

SyncUsersTyping passes when all users in `userIDs` are typing in the same typing EDU. It must see a typing EDU first before returning, even if the list of user IDs is empty.

type SyncReq

type SyncReq struct {
	// A point in time to continue a sync from. This should be the next_batch token returned by an
	// earlier call to this endpoint.
	Since string
	// The ID of a filter created using the filter API or a filter JSON object encoded as a string.
	// The server will detect whether it is an ID or a JSON object by whether the first character is
	// a "{" open brace. Passing the JSON inline is best suited to one off requests. Creating a
	// filter using the filter API is recommended for clients that reuse the same filter multiple
	// times, for example in long poll requests.
	Filter string
	// Controls whether to include the full state for all rooms the user is a member of.
	// If this is set to true, then all state events will be returned, even if since is non-empty.
	// The timeline will still be limited by the since parameter. In this case, the timeout parameter
	// will be ignored and the query will return immediately, possibly with an empty timeline.
	// If false, and since is non-empty, only state which has changed since the point indicated by
	// since will be returned.
	// By default, this is false.
	FullState bool
	// Controls whether the client is automatically marked as online by polling this API. If this
	// parameter is omitted then the client is automatically marked as online when it uses this API.
	// Otherwise if the parameter is set to “offline” then the client is not marked as being online
	// when it uses this API. When set to “unavailable”, the client is marked as being idle.
	// One of: [offline online unavailable].
	SetPresence string
	// The maximum time to wait, in milliseconds, before returning this request. If no events
	// (or other data) become available before this time elapses, the server will return a response
	// with empty fields.
	// By default, this is 1000 for Complement testing.
	TimeoutMillis string // string for easier conversion to query params
}

SyncReq contains all the /sync request configuration options. The empty struct `SyncReq{}` is valid which will do a full /sync due to lack of a since token.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL