Skip to content

Commit dd51dcb

Browse files
authored
Add tests for room version 6. (#869)
1 parent 84d7cf9 commit dd51dcb

File tree

11 files changed

+646
-25
lines changed

11 files changed

+646
-25
lines changed

lib/SyTest/Federation/Client.pm

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ use SyTest::Assertions qw( :all );
1616
use URI::Escape qw( uri_escape );
1717

1818
use constant SUPPORTED_ROOM_VERSIONS => [qw(
19-
1 2 3 4 5
20-
org.matrix.msc2260
19+
1 2 3 4 5 6
2120
)];
2221

2322
sub configure

lib/SyTest/Federation/Datastore.pm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,13 @@ sub get_backfill_events
268268
my $event = eval { $self->get_event( $id ) }
269269
or next;
270270

271+
my $room = $self->get_room( $event->{room_id} ) or
272+
croak "Unknown room $event->{room_id}";
273+
271274
push @events, $event;
272275

273276
push @event_ids, grep { !$exclude{$_} }
274-
map { $_->[0] } @{ $event->{prev_events} };
277+
@{ $room->event_ids_from_refs( $event->{prev_events} ) };
275278

276279
# Don't include this event if we encounter it again
277280
$exclude{$id} = 1;

tests/00expect_http_fail.pl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,13 @@ sub expect_m_not_found
172172
);
173173
}
174174
push @EXPORT, qw( expect_m_not_found );
175+
176+
177+
sub expect_m_bad_json
178+
{
179+
my $f = shift;
180+
return expect_matrix_error(
181+
$f, 400, 'M_BAD_JSON',
182+
);
183+
}
184+
push @EXPORT, qw( expect_m_bad_json );

tests/30rooms/08levels.pl

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@
77

88
sub lockeddown_room_fixture
99
{
10+
my ( %options ) = @_;
11+
1012
fixture(
1113
requires => [ $creator_fixture, $user_fixture,
1214
qw( can_change_power_levels ) ],
1315

1416
setup => sub {
1517
my ( $creator, $test_user ) = @_;
1618

17-
matrix_create_and_join_room( [ $creator, $test_user ] )
19+
matrix_create_and_join_room( [ $creator, $test_user ], %options )
1820
->then( sub {
1921
my ( $room_id ) = @_;
2022

@@ -154,6 +156,27 @@ sub test_powerlevel
154156

155157
$levels->{$levelname} = 10000000;
156158
})->main::expect_http_403
157-
})->SyTest::pass_on_done( "Fails at setting 75" );
159+
})->SyTest::pass_on_done( "Fails at setting 10000000" );
158160
};
159161
}
162+
163+
multi_test "Users cannot set notifications powerlevel higher than their own",
164+
requires => [ $creator_fixture, $user_fixture, lockeddown_room_fixture( room_version => "6" ),
165+
qw( can_change_power_levels )],
166+
167+
do => sub {
168+
my ( $user, undef, $room_id ) = @_;
169+
170+
matrix_change_room_power_levels( $user, $room_id, sub {
171+
my ( $levels ) = @_;
172+
173+
$levels->{notifications}{room} = 25;
174+
})->SyTest::pass_on_done( "Succeeds at setting 25" )
175+
->then( sub {
176+
matrix_change_room_power_levels( $user, $room_id, sub {
177+
my ( $levels ) = @_;
178+
179+
$levels->{notifications}{room} = 10000000;
180+
})->main::expect_http_403
181+
})->SyTest::pass_on_done( "Fails at setting 10000000" );
182+
};

tests/32room-versions.pl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use URI::Escape qw( uri_escape );
22

