Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SyncStateHas check function #440

Merged
merged 3 commits into from
Sep 2, 2022
Merged

Conversation

squahtx
Copy link
Contributor

@squahtx squahtx commented Aug 10, 2022

These will turn out to be useful when testing lazy-loading /syncs,
among other things.

Copy link
Member

@kegsay kegsay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't feel this PR should merge in its current state. I'd like to see more use cases where this functionality would be useful, and then we can see how this can be re-designed to work in a clear and consise way.

@@ -682,6 +682,34 @@ func SyncTimelineHasEventID(roomID string, eventID string) SyncCheckOpt {
})
}

// Check that the state for `roomID` has an event which passes the check function.
func SyncStateHas(roomID string, check func(gjson.Result) bool) SyncCheckOpt {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to be careful here, because this can be misused. The state section of the room contains the state at the start of the timeline, so it's entirely possible that the state to check is in the timeline and not the state. We should be very careful about checking one or the other. What is the use case here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultimately I would like to check that a lazy_load_members /sync response includes the membership of a given sender in the state section. The sender joined the room before the syncing user and their membership is not expected to appear in the timeline. The planned usage looks like this:

syncRes, _ := alice.MustSync(t,
	client.SyncReq{
		Since:  previousSyncToken,
		Filter: buildLazyLoadingSyncFilter(nil),
	},
)

err = client.SyncTimelineHasEventID(serverRoom.RoomID, event.EventID())(alice.UserID, syncRes)
if err != nil {
	t.Errorf("Did not find message in lazy-loading /sync response: %s", err)
}

err := client.SyncStateHasStateKey(serverRoom.RoomID, "m.room.member", event.Sender())(alice.UserID, syncRes)
if err != nil {
	t.Errorf("Did not find %s's m.room.member event in lazy-loading /sync response: %s", event.Sender(), err)
}

I'm avoiding MustSyncUntil because it wouldn't fail immediately if event appears in the timeline without the corresponding sender membership, and the message is expected to already be available via /sync.

}

// Check that the state for `roomID` has an event which matches the event ID.
func SyncStateHasEventID(roomID string, eventID string) SyncCheckOpt {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove: this doesn't compose well at all. What if we wanted to check the timeline for an event ID? What about ephemeral data? Room account data? Then we'd end up with:

  • SyncStateHasEventID
  • SyncTimelineHasEventID
  • SyncEphemeralHasEventID
  • SyncRoomAccountDataHasEventID

I hope it's clear how unruly and unmanageable this ends up becoming, especially if you then want to check the type/state key like SyncStateHasStateKey does. It would be better if you added functions which match func(gjson.Result) bool and compose well e.g:

  • func CheckEventIDIs(eventID) func(gjson.Result) bool
  • func CheckEventTypeIs(eventType) func(gjson.Result) bool

This would end up looking something like:

SyncStateHas(roomID, CheckEventIDIs(eventID), CheckEventTypeIs(eventType))

But this is also not great because often you want to check a few fields, though which fields depends on the test. Also, what is the relationship between the check functions: are they ANDed or ORd? At this point, it is often easier just to write the check function yourself:

SyncStateHas(roomID, func(ev gjson.Result) bool {
    		return ev.Get("type").Str == eventType && ev.Get("state_key").Str == stateKey
})

which also allows the flexibility to check say the content field easily enough. This is why we, as of yet, do not have per-event check functions: the benefits are unclear and the assertion itself is unclear.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do note that:

  • The events in the ephemeral and account_data sections do not have event_ids and we would not want to define SyncEphemeralHasEventID and SyncRoomAccountDataHasEventID as the spec stands.
  • SyncTimelineHasEventID already exists in Complement and this PR follows the existing pattern.

Shall we remove SyncTimelineHasEventID then?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

@erikjohnston erikjohnston removed the request for review from a team August 17, 2022 09:03
@richvdh richvdh requested a review from kegsay September 2, 2022 09:18
squahtx pushed a commit that referenced this pull request Sep 2, 2022
@squahtx
Copy link
Contributor Author

squahtx commented Sep 2, 2022

@kegsay The other SyncStateHas* functions have been removed, please re-review when you have time.
Alternatively, #442 includes everything from this PR, so the internal/client/client.go change in that PR can be reviewed instead.

@squahtx squahtx changed the title Add SyncStateHas* check functions Add SyncStateHas check function Sep 2, 2022
@squahtx squahtx merged commit 9d21cbf into main Sep 2, 2022
@squahtx squahtx deleted the squah/add_syncstatehas_helpers branch September 2, 2022 16:05
@squahtx
Copy link
Contributor Author

squahtx commented Sep 2, 2022

Thanks for re-reviewing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants