[dw-free] trust groups for xml-rpc protocol
[commit: http://hg.dwscoalition.org/dw-free/rev/74a45a47496a]
http://bugs.dwscoalition.org/show_bug.cgi?id=2451
Added gettrustgroups, getcircle, editcircle to the protocol.
Patch by
catness.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=2451
Added gettrustgroups, getcircle, editcircle to the protocol.
Patch by
Files modified:
- cgi-bin/ljprotocol.pl
- t/protocol.t
--------------------------------------------------------------------------------
diff -r 2b2eefda745d -r 74a45a47496a cgi-bin/ljprotocol.pl
--- a/cgi-bin/ljprotocol.pl Mon Aug 23 13:00:23 2010 +0800
+++ b/cgi-bin/ljprotocol.pl Mon Aug 23 18:25:43 2010 +0800
@@ -179,7 +179,10 @@ sub do_request
if ($method eq "login") { return login(@args); }
if ($method eq "getfriendgroups") { return getfriendgroups(@args); }
+ if ($method eq "gettrustgroups") { return gettrustgroups(@args); }
if ($method eq "getfriends") { return getfriends(@args); }
+ if ($method eq "getcircle") { return getcircle(@args); }
+ if ($method eq "editcircle") { return editcircle(@args); }
if ($method eq "friendof") { return friendof(@args); }
if ($method eq "checkfriends") { return checkfriends(@args); }
if ($method eq "getdaycounts") { return getdaycounts(@args); }
@@ -651,17 +654,23 @@ sub login
return $res;
}
+#deprecated
sub getfriendgroups
{
- my ($req, $err, $flags) = @_;
- return undef unless authenticate($req, $err, $flags);
- my $u = $flags->{'u'};
- my $res = {};
- $res->{'friendgroups'} = list_friendgroups($u);
- return fail($err, 502, "Error loading friend groups") unless $res->{'friendgroups'};
- if ($req->{'ver'} >= 1) {
- foreach (@{$res->{'friendgroups'} || []}) {
- LJ::text_out(\$_->{'name'});
+ return fail( $_[1], 504 );
+}
+
+sub gettrustgroups
+{
+ my ( $req, $err, $flags ) = @_;
+ return undef unless authenticate( $req, $err, $flags );
+ my $u = $flags->{u};
+ my $res = {};
+ $res->{trustgroups} = list_trustgroups( $u );
+ return fail( $err, 502, "Error loading trust groups" ) unless $res->{trustgroups};
+ if ( $req->{ver} >= 1 ) {
+ foreach ( @{$res->{trustgroups} || []} ) {
+ LJ::text_out( \$_->{name} );
}
}
return $res;
@@ -714,6 +723,77 @@ sub getfriends
});
if ($req->{'ver'} >= 1) {
foreach(@{$res->{'friends'}}) { LJ::text_out(\$_->{'fullname'}) };
+ }
+ return $res;
+}
+
+sub getcircle
+{
+ my ( $req, $err, $flags ) = @_;
+ return undef unless authenticate( $req, $err, $flags );
+ my $u = $flags->{u};
+ my $res = {};
+ my $limit = $LJ::MAX_WT_EDGES_LOAD;
+ $limit = $req->{limit}
+ if defined $req->{limit} && $req->{limit} < $limit;
+
+ if ( $req->{includetrustgroups} ) {
+ $res->{trustgroups} = list_trustgroups( $u );
+ return fail( $err, 502, "Error loading trust groups" ) unless $res->{trustgroups};
+ if ( $req->{ver} >= 1 ) {
+ LJ::text_out( \$_->{name} )
+ foreach ( @{$res->{trustgroups} || []} );
+ }
+ }
+ if ( $req->{includecontentfilters} ) {
+ $res->{contentfilters} = list_contentfilters( $u );
+ return fail( $err, 502, "Error loading content filters" ) unless $res->{contentfilters};
+ if ( $req->{ver} >= 1 ) {
+ LJ::text_out( \$_->{name} )
+ foreach ( @{$res->{contentfilters} || []} );
+ }
+ }
+ if ( $req->{includewatchedusers} ) {
+ $res->{watchedusers} = list_users( $u,
+ limit => $limit,
+ watched => 1,
+ includebdays => $req->{includebdays},
+ );
+ if ( $req->{ver} >= 1 ) {
+ LJ::text_out( \$_->{fullname} )
+ foreach ( @{$res->{watchedusers} || []} );
+ }
+ }
+ if ( $req->{includewatchedby} ) {
+ $res->{watchedbys} = list_users( $u,
+ limit => $limit,
+ watchedby => 1,
+ );
+ if ( $req->{ver} >= 1 ) {
+ LJ::text_out( \$_->{fullname} )
+ foreach ( @{$res->{watchedbys} || []} );
+ }
+ }
+ if ( $req->{includetrustedusers} ) {
+ $res->{trustedusers} = list_users( $u,
+ limit => $limit,
+ trusted => 1,
+ includebdays => $req->{includebdays},
+ );
+ if ($req->{ver} >= 1) {
+ LJ::text_out(\$_->{fullname})
+ foreach (@{$res->{trustedusers} || []});
+ }
+ }
+ if ( $req->{includetrustedby} ) {
+ $res->{trustedbys} = list_users( $u,
+ limit => $limit,
+ trustedby => 1,
+ );
+ if ( $req->{ver} >= 1 ) {
+ LJ::text_out( \$_->{fullname} )
+ foreach ( @{$res->{trustedbys} || []} );
+ }
}
return $res;
}
@@ -2412,6 +2492,144 @@ sub editfriendgroups {
return fail( $_[1], 504 );
}
+sub editcircle
+{
+ my ( $req, $err, $flags ) = @_;
+ return undef unless authenticate( $req, $err, $flags );
+
+ my $u = $flags->{u};
+ my $res = {};
+
+ if ( ref $req->{settrustgroups} eq 'HASH' ) {
+ while ( my ( $bit, $group ) = each %{$req->{settrustgroups}} ) {
+ my $name = $group->{name};
+ my $sortorder = $group->{sort};
+ my $public = $group->{public};
+ my %params = ( id => $bit,
+ groupname => $name,
+ _force_create => 1
+ );
+
+ $params{sortorder} = $sortorder if defined $sortorder;
+ $params{is_public} = $public if defined $public;
+ $u->edit_trust_group( %params );
+ }
+ }
+
+ if ( ref $req->{deletetrustgroups} eq 'ARRAY' ) {
+ foreach my $bit ( @{$req->{deletetrustgroups}} ) {
+ $u->delete_trust_group( id => $bit );
+ }
+ }
+
+ if ( ref $req->{setcontentfilters} eq 'HASH' ) {
+ while ( my ( $bit, $group ) = each %{$req->{setcontentfilters} } ) {
+ my $name = $group->{name};
+ my $public = $group->{public};
+ my $sortorder = $group->{sort};
+ my $cf = $u->content_filters( id => $bit );
+ if ( $cf ) {
+ $cf->name( $name )
+ if $name && $name ne $cf->name;
+ $cf->public( $public )
+ if ( defined $public ) && $public ne $cf->public;
+ $cf->sortorder( $sortorder )
+ if ( defined $sortorder ) && $sortorder ne $cf->sortorder;
+ } else {
+ my $fid = $u->create_content_filter( name => $name, public => $public, sortorder => $sortorder );
+ my $added = {
+ id => $fid,
+ name => $name,
+ };
+ push @{$res->{addedcontentfilters}}, $added;
+ }
+ }
+ }
+
+ if ( ref $req->{deletecontentfilters} eq 'ARRAY' ) {
+ foreach my $bit ( @{$req->{deletecontentfilters}} ) {
+ $u->delete_content_filter( id => $bit );
+ }
+ }
+
+ if ( ref $req->{add} eq 'ARRAY' ) {
+ foreach my $row ( @{$req->{add}} ) {
+ my $other_user = LJ::load_user( $row->{username} );
+ return fail( $err, 203 ) unless $other_user;
+ my $other_userid = $other_user->{userid};
+
+ if ( defined ( $row->{groupmask} ) ) {
+ $u->add_edge( $other_userid, trust => {
+ mask => $row->{groupmask},
+ nonotify => 1,
+ } );
+ } else {
+ if ( $row->{edge} & 1 ) {
+ $u->add_edge ( $other_userid, trust => {
+ nonotify => $u->trusts ( $other_userid ) ? 1 : 0,
+ } );
+ } else {
+ $u->remove_edge ( $other_userid, trust => {
+ nonotify => $u->trusts ( $other_userid ) ? 0 : 1,
+ } );
+ }
+ if ( $row->{edge} & 2 ) {
+ my $fg = $row->{fgcolor} || "#000000";
+ my $bg = $row->{bgcolor} || "#FFFFFF";
+ $u->add_edge ( $other_userid, watch => {
+ fgcolor => LJ::color_todb( $fg ),
+ bgcolor => LJ::color_todb( $bg ),
+ nonotify => $u->watches ( $other_userid ) ? 1 : 0,
+ } );
+ } else {
+ $u->remove_edge ( $other_userid, watch => {
+ nonotify => $u->watches ( $other_userid ) ? 0 : 1,
+ } );
+ }
+ if ( $row->{edge} ) {
+ my $myid = $u->userid;
+ my $added = {
+ username => $other_user->{user},
+ fullname => $other_user->{name},
+ trusted => $u->trusts ( $other_userid ),
+ trustedby => $other_user->trusts ( $myid ),
+ watched => $u->watches ( $other_userid ),
+ watchedby => $other_user->watches ( $myid )
+ };
+ push @{$res->{added}}, $added;
+ }
+ }
+ }
+ }
+
+ # if ( ref $req->{delete} eq 'ARRAY' ) {
+ # foreach my $row ( @{$req->{delete}} ) {
+ # not implemented yet - maybe unnecessary
+ # }
+ # }
+
+ if ( ref $req->{addtocontentfilters} eq 'ARRAY' ) {
+ foreach my $row ( @{$req->{addtocontentfilters}} ) {
+ my $other_user = LJ::load_user( $row->{username} );
+ return fail( $err, 203 ) unless $other_user;
+ my $other_userid = $other_user->{userid};
+ my $cf = $u->content_filters( id => $row->{id} );
+ $cf->add_row( userid => $other_userid ) if $cf;
+ }
+ }
+
+ if ( ref $req->{deletefromcontentfilters} eq 'ARRAY' ) {
+ foreach my $row ( @{$req->{deletefromcontentfilters}} ) {
+ my $other_user = LJ::load_user( $row->{username} );
+ return fail( $err, 203 ) unless $other_user;
+ my $other_userid = $other_user->{userid};
+ my $cf = $u->content_filters( id => $row->{id} );
+ $cf->delete_row( $other_userid ) if $cf;
+ }
+ }
+ return $res;
+}
+
sub sessionexpire {
my ($req, $err, $flags) = @_;
return undef unless authenticate($req, $err, $flags);
@@ -2544,6 +2762,74 @@ sub list_friends
last if @$res == $limitnum;
}
return $res;
+}
+
+sub list_users
+{
+ my ($u, %opts) = @_;
+
+ my %hide;
+ my $list = LJ::load_rel_user( $u, 'B' );
+ $hide{$_} = 1 foreach @{$list||[]};
+
+
+ my $friendof = $opts{trustedby} || $opts{watchedby};
+ my ( $filter, @userids );
+ if ( $friendof ) {
+ @userids = $opts{trustedby} ? $u->trusted_by_userids : $u->watched_by_userids;
+ } else {
+ $filter = $opts{trusted} ? $u->trust_list : $u->watch_list;
+ @userids = keys %{$filter};
+ }
+
+ my $limitnum = $opts{limit} + 0;
+ my @res;
+
+ my $us = LJ::load_userids( @userids );
+ while ( my( $userid, $u ) = each %$us ) {
+ next unless LJ::isu( $u );
+ next if $friendof && ! $u->is_visible;
+ next if $hide{$userid};
+
+ my $r = {
+ username => $u->user,
+ fullname => $u->display_name
+ };
+
+ if ( $u->identity ) {
+ my $i = $u->identity;
+ $r->{identity_type} = $i->pretty_type;
+ $r->{identity_value} = $i->value;
+ $r->{identity_display} = $u->display_name;
+ }
+
+ if ( $opts{includebdays} ) {
+ $r->{birthday} = $u->bday_string;
+ }
+
+ unless ( $friendof ) {
+ $r->{fgcolor} = LJ::color_fromdb( $filter->{$userid}->{fgcolor} );
+ $r->{bgcolor} = LJ::color_fromdb( $filter->{$userid}->{bgcolor} );
+ $r->{groupmask} = $filter->{$userid}->{groupmask};
+ }
+
+ $r->{type} = {
+ C => 'community',
+ Y => 'syndicated',
+ I => 'identity',
+ }->{$u->journaltype} unless $u->is_person;
+
+ $r->{status} = {
+ D => 'deleted',
+ S => 'suspended',
+ X => 'purged',
+ }->{$u->statusvis} unless $u->is_visible;
+
+ push @res, $r;
+ # won't happen for zero limit (which means no limit)
+ last if scalar @res == $limitnum;
+ }
+ return \@res;
}
sub syncitems
@@ -2686,13 +2972,13 @@ sub list_friendgroups
# warn "ljprotocol.pl: list_friendgroups called.\n";
return [];
-
-# TODO(mark): this needs updating to determine if we should send trust groups?
-# answer is yes, but we also need to move this to list_trustgroups
-# so clients don't think those are friend groups.
-
- # get the groups for this user, return undef if error
- my $groups = LJ::get_friend_group($u);
+}
+
+sub list_trustgroups
+{
+ my $u = shift;
+
+ my $groups = $u->trust_groups;
return undef unless $groups;
# we got all of the groups, so put them into an arrayref sorted by the
@@ -2705,6 +2991,23 @@ sub list_friendgroups
values %$groups;
return \@res;
+}
+
+sub list_contentfilters
+{
+ my $u = shift;
+ my @filters = $u->content_filters;
+ return [] unless @filters;
+
+ my @res = map { { id => $_->{id}, name => $_->{name},
+ public => $_->{public}, sortorder => $_->{sortorder},
+ data => join ( ' ',
+ map { my $uid = $_;
+ LJ::load_userid( $uid )->user }
+ ( keys %{$u->content_filters (id => $_->id )->data} ) ) } }
+ @filters;
+
+ return \@res;
}
sub list_usejournals {
@@ -2980,6 +3283,9 @@ sub do_request
if ($req->{'mode'} eq "getfriendgroups") {
return getfriendgroups($req, $res, $flags);
}
+ if ($req->{'mode'} eq "gettrustgroups") {
+ return gettrustgroups($req, $res, $flags);
+ }
if ($req->{'mode'} eq "getfriends") {
return getfriends($req, $res, $flags);
}
@@ -3155,6 +3461,26 @@ sub getfriendgroups
}
$res->{'success'} = "OK";
populate_friend_groups($res, $rs->{'friendgroups'});
+
+ return 1;
+}
+
+## flat wrapper
+sub gettrustgroups
+{
+ my ($req, $res, $flags) = @_;
+
+ my $err = 0;
+ my $rq = upgrade_request($req);
+
+ my $rs = LJ::Protocol::do_request('gettrustgroups', $rq, \$err, $flags);
+ unless ($rs) {
+ $res->{success} = "FAIL";
+ $res->{errmsg} = LJ::Protocol::error_message($err);
+ return 0;
+ }
+ $res->{success} = "OK";
+ populate_groups($res, 'tr', $rs->{trustgroups});
return 1;
}
@@ -3675,6 +4001,22 @@ sub populate_friend_groups
$res->{'frgrp_maxnum'} = $maxnum;
}
+## given a $res hashref and trust group (arrayref), flattens it
+sub populate_groups
+{
+ my ($res, $pfx, $fr) = @_;
+
+ my $maxnum = 0;
+ foreach my $fg ( @$fr ) {
+ my $num = $fg->{id};
+ $res->{"${pfx}_${num}_name"} = $fg->{name};
+ $res->{"${pfx}_${num}_sortorder"} = $fg->{sortorder};
+ $res->{"${pfx}_${num}_public"} = 1 if $fg->{public};
+ $maxnum = $num if ($num > $maxnum);
+ }
+ $res->{"${pfx}_maxnum"} = $maxnum;
+}
+
## given a menu tree, flattens it into $res hashref
sub populate_web_menu
{
diff -r 2b2eefda745d -r 74a45a47496a t/protocol.t
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/t/protocol.t Mon Aug 23 18:25:43 2010 +0800
@@ -0,0 +1,475 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use Test::More;
+plan tests => 191;
+
+use lib "$ENV{LJHOME}/cgi-bin";
+require 'ljlib.pl';
+require 'ljprotocol.pl';
+
+use LJ::Test qw( temp_user temp_comm );
+
+my $u = temp_user();
+my $watched = temp_user();
+my $trusted = temp_user();
+my $watchedtrusted = temp_user();
+my $comm = temp_comm();
+
+my $watcher = temp_user();
+my $truster = temp_user();
+my $watchertruster = temp_user();
+
+my @watched = ( $watched, $watchedtrusted, $comm );
+my @trusted = ( $trusted, $watchedtrusted );
+my @watchedby = ( $watcher, $watchertruster );
+my @trustedby = ( $truster, $watchertruster );
+
+$u->add_edge( $_, watch => { nonotify => 1 } ) foreach @watched;
+$u->add_edge( $_, trust => { nonotify => 1 } ) foreach @trusted;
+$_->add_edge( $u, watch => { nonotify => 1 } ) foreach @watchedby;
+$_->add_edge( $u, trust => { nonotify => 1 } ) foreach @trustedby;
+
+my $err = 0;
+my $res = {};
+
+my $do_request = sub {
+ my ( $mode, %request_args ) = @_;
+
+ my $err = 0;
+ my $req = \%request_args;
+
+ my $res = LJ::Protocol::do_request( $mode, $req, \$err, { noauth => 1 } );
+
+ return ( $res, $err );
+};
+
+
+my $check_err = sub {
+ my ( $responsecode, $expectedcode, $testmsg ) = @_;
+
+ is( $responsecode, $expectedcode,
+ "$testmsg Protocol error ($err) = " . LJ::Protocol::error_message( $err ) );
+};
+
+my $success = sub {
+ my ( $responsecode, $testmsg ) = @_;
+
+ is( $responsecode, 0, "$testmsg (success)" );
+};
+
+note( "getfriendgroups" );
+{
+ ( $res, $err ) = $do_request->( "getfriendgroups" );
+ $check_err->( $err, 504, "'getfriendgroups' is deprecated." );
+ is( $res, undef, "No response expected." );
+
+
+ ( $res, $err ) = $do_request->( "getfriendgroups", username => $u->user );
+ $check_err->( $err, 504, "'getfriendgroups' is deprecated." );
+ is( $res, undef, "No response expected." );
+}
+
+note( "gettrustgroups" );
+{
+ # test arguments:
+ # username
+
+ ( $res, $err ) = $do_request->( "gettrustgroups" );
+ $check_err->( $err, 200, "'gettrustgroups' needs a user." );
+ is( $res, undef, "No response expected." );
+
+
+ ( $res, $err ) = $do_request->( "gettrustgroups", username => $u->user );
+ $success->( $err, "'gettrustgroups' for user." );
+ ok( ref $res->{trustgroups} eq "ARRAY" && scalar @{$res->{trustgroups}} == 0,
+ "Empty trust groups list." );
+};
+
+note( "getcircle" );
+{
+ # test arguments:
+ # username
+ # limit
+ # includetrustgroups
+ # includecontentfilters
+ # includewatchedusers
+ # includewatchedby
+ # includetrustedusers
+
+ ( $res, $err ) = $do_request->( "getcircle" );
+ $check_err->( $err, 200, "'getcircle' needs a user." );
+ is( $res, undef, "No response expected." );
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user );
+ $success->( $err, "'getcircle' for user." );
+ is( scalar keys %$res, 0, "Empty circle; no arguments provided to select the subset of the circle." );
+
+ my %circle_args = (
+ # request hash key => response hash key, users
+ includewatchedby => [ "watchedbys", \@watchedby ],
+ includetrustedby => [ "trustedbys", \@trustedby ],
+ includewatchedusers => [ "watchedusers", \@watched ],
+ includetrustedusers => [ "trustedusers", \@trusted ],
+ );
+ while( my ( $include, $val ) = each %circle_args ) {
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, $include => 1 );
+ $success->( $err, "'getcircle' => $include" );
+ is( scalar keys %$res, 1, "One key: " . (keys %$res)[0] );
+ is( ref $res->{$val->[0]}, "ARRAY", "Returned an arrayref of this user's $include." );
+
+ my @cached_users = @{$val->[1]};
+ my @response_users = @{$res->{$val->[0]}};
+ is ( scalar @response_users, scalar @cached_users, "Matched the number of users who are watching/trusting." );
+
+ # check both ways that the users we added are the users we got back
+ my %cached_users = map { $_->user => 0 } @cached_users;
+ foreach my $user ( @response_users ) {
+ ok( ++$cached_users{$user->{username}}, "User from response is expected to be there." );
+ }
+ ok( $cached_users{$_}, "User appeared in the response." ) foreach keys %cached_users;
+ }
+
+ # set a limit, and check against that
+ my $old_limit = $LJ::MAX_WT_EDGES_LOAD;
+ $LJ::MAX_WT_EDGES_LOAD = 2;
+ while( my ( $include, $val ) = each %circle_args ) {
+ my @cached_users = @{$val->[1]};
+ my $limit = scalar @cached_users > $LJ::MAX_WT_EDGES_LOAD
+ ? $LJ::MAX_WT_EDGES_LOAD
+ : scalar @cached_users;
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, $include => 1,
+ limit => $LJ::MAX_WT_EDGES_LOAD + 1 );
+ $success->( $err, "'getcircle' => $include" );
+
+ # check that the users we got back are from the users we added
+ # don't check the other way, since we are over limit
+ my @response_users = @{$res->{$val->[0]}};
+ is ( scalar @response_users, $limit, "Check that the number of users who can be fetched is limited." );
+ my %cached_users = map { $_->user => 0 } @cached_users;
+ foreach my $user ( @response_users ) {
+ ok( ++$cached_users{$user->{username}}, "User from response is expected to be there." );
+ }
+ }
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includetrustgroups => 1 );
+ $success->( $err, "'getcircle' => includetrustgroups" );
+ is( scalar keys %$res, 1, "One key: " . (keys %$res)[0] );
+ ok( ref $res->{trustgroups} eq "ARRAY" && scalar @{$res->{trustgroups}} == 0,
+ "Empty trust groups list." );
+
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includecontentfilters => 1 );
+ $success->( $err, "'getcircle' => includecontentfilters" );
+ is( scalar keys %$res, 1, "One key: " . (keys %$res)[0] );
+ ok( ref $res->{contentfilters} eq "ARRAY" && scalar @{$res->{contentfilters}} == 0, "Empty list of content filters for this user." );
+
+ $LJ::MAX_WT_EDGES_LOAD = $old_limit;
+}
+
+note( "editcircle" );
+{
+ # test arguments:
+ # settrustgroups
+ # deletetrustgroups
+ # setcontentfilters
+ # deletecontentfilters
+ # add
+ # addtocontentfilters
+ # deletefromcontentfilters
+
+ ( $res, $err ) = $do_request->( "editcircle", settrustgroups => 1 );
+ $check_err->( $err, 200, "'editcircle' needs a user." );
+ is( $res, undef, "No response expected." );
+
+
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, settrustgroups => 1 );
+ $success->( $err, "No valid action provided for editcircle; ignore." );
+ is( scalar keys %$res, 0, "No action taken." );
+
+
+ my %trustgroups = (
+ 1 => {
+ name => "first",
+ sort => 1,
+ public => 0
+ },
+ 5 => {
+ name => "incomplete"
+ },
+ 10 => {
+ # no name?
+ }
+ );
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, settrustgroups => \%trustgroups );
+ $success->( $err, "Set trust groups." );
+ is( scalar keys %$res, 0, "No response expected." );
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includetrustgroups => 1 );
+ is( scalar @{$res->{trustgroups}}, scalar keys %trustgroups, "Number of trust groups match." );
+ foreach my $trustgroup ( @{$res->{trustgroups}} ) {
+ my $id = $trustgroup->{id};
+ my $orig_trustgroup = $trustgroups{$id};
+
+ is( $trustgroup->{name}, $orig_trustgroup->{name} || "", "Trustgroup name matches." );
+ is( $trustgroup->{public}, $orig_trustgroup->{public} || 0, "Trustgroup public setting matches." );
+ is( $trustgroup->{sortorder}, $orig_trustgroup->{sort} || 50, "Trustgroup sortorder matches." );
+ }
+
+
+ # then edit one trust group, and add another
+ my $edited = {
+ name => "hasname",
+ sortorder => 20,
+ public => 1,
+ };
+ $trustgroups{10} = $edited;
+
+ my $new = {
+ name => "new",
+ };
+ $trustgroups{20} = $new;
+
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, settrustgroups => { 10 => $edited, 20 => $new } );
+ $success->( $err, "Edited trust groups; those not mentioned should not be affected." );
+ is( scalar keys %$res, 0, "No response expected." );
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includetrustgroups => 1 );
+ is( scalar @{$res->{trustgroups}}, scalar keys %trustgroups, "Number of trust groups match." );
+ foreach my $trustgroup ( @{$res->{trustgroups}} ) {
+ my $id = $trustgroup->{id};
+ my $orig_trustgroup = $trustgroups{$id};
+
+ is( $trustgroup->{name}, $orig_trustgroup->{name} || "", "Trustgroup name matches." );
+ is( $trustgroup->{public}, $orig_trustgroup->{public} || 0, "Trustgroup public setting matches." );
+ is( $trustgroup->{sortorder}, $orig_trustgroup->{sort} || 50, "Trustgroup sortorder matches." );
+ }
+
+
+ # then delete some trust groups
+ delete $trustgroups{5};
+ delete $trustgroups{10};
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, deletetrustgroups => [ 10, 5 ] );
+ $success->( $err, "Deleted a trust group." );
+ is( scalar keys %$res, 0, "No response expected." );
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includetrustgroups => 1 );
+ is( scalar @{$res->{trustgroups}}, scalar keys %trustgroups, "Number of trust groups match." );
+ foreach my $trustgroup ( @{$res->{trustgroups}} ) {
+ my $id = $trustgroup->{id};
+ my $orig_trustgroup = $trustgroups{$id};
+
+ is( $trustgroup->{name}, $orig_trustgroup->{name} || "", "Trustgroup name matches." );
+ is( $trustgroup->{public}, $orig_trustgroup->{public} || 0, "Trustgroup public setting matches." );
+ is( $trustgroup->{sortorder}, $orig_trustgroup->{sort} || 50, "Trustgroup sortorder matches." );
+ }
+
+
+ # now add / edit some users' status in your circle
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, add => [ { username => "invalidusername" } ] );
+ $check_err->( $err, 203, "Tried to edit invalid user." );
+ is( scalar keys %$res, 0, "No response expected." );
+
+ # let's make our watch/trust mutual
+ # ... but not yet
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, add => [ { username => $watchertruster->user } ] );
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includewatchedusers => 1, includetrustedusers => 1 );
+
+ is( scalar @{$res->{watchedusers}}, scalar @watched, "Number of watched users did not change." );
+ is( scalar @{$res->{trustedusers}}, scalar @trusted, "Number of trusted users did not change." );
+
+ # add with trust group
+ is( $u->trustmask( $watchertruster ), 0, "Currently not trusted." );
+ ok( ! $u->trusts( $watchertruster ), "Currently not trusted." );
+ ok( ! $u->watches( $watchertruster ), "Currently not watched." );
+ ok( $watchertruster->trusts( $u ), "Trusted by." );
+ ok( $watchertruster->watches( $u ), "Watched by." );
+
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, add => [ { username => $watchertruster->user, groupmask => 201 } ] );
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includewatchedusers => 1, includetrustedusers => 1 );
+ is( scalar @{$res->{watchedusers}}, scalar @watched, "Number of watched users did not change." );
+ is( scalar @{$res->{trustedusers}}, scalar @trusted + 1, "Trusted this user." );
+ is( $u->trustmask( $watchertruster ), 201, "Trusted, with trust group that matches." );
+ ok( $u->trusts( $watchertruster ), "Currently trusted." );
+ ok( ! $u->watches( $watchertruster ), "Currently not watched." );
+ ok( $watchertruster->trusts( $u ), "Trusted by." );
+ ok( $watchertruster->watches( $u ), "Watched by." );
+
+
+ # add and remove
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, add => [ { username => $watchertruster->user, edge => 0b00 } ] );
+ is( $u->trustmask( $watchertruster ), 0, "Not trusted." );
+ ok( ! $u->trusts( $watchertruster ), "Currently not trusted." );
+ ok( ! $u->watches( $watchertruster ), "Currently not watched." );
+ ok( $watchertruster->trusts( $u ), "Trusted by." );
+ ok( $watchertruster->watches( $u ), "Watched by." );
+
+
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, add => [ { username => $watchertruster->user, edge => 0b01 } ] );
+ is( $u->trustmask( $watchertruster ), 1, "Just trust." );
+ ok( $u->trusts( $watchertruster ), "Currently trusted." );
+ ok( ! $u->watches( $watchertruster ), "Currently not watched." );
+ ok( $watchertruster->trusts( $u ), "Trusted by." );
+ ok( $watchertruster->watches( $u ), "Watched by." );
+
+
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, add => [ { username => $watchertruster->user, edge => 0b10 } ] );
+ is( $u->trustmask( $watchertruster ), 0, "Not trusted." );
+ ok( ! $u->trusts( $watchertruster ), "Currently not trusted." );
+ ok( $u->watches( $watchertruster ), "Currently watched." );
+ ok( $watchertruster->trusts( $u ), "Trusted by." );
+ ok( $watchertruster->watches( $u ), "Watched by." );
+
+
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, add => [ { username => $watchertruster->user, edge => 0b11 } ] );
+ is( $u->trustmask( $watchertruster ), 1, "Just trust." );
+ ok( $u->trusts( $watchertruster ), "Currently trusted." );
+ ok( $u->watches( $watchertruster ), "Currently watched." );
+ ok( $watchertruster->trusts( $u ), "Trusted by." );
+ ok( $watchertruster->watches( $u ), "Watched by." );
+
+
+ # edit again with groupmask, after already having created a trust mask
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, add => [ { username => $watchertruster->user, groupmask => 201 } ] );
+ is( $u->trustmask( $watchertruster ), 201, "Trusted, with trust group that matches." );
+ ok( $u->trusts( $watchertruster ), "Currently trusted." );
+ ok( $u->watches( $watchertruster ), "Currently watched." );
+ ok( $watchertruster->trusts( $u ), "Trusted by." );
+ ok( $watchertruster->watches( $u ), "Watched by." );
+
+
+ # now to
+ my %contentfilters = (
+ 1 => {
+ name => "first",
+ sort => 1,
+ public => 0
+ },
+ 2 => {
+ name => "incomplete"
+ },
+ );
+
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, setcontentfilters => \%contentfilters );
+ $success->( $err, "Set content filters." );
+ is( scalar keys %$res, 1, "Response contains only the newly added content filters." );
+ is( scalar @{$res->{addedcontentfilters}}, scalar keys %contentfilters, "Got back the newly-added content filters." );
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includecontentfilters => 1 );
+ is( scalar @{$res->{contentfilters}}, scalar keys %contentfilters, "Number of content filters match." );
+ foreach my $filter ( @{$res->{contentfilters}} ) {
+ my $id = $filter->{id};
+ my $orig_filter = $contentfilters{$id};
+
+ is( $filter->{name}, $orig_filter->{name} || "", "Filter name matches." );
+ is( $filter->{public}, $orig_filter->{public} || 0, "Filter public setting matches." );
+ is( $filter->{sortorder}, $orig_filter->{sort} || 0, "Filter sortorder matches." );
+ }
+
+ # then edit one filter, and add another
+ $edited = {
+ name => "not so incomplete",
+ sortorder => 20,
+ public => 1,
+ };
+ $contentfilters{2} = $edited;
+
+ $new = {
+ name => "new",
+ };
+ $contentfilters{3} = $new;
+
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, setcontentfilters => { 2 => $edited, 3 => $new } );
+ $success->( $err, "Edited content filters; those not mentioned should not be affected." );
+ is( scalar keys %$res, 1, "Response contains only the newly added content filters." );
+ is( scalar @{$res->{addedcontentfilters}}, 1, "Got back the newly-added content filter." );
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includecontentfilters => 1 );
+ is( scalar @{$res->{contentfilters}}, scalar keys %contentfilters, "Number of content filters match." );
+ foreach my $filter ( @{$res->{contentfilters}} ) {
+ my $id = $filter->{id};
+ my $orig_filter = $contentfilters{$id};
+
+ is( $filter->{name}, $orig_filter->{name} || "", "Filter name matches." );
+ is( $filter->{public}, $orig_filter->{public} || 0, "Filter public setting matches." );
+ is( $filter->{sortorder}, $orig_filter->{sort} || 0, "Filter sortorder matches." );
+ }
+
+
+ # then delete some content filters
+ delete $contentfilters{1};
+ delete $contentfilters{3};
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, deletecontentfilters => [ 1, 3 ] );
+ $success->( $err, "Deleted content filters." );
+ is( scalar keys %$res, 0, "No response expected." );
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includecontentfilters => 1 );
+ is( scalar @{$res->{contentfilters}}, scalar keys %contentfilters, "Number of content filters match." );
+ foreach my $filter ( @{$res->{contentfilters}} ) {
+ my $id = $filter->{id};
+ my $orig_filter = $contentfilters{$id};
+
+ is( $filter->{name}, $orig_filter->{name} || "", "Filter name matches." );
+ is( $filter->{public}, $orig_filter->{public} || 0, "Filter public setting matches." );
+ is( $filter->{sortorder}, $orig_filter->{sort} || 0, "Filter sortorder matches." );
+ }
+
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includecontentfilters => 1 );
+ ok( $res->{contentfilters}->[0]->{data} eq "", "No data for the content filter." );
+
+
+ # added non-existent user
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, addtocontentfilters => [ {
+ username => "invalid_user",
+ id => 2
+ } ] );
+ $check_err->( $err, 203, "Tried to add an invalid user to a content filter." );
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includecontentfilters => 1 );
+ ok( $res->{contentfilters}->[0]->{data} eq "", "No data for the content filter." );
+
+
+ # added a valid user
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, addtocontentfilters => [ {
+ username => $watched->user,
+ id => 2
+ } ] );
+ $success->( $err, "Added a user to a content filter." );
+ is( scalar keys %$res, 0, "No response expected." );
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includecontentfilters => 1 );
+ ok( $res->{contentfilters}->[0]->{data} ne "", "Some data in the content filter." );
+
+
+ # tried to remove a non-existent user
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, deletefromcontentfilters => [ {
+ username => "invalid_user",
+ id => 2
+ } ] );
+ $check_err->( $err, 203, "Tried to remove an invalid user from a content filter." );
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includecontentfilters => 1 );
+ ok( $res->{contentfilters}->[0]->{data} ne "", "Some data in the content filter." );
+
+
+ # tried to remove a valid user, but one not in the content filter
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, deletefromcontentfilters => [ {
+ username => $watchedtrusted->user,
+ id => 2
+ } ] );
+ $success->( $err, "Tried to remove a user who was not in the content filter." );
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includecontentfilters => 1 );
+ ok( $res->{contentfilters}->[0]->{data} ne "", "Some data in the content filter." );
+
+
+ ( $res, $err ) = $do_request->( "editcircle", username => $u->user, deletefromcontentfilters => [ {
+ username => $watched->user,
+ id => 2
+ } ] );
+ $success->( $err, "Removed a user from a content filter." );
+ is( scalar keys %$res, 0, "No response expected." );
+
+ ( $res, $err ) = $do_request->( "getcircle", username => $u->user, includecontentfilters => 1 );
+ ok( $res->{contentfilters}->[0]->{data} eq "", "No more data in the content filter." );
+}
--------------------------------------------------------------------------------