33
# We test that some basic functionality works across all room versions
4-
foreach my $version ( qw ( 1 2 3 4 5 ) ) {
4+
foreach my $version ( qw ( 1 2 3 4 5 6 ) ) {
55
multi_test "User can create and send/receive messages in a room with version $version",
66
requires => [ local_user_fixture() ],
77

tests/50federation/30room-join.pl

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,3 +1061,62 @@ sub assert_is_valid_pdu {
10611061
}),
10621062
)
10631063
};
1064+
1065+
# A homeserver receiving a `send_join` request for a room version 6 room with
1066+
# a bad JSON value (e.g. a float) should reject the request.
1067+
#
1068+
# To test this we need to:
1069+
# * Send a successful `make_join` request.
1070+
# * Add a "bad" value into the returned prototype event.
1071+
# * Make a request to `send_join`.
1072+
# * Check that the response is M_BAD_JSON.
1073+
test "Inbound: send_join rejects invalid JSON for room version 6",
1074+
requires => [ $main::OUTBOUND_CLIENT, $main::INBOUND_SERVER,
1075+
local_user_and_room_fixtures( room_opts => { room_version => "6" } ),
1076+
federation_user_id_fixture() ],
1077+
1078+
do => sub {
1079+
my ( $outbound_client, $inbound_server, $creator, $room_id, $user_id ) = @_;
1080+
my $first_home_server = $creator->server_name;
1081+
1082+
my $local_server_name = $outbound_client->server_name;
1083+
my $datastore = $inbound_server->datastore;
1084+
1085+
$outbound_client->do_request_json(
1086+
method => "GET",
1087+
hostname => $first_home_server,
1088+
uri => "/v1/make_join/$room_id/$user_id",
1089+
params => {
1090+
ver => ["6"],
1091+
},
1092+
)->then( sub {
1093+
my ( $body ) = @_;
1094+
1095+
log_if_fail "make_join body", $body;
1096+
1097+
my $protoevent = $body->{event};
1098+
1099+
# It is assumed that the make_join response is sane, other tests ensure
1100+
# this behavior.
1101+
1102+
my %event = (
1103+
( map { $_ => $protoevent->{$_} } qw(
1104+
auth_events content depth prev_events room_id sender
1105+
state_key type ) ),
1106+
1107+
origin => $local_server_name,
1108+
origin_server_ts => $inbound_server->time_ms,
1109+
);
1110+
# Insert a "bad" value into the send join, in this case a float.
1111+
${event}{content}{bad_val} = 1.1;
1112+
1113+
$datastore->sign_event( \%event );
1114+
1115+
$outbound_client->do_request_json(
1116+
method => "PUT",
1117+
hostname => $first_home_server,
1118+
uri => "/v2/send_join/$room_id/xxx",
1119+
content => \%event,
1120+
)
1121+
})->main::expect_m_bad_json;
1122+
};

tests/50federation/33room-get-missing-events.pl

Lines changed: 127 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
test "Outbound federation can request missing events",
22
requires => [ $main::OUTBOUND_CLIENT, $main::INBOUND_SERVER,
33
local_user_and_room_fixtures(
4-
user_opts => { with_events => 1 },
54
room_opts => { room_version => "1" },
65
),
76
federation_user_id_fixture() ],
@@ -10,10 +9,9 @@
109
my ( $outbound_client, $inbound_server, $creator, $room_id, $user_id ) = @_;
1110
my $first_home_server = $creator->server_name;
1211

13-
my $local_server_name = $inbound_server->server_name;
1412
my $datastore = $inbound_server->datastore;
1513

16-
my $missing_event;
14+
my $missing_event_id;
1715

