Add ActivityPub Profile Test
Fixed various serious issues while writing this test, namely database related.
This commit is contained in:
parent
58262451e3
commit
5c351efb06
@ -70,7 +70,7 @@ class ActivityPubPlugin extends Plugin
|
|||||||
*/
|
*/
|
||||||
public static function actor_url($profile)
|
public static function actor_url($profile)
|
||||||
{
|
{
|
||||||
return actor_uri($profile)."/";
|
return ActivityPubPlugin::actor_uri($profile)."/";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,10 +68,11 @@ class apActorFollowersAction extends ManagedAction
|
|||||||
ActivityPubReturn::error('Invalid page number.');
|
ActivityPubReturn::error('Invalid page number.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch Followers */
|
|
||||||
try {
|
|
||||||
$since = ($page - 1) * PROFILES_PER_MINILIST;
|
$since = ($page - 1) * PROFILES_PER_MINILIST;
|
||||||
$limit = (($page - 1) == 0 ? 1 : $page) * PROFILES_PER_MINILIST;
|
$limit = (($page - 1) == 0 ? 1 : $page) * PROFILES_PER_MINILIST;
|
||||||
|
|
||||||
|
/* Fetch Followers */
|
||||||
|
try {
|
||||||
$sub = $profile->getSubscribers($since, $limit);
|
$sub = $profile->getSubscribers($since, $limit);
|
||||||
} catch (NoResultException $e) {
|
} catch (NoResultException $e) {
|
||||||
ActivityPubReturn::error('This user has no followers.');
|
ActivityPubReturn::error('This user has no followers.');
|
||||||
|
@ -68,10 +68,11 @@ class apActorFollowingAction extends ManagedAction
|
|||||||
ActivityPubReturn::error('Invalid page number.');
|
ActivityPubReturn::error('Invalid page number.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch Following */
|
|
||||||
try {
|
|
||||||
$since = ($page - 1) * PROFILES_PER_MINILIST;
|
$since = ($page - 1) * PROFILES_PER_MINILIST;
|
||||||
$limit = (($page - 1) == 0 ? 1 : $page) * PROFILES_PER_MINILIST;
|
$limit = (($page - 1) == 0 ? 1 : $page) * PROFILES_PER_MINILIST;
|
||||||
|
|
||||||
|
/* Fetch Following */
|
||||||
|
try {
|
||||||
$sub = $profile->getSubscribed($since, $limit);
|
$sub = $profile->getSubscribed($since, $limit);
|
||||||
} catch (NoResultException $e) {
|
} catch (NoResultException $e) {
|
||||||
ActivityPubReturn::error('This user is not following anyone.');
|
ActivityPubReturn::error('This user is not following anyone.');
|
||||||
|
@ -51,13 +51,11 @@ class apActorLikedAction extends ManagedAction
|
|||||||
*/
|
*/
|
||||||
protected function handle()
|
protected function handle()
|
||||||
{
|
{
|
||||||
$nickname = $this->trimmed('nickname');
|
|
||||||
try {
|
try {
|
||||||
$user = User::getByNickname($nickname);
|
$profile = Profile::getByID($this->trimmed('id'));
|
||||||
$profile = $user->getProfile();
|
$url = ActivityPubPlugin::actor_url($profile);
|
||||||
$url = $profile->profileurl;
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
ActivityPubReturn::error('Invalid username.');
|
ActivityPubReturn::error('Invalid Actor URI.', 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
$limit = intval($this->trimmed('limit'));
|
$limit = intval($this->trimmed('limit'));
|
||||||
@ -73,7 +71,7 @@ class apActorLikedAction extends ManagedAction
|
|||||||
$limit = 80;
|
$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();
|
$faves = array();
|
||||||
while ($fave->fetch()) {
|
while ($fave->fetch()) {
|
||||||
|
@ -53,21 +53,21 @@ class Activitypub_pending_follow_requests extends Managed_DataObject
|
|||||||
*/
|
*/
|
||||||
public static function schemaDef()
|
public static function schemaDef()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'fields' => array(
|
'fields' => [
|
||||||
'local_profile_id' => array('type' => 'integer', 'not null' => true),
|
'local_profile_id' => ['type' => 'integer', 'not null' => true],
|
||||||
'remote_profile_id' => array('type' => 'integer', 'not null' => true),
|
'remote_profile_id' => ['type' => 'integer', 'not null' => true],
|
||||||
'relation_id' => array('type' => 'serial', 'not null' => true),
|
'relation_id' => ['type' => 'serial', 'not null' => true],
|
||||||
),
|
],
|
||||||
'primary key' => array('relation_id'),
|
'primary key' => ['relation_id'],
|
||||||
'unique keys' => array(
|
'unique keys' => [
|
||||||
'Activitypub_pending_follow_requests_relation_id_key' => array('relation_id'),
|
'Activitypub_pending_follow_requests_relation_id_key' => ['relation_id'],
|
||||||
),
|
],
|
||||||
'foreign keys' => array(
|
'foreign keys' => [
|
||||||
'Activitypub_pending_follow_requests_local_profile_id_fkey' => array('profile', array('local_profile_id' => 'id')),
|
'Activitypub_pending_follow_requests_local_profile_id_fkey' => ['profile', ['local_profile_id' => 'id']],
|
||||||
'Activitypub_pending_follow_requests_remote_profile_id_fkey' => array('profile', array('remote_profile_id' => 'id')),
|
'Activitypub_pending_follow_requests_remote_profile_id_fkey' => ['profile', ['remote_profile_id' => 'id']],
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct($actor, $remote_actor)
|
public function __construct($actor, $remote_actor)
|
||||||
|
@ -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
|
* @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/
|
* @link http://www.gnu.org/software/social/
|
||||||
*/
|
*/
|
||||||
class Activitypub_profile extends Profile
|
class Activitypub_profile extends Managed_DataObject
|
||||||
{
|
{
|
||||||
public $__table = 'Activitypub_profile';
|
public $__table = 'Activitypub_profile';
|
||||||
|
|
||||||
@ -50,24 +50,23 @@ class Activitypub_profile extends Profile
|
|||||||
*/
|
*/
|
||||||
public static function schemaDef()
|
public static function schemaDef()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'fields' => array(
|
'fields' => [
|
||||||
'uri' => array('type' => 'varchar', 'length' => 191, 'not null' => true),
|
'uri' => ['type' => 'text', 'not null' => true],
|
||||||
'profile_id' => array('type' => 'integer'),
|
'profile_id' => ['type' => 'integer'],
|
||||||
'inboxuri' => array('type' => 'varchar', 'length' => 191),
|
'inboxuri' => ['type' => 'text', 'not null' => true],
|
||||||
'sharedInboxuri' => array('type' => 'varchar', 'length' => 191),
|
'sharedInboxuri' => ['type' => 'text'],
|
||||||
'created' => array('type' => 'datetime', 'not null' => true),
|
'created' => ['type' => 'datetime', 'not null' => true],
|
||||||
'modified' => array('type' => 'datetime', 'not null' => true),
|
'modified' => ['type' => 'datetime', 'not null' => true],
|
||||||
),
|
],
|
||||||
'primary key' => array('uri'),
|
'primary key' => ['profile_id'],
|
||||||
'unique keys' => array(
|
'unique keys' => [
|
||||||
'Activitypub_profile_profile_id_key' => array('profile_id'),
|
'Activitypub_profile_profile_id_key' => ['profile_id'],
|
||||||
'Activitypub_profile_inboxuri_key' => array('inboxuri'),
|
],
|
||||||
),
|
'foreign keys' => [
|
||||||
'foreign keys' => array(
|
'Activitypub_profile_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
|
||||||
'Activitypub_profile_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
|
],
|
||||||
),
|
];
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,6 +171,7 @@ class Activitypub_profile extends Profile
|
|||||||
|
|
||||||
if ($ok === false) {
|
if ($ok === false) {
|
||||||
$profile->query('ROLLBACK');
|
$profile->query('ROLLBACK');
|
||||||
|
$this->query('ROLLBACK');
|
||||||
throw new ServerException('Cannot save ActivityPub profile.');
|
throw new ServerException('Cannot save ActivityPub profile.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,8 +215,15 @@ class Activitypub_profile extends Profile
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($profile as $key => $value) {
|
$fields = [
|
||||||
$aprofile->$key = $value;
|
'uri' => 'profileurl',
|
||||||
|
'nickname' => 'nickname',
|
||||||
|
'fullname' => 'fullname',
|
||||||
|
'bio' => 'bio'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($fields as $af => $pf) {
|
||||||
|
$aprofile->$af = $profile->$pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $aprofile;
|
return $aprofile;
|
||||||
|
@ -53,16 +53,14 @@ class Activitypub_rsa extends Managed_DataObject
|
|||||||
return [
|
return [
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'profile_id' => ['type' => 'integer'],
|
'profile_id' => ['type' => 'integer'],
|
||||||
'private_key' => ['type' => 'varchar', 'length' => 191],
|
'private_key' => ['type' => 'text'],
|
||||||
'public_key' => ['type' => 'varchar', 'length' => 191],
|
'public_key' => ['type' => 'text', 'not null' => true],
|
||||||
'created' => ['type' => 'datetime', 'not null' => true],
|
'created' => ['type' => 'datetime', 'not null' => true],
|
||||||
'modified' => ['type' => 'datetime', 'not null' => true],
|
'modified' => ['type' => 'datetime', 'not null' => true],
|
||||||
],
|
],
|
||||||
'primary key' => ['profile_id'],
|
'primary key' => ['profile_id'],
|
||||||
'unique keys' => [
|
'unique keys' => [
|
||||||
'Activitypub_rsa_profile_id_key' => ['profile_id'],
|
'Activitypub_rsa_profile_id_key' => ['profile_id'],
|
||||||
'Activitypub_rsa_private_key_key' => ['private_key'],
|
|
||||||
'Activitypub_rsa_public_key_key' => ['public_key'],
|
|
||||||
],
|
],
|
||||||
'foreign keys' => [
|
'foreign keys' => [
|
||||||
'Activitypub_profile_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
|
'Activitypub_profile_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
|
||||||
|
145
tests/Unit/ActivitypubProfileTest.php
Executable file
145
tests/Unit/ActivitypubProfileTest.php
Executable 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;
|
||||||
|
}
|
||||||
|
}
|
@ -114,7 +114,8 @@ class HTTPSignatureTest extends TestCase
|
|||||||
$request->getHeader('Authorization')
|
$request->getHeader('Authorization')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public function getVerifyGuzzleRequestVectors() {
|
public function getVerifyGuzzleRequestVectors()
|
||||||
|
{
|
||||||
return [
|
return [
|
||||||
/* path, headers */
|
/* path, headers */
|
||||||
['/path?query=123', ['date' => 'today', 'accept' => 'llamas']],
|
['/path?query=123', ['date' => 'today', 'accept' => 'llamas']],
|
||||||
|
@ -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']));
|
|
||||||
}
|
|
||||||
}
|
|
@ -225,7 +225,7 @@ class Activitypub_explorer
|
|||||||
* @param array $res remote response
|
* @param array $res remote response
|
||||||
* @return boolean success state
|
* @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'])) {
|
if (!isset($res['id'], $res['preferredUsername'], $res['name'], $res['summary'], $res['inbox'], $res['publicKey']['publicKeyPem'])) {
|
||||||
return false;
|
return false;
|
||||||
|
Reference in New Issue
Block a user