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

tests: Refactor the widget tests to use MockMatrixServer #4236

Merged
merged 12 commits into from
Dec 3, 2024

Conversation

toger5
Copy link
Contributor

@toger5 toger5 commented Nov 8, 2024

This is a follow up PR on: #3987
And tries to use the MockMatrixServer wherever reasonable in the widget integration tests.

  • Public API changes documented in changelogs (optional)

Signed-off-by:

Base automatically changed from toger5/widget-driver-redactions to main November 8, 2024 13:21
@toger5 toger5 force-pushed the toger5/mock-matrix-server-widget-tests branch from b0790c0 to a628d83 Compare November 8, 2024 15:25
Copy link

codecov bot commented Nov 8, 2024

Codecov Report

Attention: Patch coverage is 78.94737% with 8 lines in your changes missing coverage. Please review.

Project coverage is 85.13%. Comparing base (d49d122) to head (46bdcd9).
Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
crates/matrix-sdk/src/test_utils/mocks.rs 78.94% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4236      +/-   ##
==========================================
- Coverage   85.18%   85.13%   -0.05%     
==========================================
  Files         280      280              
  Lines       30729    30764      +35     
==========================================
+ Hits        26176    26192      +16     
- Misses       4553     4572      +19     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@poljar poljar changed the title Toger5/mock-matrix-server-widget-tests Refactor the widget tests to use MockMatrixServer Nov 8, 2024
@toger5 toger5 force-pushed the toger5/mock-matrix-server-widget-tests branch from a628d83 to b345d64 Compare November 13, 2024 16:02
@toger5
Copy link
Contributor Author

toger5 commented Nov 13, 2024

How do i test /test_utils/mocks.rs?

@toger5 toger5 force-pushed the toger5/mock-matrix-server-widget-tests branch from b345d64 to c573c2d Compare November 13, 2024 16:11
@bnjbvr
Copy link
Member

bnjbvr commented Nov 13, 2024

How do i test /test_utils/mocks.rs?

We usually don't test the test utilities; they should be straightforward enough that using them in tests would reveal their issues.

@toger5 toger5 force-pushed the toger5/mock-matrix-server-widget-tests branch from c573c2d to e8d57ca Compare November 13, 2024 16:18
@poljar
Copy link
Contributor

poljar commented Nov 13, 2024

How do i test /test_utils/mocks.rs?

Examples in the docstrings will be run as the doc tests which can run and test the mocks. At least that's how I wrote all the examples for the MatrixMockServer.

@toger5 toger5 marked this pull request as ready for review November 13, 2024 19:15
@toger5 toger5 requested a review from a team as a code owner November 13, 2024 19:15
@toger5 toger5 requested review from Hywan, bnjbvr and poljar and removed request for a team and bnjbvr November 13, 2024 19:15
@poljar poljar removed the request for review from Hywan November 14, 2024 16:13
Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

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

Thanks for working on this. Left a couple of nits about linkifying doc references and a couple more examples would be neat.

crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
impl<'a> MockEndpoint<'a, RoomMessagesEndpoint> {
/// Returns a messages endpoint that emulates success, i.e. the messages
/// provided as `response` could be retrieved.
pub fn ok(self, response: impl Into<Value>) -> MatrixMock<'a> {
Copy link
Member

Choose a reason for hiding this comment

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

No, we should not use impl Into<Value>, otherwise we lose all the usefulness of these mocking APIs by reverting to "we don't know what the return value looks like, it can be an arbitrary JSON". Instead we should use high-level types. We have another place where we do mock messages, grep for fn mock_messages (…it's even better, we do have two implementations :D).

@toger5 toger5 force-pushed the toger5/mock-matrix-server-widget-tests branch 6 times, most recently from a7d0264 to 5d5bec4 Compare November 25, 2024 14:47
@toger5 toger5 requested review from bnjbvr and poljar November 25, 2024 15:47
Copy link
Member

@bnjbvr bnjbvr left a comment

Choose a reason for hiding this comment

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

Super nice, thanks. Feel free to address the last comments, or let me know if you're bored with this PR, and then I can do it myself as a followup :)

crates/matrix-sdk/src/test_utils/mocks.rs Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
Comment on lines 1087 to 1089
let endpoint = RoomSendStateEndpoint { event_type: Some(event_type), ..self.endpoint };
let matcher = path_regex(Self::generate_path_regex(&endpoint));
Self { endpoint, mock: self.mock.and(matcher), ..self }
Copy link
Member

Choose a reason for hiding this comment

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

I think here it would be better to generate the path regex at the end, just before building the final MatrixMock.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Where would that be?
There are numerous places we build the final MatrixMock. Do you want to implement all the methods from MockEndpoint<'a, T> in
MockEndpoint<'a, RoomSendStateEndpoint>. What if someone adds a new method to the generic version that can build a matrix mock but forgets to update this version to build the regex?

Copy link
Member

Choose a reason for hiding this comment

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

You can take a look at RoomEventEndpoint as an example: it stores an optional room, set to None first:

endpoint: RoomEventEndpoint { room: None, match_event_id: false },

Then, we have a builder method to optionally set it:

pub fn room(mut self, room: impl Into<OwnedRoomId>) -> Self {
self.endpoint.room = Some(room.into());
self
}

Then, we create the final path when we want to get the final MatrixMock:

let event_path = if self.endpoint.match_event_id {
let event_id = event.kind.event_id().expect("an event id is required");
event_id.to_string()
} else {
// Event is at the end, so no need to add anything.
"".to_owned()
};
let room_path = self.endpoint.room.map_or_else(|| ".*".to_owned(), |room| room.to_string());
let mock = self
.mock
.and(path_regex(format!("^/_matrix/client/v3/rooms/{room_path}/event/{event_path}")))
.respond_with(ResponseTemplate::new(200).set_body_json(event.into_raw().json()));
MatrixMock { server: self.server, mock }

If this code were to be duplicated in multiple methods, then it could be factored out as an helper method, like generate_path_regexp does, in fact.

Does it make sense now?

Comment on lines 1146 to 1148
let endpoint = RoomSendStateEndpoint { state_key: Some(state_key), ..self.endpoint };
let matcher = path_regex(Self::generate_path_regex(&endpoint));
Self { endpoint, mock: self.mock.and(matcher), ..self }
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, same here: we should fill the state_key field in RoomSendStateEndpoint, but not make the matcher more precise there.

let matcher = path_regex(Self::generate_path_regex(&endpoint));
Self { endpoint, mock: self.mock.and(matcher), ..self }
}

Copy link
Member

Choose a reason for hiding this comment

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

note: doc comment for the ok_with_event_id is incorrect, as it duplicates the doc comment for mock_room_send without any change in the example code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean the doc comment for ok?
I suppose this is still helpful to have for ok. What other test du you have in mind?

Copy link
Member

Choose a reason for hiding this comment

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

Yes. The doc comment below is incorrect because it mentions mock_room_send while this is mock_room_send_state.

crates/matrix-sdk/src/test_utils/mocks.rs Show resolved Hide resolved
@toger5 toger5 force-pushed the toger5/mock-matrix-server-widget-tests branch from 966bf1c to 62a1fcf Compare November 26, 2024 17:35
@bnjbvr bnjbvr self-requested a review November 28, 2024 10:01
Copy link
Member

@bnjbvr bnjbvr left a comment

Choose a reason for hiding this comment

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

We're getting there!

let matcher = path_regex(Self::generate_path_regex(&endpoint));
Self { endpoint, mock: self.mock.and(matcher), ..self }
}

