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

Test API for adding and removing tags #34

Closed
wants to merge 12 commits into from
383 changes: 383 additions & 0 deletions tests/42tags.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,383 @@
push our @EXPORT, qw( matrix_add_tag );

=head2 matrix_add_tag

matrix_add_tag($user, $room_id, $tag)->get;

Add a tag to the room for the user.

=cut

sub matrix_add_tag
{
my ( $user, $room_id, $tag, $content ) = @_;

do_request_json_for( $user,
method => "PUT",
uri => "/v2_alpha/user/:user_id/rooms/$room_id/tags/$tag",
content => $content
);
}


=head2 matrix_remove_tag

matrix_remove_tag( $user, $room_id, $tag )->get;

Remove a tag from the room for the user.

=cut

sub matrix_remove_tag
{
my ( $user, $room_id, $tag ) = @_;

do_request_json_for( $user,
method => "DELETE",
uri => "/v2_alpha/user/:user_id/rooms/$room_id/tags/$tag",
content => {}
);
}


=head2 matrix_list_tags

my $tags = matrix_list_tags( $user, $room_id )->get;

List the tags on the room for the user.

=cut

sub matrix_list_tags
{
my ( $user, $room_id, $content) = @_;

do_request_json_for( $user,
method => "GET",
uri => "/v2_alpha/user/:user_id/rooms/$room_id/tags",
)->then( sub {
my ( $body ) = @_;

require_json_keys( $body, qw( tags ) );

Future->done( $body->{tags} );
});
}


test "Can add tag",
requires => [qw( first_api_client )],

provides => [qw( can_add_tag )],

do => sub {
my ( $http ) = @_;

my ( $user, $room_id );

matrix_register_user( $http, undef, with_events => 0 )->then( sub {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is it important that /events hasn't been called for this test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It isn't but I dislike calling /events unless we are going to actually use it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Then let's make the default false?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah that would be nicer from my perspective.

( $user ) = @_;

matrix_create_room( $user );
})->then( sub {
( $room_id ) = @_;

matrix_add_tag( $user, $room_id, "test_tag", {} );
})->on_done( sub {
provide can_add_tag => 1
});
};


test "Can remove tag",
requires => [qw( first_api_client )],

provides => [qw( can_remove_tag )],

do => sub {
my ( $http ) = @_;

my ( $user, $room_id );

matrix_register_user( $http, undef, with_events => 0 )->then( sub {
( $user ) = @_;

matrix_create_room( $user );
})->then( sub {
( $room_id ) = @_;

matrix_remove_tag( $user, $room_id, "test_tag" );
})->on_done( sub {
provide can_remove_tag => 1
});
};


test "Can list tags for a room",
requires => [qw( first_api_client can_add_tag can_remove_tag )],

do => sub {
my ( $http ) = @_;

my ( $user, $room_id );

matrix_register_user( $http, undef, with_events => 0 )->then( sub {
( $user ) = @_;

matrix_create_room( $user );
})->then( sub {
( $room_id ) = @_;

matrix_add_tag( $user, $room_id, "test_tag", {} );
})->then( sub {
matrix_list_tags( $user, $room_id );
})->then( sub {
my ( $tags ) = @_;

log_if_fail "Tags after add", $tags;

keys %{ $tags } == 1 or die "Expected one tag for the room";
Copy link
Contributor

Choose a reason for hiding this comment

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

Throw in a:

log_if_fail "Tags after add", $tags;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done 344649f

defined $tags->{test_tag} or die "Unexpected tag";

matrix_remove_tag( $user, $room_id, "test_tag" );
})->then( sub {
matrix_list_tags( $user, $room_id );
})->then( sub {
my ( $tags ) = @_;

log_if_fail "Tags after delete", $tags;

keys %{ $tags } == 0 or die "Expected no tags for the room";
Copy link
Contributor

Choose a reason for hiding this comment

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

log_if_fail "Tags after delete", $tags;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done 344649f


Future->done(1);
Copy link
Contributor

Choose a reason for hiding this comment

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

Spaces around 1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't seem to do that anywhere else in the code. But okay.
Done eba968f

});
};


=head2 register_user_and_create_room_and_add_tag

my ( $user, $room_id ) = register_user_and_create_room_and_add_tag( $http,
with_events => 0
)->get;

Register a new user, create a room and add a tag called "test_tag" for that
user to the room with a tag content of {"order": 1}.

=cut

sub register_user_and_create_room_and_add_tag
{
my ( $http, %params ) = @_;

my ( $user, $room_id );

matrix_register_user( $http, undef, %params )->then( sub {
( $user ) = @_;
matrix_create_room( $user );
})->then( sub {
( $room_id ) = @_;

matrix_add_tag( $user, $room_id, "test_tag", { order => 1 } );
})->then( sub {
Future->done( $user, $room_id );
});
}


=head2 check_tag_event

check_tag_event( $event );

Checks that a room tag event has the correct content.

=cut

sub check_tag_event {
my ( $event, $expect_room_id ) = @_;

log_if_fail "Tag event", $event;

my %tags = %{ $event->{content}{tags} };
keys %tags == 1 or die "Expected exactly one tag";
defined $tags{test_tag} or die "Unexpected tag";
$tags{test_tag}{order} == 1 or die "Expected order == 1";
}