1816
$outbound_client->join_room(
1917
server_name => $first_home_server,
@@ -27,14 +25,15 @@
2725
my $latest_event = $room->get_current_state_event( "m.room.member", $user_id );
2826

2927
# Generate but don't send an event
30-
$missing_event = $room->create_and_insert_event(
28+
my $missing_event = $room->create_and_insert_event(
3129
type => "m.room.message",
3230

3331
sender => $user_id,
3432
content => {
3533
body => "Message 1",
3634
},
3735
);
36+
$missing_event_id = $room->id_for_event( $missing_event );
3837

3938
# Generate another one and do send it so it will refer to the
4039
# previous in its prev_events field
@@ -43,9 +42,7 @@
4342

4443
# This would be done by $room->create_and_insert_event anyway but lets be
4544
# sure for this test
46-
prev_events => [
47-
[ $missing_event->{event_id}, $missing_event->{hashes} ],
48-
],
45+
prev_events => $room->make_event_refs( $missing_event ),
4946

5047
sender => $user_id,
5148
content => {
@@ -65,13 +62,13 @@
6562
assert_json_list( my $earliest = $body->{earliest_events} );
6663
@$earliest == 1 or
6764
die "Expected a single 'earliest_event' ID";
68-
assert_eq( $earliest->[0], $latest_event->{event_id},
65+
assert_eq( $earliest->[0], $room->id_for_event( $latest_event ),
6966
'earliest_events[0]' );
7067

7168
assert_json_list( my $latest = $body->{latest_events} );
7269
@$latest == 1 or
7370
die "Expected a single 'latest_events' ID";
74-
assert_eq( $latest->[0], $sent_event->{event_id},
71+
assert_eq( $latest->[0], $room->id_for_event( $sent_event ),
7572
'latest_events[0]' );
7673

7774
my @events = $datastore->get_backfill_events(
@@ -99,7 +96,7 @@
9996
check => sub {
10097
my ( $event ) = @_;
10198
$event->{type} eq "m.room.message" &&
102-
$event->{event_id} eq $missing_event->{event_id};
99+
$event->{event_id} eq $missing_event_id;
103100
},
104101
);
105102
});
@@ -413,3 +410,123 @@ sub sytest_user_and_room_fixture {
413410
Future->done;
414411
});
415412
};
413+
414+
# A homeserver receiving a response from `get_missing_events` for a version 6
415+
# room with a bad JSON value (e.g. a float) should discard the bad data.
416+
#
417+
# To test this we need to:
418+
# * Add an event with "bad" data into the room history, but don't send it.
419+
# * Add a "good" event into the room history and send it.
420+
# * The homeserver attempts to get the missing event (with the bad data).
421+
# * Ensure that fetching the event results in an error.
422+
test "Outbound federation will ignore a missing event with bad JSON for room version 6",
423+
requires => [ $main::OUTBOUND_CLIENT, $main::INBOUND_SERVER,
424+
federated_rooms_fixture( room_opts => { room_version => "6" } ) ],
425+
426+
do => sub {
427+
my ( $outbound_client, $inbound_server, $creator, $user_id, @rooms ) = @_;
428+
429+
my $room = @rooms[0];
430+
my $room_id = $room->{room_id};
431+
my $first_home_server = $creator->server_name;
432+
433+
my $datastore = $inbound_server->datastore;
434+
435+
# TODO: We happen to know the latest event in the server should be my
436+
# m.room.member state event, but that's a bit fragile
437+
my $latest_event = $room->get_current_state_event( "m.room.member", $user_id );
438+
439+
log_if_fail "Latest event", $latest_event;
440+
441+
# Generate but don't send an event
442+
my $missing_event = $room->create_and_insert_event(
443+
type => "m.room.message",
444+
445+
sender => $user_id,
446+
content => {
447+
body => "Message 1",
448+
# Insert a bad value here so that this event cannot be fetched.
449+
bad_val => 1.1,
450+
},
451+
);
452+
453+
log_if_fail "Missing event", $missing_event;
454+
455+
# Generate another one and do send it so it will refer to the
456+
# previous in its prev_events field
457+
my $sent_event = $room->create_and_insert_event(
458+
type => "m.room.message",
459+
460+
# This would be done by $room->create_and_insert_event anyway but lets be
461+
# sure for this test
462+
prev_events => $room->make_event_refs( $missing_event ),
463+
464+
sender => $user_id,
465+
content => {
466+
body => "Message 2",
467+
},
468+
);
469+
my $sent_event_id = $room->id_for_event( $sent_event );
470+
471+
log_if_fail "Sent event", $sent_event;
472+
473+
Future->needs_all(
474+
$inbound_server->await_request_get_missing_events( $room_id )
475+
->then( sub {
476+
my ( $req ) = @_;
477+
my $body = $req->body_from_json;
478+
479+
log_if_fail "Body", $body;
480+
481+
assert_json_keys( $body, qw( earliest_events latest_events limit ));
482+
# TODO: min_depth but I have no idea what it does
483+
484+
assert_json_list( my $earliest = $body->{earliest_events} );
485+
@$earliest == 1 or
486+
die "Expected a single 'earliest_event' ID";
487+
assert_eq( $earliest->[0], $room->id_for_event( $latest_event ),
488+
'earliest_events[0]' );
489+
490+
assert_json_list( my $latest = $body->{latest_events} );
491+
@$latest == 1 or
492+
die "Expected a single 'latest_events' ID";
493+
assert_eq( $latest->[0], $sent_event_id,
494+
'latest_events[0]' );
495+
496+
my @events = $datastore->get_backfill_events(
497+
start_at => $latest,
498+
stop_before => $earliest,
499+
limit => $body->{limit},
500+
);
501+
502+
log_if_fail "Backfilling", @events;
503+
504+
$req->respond_json( {
505+
events => \@events,
506+
} );
507+
508+
Future->done;
509+
}),
510+
511+
# Can't use send_event here because that checks none were rejected.
512+
$outbound_client->send_transaction(
513+
destination => $first_home_server,
514+
pdus => [ $sent_event ],
515+
)->then( sub {
516+
my ( $body ) = @_;
517+
518+
log_if_fail "Send response", $body;
519+
520+
assert_json_keys( $body, 'pdus' );
521+
# 'pdus' is a map from event id to error details.
522+
my $pdus = $body->{pdus};
523+
524+
# Sending the event fails since fetching the event results in
525+
# invalid JSON, thus we expect an error for the sent PDU.
526+
assert_json_keys( $pdus, $sent_event_id );
527+
assert_json_keys( $pdus->{$sent_event_id}, qw( error ) );
528+
529+
Future->done;
530+
}),
531+
);
532+
};

0 commit comments

Comments
 (0)