Copy link
Member

Choose a reason for hiding this comment

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

Yes. The doc comment below is incorrect because it mentions mock_room_send while this is mock_room_send_state.

crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
Comment on lines 1087 to 1089
let endpoint = RoomSendStateEndpoint { event_type: Some(event_type), ..self.endpoint };
let matcher = path_regex(Self::generate_path_regex(&endpoint));
Self { endpoint, mock: self.mock.and(matcher), ..self }
Copy link
Member

Choose a reason for hiding this comment

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

You can take a look at RoomEventEndpoint as an example: it stores an optional room, set to None first:

endpoint: RoomEventEndpoint { room: None, match_event_id: false },

Then, we have a builder method to optionally set it:

pub fn room(mut self, room: impl Into<OwnedRoomId>) -> Self {
self.endpoint.room = Some(room.into());
self
}

Then, we create the final path when we want to get the final MatrixMock:

let event_path = if self.endpoint.match_event_id {
let event_id = event.kind.event_id().expect("an event id is required");
event_id.to_string()
} else {
// Event is at the end, so no need to add anything.
"".to_owned()
};
let room_path = self.endpoint.room.map_or_else(|| ".*".to_owned(), |room| room.to_string());
let mock = self
.mock
.and(path_regex(format!("^/_matrix/client/v3/rooms/{room_path}/event/{event_path}")))
.respond_with(ResponseTemplate::new(200).set_body_json(event.into_raw().json()));
MatrixMock { server: self.server, mock }

If this code were to be duplicated in multiple methods, then it could be factored out as an helper method, like generate_path_regexp does, in fact.

Does it make sense now?

crates/matrix-sdk/tests/integration/event_cache.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
crates/matrix-sdk/src/test_utils/mocks.rs Outdated Show resolved Hide resolved
@bnjbvr bnjbvr changed the title Refactor the widget tests to use MockMatrixServer tests: Refactor the widget tests to use MockMatrixServer Dec 2, 2024
@bnjbvr bnjbvr force-pushed the toger5/mock-matrix-server-widget-tests branch from 62a1fcf to 77488a7 Compare December 2, 2024 16:26
@bnjbvr
Copy link
Member

bnjbvr commented Dec 2, 2024

To respond to my own suggestion in #4236 (comment): this is not possible, because it hinders usage of error500() and error_too_large(), which never define the more restricted path. I've reverted to the previous code, with a code comment explaining that it's fine to redefine a path regex, since it ought to be more specialized than the previous ones.

@bnjbvr bnjbvr enabled auto-merge (squash) December 2, 2024 16:43
Copy link
Member

@bnjbvr bnjbvr left a comment

Choose a reason for hiding this comment

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

Thanks, let's revisit the approach of finishing to construct a path regexp, because it's a bit calling for misuse, but that one is on me 😇

@bnjbvr bnjbvr merged commit e76b8f7 into main Dec 3, 2024
40 checks passed
@bnjbvr bnjbvr deleted the toger5/mock-matrix-server-widget-tests branch December 3, 2024 08:36
andybalaam pushed a commit that referenced this pull request Dec 18, 2024
This is a follow up PR on #3987.

And tries to use the `MockMatrixServer` wherever reasonable in the
widget integration tests.

---------

Co-authored-by: Benjamin Bouvier <[email protected]>
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.

3 participants