test "Tags appear in the v1 /events stream",
requires => [qw( first_api_client can_add_tag can_remove_tag )],

do => sub {
my ( $http ) = @_;

my ( $user, $room_id );

register_user_and_create_room_and_add_tag( $http,
with_events => 1
)->then( sub {
( $user, $room_id ) = @_;

await_event_for( $user, sub {
my ( $event ) = @_;
return unless $event->{type} eq "m.tag"
Copy link
Contributor

Choose a reason for hiding this comment

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

log_if_fail "Received event", $event;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done e300bd2

and $event->{room_id} eq $room_id;

check_tag_event( $event );

return 1;
});
});
};


=head2 check_private_user_data

check_private_user_data( $event );

Checks that the private_user_data section has a tag event
and that the tag event has the correct content.

=cut

sub check_private_user_data {
my ( $private_user_data ) = @_;

log_if_fail "Private User Data:", $private_user_data;

my $tag_event = $private_user_data->[0];
$tag_event->{type} eq "m.tag" or die "Expected a m.tag event";
not defined $tag_event->{room_id} or die "Unxpected room_id";

check_tag_event( $tag_event );
}


test "Tags appear in the v1 /initalSync",
Copy link
Contributor

Choose a reason for hiding this comment

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

This test and the three below it could really do with having a helper sub to factor out the common 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.

Done 6e04b07

Copy link
Contributor

Choose a reason for hiding this comment

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

I actually meant the whole create-user+create-room+set-tag structure, too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done 24b4678

requires => [qw( first_api_client can_add_tag can_remove_tag )],

do => sub {
my ( $http ) = @_;

my ( $user, $room_id );

register_user_and_create_room_and_add_tag( $http,
with_events => 0
)->then( sub {
( $user, $room_id ) = @_;

do_request_json_for( $user,
method => "GET",
uri => "/api/v1/initialSync"
);
})->then( sub {
my ( $body ) = @_;

Copy link
Contributor

Choose a reason for hiding this comment

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

log_if_fail "initialSync response", $body;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is that useful? The response body can always be extracted by running with client logging if needed?

Copy link
Contributor

Choose a reason for hiding this comment

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

The point of the log_if_fail is so that you can get context without needing to re-run the tests.

(What I really want is for the die messages to include the actual as well as the expected, but Leo tells me that log_if_fail is the correct way of achieving this)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Eh. I'd rather that we just logged the client requests on failure then rather than trying to cherry-pick which ones we thought it would be useful to log ahead of time.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes please!

my $room = $body->{rooms}[0];
require_json_keys( $room, qw( private_user_data ) );

check_private_user_data( $room->{private_user_data} );

Future->done( 1 );
});
};


test "Tags appear in the v1 room initial sync",
requires => [qw( first_api_client can_add_tag can_remove_tag )],

do => sub {
my ( $http ) = @_;

my ( $user, $room_id );
register_user_and_create_room_and_add_tag( $http,
with_events => 0
)->then( sub {
( $user, $room_id ) = @_;

do_request_json_for( $user,
method => "GET",
uri => "/api/v1/rooms/$room_id/initialSync"
);
})->then( sub {
my ( $body ) = @_;

my $room = $body;
require_json_keys( $room, qw( private_user_data ) );

check_private_user_data( $room->{private_user_data} );

Future->done( 1 );
});
};


test "Tags appear in an initial v2 /sync",
requires => [qw( first_api_client can_add_tag can_remove_tag can_sync )],

do => sub {
my ( $http ) = @_;

my ( $user, $room_id, $filter_id );

my $filter = {};

matrix_register_user_with_filter( $http, $filter )->then( sub {
( $user, $filter_id ) = @_;

matrix_create_room( $user );
})->then( sub {
( $room_id ) = @_;

matrix_add_tag( $user, $room_id, "test_tag", { order => 1 } );
})->then( sub {
matrix_sync( $user, filter => $filter_id );
})->then( sub {
my ( $body ) = @_;

my $room = $body->{rooms}{joined}{$room_id};
require_json_keys( $room, qw( private_user_data ) );

check_private_user_data( $room->{private_user_data}{events} );

Future->done( 1 );
});
};


test "Newly updated tags appear in an incremental v2 /sync",
requires => [qw( first_api_client can_add_tag can_remove_tag can_sync )],

do => sub {
my ( $http ) = @_;

my ( $user, $room_id, $filter_id, $next_batch );

my $filter = {};

matrix_register_user_with_filter( $http, $filter )->then( sub {
( $user, $filter_id ) = @_;

matrix_create_room( $user );
})->then( sub {
( $room_id ) = @_;

matrix_sync( $user, $filter => $filter_id );
})->then( sub {
my ( $body ) = @_;

$next_batch = $body->{next_batch};

matrix_add_tag( $user, $room_id, "test_tag", { order => 1 } );
})->then( sub {
matrix_sync( $user, filter => $filter_id, since => $next_batch );
})->then( sub {
my ( $body ) = @_;

my $room = $body->{rooms}{joined}{$room_id};
require_json_keys( $room, qw( private_user_data ) );

check_private_user_data( $room->{private_user_data}{events} );

Future->done( 1 );
});
};