API improvements + test fixes (#5925)

* migrate PHPUnit configuration

* replace @test annotations with #[Test] attributes, and add it where it was missing

* remove test prefix from test method names

* add PHPUnit cache to .gitignore

* Update ApiV1Controller, fix notifications favourited/reblogged/bookmarked state. Fixes #5901

* Update ApiV1Controller, fix relationship fields. Fixes #5900

* Update instance config, return proper matrix limits. Fixes #4780

* Update SearchApiV2Service, fix offset bug. Fixes #5875

* Update ApiV1Controller, add better direct error message. Fixes #4789

* Update changelog

---------

Co-authored-by: Daniel Simon <daniel.simon.dev@proton.me>
pull/5926/head^2
daniel 2025-04-08 02:18:49 -06:00 zatwierdzone przez GitHub
rodzic 7530acc28d
commit 0158941fb6
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
28 zmienionych plików z 296 dodań i 211 usunięć

2
.gitignore vendored
Wyświetl plik

@ -10,6 +10,8 @@
/.gitconfig
#/.gitignore
/.idea
/.phpunit.cache
/.phpunit.result.cache
/.vagrant
/bootstrap/cache
/docker-compose-state/

Wyświetl plik

@ -10,6 +10,11 @@
- Update Profile.vue, fix pagination ([2ea107805](https://github.com/pixelfed/pixelfed/commit/2ea107805))
- Update ProfileMigrationController, fix race condition by chaining batched jobs ([3001365025](https://github.com/pixelfed/pixelfed/commit/3001365025))
- Update Instance total post, add optional estimation for huge status tables ([5a5821fe8](https://github.com/pixelfed/pixelfed/commit/5a5821fe8))
- Update ApiV1Controller, fix notifications favourited/reblogged/bookmarked state. Fixes #5901 ([8a86808a0](https://github.com/pixelfed/pixelfed/commit/8a86808a0))
- Update ApiV1Controller, fix relationship fields. Fixes #5900 ([245ab3bc4](https://github.com/pixelfed/pixelfed/commit/245ab3bc4))
- Update instance config, return proper matrix limits. Fixes #4780 ([473201908](https://github.com/pixelfed/pixelfed/commit/473201908))
- Update SearchApiV2Service, fix offset bug. Fixes #5875 ([0a98b7ad2](https://github.com/pixelfed/pixelfed/commit/0a98b7ad2))
- Update ApiV1Controller, add better direct error message. Fixes #4789 ([658fe6898](https://github.com/pixelfed/pixelfed/commit/658fe6898))
- ([](https://github.com/pixelfed/pixelfed/commit/))
## [v0.12.5 (2025-03-23)](https://github.com/pixelfed/pixelfed/compare/v0.12.5...dev)

Wyświetl plik

@ -1734,11 +1734,11 @@ class ApiV1Controller extends Controller
'mobile_registration' => (bool) config_cache('pixelfed.open_registration') && config('auth.in_app_registration'),
'configuration' => [
'media_attachments' => [
'image_matrix_limit' => 16777216,
'image_matrix_limit' => 2073600,
'image_size_limit' => config_cache('pixelfed.max_photo_size') * 1024,
'supported_mime_types' => explode(',', config_cache('pixelfed.media_types')),
'video_frame_rate_limit' => 120,
'video_matrix_limit' => 2304000,
'video_matrix_limit' => 2073600,
'video_size_limit' => config_cache('pixelfed.max_photo_size') * 1024,
],
'polls' => [
@ -2441,6 +2441,15 @@ class ApiV1Controller extends Controller
return true;
})
->map(function ($n) use ($pid) {
if (isset($n['status'])) {
$n['status']['favourited'] = (bool) LikeService::liked($pid, $n['status']['id']);
$n['status']['reblogged'] = (bool) ReblogService::get($pid, $n['status']['id']);
$n['status']['bookmarked'] = (bool) BookmarkService::get($pid, $n['status']['id']);
}
return $n;
})
->filter(function ($n) use ($types) {
if (! $types) {
return true;
@ -3516,13 +3525,19 @@ class ApiV1Controller extends Controller
'in_reply_to_id' => 'nullable',
'media_ids' => 'sometimes|array|max:'.(int) config_cache('pixelfed.max_album_length'),
'sensitive' => 'nullable',
'visibility' => 'string|in:private,unlisted,public',
'visibility' => 'string|in:private,unlisted,public,direct',
'spoiler_text' => 'sometimes|max:140',
'place_id' => 'sometimes|integer|min:1|max:128769',
'collection_ids' => 'sometimes|array|max:3',
'comments_disabled' => 'sometimes|boolean',
]);
if ($request->filled('visibility') && $request->input('visibility') === 'direct') {
return $this->json([
'error' => 'Direct visibility is not available.',
], 400);
}
if ($request->hasHeader('idempotency-key')) {
$key = 'pf:api:v1:status:idempotency-key:'.$request->user()->id.':'.hash('sha1', $request->header('idempotency-key'));
$exists = Cache::has($key);

Wyświetl plik

@ -101,10 +101,10 @@ class ApiV2Controller extends Controller
'media_attachments' => [
'supported_mime_types' => explode(',', config_cache('pixelfed.media_types')),
'image_size_limit' => config_cache('pixelfed.max_photo_size') * 1024,
'image_matrix_limit' => 3686400,
'image_matrix_limit' => 2073600,
'video_size_limit' => config_cache('pixelfed.max_photo_size') * 1024,
'video_frame_rate_limit' => 240,
'video_matrix_limit' => 3686400,
'video_frame_rate_limit' => 120,
'video_matrix_limit' => 2073600,
],
'polls' => [
'max_options' => 0,
@ -292,7 +292,7 @@ class ApiV2Controller extends Controller
}
}
$media = new Media();
$media = new Media;
$media->status_id = null;
$media->profile_id = $profile->id;
$media->user_id = $user->id;
@ -326,9 +326,9 @@ class ApiV2Controller extends Controller
$user->save();
Cache::forget($limitKey);
$fractal = new Fractal\Manager();
$fractal->setSerializer(new ArraySerializer());
$resource = new Fractal\Resource\Item($media, new MediaTransformer());
$fractal = new Fractal\Manager;
$fractal->setSerializer(new ArraySerializer);
$resource = new Fractal\Resource\Item($media, new MediaTransformer);
$res = $fractal->createData($resource)->toArray();
$res['preview_url'] = $media->url().'?v='.time();
$res['url'] = null;

Wyświetl plik

@ -2,116 +2,120 @@
namespace App\Services;
use Illuminate\Support\Facades\Cache;
use App\Follower;
use App\FollowRequest;
use App\Profile;
use App\UserFilter;
use Illuminate\Support\Facades\Cache;
class RelationshipService
{
const CACHE_KEY = 'pf:services:urel:';
const CACHE_KEY = 'pf:services:urel:';
public static function get($aid, $tid)
{
$actor = AccountService::get($aid, true);
$target = AccountService::get($tid, true);
if(!$actor || !$target) {
return self::defaultRelation($tid);
}
public static function get($aid, $tid)
{
$actor = AccountService::get($aid, true);
$target = AccountService::get($tid, true);
if (! $actor || ! $target) {
return self::defaultRelation($tid);
}
if($actor['id'] === $target['id']) {
return self::defaultRelation($tid);
}
if ($actor['id'] === $target['id']) {
return self::defaultRelation($tid);
}
return Cache::remember(self::key("a_{$aid}:t_{$tid}"), 1209600, function() use($aid, $tid) {
return [
'id' => (string) $tid,
'following' => Follower::whereProfileId($aid)->whereFollowingId($tid)->exists(),
'followed_by' => Follower::whereProfileId($tid)->whereFollowingId($aid)->exists(),
'blocking' => UserFilter::whereUserId($aid)
->whereFilterableType('App\Profile')
->whereFilterableId($tid)
->whereFilterType('block')
->exists(),
'muting' => UserFilter::whereUserId($aid)
->whereFilterableType('App\Profile')
->whereFilterableId($tid)
->whereFilterType('mute')
->exists(),
'muting_notifications' => null,
'requested' => FollowRequest::whereFollowerId($aid)
->whereFollowingId($tid)
->exists(),
'domain_blocking' => null,
'showing_reblogs' => null,
'endorsed' => false
];
});
}
return Cache::remember(self::key("a_{$aid}:t_{$tid}"), 1209600, function () use ($aid, $tid) {
return [
'id' => (string) $tid,
'following' => Follower::whereProfileId($aid)->whereFollowingId($tid)->exists(),
'followed_by' => Follower::whereProfileId($tid)->whereFollowingId($aid)->exists(),
'blocking' => UserFilter::whereUserId($aid)
->whereFilterableType('App\Profile')
->whereFilterableId($tid)
->whereFilterType('block')
->exists(),
'muting' => UserFilter::whereUserId($aid)
->whereFilterableType('App\Profile')
->whereFilterableId($tid)
->whereFilterType('mute')
->exists(),
'muting_notifications' => false,
'requested' => FollowRequest::whereFollowerId($aid)
->whereFollowingId($tid)
->exists(),
'domain_blocking' => false,
'showing_reblogs' => false,
'endorsed' => false,
];
});
}
public static function delete($aid, $tid)
{
Cache::forget(self::key("wd:a_{$aid}:t_{$tid}"));
return Cache::forget(self::key("a_{$aid}:t_{$tid}"));
}
public static function delete($aid, $tid)
{
Cache::forget(self::key("wd:a_{$aid}:t_{$tid}"));
public static function refresh($aid, $tid)
{
Cache::forget('pf:services:follower:audience:' . $aid);
Cache::forget('pf:services:follower:audience:' . $tid);
self::delete($tid, $aid);
self::delete($aid, $tid);
self::get($tid, $aid);
return self::get($aid, $tid);
}
return Cache::forget(self::key("a_{$aid}:t_{$tid}"));
}
public static function forget($aid, $tid)
{
Cache::forget('pf:services:follower:audience:' . $aid);
Cache::forget('pf:services:follower:audience:' . $tid);
self::delete($tid, $aid);
self::delete($aid, $tid);
}
public static function refresh($aid, $tid)
{
Cache::forget('pf:services:follower:audience:'.$aid);
Cache::forget('pf:services:follower:audience:'.$tid);
self::delete($tid, $aid);
self::delete($aid, $tid);
self::get($tid, $aid);
public static function defaultRelation($tid)
{
return [
return self::get($aid, $tid);
}
public static function forget($aid, $tid)
{
Cache::forget('pf:services:follower:audience:'.$aid);
Cache::forget('pf:services:follower:audience:'.$tid);
self::delete($tid, $aid);
self::delete($aid, $tid);
}
public static function defaultRelation($tid)
{
return [
'id' => (string) $tid,
'following' => false,
'followed_by' => false,
'blocking' => false,
'muting' => false,
'muting_notifications' => null,
'muting_notifications' => false,
'requested' => false,
'domain_blocking' => null,
'showing_reblogs' => null,
'endorsed' => false
'domain_blocking' => false,
'showing_reblogs' => false,
'endorsed' => false,
];
}
}
protected static function key($suffix)
{
return self::CACHE_KEY . $suffix;
}
protected static function key($suffix)
{
return self::CACHE_KEY.$suffix;
}
public static function getWithDate($aid, $tid)
{
$res = self::get($aid, $tid);
public static function getWithDate($aid, $tid)
{
$res = self::get($aid, $tid);
if(!$res || !$res['following']) {
$res['following_since'] = null;
return $res;
}
if (! $res || ! $res['following']) {
$res['following_since'] = null;
return Cache::remember(self::key("wd:a_{$aid}:t_{$tid}"), 1209600, function() use($aid, $tid, $res) {
$tmp = Follower::whereProfileId($aid)->whereFollowingId($tid)->first();
if(!$tmp) {
$res['following_since'] = null;
return $res;
}
$res['following_since'] = str_replace('+00:00', 'Z', $tmp->created_at->format(DATE_RFC3339_EXTENDED));
return $res;
});
}
return $res;
}
return Cache::remember(self::key("wd:a_{$aid}:t_{$tid}"), 1209600, function () use ($aid, $tid, $res) {
$tmp = Follower::whereProfileId($aid)->whereFollowingId($tid)->first();
if (! $tmp) {
$res['following_since'] = null;
return $res;
}
$res['following_since'] = str_replace('+00:00', 'Z', $tmp->created_at->format(DATE_RFC3339_EXTENDED));
return $res;
});
}
}

Wyświetl plik

@ -132,7 +132,6 @@ class SearchApiV2Service
$q = $this->query->input('q');
$limit = $this->query->input('limit') ?? 20;
$offset = $this->query->input('offset') ?? 0;
$query = Str::startsWith($q, '#') ? substr($q, 1) : $q;
$query = $query.'%';
@ -214,6 +213,9 @@ class SearchApiV2Service
$user = request()->user();
$mastodonMode = self::$mastodonMode;
$query = urldecode($this->query->input('q'));
$limit = $this->query->input('limit') ?? 20;
$offset = $this->query->input('offset') ?? 0;
$banned = InstanceService::getBannedDomains();
$domainBlocks = UserFilterService::domainBlocks($user->profile_id);
if ($domainBlocks && count($domainBlocks)) {
@ -252,7 +254,12 @@ class SearchApiV2Service
if (in_array($domain, $banned)) {
return $default;
}
$default['accounts'][] = $res;
$paginated = collect($res)->take($limit)->skip($offset)->toArray();
if (! empty($paginated)) {
$default['accounts'][] = $paginated;
} else {
$default['accounts'] = [];
}
return $default;
} else {
@ -271,7 +278,12 @@ class SearchApiV2Service
if (in_array($domain, $banned)) {
return $default;
}
$default['accounts'][] = $res;
$paginated = collect($res)->take($limit)->skip($offset)->toArray();
if (! empty($paginated)) {
$default['accounts'][] = $paginated;
} else {
$default['accounts'] = [];
}
return $default;
} else {

Wyświetl plik

@ -2,11 +2,10 @@
namespace App\Transformer\Api;
use App\FollowRequest;
use App\Models\UserDomainBlock;
use App\Profile;
use Auth;
use App\{
FollowRequest,
Profile
};
use League\Fractal;
class RelationshipTransformer extends Fractal\TransformerAbstract
@ -14,27 +13,35 @@ class RelationshipTransformer extends Fractal\TransformerAbstract
public function transform(Profile $profile)
{
$auth = Auth::check();
if(!$auth) {
if (! $auth) {
return [];
}
$user = $auth ? Auth::user()->profile : false;
$requested = false;
if($user) {
$domainBlocking = false;
if ($user) {
$requested = FollowRequest::whereFollowerId($user->id)
->whereFollowingId($profile->id)
->exists();
if ($profile->domain) {
$domainBlocking = UserDomainBlock::whereProfileId($user->id)
->whereDomain($profile->domain)
->exists();
}
}
return [
'id' => (string) $profile->id,
'following' => $auth ? $user->follows($profile) : false,
'followed_by' => $auth ? $user->followedBy($profile) : false,
'blocking' => $auth ? $user->blockedIds()->contains($profile->id) : false,
'muting' => $auth ? $user->mutedIds()->contains($profile->id) : false,
'muting_notifications' => null,
'muting_notifications' => false,
'requested' => $requested,
'domain_blocking' => null,
'showing_reblogs' => null,
'endorsed' => false
'domain_blocking' => $domainBlocking,
'showing_reblogs' => false,
'endorsed' => false,
];
}
}

Wyświetl plik

@ -1,20 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage processUncoveredFiles="true">
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
backupGlobals="false"
backupStaticProperties="false"
bootstrap="vendor/autoload.php"
colors="true"
processIsolation="false"
stopOnFailure="false"
cacheDirectory=".phpunit.cache"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.5/phpunit.xsd">
<source>
<include>
<directory suffix=".php">./app</directory>
</include>
</coverage>
</source>
<testsuites>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>

Wyświetl plik

@ -2,11 +2,12 @@
namespace Tests\Feature;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class LoginTest extends TestCase
{
/** @test */
#[Test]
public function view_login_page()
{
$response = $this->get('login');

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit;
use App\Util\ActivityPub\Helpers;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class APAnnounceStrategyTest extends TestCase
@ -26,22 +27,26 @@ class APAnnounceStrategyTest extends TestCase
$this->pleroma = json_decode('{"@context":"https://www.w3.org/ns/activitystreams","actor":"https://pleroma.site/users/pixeldev","cc":["https://www.w3.org/ns/activitystreams#Public"],"context":"tag:mastodon.social,2018-10-14:objectId=59146153:objectType=Conversation","context_id":12325955,"id":"https://pleroma.site/activities/db2273eb-d504-4e3a-8f74-c343d069755a","object":"https://mastodon.social/users/dansup/statuses/100891324792793720","published":"2018-10-14T01:22:18.554227Z","to":["https://pleroma.site/users/pixeldev/followers","https://mastodon.social/users/dansup"],"type":"Announce"}', true);
}
public function testBasicValidation()
#[Test]
public function basicValidation()
{
$this->assertFalse(Helpers::validateObject($this->invalid));
}
public function testMastodonValidation()
#[Test]
public function mastodonValidation()
{
$this->assertTrue(Helpers::validateObject($this->mastodon));
}
public function testPleromaValidation()
#[Test]
public function pleromaValidation()
{
$this->assertTrue(Helpers::validateObject($this->pleroma));
}
public function testMastodonAudienceScope()
#[Test]
public function mastodonAudienceScope()
{
$scope = Helpers::normalizeAudience($this->mastodon, false);
$actual = [
@ -56,7 +61,8 @@ class APAnnounceStrategyTest extends TestCase
$this->assertEquals($scope, $actual);
}
public function testPleromaAudienceScope()
#[Test]
public function pleromaAudienceScope()
{
$scope = Helpers::normalizeAudience($this->pleroma, false);
$actual = [
@ -71,7 +77,8 @@ class APAnnounceStrategyTest extends TestCase
$this->assertEquals($scope, $actual);
}
public function testInvalidAudienceScope()
#[Test]
public function invalidAudienceScope()
{
$scope = Helpers::normalizeAudience($this->invalid, false);
$actual = [

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit\ActivityPub;
use App\Util\ActivityPub\Helpers;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class AudienceScopeTest extends TestCase
@ -28,22 +29,26 @@ class AudienceScopeTest extends TestCase
$this->pleroma = json_decode('{"@context":"https://www.w3.org/ns/activitystreams","actor":"https://pleroma.site/users/pixeldev","cc":["https://www.w3.org/ns/activitystreams#Public"],"context":"tag:mastodon.social,2018-10-14:objectId=59146153:objectType=Conversation","context_id":12325955,"id":"https://pleroma.site/activities/db2273eb-d504-4e3a-8f74-c343d069755a","object":"https://mastodon.social/users/dansup/statuses/100891324792793720","published":"2018-10-14T01:22:18.554227Z","to":["https://pleroma.site/users/pixeldev/followers","https://mastodon.social/users/dansup"],"type":"Announce"}', true);
}
public function testBasicValidation()
#[Test]
public function basicValidation()
{
$this->assertFalse(Helpers::validateObject($this->invalid));
}
public function testMastodonValidation()
#[Test]
public function mastodonValidation()
{
$this->assertTrue(Helpers::validateObject($this->mastodon));
}
public function testPleromaValidation()
#[Test]
public function pleromaValidation()
{
$this->assertTrue(Helpers::validateObject($this->pleroma));
}
public function testMastodonAudienceScope()
#[Test]
public function mastodonAudienceScope()
{
$scope = Helpers::normalizeAudience($this->mastodon, false);
$actual = [
@ -58,7 +63,8 @@ class AudienceScopeTest extends TestCase
$this->assertEquals($scope, $actual);
}
public function testPleromaAudienceScope()
#[Test]
public function pleromaAudienceScope()
{
$scope = Helpers::normalizeAudience($this->pleroma, false);
$actual = [
@ -73,7 +79,8 @@ class AudienceScopeTest extends TestCase
$this->assertEquals($scope, $actual);
}
public function testInvalidAudienceScope()
#[Test]
public function invalidAudienceScope()
{
$scope = Helpers::normalizeAudience($this->invalid, false);
$actual = [

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit\ActivityPub;
use App\Util\ActivityPub\Helpers;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class NoteAttachmentTest extends TestCase
@ -28,25 +29,29 @@ class NoteAttachmentTest extends TestCase
$this->invalidMime = json_decode('{"id":"https://mastodon.social/users/dansup/statuses/100889802384218791/activity","type":"Create","actor":"https://mastodon.social/users/dansup","published":"2018-10-13T18:43:33Z","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://mastodon.social/users/dansup/followers"],"object":{"id":"https://mastodon.social/users/dansup/statuses/100889802384218791","type":"Note","summary":null,"inReplyTo":null,"published":"2018-10-13T18:43:33Z","url":"https://mastodon.social/@dansup/100889802384218791","attributedTo":"https://mastodon.social/users/dansup","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://mastodon.social/users/dansup/followers"],"sensitive":false,"atomUri":"https://mastodon.social/users/dansup/statuses/100889802384218791","inReplyToAtomUri":null,"conversation":"tag:mastodon.social,2018-10-13:objectId=59103420:objectType=Conversation","content":"<p>Good Morning! <a href=\"https://mastodon.social/tags/coffee\" class=\"mention hashtag\" rel=\"tag\">#<span>coffee</span></a></p>","contentMap":{"en":"<p>Good Morning! <a href=\"https://mastodon.social/tags/coffee\" class=\"mention hashtag\" rel=\"tag\">#<span>coffee</span></a></p>"},"attachment":[{"type":"Document","mediaType":"image/webp","url":"https://files.mastodon.social/media_attachments/files/007/110/573/original/96a196885a77c9a4.jpg","name":null}],"tag":[{"type":"Hashtag","href":"https://mastodon.social/tags/coffee","name":"#coffee"}]}}', true, 9);
}
public function testPixelfed()
#[Test]
public function pixelfed()
{
$valid = Helpers::verifyAttachments($this->pixelfed);
$this->assertTrue($valid);
}
public function testMastodon()
#[Test]
public function mastodon()
{
$valid = Helpers::verifyAttachments($this->mastodon);
$this->assertTrue($valid);
}
public function testInvalidAttachmentType()
#[Test]
public function invalidAttachmentType()
{
$valid = Helpers::verifyAttachments($this->invalidType);
$this->assertFalse($valid);
}
public function testInvalidMimeType()
#[Test]
public function invalidMimeType()
{
$valid = Helpers::verifyAttachments($this->invalidMime);
$this->assertFalse($valid);

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit\ActivityPub;
use App\Util\ActivityPub\Helpers;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class RemoteFollowTest extends TestCase
@ -17,7 +18,7 @@ class RemoteFollowTest extends TestCase
}
/** @test */
#[Test]
public function validateMastodonFollowObject()
{
$mastodon = json_decode($this->mastodon, true);

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit\ActivityPub;
use App\Util\ActivityPub\Validator\StoryValidator;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
class StoryValidationTest extends TestCase
@ -16,13 +17,13 @@ class StoryValidationTest extends TestCase
$this->activity = json_decode('{"@context":"https://www.w3.org/ns/activitystreams","id":"https://pixelfed.test/stories/dansup/338581222496276480","type":"Story","to":["https://pixelfed.test/users/dansup/followers"],"cc":[],"attributedTo":"https://pixelfed.test/users/dansup","published":"2021-09-01T07:20:53+00:00","expiresAt":"2021-09-02T07:21:04+00:00","duration":3,"can_reply":true,"can_react":true,"attachment":{"type":"Image","url":"https://pixelfed.test/storage/_esm.t3/xV9/R2LF1xwhAA/011oqKVPDySG3WCPW7yIs2wobvccoITMnG/yT_FZX04f2DCzTA3K8HD2OS7FptXTHPiE1c_ZkHASBQ8UlPKH4.jpg","mediaType":"image/jpeg"}}', true);
}
/** @test */
#[Test]
public function schemaTest()
{
$this->assertTrue(StoryValidator::validate($this->activity));
}
/** @test */
#[Test]
public function invalidContext()
{
$activity = $this->activity;
@ -31,7 +32,7 @@ class StoryValidationTest extends TestCase
$this->assertFalse(StoryValidator::validate($activity));
}
/** @test */
#[Test]
public function missingContext()
{
$activity = $this->activity;
@ -39,7 +40,7 @@ class StoryValidationTest extends TestCase
$this->assertFalse(StoryValidator::validate($activity));
}
/** @test */
#[Test]
public function missingId()
{
$activity = $this->activity;
@ -47,7 +48,7 @@ class StoryValidationTest extends TestCase
$this->assertFalse(StoryValidator::validate($activity));
}
/** @test */
#[Test]
public function missingType()
{
$activity = $this->activity;
@ -55,7 +56,7 @@ class StoryValidationTest extends TestCase
$this->assertFalse(StoryValidator::validate($activity));
}
/** @test */
#[Test]
public function invalidType()
{
$activity = $this->activity;
@ -63,7 +64,7 @@ class StoryValidationTest extends TestCase
$this->assertFalse(StoryValidator::validate($activity));
}
/** @test */
#[Test]
public function missingTo()
{
$activity = $this->activity;
@ -71,7 +72,7 @@ class StoryValidationTest extends TestCase
$this->assertFalse(StoryValidator::validate($activity));
}
/** @test */
#[Test]
public function missingTimestamps()
{
$activity = $this->activity;

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit\ActivityPub;
use App\Util\ActivityPub\Validator\UpdatePersonValidator;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
class UpdatePersonValidationTest extends TestCase
@ -16,13 +17,13 @@ class UpdatePersonValidationTest extends TestCase
$this->activity = json_decode('{"type":"Update","object":{"url":"http://mastodon.example.org/@gargron","type":"Person","summary":"<p>Some bio</p>","publicKey":{"publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0gs3VnQf6am3R+CeBV4H\nlfI1HZTNRIBHgvFszRZkCERbRgEWMu+P+I6/7GJC5H5jhVQ60z4MmXcyHOGmYMK/\n5XyuHQz7V2Ssu1AxLfRN5Biq1ayb0+DT/E7QxNXDJPqSTnstZ6C7zKH/uAETqg3l\nBonjCQWyds+IYbQYxf5Sp3yhvQ80lMwHML3DaNCMlXWLoOnrOX5/yK5+dedesg2\n/HIvGk+HEt36vm6hoH7bwPuEkgA++ACqwjXRe5Mta7i3eilHxFaF8XIrJFARV0t\nqOu4GID/jG6oA+swIWndGrtR2QRJIt9QIBFfK3HG5M0koZbY1eTqwNFRHFL3xaD\nUQIDAQAB\n-----END PUBLIC KEY-----\n","owner":"http://mastodon.example.org/users/gargron","id":"http://mastodon.example.org/users/gargron#main-key"},"preferredUsername":"gargron","outbox":"http://mastodon.example.org/users/gargron/outbox","name":"gargle","manuallyApprovesFollowers":false,"inbox":"http://mastodon.example.org/users/gargron/inbox","id":"http://mastodon.example.org/users/gargron","following":"http://mastodon.example.org/users/gargron/following","followers":"http://mastodon.example.org/users/gargron/followers","endpoints":{"sharedInbox":"http://mastodon.example.org/inbox"},"attachment":[{"type":"PropertyValue","name":"foo","value":"updated"},{"type":"PropertyValue","name":"foo1","value":"updated"}],"icon":{"type":"Image","mediaType":"image/jpeg","url":"https://cd.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"},"image":{"type":"Image","mediaType":"image/png","url":"https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"}},"id":"http://mastodon.example.org/users/gargron#updates/1519563538","actor":"http://mastodon.example.org/users/gargron","@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"toot":"http://joinmastodon.org/ns#","sensitive":"as:sensitive","ostatus":"http://ostatus.org#","movedTo":"as:movedTo","manuallyApprovesFollowers":"as:manuallyApprovesFollowers","inReplyToAtomUri":"ostatus:inReplyToAtomUri","conversation":"ostatus:conversation","atomUri":"ostatus:atomUri","Hashtag":"as:Hashtag","Emoji":"toot:Emoji"}]}', true);
}
/** @test */
#[Test]
public function schemaTest()
{
$this->assertTrue(UpdatePersonValidator::validate($this->activity));
}
/** @test */
#[Test]
public function invalidContext()
{
$activity = $this->activity;
@ -31,7 +32,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function missingContext()
{
$activity = $this->activity;
@ -39,7 +40,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function missingId()
{
$activity = $this->activity;
@ -47,7 +48,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function missingType()
{
$activity = $this->activity;
@ -55,7 +56,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function invalidType()
{
$activity = $this->activity;
@ -63,7 +64,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function invalidObjectType()
{
$activity = $this->activity;
@ -71,7 +72,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function invalidActorMatchingObjectId()
{
$activity = $this->activity;
@ -79,7 +80,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function invalidActorUrlMatchingObjectId()
{
$activity = $this->activity;
@ -87,7 +88,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function missingActorPublicKey()
{
$activity = $this->activity;
@ -95,7 +96,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function invalidActorPublicKey()
{
$activity = $this->activity;
@ -103,7 +104,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function invalidActorPublicKeyId()
{
$activity = $this->activity;
@ -111,7 +112,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function invalidActorPublicKeyIdHost()
{
$activity = $this->activity;
@ -119,7 +120,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function invalidActorAvatar()
{
$activity = $this->activity;
@ -127,7 +128,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function invalidActorAvatarMediaType()
{
$activity = $this->activity;
@ -135,7 +136,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertFalse(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function validActorAvatarMediaTypePng()
{
$activity = $this->activity;
@ -143,7 +144,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertTrue(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function validActorAvatarMediaTypeJpeg()
{
$activity = $this->activity;
@ -151,7 +152,7 @@ class UpdatePersonValidationTest extends TestCase
$this->assertTrue(UpdatePersonValidator::validate($activity));
}
/** @test */
#[Test]
public function validActorAvatarMediaUrl()
{
$activity = $this->activity;

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit\ActivityPub\Verb;
use App\Util\ActivityPub\Validator\Accept;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class AcceptVerbTest extends TestCase
@ -77,19 +78,19 @@ class AcceptVerbTest extends TestCase
];
}
/** @test */
#[Test]
public function basic_accept()
{
$this->assertTrue(Accept::validate($this->validAccept));
}
/** @test */
#[Test]
public function invalid_accept()
{
$this->assertFalse(Accept::validate($this->invalidAccept));
}
/** @test */
#[Test]
public function mastodon_accept()
{
$this->assertTrue(Accept::validate($this->mastodonAccept));

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit\ActivityPub\Verb;
use App\Util\ActivityPub\Validator\Announce;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class AnnounceTest extends TestCase
@ -138,32 +139,32 @@ class AnnounceTest extends TestCase
];
}
/** @test */
#[Test]
public function basic_accept()
{
$this->assertTrue(Announce::validate($this->validAnnounce));
}
/** @test */
#[Test]
public function invalid_accept()
{
$this->assertFalse(Announce::validate($this->invalidAnnounce));
}
/** @test */
#[Test]
public function context_missing()
{
$this->assertFalse(Announce::validate($this->contextMissing));
}
/** @test */
#[Test]
public function invalid_actor()
{
$this->assertFalse(Announce::validate($this->invalidActor));
$this->assertFalse(Announce::validate($this->invalidActor2));
}
/** @test */
#[Test]
public function mastodon_announce()
{
$this->assertTrue(Announce::validate($this->mastodonAnnounce));

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit\ActivityPub\Verb;
use App\Util\ActivityPub\Validator\Follow;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class FollowTest extends TestCase
@ -44,7 +45,7 @@ class FollowTest extends TestCase
];
}
/** @test */
#[Test]
public function basic_follow()
{
$this->assertTrue(Follow::validate($this->basicFollow));

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit\ActivityPub\Verb;
use App\Util\ActivityPub\Validator\Like;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class LikeTest extends TestCase
@ -44,7 +45,7 @@ class LikeTest extends TestCase
];
}
/** @test */
#[Test]
public function basic_like()
{
$this->assertTrue(Like::validate($this->basicLike));

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit\ActivityPub\Verb;
use App\Util\ActivityPub\Validator\UndoFollow;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class UndoFollowTest extends TestCase
@ -28,13 +29,13 @@ class UndoFollowTest extends TestCase
];
}
/** @test */
#[Test]
public function valid_undo_follow()
{
$this->assertTrue(UndoFollow::validate($this->validUndo));
}
/** @test */
#[Test]
public function invalid_undo_follow()
{
$this->assertFalse(UndoFollow::validate($this->invalidUndo));

Wyświetl plik

@ -2,6 +2,7 @@
namespace Tests\Unit;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
class ActivityPubTagObjectTest extends TestCase
@ -9,7 +10,8 @@ class ActivityPubTagObjectTest extends TestCase
/**
* A basic unit test example.
*/
public function test_gotosocial(): void
#[Test]
public function gotosocial(): void
{
$res = [
"tag" => [
@ -33,7 +35,8 @@ class ActivityPubTagObjectTest extends TestCase
$this->assertTrue($tags->count() === 1);
}
public function test_pixelfed_hashtags(): void
#[Test]
public function pixelfed_hashtags(): void
{
$res = [
"tag" => [
@ -94,8 +97,8 @@ class ActivityPubTagObjectTest extends TestCase
$this->assertTrue($tags->count() === 7);
}
public function test_pixelfed_mentions(): void
#[Test]
public function pixelfed_mentions(): void
{
$res = [
"tag" => [

Wyświetl plik

@ -3,11 +3,12 @@
namespace Tests\Unit;
use App\Util\Lexer\Bearcap;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
class BearcapTest extends TestCase
{
/** @test */
#[Test]
public function validTest()
{
$str = 'bear:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&u=https://pixelfed.test/stories/admin/337892163734081536';
@ -19,7 +20,7 @@ class BearcapTest extends TestCase
$this->assertEquals($expected, $actual);
}
/** @test */
#[Test]
public function invalidTokenParameterName()
{
$str = 'bear:?token=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&u=https://pixelfed.test/stories/admin/337892163734081536';
@ -27,7 +28,7 @@ class BearcapTest extends TestCase
$this->assertFalse($actual);
}
/** @test */
#[Test]
public function invalidUrlParameterName()
{
$str = 'bear:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&url=https://pixelfed.test/stories/admin/337892163734081536';
@ -35,7 +36,7 @@ class BearcapTest extends TestCase
$this->assertFalse($actual);
}
/** @test */
#[Test]
public function invalidScheme()
{
$str = 'bearcap:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&url=https://pixelfed.test/stories/admin/337892163734081536';
@ -43,7 +44,7 @@ class BearcapTest extends TestCase
$this->assertFalse($actual);
}
/** @test */
#[Test]
public function missingToken()
{
$str = 'bear:?u=https://pixelfed.test/stories/admin/337892163734081536';
@ -51,7 +52,7 @@ class BearcapTest extends TestCase
$this->assertFalse($actual);
}
/** @test */
#[Test]
public function missingUrl()
{
$str = 'bear:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2';
@ -59,7 +60,7 @@ class BearcapTest extends TestCase
$this->assertFalse($actual);
}
/** @test */
#[Test]
public function invalidHttpUrl()
{
$str = 'bear:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&u=http://pixelfed.test/stories/admin/337892163734081536';
@ -67,7 +68,7 @@ class BearcapTest extends TestCase
$this->assertFalse($actual);
}
/** @test */
#[Test]
public function invalidUrlSchema()
{
$str = 'bear:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&u=phar://pixelfed.test/stories/admin/337892163734081536';

Wyświetl plik

@ -3,6 +3,7 @@
namespace Tests\Unit;
use phpseclib\Crypt\RSA;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class CryptoTest extends TestCase
@ -12,12 +13,14 @@ class CryptoTest extends TestCase
*
* @return void
*/
public function testLibraryInstalled()
#[Test]
public function libraryInstalled()
{
$this->assertTrue(class_exists('\phpseclib\Crypt\RSA'));
}
public function testRSASigning()
#[Test]
public function RSASigning()
{
$rsa = new RSA();
extract($rsa->createKey());

Wyświetl plik

@ -3,11 +3,12 @@
namespace Tests\Unit\Lexer;
use App\Util\Lexer\RestrictedNames;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class RestrictedNameTest extends TestCase
{
/** @test */
#[Test]
public function restrictedUsername()
{
$names = RestrictedNames::get();

Wyświetl plik

@ -5,6 +5,7 @@ namespace Tests\Unit\Lexer;
use App\Status;
use App\Util\Lexer\Autolink;
use App\Util\Lexer\Extractor;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class StatusLexerTest extends TestCase
@ -21,7 +22,8 @@ class StatusLexerTest extends TestCase
$this->autolink = Autolink::create()->autolink($this->status);
}
public function testLexerExtractor()
#[Test]
public function lexerExtractor()
{
$expected = [
'hashtags' => [
@ -56,13 +58,14 @@ class StatusLexerTest extends TestCase
$this->assertEquals($this->entities, $expected);
}
public function testAutolink()
#[Test]
public function autolink()
{
$expected = '<a class="u-url mention" href="https://pixelfed.dev/pixelfed" rel="external nofollow noopener" target="_blank">@pixelfed</a> hi, really like the website! <a href="https://pixelfed.dev/discover/tags/píxelfed?src=hash" title="#píxelfed" class="u-url hashtag" rel="external nofollow noopener">#píxelfed</a>';
$this->assertEquals($this->autolink, $expected);
}
/** @test * */
#[Test]
public function remoteMention()
{
$expected = [
@ -106,7 +109,7 @@ class StatusLexerTest extends TestCase
$this->assertEquals($actual, $expected);
}
/** @test * */
#[Test]
public function mentionLimit()
{
$text = '@test1 @test @test2 @test3 @test4 @test5 @test6 @test7 @test8 @test9 @test10 @test11 @test12 @test13 @test14 @test15 @test16 @test17 @test18 @test19 test post';
@ -116,7 +119,7 @@ class StatusLexerTest extends TestCase
$this->assertEquals(Status::MAX_MENTIONS, $count);
}
/** @test * */
#[Test]
public function hashtagLimit()
{
$text = '#hashtag0 #hashtag1 #hashtag2 #hashtag3 #hashtag4 #hashtag5 #hashtag6 #hashtag7 #hashtag8 #hashtag9 #hashtag10 #hashtag11 #hashtag12 #hashtag13 #hashtag14 #hashtag15 #hashtag16 #hashtag17 #hashtag18 #hashtag19 #hashtag20 #hashtag21 #hashtag22 #hashtag23 #hashtag24 #hashtag25 #hashtag26 #hashtag27 #hashtag28 #hashtag29 #hashtag30 #hashtag31 #hashtag0 #hashtag1 #hashtag2 #hashtag3 #hashtag4 #hashtag5 #hashtag6 #hashtag7 #hashtag8 #hashtag9 #hashtag10 #hashtag11 #hashtag12 #hashtag13 #hashtag14 #hashtag15 #hashtag16 #hashtag17 #hashtag18 #hashtag19 #hashtag20 #hashtag21 #hashtag22 #hashtag23 #hashtag24 #hashtag25 #hashtag26 #hashtag27 #hashtag28 #hashtag29 #hashtag30 #hashtag31';
@ -127,7 +130,7 @@ class StatusLexerTest extends TestCase
}
/** @test * */
#[Test]
public function linkLimit()
{
$text = 'https://example.org https://example.net https://example.com https://example.com https://example.net';

Wyświetl plik

@ -4,11 +4,12 @@ namespace Tests\Unit\Lexer;
use App\Util\Lexer\Autolink;
use App\Util\Lexer\Extractor;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class UsernameTest extends TestCase
{
/** @test * */
#[Test]
public function genericUsername()
{
$username = '@dansup';
@ -38,7 +39,7 @@ class UsernameTest extends TestCase
$this->assertEquals($expectedEntity, $entities);
}
/** @test * */
#[Test]
public function usernameWithPeriod()
{
$username = '@dansup.two';
@ -68,7 +69,7 @@ class UsernameTest extends TestCase
$this->assertEquals($expectedEntity, $entities);
}
/** @test * */
#[Test]
public function usernameWithDash()
{
$username = '@dansup-too';
@ -98,7 +99,7 @@ class UsernameTest extends TestCase
$this->assertEquals($expectedEntity, $entities);
}
/** @test * */
#[Test]
public function usernameWithUnderscore()
{
$username = '@dansup_too';
@ -128,7 +129,7 @@ class UsernameTest extends TestCase
$this->assertEquals($expectedEntity, $entities);
}
/** @test * */
#[Test]
public function multipleMentions()
{
$text = 'hello @dansup and @pixelfed.team from @username_underscore';
@ -175,7 +176,7 @@ class UsernameTest extends TestCase
$this->assertEquals($expectedEntity, $entities);
}
/** @test * */
#[Test]
public function germanUmlatsAutolink()
{
$mentions = "@März and @königin and @Glück";
@ -185,7 +186,7 @@ class UsernameTest extends TestCase
$this->assertEquals($expectedAutolink, $autolink);
}
/** @test * */
#[Test]
public function germanUmlatsExtractor()
{
$mentions = "@März and @königin and @Glück";
@ -229,7 +230,7 @@ class UsernameTest extends TestCase
$this->assertEquals($expectedEntity, $entities);
}
/** @test * */
#[Test]
public function germanUmlatsWebfingerAutolink()
{
$mentions = "hello @märz@example.org!";

Wyświetl plik

@ -2,12 +2,13 @@
namespace Tests\Unit;
use PHPUnit\Framework\Attributes\Test;
use Purify;
use Tests\TestCase;
class PurifierTest extends TestCase
{
/** @test */
#[Test]
public function puckTest()
{
$actual = Purify::clean("<span class=\"fa-spin fa\">catgirl spinning around in the interblag</span>");

Wyświetl plik

@ -3,11 +3,12 @@
namespace Tests\Unit;
use App\Util\Lexer\Nickname;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class WebfingerTest extends TestCase
{
/** @test */
#[Test]
public function webfingerTest()
{
$expected = [