From eb6da20375804468c3eb278b73b72b98161ee9f4 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 6 Jan 2023 18:21:49 +0000 Subject: [PATCH 1/5] Add GetAllPushRules, GetPushRule, SetPushRule client helper methods Some helper methods to get and set push rules. --- internal/client/client.go | 71 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/internal/client/client.go b/internal/client/client.go index cd5a5b80..2a3ac5b2 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -188,6 +188,77 @@ func (c *CSAPI) SetRoomAccountData(t *testing.T, roomID string, eventType string return c.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "user", c.UserID, "rooms", roomID, "account_data", eventType}, WithJSONBody(t, content)) } +// 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 (c *CSAPI) GetAllPushRules(t *testing.T) gjson.Result { + t.Helper() + + // We have to supply an empty string to the end of this path in order to generate a trailing slash. + // See https://github.com/matrix-org/matrix-spec/issues/457 + res := c.MustDoFunc(t, "GET", []string{"_matrix", "client", "v3", "pushrules", ""}) + pushRulesBytes := ParseJSON(t, res) + return gjson.ParseBytes(pushRulesBytes) +} + +// 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 (c *CSAPI) GetPushRule(t *testing.T, scope string, kind string, ruleID string) gjson.Result { + t.Helper() + + res := c.MustDoFunc(t, "GET", []string{"_matrix", "client", "v3", "pushrules", scope, kind, ruleID}) + pushRuleBytes := ParseJSON(t, res) + return gjson.ParseBytes(pushRuleBytes) +} + +// SetPushRule creates a new push rule on the user, or modifies an existing one. +// `before` and `after` parameters can be provided, which if set will map to the +// `before` and `after` query parameters on the set push rules endpoint: +// https://spec.matrix.org/v1.5/client-server-api/#get_matrixclientv3pushrules. +// +// 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 (c *CSAPI) SetPushRule(t *testing.T, scope string, kind string, ruleID string, body map[string]interface{}, before *string, after *string) *http.Response { + t.Helper() + + // If the `before` or `after` arguments have been provided, construct same-named query parameters + queryParams := url.Values{} + if before != nil { + queryParams.Add("before", *before) + } + if after != nil { + queryParams.Add("after", *after) + } + + return c.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "pushrules", scope, kind, ruleID}, WithJSONBody(t, body), WithQueries(queryParams)) +} + // 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 (c *CSAPI) SendEventSynced(t *testing.T, roomID string, e b.Event) string { From 9c590e015f8a1dbef95d01a3fd6039fd54fad4ca Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 6 Jan 2023 18:22:17 +0000 Subject: [PATCH 2/5] Update push_test.go to use the new helpers --- tests/csapi/push_test.go | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/tests/csapi/push_test.go b/tests/csapi/push_test.go index efcb6bcc..81157294 100644 --- a/tests/csapi/push_test.go +++ b/tests/csapi/push_test.go @@ -20,26 +20,16 @@ func TestPushRuleCacheHealth(t *testing.T) { alice := deployment.Client(t, "hs1", "@alice:hs1") - alice.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "pushrules", "global", "sender", alice.UserID}, client.WithJSONBody(t, map[string]interface{}{ + // Set a global push rule + alice.SetPushRule(t, "global", "sender", alice.UserID, map[string]interface{}{ "actions": []string{"dont_notify"}, - })) + }, nil, nil) - // the extra "" is to make sure the submitted URL ends with a trailing slash - res := alice.MustDoFunc(t, "GET", []string{"_matrix", "client", "v3", "pushrules", ""}) + // Fetch the rule once and check its contents + must.MatchGJSON(t, alice.GetAllPushRules(t), match.JSONKeyEqual("global.sender.0.actions.0", "dont_notify")) - must.MatchResponse(t, res, match.HTTPResponse{ - JSON: []match.JSON{ - match.JSONKeyEqual("global.sender.0.actions.0", "dont_notify"), - }, - }) - - res = alice.MustDoFunc(t, "GET", []string{"_matrix", "client", "v3", "pushrules", ""}) - - must.MatchResponse(t, res, match.HTTPResponse{ - JSON: []match.JSON{ - match.JSONKeyEqual("global.sender.0.actions.0", "dont_notify"), - }, - }) + // Fetch the rule and check its contents again. It should not have changed. + must.MatchGJSON(t, alice.GetAllPushRules(t), match.JSONKeyEqual("global.sender.0.actions.0", "dont_notify")) } func TestPushSync(t *testing.T) { From 93dd7ebdc600f5bb338951d345a853db03b0e797 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 6 Jan 2023 18:22:38 +0000 Subject: [PATCH 3/5] Fix a small typo Found while traversing the codebase. --- tests/csapi/account_change_password_pushers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/csapi/account_change_password_pushers_test.go b/tests/csapi/account_change_password_pushers_test.go index ab660ea5..3291fc88 100644 --- a/tests/csapi/account_change_password_pushers_test.go +++ b/tests/csapi/account_change_password_pushers_test.go @@ -59,7 +59,7 @@ func TestChangePasswordPushers(t *testing.T) { }) // sytest: Pushers created with a the same access token are not deleted on password change - t.Run("Pushers created with a the same access token are not deleted on password change", func(t *testing.T) { + t.Run("Pushers created with the same access token are not deleted on password change", func(t *testing.T) { reqBody := client.WithJSONBody(t, map[string]interface{}{ "data": map[string]interface{}{ "url": "https://dummy.url/_matrix/push/v1/notify", From 87c7103150e3fc771c21e1a34c5256c6b4384b9c Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 9 Jan 2023 14:57:30 +0000 Subject: [PATCH 4/5] Switch SetPushRule to use non-string pointers; update push_test.go --- internal/client/client.go | 15 ++++++++------- tests/csapi/push_test.go | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/internal/client/client.go b/internal/client/client.go index 2a3ac5b2..be8b09ac 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -235,8 +235,9 @@ func (c *CSAPI) GetPushRule(t *testing.T, scope string, kind string, ruleID stri } // SetPushRule creates a new push rule on the user, or modifies an existing one. -// `before` and `after` parameters can be provided, which if set will map to the -// `before` and `after` query parameters on the set push rules endpoint: +// 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/#get_matrixclientv3pushrules. // // Example of setting a push rule with ID 'com.example.rule2' that must come after 'com.example.rule1': @@ -244,16 +245,16 @@ func (c *CSAPI) GetPushRule(t *testing.T, scope string, kind string, ruleID stri // c.SetPushRule(t, "global", "underride", "com.example.rule2", map[string]interface{}{ // "actions": []string{"dont_notify"}, // }, nil, "com.example.rule1") -func (c *CSAPI) SetPushRule(t *testing.T, scope string, kind string, ruleID string, body map[string]interface{}, before *string, after *string) *http.Response { +func (c *CSAPI) SetPushRule(t *testing.T, scope string, kind string, ruleID string, body map[string]interface{}, before string, after string) *http.Response { t.Helper() // If the `before` or `after` arguments have been provided, construct same-named query parameters queryParams := url.Values{} - if before != nil { - queryParams.Add("before", *before) + if before != "" { + queryParams.Add("before", before) } - if after != nil { - queryParams.Add("after", *after) + if after != "" { + queryParams.Add("after", after) } return c.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "pushrules", scope, kind, ruleID}, WithJSONBody(t, body), WithQueries(queryParams)) diff --git a/tests/csapi/push_test.go b/tests/csapi/push_test.go index 81157294..12237e76 100644 --- a/tests/csapi/push_test.go +++ b/tests/csapi/push_test.go @@ -23,7 +23,7 @@ func TestPushRuleCacheHealth(t *testing.T) { // Set a global push rule alice.SetPushRule(t, "global", "sender", alice.UserID, map[string]interface{}{ "actions": []string{"dont_notify"}, - }, nil, nil) + }, "", "") // Fetch the rule once and check its contents must.MatchGJSON(t, alice.GetAllPushRules(t), match.JSONKeyEqual("global.sender.0.actions.0", "dont_notify")) From 18babb733272bde3042ccb1067d472dde6dafaa7 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 9 Jan 2023 17:19:44 +0000 Subject: [PATCH 5/5] fix spec URL in docstring of SetPushRule --- internal/client/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/client/client.go b/internal/client/client.go index be8b09ac..eaabca5b 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -238,7 +238,7 @@ func (c *CSAPI) GetPushRule(t *testing.T, scope string, kind string, ruleID stri // 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/#get_matrixclientv3pushrules. +// 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': //