Add ActivityPub Profile Test

Fixed various serious issues while writing this test, namely database related.
This commit is contained in:
Diogo Cordeiro 2018-07-28 15:52:47 +01:00
parent 58262451e3
commit 5c351efb06
11 changed files with 207 additions and 89 deletions

View File

@ -70,7 +70,7 @@ class ActivityPubPlugin extends Plugin
*/
public static function actor_url($profile)
{
return actor_uri($profile)."/";
return ActivityPubPlugin::actor_uri($profile)."/";
}
/**

View File

@ -68,10 +68,11 @@ class apActorFollowersAction extends ManagedAction
ActivityPubReturn::error('Invalid page number.');
}
/* Fetch Followers */
try {
$since = ($page - 1) * PROFILES_PER_MINILIST;
$limit = (($page - 1) == 0 ? 1 : $page) * PROFILES_PER_MINILIST;
/* Fetch Followers */
try {
$sub = $profile->getSubscribers($since, $limit);
} catch (NoResultException $e) {
ActivityPubReturn::error('This user has no followers.');

View File

@ -68,10 +68,11 @@ class apActorFollowingAction extends ManagedAction
ActivityPubReturn::error('Invalid page number.');
}
/* Fetch Following */
try {
$since = ($page - 1) * PROFILES_PER_MINILIST;
$limit = (($page - 1) == 0 ? 1 : $page) * PROFILES_PER_MINILIST;
/* Fetch Following */
try {
$sub = $profile->getSubscribed($since, $limit);
} catch (NoResultException $e) {
ActivityPubReturn::error('This user is not following anyone.');

View File

@ -51,13 +51,11 @@ class apActorLikedAction extends ManagedAction
*/
protected function handle()
{
$nickname = $this->trimmed('nickname');
try {
$user = User::getByNickname($nickname);
$profile = $user->getProfile();
$url = $profile->profileurl;
$profile = Profile::getByID($this->trimmed('id'));
$url = ActivityPubPlugin::actor_url($profile);
} catch (Exception $e) {
ActivityPubReturn::error('Invalid username.');
ActivityPubReturn::error('Invalid Actor URI.', 404);
}
$limit = intval($this->trimmed('limit'));
@ -73,7 +71,7 @@ class apActorLikedAction extends ManagedAction
$limit = 80;
}
$fave = $this->fetch_faves($user->getID(), $limit, $since_id, $max_id);
$fave = $this->fetch_faves($profile->getID(), $limit, $since_id, $max_id);
$faves = array();
while ($fave->fetch()) {

View File

@ -53,21 +53,21 @@ class Activitypub_pending_follow_requests extends Managed_DataObject
*/
public static function schemaDef()
{
return array(
'fields' => array(
'local_profile_id' => array('type' => 'integer', 'not null' => true),
'remote_profile_id' => array('type' => 'integer', 'not null' => true),
'relation_id' => array('type' => 'serial', 'not null' => true),
),
'primary key' => array('relation_id'),
'unique keys' => array(
'Activitypub_pending_follow_requests_relation_id_key' => array('relation_id'),
),
'foreign keys' => array(
'Activitypub_pending_follow_requests_local_profile_id_fkey' => array('profile', array('local_profile_id' => 'id')),
'Activitypub_pending_follow_requests_remote_profile_id_fkey' => array('profile', array('remote_profile_id' => 'id')),
),
);
return [
'fields' => [
'local_profile_id' => ['type' => 'integer', 'not null' => true],
'remote_profile_id' => ['type' => 'integer', 'not null' => true],
'relation_id' => ['type' => 'serial', 'not null' => true],
],
'primary key' => ['relation_id'],
'unique keys' => [
'Activitypub_pending_follow_requests_relation_id_key' => ['relation_id'],
],
'foreign keys' => [
'Activitypub_pending_follow_requests_local_profile_id_fkey' => ['profile', ['local_profile_id' => 'id']],
'Activitypub_pending_follow_requests_remote_profile_id_fkey' => ['profile', ['remote_profile_id' => 'id']],
],
];
}
public function __construct($actor, $remote_actor)

View File

@ -38,7 +38,7 @@ if (!defined('GNUSOCIAL')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
class Activitypub_profile extends Profile
class Activitypub_profile extends Managed_DataObject
{
public $__table = 'Activitypub_profile';
@ -50,24 +50,23 @@ class Activitypub_profile extends Profile
*/
public static function schemaDef()
{
return array(
'fields' => array(
'uri' => array('type' => 'varchar', 'length' => 191, 'not null' => true),
'profile_id' => array('type' => 'integer'),
'inboxuri' => array('type' => 'varchar', 'length' => 191),
'sharedInboxuri' => array('type' => 'varchar', 'length' => 191),
'created' => array('type' => 'datetime', 'not null' => true),
'modified' => array('type' => 'datetime', 'not null' => true),
),
'primary key' => array('uri'),
'unique keys' => array(
'Activitypub_profile_profile_id_key' => array('profile_id'),
'Activitypub_profile_inboxuri_key' => array('inboxuri'),
),
'foreign keys' => array(
'Activitypub_profile_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
),
);
return [
'fields' => [
'uri' => ['type' => 'text', 'not null' => true],
'profile_id' => ['type' => 'integer'],
'inboxuri' => ['type' => 'text', 'not null' => true],
'sharedInboxuri' => ['type' => 'text'],
'created' => ['type' => 'datetime', 'not null' => true],
'modified' => ['type' => 'datetime', 'not null' => true],
],
'primary key' => ['profile_id'],
'unique keys' => [
'Activitypub_profile_profile_id_key' => ['profile_id'],
],
'foreign keys' => [
'Activitypub_profile_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
],
];
}
/**
@ -172,6 +171,7 @@ class Activitypub_profile extends Profile
if ($ok === false) {
$profile->query('ROLLBACK');
$this->query('ROLLBACK');
throw new ServerException('Cannot save ActivityPub profile.');
}
}
@ -215,8 +215,15 @@ class Activitypub_profile extends Profile
}
}
foreach ($profile as $key => $value) {
$aprofile->$key = $value;
$fields = [
'uri' => 'profileurl',
'nickname' => 'nickname',
'fullname' => 'fullname',
'bio' => 'bio'
];
foreach ($fields as $af => $pf) {
$aprofile->$af = $profile->$pf;
}
return $aprofile;

View File

@ -53,16 +53,14 @@ class Activitypub_rsa extends Managed_DataObject
return [
'fields' => [
'profile_id' => ['type' => 'integer'],
'private_key' => ['type' => 'varchar', 'length' => 191],
'public_key' => ['type' => 'varchar', 'length' => 191],
'private_key' => ['type' => 'text'],
'public_key' => ['type' => 'text', 'not null' => true],
'created' => ['type' => 'datetime', 'not null' => true],
'modified' => ['type' => 'datetime', 'not null' => true],
],
'primary key' => ['profile_id'],
'unique keys' => [
'Activitypub_rsa_profile_id_key' => ['profile_id'],
'Activitypub_rsa_private_key_key' => ['private_key'],
'Activitypub_rsa_public_key_key' => ['public_key'],
],
'foreign keys' => [
'Activitypub_profile_profile_id_fkey' => ['profile', ['profile_id' => 'id']],

View File

@ -0,0 +1,145 @@
<?php
namespace Tests\Unit;
use Tests\TestCase;
class ProfileObjectTest extends TestCase
{
public function testLibraryInstalled()
{
$this->assertTrue(class_exists('\Activitypub_profile'));
}
public function testActivitypubProfile()
{
// Mimic proper ACCEPT header
$_SERVER['HTTP_ACCEPT'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams';
/* Test do_insert() */
$aprofile = new \Activitypub_profile();
$aprofile->uri = 'https://testinstance.net/index.php/user/1';
$aprofile->nickname = 'test1';
$aprofile->fullname = 'Test User 1';
$aprofile->bio = 'I am a nice test 1 guy';
$aprofile->inboxuri = "https://testinstance.net/index.php/user/1/inbox.json";
$aprofile->sharedInboxuri = "https://testinstance.net/inbox.json";
$aprofile->do_insert();
/* Test local_profile() */
$profile = $aprofile->local_profile();
/* Test from_profile() and create_from_local_profile() */
$this->assertTrue($this->compare_aprofiles($aprofile, \Activitypub_profile::from_profile($profile)));
/* Create Keys for Test User 1 */
$apRSA = new \Activitypub_rsa();
$apRSA->profile_id = $profile->getID();
\Activitypub_rsa::generate_keys($apRSA->private_key, $apRSA->public_key);
$apRSA->store_keys();
/* Test profile_to_array() */
// Fetch ActivityPub Actor Object representation
$profile_array = \Activitypub_profile::profile_to_array($profile);
// Check type
$this->assertTrue(is_array($profile_array));
// Test with Explorer's Profile Tester
$this->assertTrue(\Activitypub_explorer::validate_remote_response($profile_array));
/* Test get_inbox() */
$this->assertTrue($aprofile->sharedInboxuri == $aprofile->get_inbox());
/* Test get_uri() */
$this->assertTrue($aprofile->uri == $aprofile->get_uri());
/* Test get_from_uri() */
$this->assertTrue($this->compare_aprofiles($aprofile, \Activitypub_profile::get_from_uri($aprofile->uri)));
/* Remove Remote User Test 1 */
$old_id = $profile->getID();
$apRSA->delete();
$aprofile->delete();
$profile->delete();
// Check if successfuly removed
try {
\Profile::getById($old_id);
$this->assertTrue(false);
} catch (\NoResultException $e) {
$this->assertTrue(true);
}
/* Test ensure_web_finger() */
// TODO: Maybe elaborate on this function's tests
try {
\Activitypub_profile::ensure_web_finger('test1@testinstance.net');
$this->assertTrue(false);
} catch (\Exception $e) {
$this->assertTrue($e->getMessage() == 'Not a valid webfinger address.' ||
$e->getMessage() == 'Not a valid webfinger address (via cache).');
}
}
// Helpers
private function compare_profiles(\Profile $a, \Profile $b)
{
if (($av = $a->getID()) != ($bv = $b->getID())) {
throw new Exception('Compare Profiles 1 Fail: $a: '.$av.' is different from $b: '.$bv);
}
if (($av = $a->getNickname()) != ($bv = $b->getNickname())) {
throw new Exception('Compare Profiles 2 Fail: $a: '.$av.' is different from $b: '.$bv);
}
if (($av = $a->getFullname()) != ($bv = $b->getFullname())) {
throw new Exception('Compare Profiles 3 Fail: $a: '.$av.' is different from $b: '.$bv);
}
if (($av = $a->getUrl()) != ($bv = $b->getUrl())) {
throw new Exception('Compare Profiles 4 Fail: $a: '.$av.' is different from $b: '.$bv);
}
if (($av = $a->getDescription()) != ($bv = $b->getDescription())) {
throw new Exception('Compare Profiles 5 Fail: $a: '.$av.' is different from $b: '.$bv);
}
if (($av = $a->getLocation()) != ($bv = $b->getLocation())) {
throw new Exception('Compare Profiles 6 Fail: $a: '.$av.' is different from $b: '.$bv);
}
if (($av = $a->getNickname()) != ($bv = $b->getNickname())) {
throw new Exception('Compare Profiles 7 Fail: $a: '.$av.' is different from $b: '.$bv);
}
if (($av = $a->lat) != ($bv = $b->lat)) {
throw new Exception('Compare Profiles 8 Fail: $a: '.$av.' is different from $b: '.$bv);
}
if (($av = $a->lon) != ($bv = $b->lon)) {
throw new Exception('Compare Profiles 9 Fail: $a: '.$av.' is different from $b: '.$bv);
}
return true;
}
private function compare_aprofiles(\Activitypub_profile $a, \Activitypub_profile $b)
{
if (($av = $a->get_uri()) != ($bv = $b->get_uri())) {
throw new Exception('Compare AProfiles 1 Fail: $a: '.$av.' is different from $b: '.$bv);
}
if (($av = $a->profile_id) != ($bv = $b->profile_id)) {
throw new Exception('Compare AProfiles 2 Fail: $a: '.$av.' is different from $b: '.$bv);
}
if (($av = $a->inboxuri) != ($bv = $b->inboxuri)) {
throw new Exception('Compare AProfiles 3 Fail: $a: '.$av.' is different from $b: '.$bv);
}
if (($av = $a->sharedInboxuri) != ($bv = $b->sharedInboxuri)) {
throw new Exception('Compare AProfiles 1 Fail: $a: '.$av.' is different from $b: '.$bv);
}
return true;
}
}

View File

@ -114,7 +114,8 @@ class HTTPSignatureTest extends TestCase
$request->getHeader('Authorization')
);
}
public function getVerifyGuzzleRequestVectors() {
public function getVerifyGuzzleRequestVectors()
{
return [
/* path, headers */
['/path?query=123', ['date' => 'today', 'accept' => 'llamas']],

View File

@ -1,33 +0,0 @@
<?php
namespace Tests\Unit;
use Tests\TestCase;
class ProfileObjectTest extends TestCase
{
public function testLibraryInstalled()
{
$this->assertTrue(class_exists('\Activitypub_profile'));
}
public function testProfileObject()
{
// TODO: Improve this test.
$this->assertTrue(true);
return;
// Mimic proper ACCEPT header
$_SERVER['HTTP_ACCEPT'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams';
// Fetch profile
$user = \Profile::getKV('id', 1);
// Fetch ActivityPub Actor Object representation
$profile = \Activitypub_profile::profile_to_array($user);
$this->assertTrue(is_array($profile));
$this->assertTrue(isset($profile['inbox']));
$this->assertTrue(isset($profile['outbox']));
}
}

View File

@ -225,7 +225,7 @@ class Activitypub_explorer
* @param array $res remote response
* @return boolean success state
*/
private static function validate_remote_response($res)
public static function validate_remote_response($res)
{
if (!isset($res['id'], $res['preferredUsername'], $res['name'], $res['summary'], $res['inbox'], $res['publicKey']['publicKeyPem'])) {
return false;