commit 2330eeaa705b3910f2dde5faeda8a1f3714a8b8a
parent d67c0f0e0fe1a4c45972ca40fdd9aa681f7f2365
Author: kyle <kyle@0x30.net>
Date: Tue, 29 Dec 2015 16:05:25 -0700
sl: tweak list_get_other algorithm
- before, if 2 friends were in a list that you were not in, and you did a
list_get_other request, two identical lists would come back in the response
- change this so that identical lists will instead be returned as one list with
multiple members
- add a new test for this case
Diffstat:
4 files changed, 109 insertions(+), 3 deletions(-)
diff --git a/sl b/sl
@@ -449,8 +449,8 @@ sub msg_list_get_other {
push @list_ids, $list_id;
}
- my @other_lists;
# now calculate which lists this device id should see
+ my (%members, %names);
$sth{mutual_friend_select}->execute($msg);
while (my ($friend_id) = $sth{mutual_friend_select}->fetchrow_array()) {
@@ -467,12 +467,18 @@ sub msg_list_get_other {
# filter out lists this device id is already in
next if (grep {$_ eq $id} @list_ids);
+ push(@{ $members{$id} }, $friend_phnum);
+ $names{$id} = $name;
log_print("list_get_other: found list '$name'\n");
- push @other_lists, "$id\0$name\0$friend_phnum";
}
}
- return "ok\0" . join("\n", @other_lists);
+ my @lists;
+ for (keys %names) {
+ push @lists, "$_\0$names{$_}\0" . join("\0", @{$members{$_}});
+ }
+
+ return "ok\0" . join("\n", @lists);
}
sub msg_list_items
diff --git a/tests/multiple_friends_same_other_list/Makefile b/tests/multiple_friends_same_other_list/Makefile
@@ -0,0 +1 @@
+include ../test.mk
diff --git a/tests/multiple_friends_same_other_list/server.log.good b/tests/multiple_friends_same_other_list/server.log.good
@@ -0,0 +1,38 @@
+accepting connections on <ip>:<port> (pid = <digits>)
+new connection (pid = <digits>)
+ssl ok, ver = 'TLSv1_2' cipher = 'ECDHE-RSA-AES128-SHA256'
+new_device: success, <digits>:<base64> os <base64>
+add_friend: <base64> adding <digits>
+add_friend: added friend is a member
+add_friend: friends device id is <base64>
+add_friend: found mutual friendship
+join_list: device <base64>
+join_list: list <base64>
+join_list: device <base64> has been added to list <base64>
+disconnected!
+new connection (pid = <digits>)
+ssl ok, ver = 'TLSv1_2' cipher = 'ECDHE-RSA-AES128-SHA256'
+new_device: success, <digits>:<base64> os <base64>
+add_friend: <base64> adding <digits>
+add_friend: added friend is a member
+add_friend: friends device id is <base64>
+add_friend: found mutual friendship
+new_list: <string>
+new_list: adding first member devid = <base64>
+new_list: fingerprint = <base64>
+disconnected!
+new connection (pid = <digits>)
+ssl ok, ver = 'TLSv1_2' cipher = 'ECDHE-RSA-AES128-SHA256'
+new_device: success, <digits>:<base64> os <base64>
+add_friend: <base64> adding <digits>
+add_friend: added friend is a member
+add_friend: friends device id is <base64>
+add_friend: <base64> adding <digits>
+add_friend: added friend is a member
+add_friend: friends device id is <base64>
+list_get_other: gathering lists for <base64>
+list_get_other: found mutual friend <base64>
+list_get_other: found list <string>
+list_get_other: found mutual friend <base64>
+list_get_other: found list <string>
+disconnected!
diff --git a/tests/multiple_friends_same_other_list/test.pl b/tests/multiple_friends_same_other_list/test.pl
@@ -0,0 +1,61 @@
+#!/usr/bin/perl -I../
+use strict;
+use warnings;
+use test;
+
+# this test makes sure that when 2 friends of yours are in the same list that
+# your not in, that the list doesn't show up twice in your list_get_other
+# request.
+
+my @phnums = ("4038675309", "4037082094", "4036080226");
+my @sockets;
+my @device_ids;
+
+# create new devices for 0, 1 and 2
+for (0..2) {
+ $sockets[$_] = new_socket();
+
+ send_msg($sockets[$_], 'new_device', "$phnums[$_]\0unix");
+ my ($msg) = recv_msg($sockets[$_], 'new_device');
+
+ $device_ids[$_] = check_status($msg, 'ok');
+}
+
+# 0 and 1 need to be mutual friends
+send_msg($sockets[0], 'add_friend', "$device_ids[0]\0$phnums[1]");
+recv_msg($sockets[0], 'add_friend');
+send_msg($sockets[1], 'add_friend', "$device_ids[1]\0$phnums[0]");
+recv_msg($sockets[1], 'add_friend');
+
+# 0 and 2 need to be mutual friends too
+send_msg($sockets[0], 'add_friend', "$device_ids[0]\0$phnums[2]");
+recv_msg($sockets[0], 'add_friend');
+send_msg($sockets[2], 'add_friend', "$device_ids[2]\0$phnums[0]");
+recv_msg($sockets[2], 'add_friend');
+
+# 1 and 2 need to be in the same list
+send_msg($sockets[1], 'new_list', "$device_ids[1]\0this is a new list");
+my ($msg_data) = recv_msg($sockets[1], 'new_list');
+
+my $list_data = check_status($msg_data, 'ok');
+my ($list_id) = split("\0", $list_data);
+
+send_msg($sockets[2], 'join_list', "$device_ids[2]\0$list_id");
+($msg_data) = recv_msg($sockets[2], 'join_list');
+
+check_status($msg_data, 'ok');
+
+# 0 requests his other lists
+send_msg($sockets[0], 'list_get_other', "$device_ids[0]");
+($msg_data) = recv_msg($sockets[0], 'list_get_other');
+
+my $raw_lists = check_status($msg_data, 'ok');
+my @lists = split("\n", $raw_lists);
+fail "expected 1 list, got " . @lists if (@lists != 1);
+
+# 0 makes sure he got a single list with both members in it
+my ($id, $name, @members) = split("\0", $lists[0]);
+fail "expected 2 list members, got " . @members if (@members != 2);
+fail "bad list id '$id', expected '$list_id'" if ($id ne $list_id);
+fail "expected member '$phnums[1]'" unless (grep {$_ eq $phnums[1]} @phnums);
+fail "expected member '$phnums[2]'" unless (grep {$_ eq $phnums[2]} @phnums);