Update tests directory structure to follow plugin structure
This commit is contained in:
parent
be0a10dc22
commit
51eb8e2b51
22 changed files with 419 additions and 515 deletions
|
@ -48,20 +48,20 @@
|
||||||
],
|
],
|
||||||
"test": [
|
"test": [
|
||||||
"@prepare-test",
|
"@prepare-test",
|
||||||
"@test-vs-event-list",
|
"@test-integration-vs-event-list",
|
||||||
"@test-the-events-calendar",
|
"@test-integration-the-events-calendar",
|
||||||
"@test-gatherpress",
|
"@test-integration-gatherpress",
|
||||||
"@test-events-manager",
|
"@test-integration- events-manager",
|
||||||
"@test-wp-event-manager",
|
"@test-integration-wp-event-manager",
|
||||||
"@test-eventin",
|
"@test-integration-eventin",
|
||||||
"@test-modern-events-calendar-lite",
|
"@test-integration-modern-events-calendar-lite",
|
||||||
"@test-eventprime",
|
"@test-integration-eventprime",
|
||||||
"@test-event-organiser",
|
"@test-integration-event-organiser",
|
||||||
"@test-event-bridge-for-activitypub-event-sources"
|
"@test-event-sources"
|
||||||
],
|
],
|
||||||
"test-debug": [
|
"test-debug": [
|
||||||
"@prepare-test",
|
"@prepare-test",
|
||||||
"@test-the-events-calendar"
|
"@test-event-sources"
|
||||||
],
|
],
|
||||||
"test-vs-event-list": "phpunit --filter=vs_event_list",
|
"test-vs-event-list": "phpunit --filter=vs_event_list",
|
||||||
"test-the-events-calendar": "phpunit --filter=the_events_calendar",
|
"test-the-events-calendar": "phpunit --filter=the_events_calendar",
|
||||||
|
@ -72,8 +72,8 @@
|
||||||
"test-modern-events-calendar-lite": "phpunit --filter=modern_events_calendar_lite",
|
"test-modern-events-calendar-lite": "phpunit --filter=modern_events_calendar_lite",
|
||||||
"test-eventprime": "phpunit --filter=eventprime",
|
"test-eventprime": "phpunit --filter=eventprime",
|
||||||
"test-event-organiser": "phpunit --filter=event_organiser",
|
"test-event-organiser": "phpunit --filter=event_organiser",
|
||||||
"test-event-bridge-for-activitypub-shortcodes": "phpunit --filter=event_bridge_for_activitypub_shortcodes",
|
"test-event-bridge-for-activitypub-shortcodes": "phpunit --filter=shortcodes",
|
||||||
"test-event-bridge-for-activitypub-event-sources": "phpunit --filter=event_bridge_for_activitypub_event_sources",
|
"test-event-sources": "phpunit --filter=event_sources",
|
||||||
"test-all": "phpunit"
|
"test-all": "phpunit"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,7 @@ namespace Event_Bridge_For_ActivityPub\ActivityPub;
|
||||||
// Exit if accessed directly.
|
// Exit if accessed directly.
|
||||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||||
|
|
||||||
use DateTime;
|
use Event_Bridge_For_ActivityPub\Event_Sources;
|
||||||
use DateTimeZone;
|
|
||||||
use Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources;
|
|
||||||
use Event_Bridge_For_ActivityPub\ActivityPub\Handler\Accept;
|
use Event_Bridge_For_ActivityPub\ActivityPub\Handler\Accept;
|
||||||
use Event_Bridge_For_ActivityPub\ActivityPub\Handler\Update;
|
use Event_Bridge_For_ActivityPub\ActivityPub\Handler\Update;
|
||||||
use Event_Bridge_For_ActivityPub\ActivityPub\Handler\Create;
|
use Event_Bridge_For_ActivityPub\ActivityPub\Handler\Create;
|
||||||
|
@ -34,92 +32,9 @@ class Handler {
|
||||||
Delete::init();
|
Delete::init();
|
||||||
\add_filter(
|
\add_filter(
|
||||||
'activitypub_validate_object',
|
'activitypub_validate_object',
|
||||||
array( self::class, 'validate_object' ),
|
array( Event_Sources::class, 'validate_event_object' ),
|
||||||
12,
|
12,
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate the object.
|
|
||||||
*
|
|
||||||
* @param bool $valid The validation state.
|
|
||||||
* @param string $param The object parameter.
|
|
||||||
* @param \WP_REST_Request $request The request object.
|
|
||||||
*
|
|
||||||
* @return bool The validation state: true if valid, false if not.
|
|
||||||
*/
|
|
||||||
public static function validate_object( $valid, $param, $request ) {
|
|
||||||
$json_params = $request->get_json_params();
|
|
||||||
|
|
||||||
if ( isset( $json_params['object']['type'] ) && 'Event' === $json_params['object']['type'] ) {
|
|
||||||
$valid = true;
|
|
||||||
} else {
|
|
||||||
return $valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( empty( $json_params['type'] ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( empty( $json_params['actor'] ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! in_array( $json_params['type'], array( 'Create', 'Update', 'Delete', 'Announce' ), true ) || is_wp_error( $request ) ) {
|
|
||||||
return $valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
$object = $json_params['object'];
|
|
||||||
|
|
||||||
if ( ! is_array( $object ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$required = array(
|
|
||||||
'id',
|
|
||||||
'startTime',
|
|
||||||
'name',
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( array_intersect( $required, array_keys( $object ) ) !== $required ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a given DateTime is already passed.
|
|
||||||
*
|
|
||||||
* @param string $time_string The ActivityPub like time string.
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function is_time_passed( $time_string ) {
|
|
||||||
// Create a DateTime object from the ActivityPub time string.
|
|
||||||
$time = new DateTime( $time_string, new DateTimeZone( 'UTC' ) );
|
|
||||||
|
|
||||||
// Get the current time in UTC.
|
|
||||||
$current_time = new DateTime( 'now', new DateTimeZone( 'UTC' ) );
|
|
||||||
|
|
||||||
// Compare the event time with the current time.
|
|
||||||
return $time < $current_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that an ActivityPub actor is an event source (i.e. it is followed by the ActivityPub blog actor).
|
|
||||||
*
|
|
||||||
* @param string $actor_id The actor ID.
|
|
||||||
* @return bool True if the ActivityPub actor ID is followed, false otherwise.
|
|
||||||
*/
|
|
||||||
public static function actor_is_event_source( $actor_id ) {
|
|
||||||
$event_sources = Event_Sources::get_event_sources();
|
|
||||||
foreach ( $event_sources as $event_source ) {
|
|
||||||
if ( $actor_id === $event_source->get_id() ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,7 @@ class Event_Sources {
|
||||||
/**
|
/**
|
||||||
* Get all Event-Sources.
|
* Get all Event-Sources.
|
||||||
*
|
*
|
||||||
* @return array The Term list of Event Sources.
|
* @return Event_Source[] A List of all Event Sources (follows).
|
||||||
*/
|
*/
|
||||||
public static function get_event_sources() {
|
public static function get_event_sources() {
|
||||||
return self::get_event_sources_with_count()['actors'];
|
return self::get_event_sources_with_count()['actors'];
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
namespace Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
||||||
|
|
||||||
use Activitypub\Collection\Actors;
|
use Activitypub\Collection\Actors;
|
||||||
|
use Event_Bridge_For_ActivityPub\Event_Sources;
|
||||||
use Event_Bridge_For_ActivityPub\Setup;
|
use Event_Bridge_For_ActivityPub\Setup;
|
||||||
use Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
|
||||||
|
|
||||||
use function Activitypub\is_activity_public;
|
use function Activitypub\is_activity_public;
|
||||||
|
|
||||||
|
@ -36,12 +36,12 @@ class Create {
|
||||||
* @param int $user_id The id of the local blog-user.
|
* @param int $user_id The id of the local blog-user.
|
||||||
*/
|
*/
|
||||||
public static function handle_create( $activity, $user_id ) {
|
public static function handle_create( $activity, $user_id ) {
|
||||||
// We only process activities that are target to the application user.
|
// We only process activities that are target to the blog actor.
|
||||||
if ( Actors::BLOG_USER_ID !== $user_id ) {
|
if ( Actors::BLOG_USER_ID !== $user_id ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! Handler::actor_is_event_source( $activity['actor'] ) ) {
|
if ( ! Event_Sources::actor_is_event_source( $activity['actor'] ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +55,12 @@ class Create {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Handler::is_time_passed( $activity['object']['startTime'] ) ) {
|
if ( Event_Sources::is_time_passed( $activity['object']['startTime'] ) ) {
|
||||||
return;
|
return new \WP_Error(
|
||||||
|
'event_bridge_for_activitypub_not_accepting_events_from_the_past',
|
||||||
|
__( 'We do not accept this event because it took place in the past.', 'event-bridge-for-activitypub' ),
|
||||||
|
array( 'status' => 403 )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$transmogrifier = Setup::get_transmogrifier();
|
$transmogrifier = Setup::get_transmogrifier();
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
namespace Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
||||||
|
|
||||||
use Activitypub\Collection\Actors;
|
use Activitypub\Collection\Actors;
|
||||||
|
use Event_Bridge_For_ActivityPub\Event_Sources;
|
||||||
use Event_Bridge_For_ActivityPub\Setup;
|
use Event_Bridge_For_ActivityPub\Setup;
|
||||||
use Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle Delete requests.
|
* Handle Delete requests.
|
||||||
|
@ -39,7 +39,7 @@ class Delete {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! Handler::actor_is_event_source( $activity['actor'] ) ) {
|
if ( ! Event_Sources::actor_is_event_source( $activity['actor'] ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,10 +48,6 @@ class Delete {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Handler::is_time_passed( $activity['object']['startTime'] ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$transmogrifier = Setup::get_transmogrifier();
|
$transmogrifier = Setup::get_transmogrifier();
|
||||||
|
|
||||||
if ( ! $transmogrifier ) {
|
if ( ! $transmogrifier ) {
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
namespace Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
||||||
|
|
||||||
use Activitypub\Collection\Actors;
|
use Activitypub\Collection\Actors;
|
||||||
|
use Event_Bridge_For_ActivityPub\Event_Sources;
|
||||||
use Event_Bridge_For_ActivityPub\Setup;
|
use Event_Bridge_For_ActivityPub\Setup;
|
||||||
use Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
|
||||||
|
|
||||||
use function Activitypub\is_activity_public;
|
use function Activitypub\is_activity_public;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class Update {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! Handler::actor_is_event_source( $activity['actor'] ) ) {
|
if ( ! Event_Sources::actor_is_event_source( $activity['actor'] ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ class Update {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Handler::is_time_passed( $activity['object']['startTime'] ) ) {
|
if ( Event_Sources::is_time_passed( $activity['object']['startTime'] ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,30 +74,6 @@ abstract class Base {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate a time string if it is according to the ActivityPub specification.
|
|
||||||
*
|
|
||||||
* @param string $time_string The time string.
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function is_valid_activitypub_time_string( $time_string ) {
|
|
||||||
// Try to create a DateTime object from the input string.
|
|
||||||
try {
|
|
||||||
$date = new DateTime( $time_string );
|
|
||||||
} catch ( Exception $e ) {
|
|
||||||
// If parsing fails, it's not valid.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the timezone is correctly formatted (e.g., 'Z' or a valid offset).
|
|
||||||
$timezone = $date->getTimezone();
|
|
||||||
$formatted_timezone = $timezone->getName();
|
|
||||||
|
|
||||||
// Return true only if the time string includes 'Z' or a valid timezone offset.
|
|
||||||
$valid = 'Z' === $formatted_timezone || preg_match( '/^[+-]\d{2}:\d{2}$/ ', $formatted_timezone );
|
|
||||||
return $valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the image URL and alt-text of an ActivityPub object.
|
* Get the image URL and alt-text of an ActivityPub object.
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,11 +10,14 @@
|
||||||
namespace Event_Bridge_For_ActivityPub;
|
namespace Event_Bridge_For_ActivityPub;
|
||||||
|
|
||||||
use Activitypub\Model\Blog;
|
use Activitypub\Model\Blog;
|
||||||
|
use DateTime;
|
||||||
|
use DateTimeZone;
|
||||||
use Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources as Event_Sources_Collection;
|
use Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources as Event_Sources_Collection;
|
||||||
use Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
use Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
||||||
use Event_Bridge_For_ActivityPub\Admin\User_Interface;
|
use Event_Bridge_For_ActivityPub\Admin\User_Interface;
|
||||||
use Event_Bridge_For_ActivityPub\Integrations\Event_Plugin_Integration;
|
use Event_Bridge_For_ActivityPub\Integrations\Event_Plugin_Integration;
|
||||||
use Event_Bridge_For_ActivityPub\Integrations\Feature_Event_Sources;
|
use Event_Bridge_For_ActivityPub\Integrations\Feature_Event_Sources;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
use function Activitypub\get_remote_metadata_by_actor;
|
use function Activitypub\get_remote_metadata_by_actor;
|
||||||
use function Activitypub\is_activitypub_request;
|
use function Activitypub\is_activitypub_request;
|
||||||
|
@ -244,7 +247,7 @@ class Event_Sources {
|
||||||
/**
|
/**
|
||||||
* Get an array will all unique hosts of all Event-Sources.
|
* Get an array will all unique hosts of all Event-Sources.
|
||||||
*
|
*
|
||||||
* @return array The Term list of Event Sources.
|
* @return array A list with all unique hosts of all Event Sources' ActivityPub IDs.
|
||||||
*/
|
*/
|
||||||
public static function get_event_sources_hosts() {
|
public static function get_event_sources_hosts() {
|
||||||
$hosts = get_transient( 'event_bridge_for_activitypub_event_sources_hosts' );
|
$hosts = get_transient( 'event_bridge_for_activitypub_event_sources_hosts' );
|
||||||
|
@ -253,7 +256,7 @@ class Event_Sources {
|
||||||
return $hosts;
|
return $hosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
$actors = Event_Sources_Collection::get_event_sources_with_count()['actors'];
|
$actors = Event_Sources_Collection::get_event_sources();
|
||||||
|
|
||||||
$hosts = array();
|
$hosts = array();
|
||||||
foreach ( $actors as $actor ) {
|
foreach ( $actors as $actor ) {
|
||||||
|
@ -273,7 +276,7 @@ class Event_Sources {
|
||||||
/**
|
/**
|
||||||
* Get add Event Sources ActivityPub IDs.
|
* Get add Event Sources ActivityPub IDs.
|
||||||
*
|
*
|
||||||
* @return array The Term list of Event Sources.
|
* @return array A list with the ActivityPub IDs of all Event Sources (follows).
|
||||||
*/
|
*/
|
||||||
public static function get_event_sources_ids() {
|
public static function get_event_sources_ids() {
|
||||||
$ids = get_transient( 'event_bridge_for_activitypub_event_sources_ids' );
|
$ids = get_transient( 'event_bridge_for_activitypub_event_sources_ids' );
|
||||||
|
@ -282,7 +285,7 @@ class Event_Sources {
|
||||||
return $ids;
|
return $ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
$actors = Event_Sources_Collection::get_event_sources_with_count()['actors'];
|
$actors = Event_Sources_Collection::get_event_sources();
|
||||||
|
|
||||||
$ids = array();
|
$ids = array();
|
||||||
foreach ( $actors as $actor ) {
|
foreach ( $actors as $actor ) {
|
||||||
|
@ -304,4 +307,115 @@ class Event_Sources {
|
||||||
$event_sources_hosts = self::get_event_sources_hosts();
|
$event_sources_hosts = self::get_event_sources_hosts();
|
||||||
return array_merge( $hosts, $event_sources_hosts );
|
return array_merge( $hosts, $event_sources_hosts );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the event object.
|
||||||
|
*
|
||||||
|
* @param bool $valid The validation state.
|
||||||
|
* @param string $param The object parameter.
|
||||||
|
* @param \WP_REST_Request $request The request object.
|
||||||
|
*
|
||||||
|
* @return bool|WP_Error The validation state: true if valid, false if not.
|
||||||
|
*/
|
||||||
|
public static function validate_event_object( $valid, $param, $request ) {
|
||||||
|
$json_params = $request->get_json_params();
|
||||||
|
|
||||||
|
if ( isset( $json_params['object']['type'] ) && 'Event' === $json_params['object']['type'] ) {
|
||||||
|
$valid = true;
|
||||||
|
} else {
|
||||||
|
return $valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( empty( $json_params['type'] ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( empty( $json_params['actor'] ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! in_array( $json_params['type'], array( 'Create', 'Update', 'Delete', 'Announce' ), true ) || is_wp_error( $request ) ) {
|
||||||
|
return $valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
$object = $json_params['object'];
|
||||||
|
|
||||||
|
if ( ! is_array( $object ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$required = array(
|
||||||
|
'id',
|
||||||
|
'startTime',
|
||||||
|
'name',
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( array_intersect( $required, array_keys( $object ) ) !== $required ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! self::is_valid_activitypub_time_string( $object['startTime'] ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a time string if it is according to the ActivityPub specification.
|
||||||
|
*
|
||||||
|
* @param string $time_string The time string.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function is_valid_activitypub_time_string( $time_string ) {
|
||||||
|
// Try to create a DateTime object from the input string.
|
||||||
|
try {
|
||||||
|
$date = new DateTime( $time_string );
|
||||||
|
} catch ( Exception $e ) {
|
||||||
|
// If parsing fails, it's not valid.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the timezone is correctly formatted (e.g., 'Z' or a valid offset).
|
||||||
|
$timezone = $date->getTimezone();
|
||||||
|
$formatted_timezone = $timezone->getName();
|
||||||
|
|
||||||
|
// Return true only if the time string includes 'Z' or a valid timezone offset.
|
||||||
|
$valid = 'Z' === $formatted_timezone || preg_match( '/^[+-]\d{2}:\d{2}$/ ', $formatted_timezone );
|
||||||
|
return $valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given DateTime is already passed.
|
||||||
|
*
|
||||||
|
* @param string $time_string The ActivityPub like time string.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function is_time_passed( $time_string ) {
|
||||||
|
// Create a DateTime object from the ActivityPub time string.
|
||||||
|
$time = new DateTime( $time_string, new DateTimeZone( 'UTC' ) );
|
||||||
|
|
||||||
|
// Get the current time in UTC.
|
||||||
|
$current_time = new DateTime( 'now', new DateTimeZone( 'UTC' ) );
|
||||||
|
|
||||||
|
// Compare the event time with the current time.
|
||||||
|
return $time < $current_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that an ActivityPub actor is an event source (i.e. it is followed by the ActivityPub blog actor).
|
||||||
|
*
|
||||||
|
* @param string $actor_id The actor ID.
|
||||||
|
* @return bool True if the ActivityPub actor ID is followed, false otherwise.
|
||||||
|
*/
|
||||||
|
public static function actor_is_event_source( $actor_id ) {
|
||||||
|
$event_sources = Event_Sources_Collection::get_event_sources();
|
||||||
|
foreach ( $event_sources as $event_source ) {
|
||||||
|
if ( $actor_id === $event_source->get_id() ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
>
|
>
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite name="testing">
|
<testsuite name="testing">
|
||||||
<directory prefix="test-" suffix=".php">./tests/</directory>
|
<directory prefix="class-test-" suffix=".php">./tests/</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
* @package Event_Bridge_For_ActivityPub
|
* @package Event_Bridge_For_ActivityPub
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Defined here because setting them in .wp-env.json doesn't work for some reason.
|
||||||
|
\define( 'WP_TESTS_DOMAIN', 'example.org' );
|
||||||
|
\define( 'WP_SITEURL', 'http://example.org' );
|
||||||
|
\define( 'WP_HOME', 'http://example.org' );
|
||||||
|
|
||||||
$_tests_dir = getenv( 'WP_TESTS_DIR' );
|
$_tests_dir = getenv( 'WP_TESTS_DIR' );
|
||||||
|
|
||||||
if ( ! $_tests_dir ) {
|
if ( ! $_tests_dir ) {
|
||||||
|
@ -96,9 +101,12 @@ function _manually_load_plugin() {
|
||||||
|
|
||||||
if ( $plugin_file ) {
|
if ( $plugin_file ) {
|
||||||
_manually_load_event_plugin( $plugin_file );
|
_manually_load_event_plugin( $plugin_file );
|
||||||
} elseif ( 'event_bridge_for_activitypub_event_sources' === $event_bridge_for_activitypub_integration_filter ) {
|
} elseif ( 'event_sources' === $event_bridge_for_activitypub_integration_filter ) {
|
||||||
// For the Event Sources feature we currently only test with GatherPress.
|
// For the Event Sources feature we currently only test with GatherPress.
|
||||||
_manually_load_event_plugin( 'gatherpress/gatherpress.php' );
|
_manually_load_event_plugin( 'gatherpress/gatherpress.php' );
|
||||||
|
\update_option( 'event_bridge_for_activitypub_event_sources_active', true );
|
||||||
|
\update_option( 'event_bridge_for_activitypub_plugin_used_for_event_source_feature', 'GatherPress' );
|
||||||
|
\update_option( 'activitypub_actor_mode', ACTIVITYPUB_BLOG_MODE );
|
||||||
} else {
|
} else {
|
||||||
// For all other tests we mainly use the Events Calendar as a reference.
|
// For all other tests we mainly use the Events Calendar as a reference.
|
||||||
_manually_load_event_plugin( 'the-events-calendar/the-events-calendar.php' );
|
_manually_load_event_plugin( 'the-events-calendar/the-events-calendar.php' );
|
||||||
|
@ -121,6 +129,9 @@ function _manually_load_plugin() {
|
||||||
|
|
||||||
// At last manually load our WordPress plugin.
|
// At last manually load our WordPress plugin.
|
||||||
require dirname( __DIR__ ) . '/event-bridge-for-activitypub.php';
|
require dirname( __DIR__ ) . '/event-bridge-for-activitypub.php';
|
||||||
|
|
||||||
|
// Always manually load the ActivityPub plugin.
|
||||||
|
require_once $plugin_dir . 'activitypub/activitypub.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
|
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
|
||||||
|
|
|
@ -5,10 +5,14 @@
|
||||||
* @package Event_Bridge_For_ActivityPub
|
* @package Event_Bridge_For_ActivityPub
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Event_Bridge_For_ActivityPub\Tests\ActivityPub\Transformer;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample test case.
|
* Sample test case.
|
||||||
*/
|
*/
|
||||||
class Test_Event_Organiser extends WP_UnitTestCase {
|
class Test_Event_Organiser extends \WP_UnitTestCase {
|
||||||
/**
|
/**
|
||||||
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
||||||
*/
|
*/
|
|
@ -6,14 +6,12 @@
|
||||||
* @license AGPL-3.0-or-later
|
* @license AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use Activitypub\Shortcodes;
|
namespace Event_Bridge_For_ActivityPup\Tests\ActivityPub\Transformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for Activitypub Shortcodes.
|
* Test class for Shortcodes.
|
||||||
*
|
|
||||||
* @coversDefaultClass \Activitypub\Shortcodes
|
|
||||||
*/
|
*/
|
||||||
class Test_Activitypub_Event_Bridge_Shortcodes extends WP_UnitTestCase {
|
class Test_Event extends \WP_UnitTestCase {
|
||||||
/**
|
/**
|
||||||
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
||||||
*/
|
*/
|
|
@ -5,10 +5,12 @@
|
||||||
* @package Event_Bridge_For_ActivityPub
|
* @package Event_Bridge_For_ActivityPub
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Event_Bridge_For_ActivityPub\Tests\ActivityPub\Transformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test cases for WP Event Solution.
|
* Test cases for WP Event Solution.
|
||||||
*/
|
*/
|
||||||
class Test_Eventin extends WP_UnitTestCase {
|
class Test_Eventin extends \WP_UnitTestCase {
|
||||||
/**
|
/**
|
||||||
* Basic Mock-up event.
|
* Basic Mock-up event.
|
||||||
*/
|
*/
|
|
@ -5,10 +5,12 @@
|
||||||
* @package Event_Bridge_For_ActivityPub
|
* @package Event_Bridge_For_ActivityPub
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Event_Bridge_For_ActivityPub\Tests\ActivityPub\Transformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample test case.
|
* Sample test case.
|
||||||
*/
|
*/
|
||||||
class Test_EventPrime extends WP_UnitTestCase {
|
class Test_EventPrime extends \WP_UnitTestCase {
|
||||||
/**
|
/**
|
||||||
* Mockup venues of certain complexity.
|
* Mockup venues of certain complexity.
|
||||||
*
|
*
|
|
@ -5,10 +5,12 @@
|
||||||
* @package Event_Bridge_For_ActivityPub
|
* @package Event_Bridge_For_ActivityPub
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Event_Bridge_For_ActivityPub\Tests\ActivityPub\Transformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample test case.
|
* Sample test case.
|
||||||
*/
|
*/
|
||||||
class Test_Events_Manager extends WP_UnitTestCase {
|
class Test_Events_Manager extends \WP_UnitTestCase {
|
||||||
/**
|
/**
|
||||||
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
||||||
*/
|
*/
|
|
@ -5,10 +5,12 @@
|
||||||
* @package Event_Bridge_For_ActivityPub
|
* @package Event_Bridge_For_ActivityPub
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Event_Bridge_For_ActivityPub\Tests\ActivityPub\Transformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample test case.
|
* Sample test case.
|
||||||
*/
|
*/
|
||||||
class Test_GatherPress extends WP_UnitTestCase {
|
class Test_GatherPress extends \WP_UnitTestCase {
|
||||||
/**
|
/**
|
||||||
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
||||||
*/
|
*/
|
|
@ -5,10 +5,12 @@
|
||||||
* @package Event_Bridge_For_ActivityPub
|
* @package Event_Bridge_For_ActivityPub
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Event_Bridge_For_ActivityPub\Tests\ActivityPub\Transformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample test case.
|
* Sample test case.
|
||||||
*/
|
*/
|
||||||
class Test_Modern_Events_Calendar_Lite extends WP_UnitTestCase {
|
class Test_Modern_Events_Calendar_Lite extends \WP_UnitTestCase {
|
||||||
/**
|
/**
|
||||||
* The MEC main instance.
|
* The MEC main instance.
|
||||||
*
|
*
|
|
@ -5,10 +5,12 @@
|
||||||
* @package Event_Bridge_For_ActivityPub
|
* @package Event_Bridge_For_ActivityPub
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Event_Bridge_For_ActivityPub\Tests\ActivityPub\Transformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample test case.
|
* Sample test case.
|
||||||
*/
|
*/
|
||||||
class Test_VS_Event_List extends WP_UnitTestCase {
|
class Test_VS_Event_List extends \WP_UnitTestCase {
|
||||||
/**
|
/**
|
||||||
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
||||||
*/
|
*/
|
|
@ -5,10 +5,12 @@
|
||||||
* @package Event_Bridge_For_ActivityPub
|
* @package Event_Bridge_For_ActivityPub
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Event_Bridge_For_ActivityPub\Tests\ActivityPub\Transformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample test case.
|
* Sample test case.
|
||||||
*/
|
*/
|
||||||
class Test_The_Events_Calendar extends WP_UnitTestCase {
|
class Test_The_Events_Calendar extends \WP_UnitTestCase {
|
||||||
/**
|
/**
|
||||||
* Mockup events of certain complexity.
|
* Mockup events of certain complexity.
|
||||||
*/
|
*/
|
|
@ -5,10 +5,12 @@
|
||||||
* @package Event_Bridge_For_ActivityPub
|
* @package Event_Bridge_For_ActivityPub
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Event_Bridge_For_ActivityPub\Tests\ActivityPub\Transformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample test case.
|
* Sample test case.
|
||||||
*/
|
*/
|
||||||
class Test_WP_Event_Manager extends WP_UnitTestCase {
|
class Test_WP_Event_Manager extends \WP_UnitTestCase {
|
||||||
/**
|
/**
|
||||||
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
||||||
*/
|
*/
|
226
tests/includes/class-test-event-sources.php
Normal file
226
tests/includes/class-test-event-sources.php
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Test file for the Event Sources feature.
|
||||||
|
*
|
||||||
|
* @package Event_Bridge_For_ActivityPub
|
||||||
|
* @since 1.0.0
|
||||||
|
* @license AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Event_Bridge_For_ActivityPub\Tests;
|
||||||
|
|
||||||
|
use WP_REST_Request;
|
||||||
|
use WP_REST_Server;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class for Activitypub Rest Inbox.
|
||||||
|
*
|
||||||
|
* @coversDefaultClass \Event_Bridge_For_ActivityPub\Event_Sources
|
||||||
|
*/
|
||||||
|
class Test_Event_Sources extends \WP_UnitTestCase {
|
||||||
|
const FOLLOWED_ACTOR = array(
|
||||||
|
'id' => 'https://remote.example/@organizer',
|
||||||
|
'type' => 'Person',
|
||||||
|
'inbox' => 'https://remote.example/@organizer/inbox',
|
||||||
|
'outbox' => 'https://remote.example/@organizer/outbox',
|
||||||
|
'name' => 'The Organizer',
|
||||||
|
'summary' => 'Just a random organizer of events in the Fediverse',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post ID.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected static $event_source_post_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST Server.
|
||||||
|
*
|
||||||
|
* @var WP_REST_Server
|
||||||
|
*/
|
||||||
|
protected $server;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create fake data before tests run.
|
||||||
|
*
|
||||||
|
* @param WP_UnitTest_Factory $factory Helper that creates fake data.
|
||||||
|
*/
|
||||||
|
public static function wpSetUpBeforeClass( $factory ) {
|
||||||
|
// Follow actor.
|
||||||
|
$event_source = new \Event_Bridge_For_ActivityPub\ActivityPub\Model\Event_Source();
|
||||||
|
$event_source->from_array( self::FOLLOWED_ACTOR );
|
||||||
|
$post_id = $event_source->save();
|
||||||
|
self::$event_source_post_id = $post_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the test.
|
||||||
|
*/
|
||||||
|
public function set_up() {
|
||||||
|
\add_option( 'permalink_structure', '/%postname%/' );
|
||||||
|
|
||||||
|
global $wp_rest_server;
|
||||||
|
$wp_rest_server = new WP_REST_Server();
|
||||||
|
$this->server = $wp_rest_server;
|
||||||
|
|
||||||
|
do_action( 'rest_api_init' );
|
||||||
|
|
||||||
|
\Activitypub\Rest\Server::add_hooks();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tear down the test.
|
||||||
|
*/
|
||||||
|
public function tear_down() {
|
||||||
|
\delete_option( 'permalink_structure' );
|
||||||
|
\add_filter( 'activitypub_defer_signature_verification', '__return_false' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test receiving event from followed actor.
|
||||||
|
*/
|
||||||
|
public function test_incoming_event() {
|
||||||
|
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
||||||
|
|
||||||
|
$json = array(
|
||||||
|
'id' => 'https://remote.example/@organizer/events/new-year-party#create',
|
||||||
|
'type' => 'Create',
|
||||||
|
'actor' => 'https://remote.example/@organizer',
|
||||||
|
'object' => array(
|
||||||
|
'id' => 'https://remote.example/@organizer/events/new-year-party',
|
||||||
|
'type' => 'Event',
|
||||||
|
'startTime' => \gmdate( 'Y-m-d\TH:i:s\Z', time() + WEEK_IN_SECONDS ),
|
||||||
|
'name' => 'New Years Party 50/51',
|
||||||
|
'to' => 'https://www.w3.org/ns/activitystreams#Public',
|
||||||
|
'published' => '2020-01-01T00:00:00Z',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$request = new WP_REST_Request( 'POST', '/activitypub/1.0/users/0/inbox' );
|
||||||
|
$request->set_header( 'Content-Type', 'application/activity+json' );
|
||||||
|
$request->set_body( \wp_json_encode( $json ) );
|
||||||
|
|
||||||
|
// Dispatch the request.
|
||||||
|
$response = \rest_do_request( $request );
|
||||||
|
$this->assertEquals( 202, $response->get_status() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test receiving event from followed actor with missing start time.
|
||||||
|
*/
|
||||||
|
public function test_incoming_create_with_missing_start_time() {
|
||||||
|
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
||||||
|
|
||||||
|
$json = array(
|
||||||
|
'id' => 'https://remote.example/@organizer/events/new-year-party#create',
|
||||||
|
'type' => 'Create',
|
||||||
|
'actor' => 'https://remote.example/@organizer',
|
||||||
|
'object' => array(
|
||||||
|
'id' => 'https://remote.example/@organizer/events/new-year-party',
|
||||||
|
'type' => 'Event',
|
||||||
|
'name' => 'New Years Party 50/51',
|
||||||
|
'to' => 'https://www.w3.org/ns/activitystreams#Public',
|
||||||
|
'published' => '2020-01-01T00:00:00Z',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$request = new WP_REST_Request( 'POST', '/activitypub/1.0/users/0/inbox' );
|
||||||
|
$request->set_header( 'Content-Type', 'application/activity+json' );
|
||||||
|
$request->set_body( \wp_json_encode( $json ) );
|
||||||
|
|
||||||
|
// Dispatch the request.
|
||||||
|
$response = \rest_do_request( $request );
|
||||||
|
$this->assertEquals( 400, $response->get_status() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test receiving event from followed actor with wrongly formatted start time.
|
||||||
|
*/
|
||||||
|
public function test_incoming_event_with_faulty_start_time() {
|
||||||
|
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
||||||
|
|
||||||
|
$json = array(
|
||||||
|
'id' => 'https://remote.example/@organizer/events/new-year-party#create',
|
||||||
|
'type' => 'Create',
|
||||||
|
'actor' => 'https://remote.example/@organizer',
|
||||||
|
'object' => array(
|
||||||
|
'id' => 'https://remote.example/@organizer/events/new-year-party',
|
||||||
|
'type' => 'Event',
|
||||||
|
'name' => 'New Years Party 50/51',
|
||||||
|
'startTime' => \gmdate( 'Y-m-d\TH:i:s\Z', time() + WEEK_IN_SECONDS ),
|
||||||
|
'to' => 'https://www.w3.org/ns/activitystreams#Public',
|
||||||
|
'published' => '2020-01-01T00:00:00Z',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$request = new WP_REST_Request( 'POST', '/activitypub/1.0/users/0/inbox' );
|
||||||
|
$request->set_header( 'Content-Type', 'application/activity+json' );
|
||||||
|
$request->set_body( \wp_json_encode( $json ) );
|
||||||
|
|
||||||
|
// Dispatch the request.
|
||||||
|
$response = \rest_do_request( $request );
|
||||||
|
$this->assertEquals( 401, $response->get_status() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We do understand, but do not care about incoming events that happened in the past.
|
||||||
|
*/
|
||||||
|
public function test_incoming_event_which_took_place_in_the_past() {
|
||||||
|
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
||||||
|
|
||||||
|
$json = array(
|
||||||
|
'id' => 'https://remote.example/@organizer/events/new-year-party#create',
|
||||||
|
'type' => 'Create',
|
||||||
|
'actor' => 'https://remote.example/@organizer',
|
||||||
|
'object' => array(
|
||||||
|
'id' => 'https://remote.example/@organizer/events/new-year-party',
|
||||||
|
'type' => 'Event',
|
||||||
|
'name' => 'New Years Party 50/51',
|
||||||
|
'startTime' => \gmdate( 'Y-m-d\TH:i:s\Z', time() - WEEK_IN_SECONDS ),
|
||||||
|
'to' => 'https://www.w3.org/ns/activitystreams#Public',
|
||||||
|
'published' => '2020-01-01T00:00:00Z',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$request = new WP_REST_Request( 'POST', '/activitypub/1.0/users/0/inbox' );
|
||||||
|
$request->set_header( 'Content-Type', 'application/activity+json' );
|
||||||
|
$request->set_body( \wp_json_encode( $json ) );
|
||||||
|
|
||||||
|
// Dispatch the request.
|
||||||
|
$response = \rest_do_request( $request );
|
||||||
|
// This should be 403 but it is not possible without lots of hacks at the moment.
|
||||||
|
$this->assertEquals( 401, $response->get_status() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test receiving event from actor we do not follow.
|
||||||
|
*/
|
||||||
|
public function test_incoming_create_from_non_followed_actor() {
|
||||||
|
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
||||||
|
|
||||||
|
$json = array(
|
||||||
|
'id' => 'https://remote.example/@another_organizer/events/new-year-party#create',
|
||||||
|
'type' => 'Create',
|
||||||
|
'actor' => 'https://remote.example/@another_organizer',
|
||||||
|
'object' => array(
|
||||||
|
'id' => 'https://remote.example/@another_organizer/events/new-year-party',
|
||||||
|
'type' => 'Event',
|
||||||
|
'startTime' => '2050-12-31T18:00:00Z',
|
||||||
|
'name' => 'New Years Party 50/51',
|
||||||
|
'to' => 'https://www.w3.org/ns/activitystreams#Public',
|
||||||
|
'published' => '2020-01-01T00:00:00Z',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$request = new WP_REST_Request( 'POST', '/activitypub/1.0/users/0/inbox' );
|
||||||
|
$request->set_header( 'Content-Type', 'application/activity+json' );
|
||||||
|
$request->set_body( \wp_json_encode( $json ) );
|
||||||
|
|
||||||
|
// Dispatch the request.
|
||||||
|
$response = \rest_do_request( $request );
|
||||||
|
$this->assertEquals( 401, $response->get_status() );
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,356 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Test file for the Event Sources feature.
|
|
||||||
*
|
|
||||||
* @package Event_Bridge_For_ActivityPub
|
|
||||||
* @since 1.0.0
|
|
||||||
* @license AGPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test class for Activitypub Rest Inbox.
|
|
||||||
*
|
|
||||||
* @coversDefaultClass \Activitypub\Rest\Inbox
|
|
||||||
*/
|
|
||||||
class Test_Event_Bridge_For_ActivityPub_Event_Sources extends WP_UnitTestCase {
|
|
||||||
/**
|
|
||||||
* Set up the test.
|
|
||||||
*/
|
|
||||||
public function set_up() {
|
|
||||||
\add_option( 'permalink_structure', '/%postname%/' );
|
|
||||||
|
|
||||||
\Activitypub\Rest\Server::add_hooks();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tear down the test.
|
|
||||||
*/
|
|
||||||
public function tear_down() {
|
|
||||||
\delete_option( 'permalink_structure' );
|
|
||||||
\add_filter( 'activitypub_defer_signature_verification', '__return_false' );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the inbox signature issue.
|
|
||||||
*/
|
|
||||||
public function test_inbox_signature_issue() {
|
|
||||||
\add_filter( 'activitypub_defer_signature_verification', '__return_false' );
|
|
||||||
|
|
||||||
$json = array(
|
|
||||||
'id' => 'https://remote.example/@id',
|
|
||||||
'type' => 'Follow',
|
|
||||||
'actor' => 'https://remote.example/@test',
|
|
||||||
'object' => 'https://local.example/@test',
|
|
||||||
);
|
|
||||||
|
|
||||||
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/users/1/inbox' );
|
|
||||||
$request->set_header( 'Content-Type', 'application/activity+json' );
|
|
||||||
$request->set_body( \wp_json_encode( $json ) );
|
|
||||||
|
|
||||||
$response = \rest_do_request( $request );
|
|
||||||
|
|
||||||
$this->assertEquals( 401, $response->get_status() );
|
|
||||||
$this->assertEquals( 'activitypub_signature_verification', $response->get_data()['code'] );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test missing attribute.
|
|
||||||
*/
|
|
||||||
public function test_missing_attribute() {
|
|
||||||
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
|
||||||
|
|
||||||
$json = array(
|
|
||||||
'id' => 'https://remote.example/@id',
|
|
||||||
'type' => 'Follow',
|
|
||||||
'actor' => 'https://remote.example/@test',
|
|
||||||
);
|
|
||||||
|
|
||||||
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/users/1/inbox' );
|
|
||||||
$request->set_header( 'Content-Type', 'application/activity+json' );
|
|
||||||
$request->set_body( \wp_json_encode( $json ) );
|
|
||||||
|
|
||||||
$response = \rest_do_request( $request );
|
|
||||||
|
|
||||||
$this->assertEquals( 400, $response->get_status() );
|
|
||||||
$this->assertEquals( 'rest_missing_callback_param', $response->get_data()['code'] );
|
|
||||||
$this->assertEquals( 'object', $response->get_data()['data']['params'][0] );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test follow request.
|
|
||||||
*/
|
|
||||||
public function test_follow_request() {
|
|
||||||
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
|
||||||
|
|
||||||
$json = array(
|
|
||||||
'id' => 'https://remote.example/@id',
|
|
||||||
'type' => 'Follow',
|
|
||||||
'actor' => 'https://remote.example/@test',
|
|
||||||
'object' => 'https://local.example/@test',
|
|
||||||
);
|
|
||||||
|
|
||||||
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/users/1/inbox' );
|
|
||||||
$request->set_header( 'Content-Type', 'application/activity+json' );
|
|
||||||
$request->set_body( \wp_json_encode( $json ) );
|
|
||||||
|
|
||||||
// Dispatch the request.
|
|
||||||
$response = \rest_do_request( $request );
|
|
||||||
$this->assertEquals( 202, $response->get_status() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test follow request global inbox.
|
|
||||||
*/
|
|
||||||
public function test_follow_request_global_inbox() {
|
|
||||||
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
|
||||||
|
|
||||||
$json = array(
|
|
||||||
'id' => 'https://remote.example/@id',
|
|
||||||
'type' => 'Follow',
|
|
||||||
'actor' => 'https://remote.example/@test',
|
|
||||||
'object' => 'https://local.example/@test',
|
|
||||||
);
|
|
||||||
|
|
||||||
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/inbox' );
|
|
||||||
$request->set_header( 'Content-Type', 'application/activity+json' );
|
|
||||||
$request->set_body( \wp_json_encode( $json ) );
|
|
||||||
|
|
||||||
// Dispatch the request.
|
|
||||||
$response = \rest_do_request( $request );
|
|
||||||
$this->assertEquals( 202, $response->get_status() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test create request with a remote actor.
|
|
||||||
*/
|
|
||||||
public function test_create_request() {
|
|
||||||
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
|
||||||
|
|
||||||
// Invalid request, because of an invalid object.
|
|
||||||
$json = array(
|
|
||||||
'id' => 'https://remote.example/@id',
|
|
||||||
'type' => 'Create',
|
|
||||||
'actor' => 'https://remote.example/@test',
|
|
||||||
'object' => 'https://local.example/@test',
|
|
||||||
);
|
|
||||||
|
|
||||||
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/users/1/inbox' );
|
|
||||||
$request->set_header( 'Content-Type', 'application/activity+json' );
|
|
||||||
$request->set_body( \wp_json_encode( $json ) );
|
|
||||||
|
|
||||||
// Dispatch the request.
|
|
||||||
$response = \rest_do_request( $request );
|
|
||||||
$this->assertEquals( 400, $response->get_status() );
|
|
||||||
$this->assertEquals( 'rest_invalid_param', $response->get_data()['code'] );
|
|
||||||
|
|
||||||
// Valid request, because of a valid object.
|
|
||||||
$json['object'] = array(
|
|
||||||
'id' => 'https://remote.example/post/test',
|
|
||||||
'type' => 'Note',
|
|
||||||
'content' => 'Hello, World!',
|
|
||||||
'inReplyTo' => 'https://local.example/post/test',
|
|
||||||
'published' => '2020-01-01T00:00:00Z',
|
|
||||||
);
|
|
||||||
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/users/1/inbox' );
|
|
||||||
$request->set_header( 'Content-Type', 'application/activity+json' );
|
|
||||||
$request->set_body( \wp_json_encode( $json ) );
|
|
||||||
|
|
||||||
// Dispatch the request.
|
|
||||||
$response = \rest_do_request( $request );
|
|
||||||
$this->assertEquals( 202, $response->get_status() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test create request global inbox.
|
|
||||||
*/
|
|
||||||
public function test_create_request_global_inbox() {
|
|
||||||
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
|
||||||
|
|
||||||
// Invalid request, because of an invalid object.
|
|
||||||
$json = array(
|
|
||||||
'id' => 'https://remote.example/@id',
|
|
||||||
'type' => 'Create',
|
|
||||||
'actor' => 'https://remote.example/@test',
|
|
||||||
'object' => 'https://local.example/@test',
|
|
||||||
);
|
|
||||||
|
|
||||||
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/inbox' );
|
|
||||||
$request->set_header( 'Content-Type', 'application/activity+json' );
|
|
||||||
$request->set_body( \wp_json_encode( $json ) );
|
|
||||||
|
|
||||||
// Dispatch the request.
|
|
||||||
$response = \rest_do_request( $request );
|
|
||||||
$this->assertEquals( 400, $response->get_status() );
|
|
||||||
$this->assertEquals( 'rest_invalid_param', $response->get_data()['code'] );
|
|
||||||
|
|
||||||
// Valid request, because of a valid object.
|
|
||||||
$json['object'] = array(
|
|
||||||
'id' => 'https://remote.example/post/test',
|
|
||||||
'type' => 'Note',
|
|
||||||
'content' => 'Hello, World!',
|
|
||||||
'inReplyTo' => 'https://local.example/post/test',
|
|
||||||
'published' => '2020-01-01T00:00:00Z',
|
|
||||||
);
|
|
||||||
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/inbox' );
|
|
||||||
$request->set_header( 'Content-Type', 'application/activity+json' );
|
|
||||||
$request->set_body( \wp_json_encode( $json ) );
|
|
||||||
|
|
||||||
// Dispatch the request.
|
|
||||||
$response = \rest_do_request( $request );
|
|
||||||
$this->assertEquals( 202, $response->get_status() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test update request.
|
|
||||||
*/
|
|
||||||
public function test_update_request() {
|
|
||||||
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
|
||||||
|
|
||||||
$json = array(
|
|
||||||
'id' => 'https://remote.example/@id',
|
|
||||||
'type' => 'Update',
|
|
||||||
'actor' => 'https://remote.example/@test',
|
|
||||||
'object' => array(
|
|
||||||
'id' => 'https://remote.example/post/test',
|
|
||||||
'type' => 'Note',
|
|
||||||
'content' => 'Hello, World!',
|
|
||||||
'inReplyTo' => 'https://local.example/post/test',
|
|
||||||
'published' => '2020-01-01T00:00:00Z',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/users/1/inbox' );
|
|
||||||
$request->set_header( 'Content-Type', 'application/activity+json' );
|
|
||||||
$request->set_body( \wp_json_encode( $json ) );
|
|
||||||
|
|
||||||
// Dispatch the request.
|
|
||||||
$response = \rest_do_request( $request );
|
|
||||||
$this->assertEquals( 202, $response->get_status() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test like request.
|
|
||||||
*/
|
|
||||||
public function test_like_request() {
|
|
||||||
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
|
||||||
|
|
||||||
$json = array(
|
|
||||||
'id' => 'https://remote.example/@id',
|
|
||||||
'type' => 'Like',
|
|
||||||
'actor' => 'https://remote.example/@test',
|
|
||||||
'object' => 'https://local.example/post/test',
|
|
||||||
);
|
|
||||||
|
|
||||||
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/users/1/inbox' );
|
|
||||||
$request->set_header( 'Content-Type', 'application/activity+json' );
|
|
||||||
$request->set_body( \wp_json_encode( $json ) );
|
|
||||||
|
|
||||||
// Dispatch the request.
|
|
||||||
$response = \rest_do_request( $request );
|
|
||||||
$this->assertEquals( 202, $response->get_status() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test announce request.
|
|
||||||
*/
|
|
||||||
public function test_announce_request() {
|
|
||||||
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
|
|
||||||
|
|
||||||
$json = array(
|
|
||||||
'id' => 'https://remote.example/@id',
|
|
||||||
'type' => 'Announce',
|
|
||||||
'actor' => 'https://remote.example/@test',
|
|
||||||
'object' => 'https://local.example/post/test',
|
|
||||||
);
|
|
||||||
|
|
||||||
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/users/1/inbox' );
|
|
||||||
$request->set_header( 'Content-Type', 'application/activity+json' );
|
|
||||||
$request->set_body( \wp_json_encode( $json ) );
|
|
||||||
|
|
||||||
// Dispatch the request.
|
|
||||||
$response = \rest_do_request( $request );
|
|
||||||
$this->assertEquals( 202, $response->get_status() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test whether an activity is public.
|
|
||||||
*
|
|
||||||
* @dataProvider the_data_provider
|
|
||||||
*
|
|
||||||
* @param array $data The data.
|
|
||||||
* @param bool $check The check.
|
|
||||||
*/
|
|
||||||
public function test_is_activity_public( $data, $check ) {
|
|
||||||
$this->assertEquals( $check, Activitypub\is_activity_public( $data ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data provider.
|
|
||||||
*
|
|
||||||
* @return array[]
|
|
||||||
*/
|
|
||||||
public function the_data_provider() {
|
|
||||||
return array(
|
|
||||||
array(
|
|
||||||
array(
|
|
||||||
'cc' => array(
|
|
||||||
'https://example.org/@test',
|
|
||||||
'https://example.com/@test2',
|
|
||||||
),
|
|
||||||
'to' => 'https://www.w3.org/ns/activitystreams#Public',
|
|
||||||
'object' => array(),
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
array(
|
|
||||||
'cc' => array(
|
|
||||||
'https://example.org/@test',
|
|
||||||
'https://example.com/@test2',
|
|
||||||
),
|
|
||||||
'to' => array(
|
|
||||||
'https://www.w3.org/ns/activitystreams#Public',
|
|
||||||
),
|
|
||||||
'object' => array(),
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
array(
|
|
||||||
'cc' => array(
|
|
||||||
'https://example.org/@test',
|
|
||||||
'https://example.com/@test2',
|
|
||||||
),
|
|
||||||
'object' => array(),
|
|
||||||
),
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
array(
|
|
||||||
'cc' => array(
|
|
||||||
'https://example.org/@test',
|
|
||||||
'https://example.com/@test2',
|
|
||||||
),
|
|
||||||
'object' => array(
|
|
||||||
'to' => 'https://www.w3.org/ns/activitystreams#Public',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
array(
|
|
||||||
'cc' => array(
|
|
||||||
'https://example.org/@test',
|
|
||||||
'https://example.com/@test2',
|
|
||||||
),
|
|
||||||
'object' => array(
|
|
||||||
'to' => array(
|
|
||||||
'https://www.w3.org/ns/activitystreams#Public',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue