mirror of
https://github.com/flarum/core.git
synced 2025-08-06 08:27:42 +02:00
refactor: JSON:API (#3971)
* refactor: json:api refactor iteration 1 * chore: delete dead code * fix: regressions * chore: move additions/changes to package * feat: AccessTokenResource * feat: allow dependency injection in resources * feat: `ApiResource` extender * feat: improve * feat: refactor tags extension * feat: refactor flags extension * fix: regressions * fix: drop bc layer * feat: refactor suspend extension * feat: refactor subscriptions extension * feat: refactor approval extension * feat: refactor sticky extension * feat: refactor nicknames extension * feat: refactor mentions extension * feat: refactor lock extension * feat: refactor likes extension * chore: merge conflicts * feat: refactor extension-manager extension * feat: context current endpoint helpers * chore: minor * feat: cleaner sortmap implementation * chore: drop old package * chore: not needed (auto scoping) * fix: actor only fields * refactor: simplify index endpoint * feat: eager loading * test: adapt * test: phpstan * test: adapt * fix: typing * fix: approving content * tet: adapt frontend tests * chore: typings * chore: review * fix: breaking change
This commit is contained in:
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Tests\integration\api;
|
||||
|
||||
use Flarum\Api\Controller\AbstractSerializeController;
|
||||
use Flarum\Extend;
|
||||
use Flarum\Testing\integration\TestCase;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
use Tobscure\JsonApi\ElementInterface;
|
||||
use Tobscure\JsonApi\SerializerInterface;
|
||||
|
||||
class AbstractSerializeControllerTest extends TestCase
|
||||
{
|
||||
public function test_missing_serializer_class_throws_exception()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Routes('api'))
|
||||
->get('/dummy-serialize', 'dummy-serialize', DummySerializeController::class)
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/dummy-serialize')
|
||||
);
|
||||
|
||||
$json = json_decode($contents = (string) $response->getBody(), true);
|
||||
|
||||
$this->assertEquals(500, $response->getStatusCode(), $contents);
|
||||
$this->assertStringStartsWith('InvalidArgumentException: Serializer required for controller: '.DummySerializeController::class, $json['errors'][0]['detail']);
|
||||
}
|
||||
}
|
||||
|
||||
class DummySerializeController extends AbstractSerializeController
|
||||
{
|
||||
public ?string $serializer = null;
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): mixed
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function createElement(mixed $data, SerializerInterface $serializer): ElementInterface
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
}
|
@@ -53,6 +53,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => $authenticatedAs,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'access-tokens',
|
||||
'attributes' => [
|
||||
'title' => 'Dev'
|
||||
]
|
||||
@@ -61,7 +62,7 @@ class CreateTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(201, $response->getStatusCode());
|
||||
$this->assertEquals(201, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,6 +76,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => $authenticatedAs,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'access-tokens',
|
||||
'attributes' => [
|
||||
'title' => 'Dev'
|
||||
]
|
||||
@@ -83,7 +85,7 @@ class CreateTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(403, $response->getStatusCode());
|
||||
$this->assertEquals(403, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,10 +96,16 @@ class CreateTest extends TestCase
|
||||
$response = $this->send(
|
||||
$this->request('POST', '/api/access-tokens', [
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'access-tokens',
|
||||
'attributes' => []
|
||||
]
|
||||
]
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(422, $response->getStatusCode());
|
||||
$this->assertEquals(422, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
|
||||
public function canCreateTokens(): array
|
||||
|
@@ -43,6 +43,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'discussions',
|
||||
'attributes' => [
|
||||
'title' => 'Test post',
|
||||
'content' => '',
|
||||
@@ -52,10 +53,11 @@ class CreateTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(422, $response->getStatusCode());
|
||||
$body = (string) $response->getBody();
|
||||
|
||||
$this->assertEquals(422, $response->getStatusCode(), $body);
|
||||
|
||||
// The response body should contain details about the failed validation
|
||||
$body = (string) $response->getBody();
|
||||
$this->assertJson($body);
|
||||
$this->assertEquals([
|
||||
'errors' => [
|
||||
@@ -79,6 +81,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'discussions',
|
||||
'attributes' => [
|
||||
'title' => '',
|
||||
'content' => 'Test post',
|
||||
@@ -115,6 +118,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'discussions',
|
||||
'attributes' => [
|
||||
'title' => 'test - too-obscure',
|
||||
'content' => 'predetermined content for automated testing - too-obscure',
|
||||
@@ -124,11 +128,13 @@ class CreateTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(201, $response->getStatusCode());
|
||||
$body = $response->getBody()->getContents();
|
||||
|
||||
$this->assertEquals(201, $response->getStatusCode(), $body);
|
||||
|
||||
/** @var Discussion $discussion */
|
||||
$discussion = Discussion::firstOrFail();
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
$data = json_decode($body, true);
|
||||
|
||||
$this->assertEquals('test - too-obscure', $discussion->title);
|
||||
$this->assertEquals('test - too-obscure', Arr::get($data, 'data.attributes.title'));
|
||||
@@ -147,6 +153,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'discussions',
|
||||
'attributes' => [
|
||||
'title' => '我是一个土豆',
|
||||
'content' => 'predetermined content for automated testing',
|
||||
@@ -179,6 +186,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'discussions',
|
||||
'attributes' => [
|
||||
'title' => '我是一个土豆',
|
||||
'content' => 'predetermined content for automated testing',
|
||||
@@ -206,6 +214,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'discussions',
|
||||
'attributes' => [
|
||||
'title' => 'test - too-obscure',
|
||||
'content' => 'predetermined content for automated testing - too-obscure',
|
||||
@@ -220,6 +229,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'discussions',
|
||||
'attributes' => [
|
||||
'title' => 'test - too-obscure',
|
||||
'content' => 'Second predetermined content for automated testing - too-obscure',
|
||||
@@ -242,6 +252,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'discussions',
|
||||
'attributes' => [
|
||||
'title' => 'test - too-obscure',
|
||||
'content' => 'predetermined content for automated testing - too-obscure',
|
||||
@@ -256,6 +267,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'discussions',
|
||||
'attributes' => [
|
||||
'title' => 'test - too-obscure',
|
||||
'content' => 'Second predetermined content for automated testing - too-obscure',
|
||||
|
@@ -56,7 +56,7 @@ class ShowTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertEquals(200, $response->getStatusCode(), $response->getBody()->getContents());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +74,7 @@ class ShowTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertEquals(200, $response->getStatusCode(), $response->getBody()->getContents());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,7 +116,7 @@ class ShowTest extends TestCase
|
||||
|
||||
$json = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertEquals(2, Arr::get($json, 'data.relationships.posts.data.0.id'));
|
||||
$this->assertEquals(2, Arr::get($json, 'data.relationships.posts.data.0.id'), $response->getBody()->getContents());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +128,7 @@ class ShowTest extends TestCase
|
||||
$this->request('GET', '/api/discussions/2')
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertEquals(200, $response->getStatusCode(), $response->getBody()->getContents());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -45,7 +45,8 @@ class ShowTest extends TestCase
|
||||
|
||||
$json = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayNotHasKey('actor', Arr::get($json, 'data.relationships'));
|
||||
$this->assertArrayHasKey('actor', Arr::get($json, 'data.relationships'));
|
||||
$this->assertNull(Arr::get($json, 'data.relationships.actor.data'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -45,7 +45,7 @@ class CreateTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(422, $response->getStatusCode());
|
||||
$this->assertEquals(400, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,6 +58,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'groups',
|
||||
'attributes' => [
|
||||
'nameSingular' => 'flarumite',
|
||||
'namePlural' => 'flarumites',
|
||||
@@ -69,10 +70,12 @@ class CreateTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(201, $response->getStatusCode());
|
||||
$body = $response->getBody()->getContents();
|
||||
|
||||
$this->assertEquals(201, $response->getStatusCode(), $body);
|
||||
|
||||
// Verify API response body
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
$data = json_decode($body, true);
|
||||
$this->assertEquals('flarumite', Arr::get($data, 'data.attributes.nameSingular'));
|
||||
$this->assertEquals('flarumites', Arr::get($data, 'data.attributes.namePlural'));
|
||||
$this->assertEquals('test', Arr::get($data, 'data.attributes.icon'));
|
||||
@@ -96,6 +99,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'groups',
|
||||
'attributes' => [
|
||||
'nameSingular' => 'flarumite',
|
||||
'namePlural' => 'flarumites',
|
||||
|
@@ -76,7 +76,7 @@ class ShowTest extends TestCase
|
||||
);
|
||||
|
||||
// Hidden group should not be returned for guest
|
||||
$this->assertEquals(404, $response->getStatusCode());
|
||||
$this->assertEquals(404, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,7 +110,7 @@ class ShowTest extends TestCase
|
||||
|
||||
// If group does not exist in database, controller
|
||||
// should reject the request with 404 Not found
|
||||
$this->assertEquals(404, $response->getStatusCode());
|
||||
$this->assertEquals(404, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
|
||||
protected function hiddenGroup(): array
|
||||
|
@@ -54,6 +54,6 @@ class ListTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertEquals(200, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Tests\integration\api\notifications;
|
||||
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Notification\Notification;
|
||||
use Flarum\Post\Post;
|
||||
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
|
||||
use Flarum\Testing\integration\TestCase;
|
||||
use Flarum\User\User;
|
||||
|
||||
class UpdateTest extends TestCase
|
||||
{
|
||||
use RetrievesAuthorizedUsers;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->prepareDatabase([
|
||||
User::class => [
|
||||
$this->normalUser(),
|
||||
],
|
||||
Discussion::class => [
|
||||
['id' => 1, 'title' => 'Foo', 'comment_count' => 1, 'user_id' => 2],
|
||||
],
|
||||
Post::class => [
|
||||
['id' => 1, 'discussion_id' => 1, 'user_id' => 2, 'type' => 'comment', 'content' => 'Foo'],
|
||||
],
|
||||
Notification::class => [
|
||||
['id' => 1, 'user_id' => 2, 'from_user_id' => 1, 'type' => 'discussionRenamed', 'subject_id' => 1, 'read_at' => null],
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function can_mark_all_as_read()
|
||||
{
|
||||
$response = $this->send(
|
||||
$this->request('PATCH', '/api/notifications/1', [
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'notifications',
|
||||
'attributes' => [
|
||||
'isRead' => true
|
||||
],
|
||||
],
|
||||
],
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
}
|
@@ -71,18 +71,21 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => $actorId,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'posts',
|
||||
'attributes' => [
|
||||
'content' => 'reply with predetermined content for automated testing - too-obscure',
|
||||
],
|
||||
'relationships' => [
|
||||
'discussion' => ['data' => ['id' => $discussionId]],
|
||||
'discussion' => [
|
||||
'data' => ['type' => 'discussions', 'id' => $discussionId]
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals($responseStatus, $response->getStatusCode());
|
||||
$this->assertEquals($responseStatus, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
|
||||
public function discussionRepliesPrvider(): array
|
||||
@@ -106,6 +109,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'posts',
|
||||
'attributes' => [
|
||||
'content' => 'reply with predetermined content for automated testing - too-obscure',
|
||||
],
|
||||
@@ -122,6 +126,7 @@ class CreateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'posts',
|
||||
'attributes' => [
|
||||
'content' => 'Second reply with predetermined content for automated testing - too-obscure',
|
||||
],
|
||||
@@ -133,6 +138,6 @@ class CreateTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(429, $response->getStatusCode());
|
||||
$this->assertEquals(429, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
}
|
||||
|
@@ -74,8 +74,10 @@ class ListTest extends TestCase
|
||||
$this->request('GET', '/api/posts', ['authenticatedAs' => 1])
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
$body = $response->getBody()->getContents();
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode(), $body);
|
||||
$data = json_decode($body, true);
|
||||
|
||||
$this->assertEquals(5, count($data['data']));
|
||||
}
|
||||
|
@@ -39,15 +39,19 @@ class CreateTest extends TestCase
|
||||
'POST',
|
||||
'/api/users',
|
||||
[
|
||||
'json' => ['data' => ['attributes' => []]],
|
||||
'json' => ['data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [],
|
||||
]],
|
||||
]
|
||||
)->withAttribute('bypassCsrfToken', true)
|
||||
);
|
||||
|
||||
$this->assertEquals(422, $response->getStatusCode());
|
||||
$body = (string) $response->getBody();
|
||||
|
||||
$this->assertEquals(422, $response->getStatusCode(), $body);
|
||||
|
||||
// The response body should contain details about the failed validation
|
||||
$body = (string) $response->getBody();
|
||||
$this->assertJson($body);
|
||||
$this->assertEquals([
|
||||
'errors' => [
|
||||
@@ -96,7 +100,7 @@ class CreateTest extends TestCase
|
||||
)->withAttribute('bypassCsrfToken', true)
|
||||
);
|
||||
|
||||
$this->assertEquals(201, $response->getStatusCode());
|
||||
$this->assertEquals(201, $response->getStatusCode(), (string) $response->getBody());
|
||||
|
||||
/** @var User $user */
|
||||
$user = User::where('username', 'test')->firstOrFail();
|
||||
@@ -227,12 +231,12 @@ class CreateTest extends TestCase
|
||||
$this->assertJson($body);
|
||||
$decodedBody = json_decode($body, true);
|
||||
|
||||
$this->assertEquals(500, $response->getStatusCode());
|
||||
$this->assertEquals(422, $response->getStatusCode(), $body);
|
||||
|
||||
$firstError = $decodedBody['errors'][0];
|
||||
|
||||
// Check that the error is an invalid URI
|
||||
$this->assertStringStartsWith('InvalidArgumentException: Provided avatar URL must have scheme http or https. Scheme provided was '.$regToken['scheme'].'.', $firstError['detail']);
|
||||
$this->assertStringContainsString('Provided avatar URL must have scheme http or https. Scheme provided was '.$regToken['scheme'].'.', $firstError['detail']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,12 +305,12 @@ class CreateTest extends TestCase
|
||||
$this->assertJson($body);
|
||||
$decodedBody = json_decode($body, true);
|
||||
|
||||
$this->assertEquals(500, $response->getStatusCode());
|
||||
$this->assertEquals(422, $response->getStatusCode(), $body);
|
||||
|
||||
$firstError = $decodedBody['errors'][0];
|
||||
|
||||
// Check that the error is an invalid URI
|
||||
$this->assertStringStartsWith('InvalidArgumentException: Provided avatar URL must be a valid URI.', $firstError['detail']);
|
||||
$this->assertStringContainsString('Provided avatar URL must be a valid URI.', $firstError['detail']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +378,7 @@ class CreateTest extends TestCase
|
||||
)->withAttribute('bypassCsrfToken', true)
|
||||
);
|
||||
|
||||
$this->assertEquals(201, $response->getStatusCode());
|
||||
$this->assertEquals(201, $response->getStatusCode(), (string) $response->getBody());
|
||||
|
||||
$user = User::where('username', $regToken->user_attributes['username'])->firstOrFail();
|
||||
|
||||
|
@@ -86,7 +86,7 @@ class GroupSearchTest extends TestCase
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
|
||||
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
|
||||
$this->assertCount(0, $responseBodyContents['included'], json_encode($responseBodyContents));
|
||||
|
||||
$response = $this->createRequest(['admins'], 2);
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
@@ -99,7 +99,7 @@ class GroupSearchTest extends TestCase
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
|
||||
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
|
||||
$this->assertCount(0, $responseBodyContents['included'], json_encode($responseBodyContents));
|
||||
|
||||
$response = $this->createRequest(['1'], 2);
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
@@ -112,7 +112,7 @@ class GroupSearchTest extends TestCase
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
|
||||
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
|
||||
$this->assertCount(0, $responseBodyContents['included'], json_encode($responseBodyContents));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,7 +131,7 @@ class GroupSearchTest extends TestCase
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
|
||||
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
|
||||
$this->assertCount(0, $responseBodyContents['included'], json_encode($responseBodyContents));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,10 +149,8 @@ class GroupSearchTest extends TestCase
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
$this->assertCount(4, $responseBodyContents['data'], json_encode($responseBodyContents));
|
||||
$this->assertCount(4, $responseBodyContents['included'], json_encode($responseBodyContents));
|
||||
$this->assertEquals(1, $responseBodyContents['included'][0]['id']);
|
||||
$this->assertEquals(4, $responseBodyContents['included'][1]['id']);
|
||||
$this->assertEquals(5, $responseBodyContents['included'][2]['id']);
|
||||
$this->assertEquals(6, $responseBodyContents['included'][3]['id']);
|
||||
|
||||
$this->assertEqualsCanonicalizing([1, 4, 5, 6], array_column($responseBodyContents['included'], 'id'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,7 +169,7 @@ class GroupSearchTest extends TestCase
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
|
||||
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
|
||||
$this->assertCount(0, $responseBodyContents['included'], json_encode($responseBodyContents));
|
||||
|
||||
$response = $this->createRequest(['admins'], 1);
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
@@ -184,7 +182,7 @@ class GroupSearchTest extends TestCase
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
|
||||
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
|
||||
$this->assertCount(0, $responseBodyContents['included'], json_encode($responseBodyContents));
|
||||
|
||||
$response = $this->createRequest(['1'], 1);
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
@@ -197,7 +195,7 @@ class GroupSearchTest extends TestCase
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
|
||||
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
|
||||
$this->assertCount(0, $responseBodyContents['included'], json_encode($responseBodyContents));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,11 +223,8 @@ class GroupSearchTest extends TestCase
|
||||
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
|
||||
$this->assertCount(5, $responseBodyContents['data'], json_encode($responseBodyContents));
|
||||
$this->assertCount(5, $responseBodyContents['included'], json_encode($responseBodyContents));
|
||||
$this->assertEquals(1, $responseBodyContents['included'][0]['id']);
|
||||
$this->assertEquals(99, $responseBodyContents['included'][1]['id']);
|
||||
$this->assertEquals(4, $responseBodyContents['included'][2]['id']);
|
||||
$this->assertEquals(5, $responseBodyContents['included'][3]['id']);
|
||||
$this->assertEquals(6, $responseBodyContents['included'][4]['id']);
|
||||
|
||||
$this->assertEqualsCanonicalizing([1, 99, 4, 5, 6], array_column($responseBodyContents['included'], 'id'));
|
||||
}
|
||||
|
||||
private function createRequest(array $group, int $userId = null)
|
||||
|
@@ -102,6 +102,7 @@ class PasswordEmailTokensTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'email' => 'new-normal@machine.local'
|
||||
]
|
||||
@@ -113,7 +114,7 @@ class PasswordEmailTokensTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertEquals(200, $response->getStatusCode(), $response->getBody());
|
||||
$this->assertEquals(1, EmailToken::query()->where('user_id', 2)->count());
|
||||
}
|
||||
|
||||
|
@@ -45,7 +45,7 @@ class SendActivationEmailTest extends TestCase
|
||||
);
|
||||
|
||||
// We don't want to delay tests too long.
|
||||
EmailActivationThrottler::$timeout = 5;
|
||||
EmailActivationThrottler::$timeout = 1;
|
||||
sleep(EmailActivationThrottler::$timeout + 1);
|
||||
}
|
||||
|
||||
|
@@ -48,7 +48,7 @@ class SendPasswordResetEmailTest extends TestCase
|
||||
);
|
||||
|
||||
// We don't want to delay tests too long.
|
||||
PasswordResetThrottler::$timeout = 5;
|
||||
PasswordResetThrottler::$timeout = 1;
|
||||
sleep(PasswordResetThrottler::$timeout + 1);
|
||||
}
|
||||
|
||||
|
@@ -68,13 +68,15 @@ class UpdateTest extends TestCase
|
||||
$response = $this->send(
|
||||
$this->request('PATCH', '/api/users/2', [
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [],
|
||||
'json' => [
|
||||
'data' => []
|
||||
],
|
||||
])
|
||||
);
|
||||
|
||||
// Test for successful response and that the email is included in the response
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertStringContainsString('normal@machine.local', (string) $response->getBody());
|
||||
$this->assertEquals(200, $response->getStatusCode(), $body = (string) $response->getBody());
|
||||
$this->assertStringContainsString('normal@machine.local', $body);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,13 +87,15 @@ class UpdateTest extends TestCase
|
||||
$response = $this->send(
|
||||
$this->request('PATCH', '/api/users/1', [
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [],
|
||||
'json' => [
|
||||
'data' => []
|
||||
],
|
||||
])
|
||||
);
|
||||
|
||||
// Make sure sensitive information is not made public
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertStringNotContainsString('admin@machine.local', (string) $response->getBody());
|
||||
$this->assertEquals(200, $response->getStatusCode(), $body = (string) $response->getBody());
|
||||
$this->assertStringNotContainsString('admin@machine.local', $body);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,7 +111,7 @@ class UpdateTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertEquals(200, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,6 +124,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'email' => 'someOtherEmail@example.com',
|
||||
]
|
||||
@@ -131,7 +136,7 @@ class UpdateTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(401, $response->getStatusCode());
|
||||
$this->assertEquals(401, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,6 +149,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'email' => 'someOtherEmail@example.com',
|
||||
]
|
||||
@@ -180,7 +186,7 @@ class UpdateTest extends TestCase
|
||||
);
|
||||
|
||||
// We don't want to delay tests too long.
|
||||
EmailChangeThrottler::$timeout = 5;
|
||||
EmailChangeThrottler::$timeout = 1;
|
||||
sleep(EmailChangeThrottler::$timeout + 1);
|
||||
}
|
||||
|
||||
@@ -223,6 +229,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'username' => 'iCantChangeThis',
|
||||
],
|
||||
@@ -243,6 +250,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'preferences' => [
|
||||
'something' => 'else'
|
||||
@@ -268,7 +276,7 @@ class UpdateTest extends TestCase
|
||||
'relationships' => [
|
||||
'groups' => [
|
||||
'data' => [
|
||||
['id' => 1, 'type' => 'group']
|
||||
['id' => 1, 'type' => 'groups']
|
||||
]
|
||||
]
|
||||
],
|
||||
@@ -289,6 +297,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'markedAllAsReadAt' => Carbon::now()
|
||||
],
|
||||
@@ -309,6 +318,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'isEmailConfirmed' => true
|
||||
],
|
||||
@@ -345,6 +355,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 3,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'email' => 'someOtherEmail@example.com',
|
||||
]
|
||||
@@ -368,6 +379,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 3,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'username' => 'iCantChangeThis',
|
||||
],
|
||||
@@ -391,7 +403,7 @@ class UpdateTest extends TestCase
|
||||
'relationships' => [
|
||||
'groups' => [
|
||||
'data' => [
|
||||
['id' => 1, 'type' => 'group']
|
||||
['id' => 1, 'type' => 'groups']
|
||||
]
|
||||
]
|
||||
],
|
||||
@@ -412,6 +424,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'isEmailConfirmed' => true
|
||||
],
|
||||
@@ -450,6 +463,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 3,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'email' => 'someOtherEmail@example.com',
|
||||
]
|
||||
@@ -471,6 +485,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 3,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'username' => 'iCanChangeThis',
|
||||
],
|
||||
@@ -492,6 +507,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 3,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'email' => 'someOtherEmail@example.com',
|
||||
]
|
||||
@@ -513,6 +529,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 3,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'username' => 'iCanChangeThis',
|
||||
],
|
||||
@@ -537,7 +554,7 @@ class UpdateTest extends TestCase
|
||||
'relationships' => [
|
||||
'groups' => [
|
||||
'data' => [
|
||||
['id' => 4, 'type' => 'group']
|
||||
['id' => 4, 'type' => 'groups']
|
||||
]
|
||||
]
|
||||
],
|
||||
@@ -545,7 +562,7 @@ class UpdateTest extends TestCase
|
||||
],
|
||||
])
|
||||
);
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertEquals(200, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -585,7 +602,7 @@ class UpdateTest extends TestCase
|
||||
'relationships' => [
|
||||
'groups' => [
|
||||
'data' => [
|
||||
['id' => 1, 'type' => 'group']
|
||||
['id' => 1, 'type' => 'groups']
|
||||
]
|
||||
]
|
||||
],
|
||||
@@ -610,7 +627,7 @@ class UpdateTest extends TestCase
|
||||
'relationships' => [
|
||||
'groups' => [
|
||||
'data' => [
|
||||
['id' => 1, 'type' => 'group']
|
||||
['id' => 1, 'type' => 'groups']
|
||||
]
|
||||
]
|
||||
],
|
||||
@@ -632,6 +649,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 2,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'isEmailConfirmed' => true
|
||||
],
|
||||
@@ -652,6 +670,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'preferences' => [
|
||||
'something' => 'else'
|
||||
@@ -674,6 +693,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'markedAllAsReadAt' => Carbon::now()
|
||||
],
|
||||
@@ -694,6 +714,7 @@ class UpdateTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => 'users',
|
||||
'attributes' => [
|
||||
'isEmailConfirmed' => true
|
||||
],
|
||||
@@ -724,7 +745,7 @@ class UpdateTest extends TestCase
|
||||
],
|
||||
])
|
||||
);
|
||||
$this->assertEquals(403, $response->getStatusCode());
|
||||
$this->assertEquals(403, $response->getStatusCode(), (string) $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -10,24 +10,23 @@
|
||||
namespace Flarum\Tests\integration\extenders;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Flarum\Api\Controller\AbstractShowController;
|
||||
use Flarum\Api\Controller\ListDiscussionsController;
|
||||
use Flarum\Api\Controller\ListUsersController;
|
||||
use Flarum\Api\Controller\ShowDiscussionController;
|
||||
use Flarum\Api\Controller\ShowForumController;
|
||||
use Flarum\Api\Controller\ShowPostController;
|
||||
use Flarum\Api\Controller\ShowUserController;
|
||||
use Flarum\Api\Serializer\DiscussionSerializer;
|
||||
use Flarum\Api\Serializer\ForumSerializer;
|
||||
use Flarum\Api\Serializer\PostSerializer;
|
||||
use Flarum\Api\Serializer\UserSerializer;
|
||||
use Flarum\Api\Context;
|
||||
use Flarum\Api\Endpoint\Index;
|
||||
use Flarum\Api\Endpoint\Show;
|
||||
use Flarum\Api\Resource\AbstractDatabaseResource;
|
||||
use Flarum\Api\Resource\DiscussionResource;
|
||||
use Flarum\Api\Resource\UserResource;
|
||||
use Flarum\Api\Schema\Relationship\ToMany;
|
||||
use Flarum\Api\Sort\SortColumn;
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Extend;
|
||||
use Flarum\Foundation\ValidationException;
|
||||
use Flarum\Post\Post;
|
||||
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
|
||||
use Flarum\Testing\integration\TestCase;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Support\Arr;
|
||||
use Tobyz\JsonApiServer\Schema\Field\Field;
|
||||
|
||||
class ApiControllerTest extends TestCase
|
||||
{
|
||||
@@ -52,6 +51,7 @@ class ApiControllerTest extends TestCase
|
||||
Post::class => [
|
||||
['id' => 1, 'discussion_id' => 3, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'type' => 'discussionRenamed', 'content' => '<t><p>can i haz relationz?</p></t>'],
|
||||
['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'type' => 'discussionRenamed', 'content' => '<t><p>can i haz relationz?</p></t>'],
|
||||
['id' => 3, 'discussion_id' => 1, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'type' => 'discussionRenamed', 'content' => '<t><p>can i haz relationz?</p></t>'],
|
||||
['id' => 3, 'discussion_id' => 1, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'discussionRenamed', 'content' => '<t><p>can i haz relationz?</p></t>'],
|
||||
],
|
||||
]);
|
||||
@@ -60,12 +60,16 @@ class ApiControllerTest extends TestCase
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function prepare_data_serialization_callback_works_if_added()
|
||||
public function after_endpoint_callback_works_if_added()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ShowDiscussionController::class))
|
||||
->prepareDataForSerialization(function ($controller, Discussion $discussion) {
|
||||
$discussion->title = 'dataSerializationPrepCustomTitle';
|
||||
(new Extend\ApiResource(DiscussionResource::class))
|
||||
->endpoint(Show::class, function (Show $endpoint): Show {
|
||||
return $endpoint->after(function ($context, Discussion $discussion) {
|
||||
$discussion->title = 'dataSerializationPrepCustomTitle';
|
||||
|
||||
return $discussion;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -75,19 +79,21 @@ class ApiControllerTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
$payload = json_decode($body = $response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertEquals('dataSerializationPrepCustomTitle', $payload['data']['attributes']['title']);
|
||||
$this->assertEquals('dataSerializationPrepCustomTitle', $payload['data']['attributes']['title'], $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function prepare_data_serialization_callback_works_with_invokable_classes()
|
||||
public function after_endpoint_callback_works_with_invokable_classes()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ShowDiscussionController::class))
|
||||
->prepareDataForSerialization(CustomPrepareDataSerializationInvokableClass::class)
|
||||
(new Extend\ApiResource(DiscussionResource::class))
|
||||
->endpoint(Show::class, function (Show $endpoint): Show {
|
||||
return $endpoint->after(CustomAfterEndpointInvokableClass::class);
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -96,72 +102,26 @@ class ApiControllerTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
$payload = json_decode($body = $response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertEquals(CustomPrepareDataSerializationInvokableClass::class, $payload['data']['attributes']['title']);
|
||||
$this->assertEquals(CustomAfterEndpointInvokableClass::class, $payload['data']['attributes']['title'], $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function prepare_data_serialization_allows_passing_args_by_reference_with_closures()
|
||||
public function after_endpoint_callback_works_if_added_to_parent_class()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->hasMany('referenceTest', UserSerializer::class),
|
||||
(new Extend\ApiController(ShowForumController::class))
|
||||
->addInclude('referenceTest')
|
||||
->prepareDataForSerialization(function ($controller, &$data) {
|
||||
$data['referenceTest'] = User::limit(2)->get();
|
||||
})
|
||||
);
|
||||
(new Extend\ApiResource(AbstractDatabaseResource::class))
|
||||
->endpoint(Show::class, function (Show $endpoint): Show {
|
||||
return $endpoint->after(function (Context $context, object $model) {
|
||||
if ($context->collection instanceof DiscussionResource) {
|
||||
$model->title = 'dataSerializationPrepCustomTitle2';
|
||||
}
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('referenceTest', $payload['data']['relationships']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function prepare_data_serialization_allows_passing_args_by_reference_with_invokable_classes()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->hasMany('referenceTest2', UserSerializer::class),
|
||||
(new Extend\ApiController(ShowForumController::class))
|
||||
->addInclude('referenceTest2')
|
||||
->prepareDataForSerialization(CustomInvokableClassArgsReference::class)
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('referenceTest2', $payload['data']['relationships']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function prepare_data_serialization_callback_works_if_added_to_parent_class()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(AbstractShowController::class))
|
||||
->prepareDataForSerialization(function ($controller, Discussion $discussion) {
|
||||
if ($controller instanceof ShowDiscussionController) {
|
||||
$discussion->title = 'dataSerializationPrepCustomTitle2';
|
||||
}
|
||||
return $model;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -179,18 +139,26 @@ class ApiControllerTest extends TestCase
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function prepare_data_serialization_callback_prioritizes_child_classes()
|
||||
public function after_endpoint_callback_prioritizes_child_classes()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(AbstractShowController::class))
|
||||
->prepareDataForSerialization(function ($controller, Discussion $discussion) {
|
||||
if ($controller instanceof ShowDiscussionController) {
|
||||
$discussion->title = 'dataSerializationPrepCustomTitle3';
|
||||
}
|
||||
(new Extend\ApiResource(DiscussionResource::class))
|
||||
->endpoint(Show::class, function (Show $endpoint): Show {
|
||||
return $endpoint->after(function (Context $context, object $model) {
|
||||
$model->title = 'dataSerializationPrepCustomTitle4';
|
||||
|
||||
return $model;
|
||||
});
|
||||
}),
|
||||
(new Extend\ApiController(ShowDiscussionController::class))
|
||||
->prepareDataForSerialization(function ($controller, Discussion $discussion) {
|
||||
$discussion->title = 'dataSerializationPrepCustomTitle4';
|
||||
(new Extend\ApiResource(AbstractDatabaseResource::class))
|
||||
->endpoint(Show::class, function (Show $endpoint): Show {
|
||||
return $endpoint->after(function (Context $context, object $model) {
|
||||
if ($context->collection instanceof DiscussionResource) {
|
||||
$model->title = 'dataSerializationPrepCustomTitle3';
|
||||
}
|
||||
|
||||
return $model;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -200,22 +168,22 @@ class ApiControllerTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
$payload = json_decode($body = $response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertEquals('dataSerializationPrepCustomTitle4', $payload['data']['attributes']['title']);
|
||||
$this->assertEquals('dataSerializationPrepCustomTitle4', $payload['data']['attributes']['title'], $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function prepare_data_query_callback_works_if_added_to_parent_class()
|
||||
public function before_endpoint_callback_works_if_added_to_parent_class()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(AbstractShowController::class))
|
||||
->prepareDataQuery(function ($controller) {
|
||||
if ($controller instanceof ShowDiscussionController) {
|
||||
$controller->setSerializer(CustomDiscussionSerializer2::class);
|
||||
}
|
||||
(new Extend\ApiResource(AbstractDatabaseResource::class))
|
||||
->endpoint(Show::class, function (Show $endpoint): Show {
|
||||
return $endpoint->before(function () {
|
||||
throw new ValidationException(['field' => 'error on purpose']);
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -225,26 +193,29 @@ class ApiControllerTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
$body = $response->getBody()->getContents();
|
||||
|
||||
$this->assertArrayHasKey('customSerializer2', $payload['data']['attributes']);
|
||||
$this->assertEquals(422, $response->getStatusCode(), $body);
|
||||
$this->assertStringContainsString('error on purpose', $body, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function prepare_data_query_callback_prioritizes_child_classes()
|
||||
public function before_endpoint_callback_prioritizes_child_classes()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(AbstractShowController::class))
|
||||
->prepareDataForSerialization(function ($controller) {
|
||||
if ($controller instanceof ShowDiscussionController) {
|
||||
$controller->setSerializer(CustomDiscussionSerializer2::class);
|
||||
}
|
||||
(new Extend\ApiResource(DiscussionResource::class))
|
||||
->endpoint(Show::class, function (Show $endpoint): Show {
|
||||
return $endpoint->before(function () {
|
||||
throw new ValidationException(['field' => 'error on purpose from exact resource']);
|
||||
});
|
||||
}),
|
||||
(new Extend\ApiController(ShowDiscussionController::class))
|
||||
->prepareDataForSerialization(function ($controller) {
|
||||
$controller->setSerializer(CustomDiscussionSerializer::class);
|
||||
(new Extend\ApiResource(AbstractDatabaseResource::class))
|
||||
->endpoint(Show::class, function (Show $endpoint): Show {
|
||||
return $endpoint->before(function () {
|
||||
throw new ValidationException(['field' => 'error on purpose from abstract resource']);
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -254,95 +225,10 @@ class ApiControllerTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
$body = $response->getBody()->getContents();
|
||||
|
||||
$this->assertArrayHasKey('customSerializer', $payload['data']['attributes']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_serializer_doesnt_work_by_default()
|
||||
{
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/discussions/1', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayNotHasKey('customSerializer', $payload['data']['attributes']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_serializer_works_if_set()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ShowDiscussionController::class))
|
||||
->setSerializer(CustomDiscussionSerializer::class)
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/discussions/1', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('customSerializer', $payload['data']['attributes']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_serializer_works_if_set_with_invokable_class()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ShowPostController::class))
|
||||
->setSerializer(CustomPostSerializer::class, CustomApiControllerInvokableClass::class)
|
||||
);
|
||||
$this->prepareDatabase([
|
||||
Post::class => [
|
||||
['id' => 1, 'discussion_id' => 1, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>'],
|
||||
],
|
||||
]);
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/posts/1', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('customSerializer', $payload['data']['attributes']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_serializer_doesnt_work_with_false_callback_return()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->setSerializer(CustomUserSerializer::class, function () {
|
||||
return false;
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/users/2', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayNotHasKey('customSerializer', $payload['data']['attributes']);
|
||||
$this->assertEquals(422, $response->getStatusCode(), $body);
|
||||
$this->assertStringContainsString('error on purpose from abstract resource', $body, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -370,10 +256,15 @@ class ApiControllerTest extends TestCase
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasMany('customApiControllerRelation', Discussion::class, 'user_id'),
|
||||
(new Extend\ApiSerializer(UserSerializer::class))
|
||||
->hasMany('customApiControllerRelation', DiscussionSerializer::class),
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->addInclude('customApiControllerRelation')
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->fields(fn () => [
|
||||
ToMany::make('customApiControllerRelation')
|
||||
->type('discussions')
|
||||
->includable(),
|
||||
])
|
||||
->endpoint(Show::class, function (Show $endpoint): Show {
|
||||
return $endpoint->addDefaultInclude(['customApiControllerRelation']);
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -382,9 +273,9 @@ class ApiControllerTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
$payload = json_decode($body = $response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('customApiControllerRelation', $payload['data']['relationships']);
|
||||
$this->assertArrayHasKey('customApiControllerRelation', $payload['data']['relationships'] ?? [], $body);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,10 +286,12 @@ class ApiControllerTest extends TestCase
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasMany('customApiControllerRelation2', Discussion::class, 'user_id'),
|
||||
(new Extend\ApiSerializer(UserSerializer::class))
|
||||
->hasMany('customApiControllerRelation2', DiscussionSerializer::class),
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->addOptionalInclude('customApiControllerRelation2')
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->fields(fn () => [
|
||||
ToMany::make('customApiControllerRelation2')
|
||||
->type('discussions')
|
||||
->includable(),
|
||||
])
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -411,7 +304,7 @@ class ApiControllerTest extends TestCase
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('customApiControllerRelation2', $payload['data']['relationships']);
|
||||
$this->assertArrayHasKey('customApiControllerRelation2', $payload['data']['relationships'] ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,8 +329,10 @@ class ApiControllerTest extends TestCase
|
||||
public function custom_relationship_not_included_if_removed()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->removeInclude('groups')
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->endpoint(Show::class, function (Show $endpoint): Show {
|
||||
return $endpoint->removeDefaultInclude(['groups']);
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -459,11 +354,13 @@ class ApiControllerTest extends TestCase
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasMany('customApiControllerRelation2', Discussion::class, 'user_id'),
|
||||
(new Extend\ApiSerializer(UserSerializer::class))
|
||||
->hasMany('customApiControllerRelation2', DiscussionSerializer::class),
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->addOptionalInclude('customApiControllerRelation2')
|
||||
->removeOptionalInclude('customApiControllerRelation2')
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->fields(fn () => [
|
||||
ToMany::make('customApiControllerRelation2')
|
||||
->type('discussions')
|
||||
->includable(),
|
||||
])
|
||||
->field('customApiControllerRelation2', fn (Field $field) => $field->includable(false))
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -499,8 +396,10 @@ class ApiControllerTest extends TestCase
|
||||
public function custom_limit_works_if_set()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ListDiscussionsController::class))
|
||||
->setLimit(1)
|
||||
(new Extend\ApiResource(DiscussionResource::class))
|
||||
->endpoint(Index::class, function (Index $endpoint): Index {
|
||||
return $endpoint->limit(1);
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -520,8 +419,10 @@ class ApiControllerTest extends TestCase
|
||||
public function custom_max_limit_works_if_set()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ListDiscussionsController::class))
|
||||
->setMaxLimit(1)
|
||||
(new Extend\ApiResource(DiscussionResource::class))
|
||||
->endpoint(Index::class, function (Index $endpoint): Index {
|
||||
return $endpoint->maxLimit(1);
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -553,37 +454,16 @@ class ApiControllerTest extends TestCase
|
||||
$this->assertEquals(400, $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_sort_field_doesnt_work_with_false_callback_return()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ListDiscussionsController::class))
|
||||
->addSortField('userId', function () {
|
||||
return false;
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/discussions', [
|
||||
'authenticatedAs' => 1,
|
||||
])->withQueryParams([
|
||||
'sort' => 'userId',
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(400, $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_sort_field_exists_if_added()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ListDiscussionsController::class))
|
||||
->addSortField('userId')
|
||||
(new Extend\ApiResource(DiscussionResource::class))
|
||||
->sorts(fn () => [
|
||||
SortColumn::make('userId')
|
||||
]),
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -594,9 +474,9 @@ class ApiControllerTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
$payload = json_decode($body = $response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertEquals(200, $response->getStatusCode(), $body);
|
||||
$this->assertEquals([3, 1, 2], Arr::pluck($payload['data'], 'id'));
|
||||
}
|
||||
|
||||
@@ -622,8 +502,8 @@ class ApiControllerTest extends TestCase
|
||||
public function custom_sort_field_doesnt_exist_if_removed()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ListDiscussionsController::class))
|
||||
->removeSortField('createdAt')
|
||||
(new Extend\ApiResource(DiscussionResource::class))
|
||||
->removeSorts(['createdAt'])
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -634,7 +514,7 @@ class ApiControllerTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(400, $response->getStatusCode());
|
||||
$this->assertEquals(400, $response->getStatusCode(), $response->getBody()->getContents());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -643,9 +523,13 @@ class ApiControllerTest extends TestCase
|
||||
public function custom_sort_field_works_if_set()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ListDiscussionsController::class))
|
||||
->addSortField('userId')
|
||||
->setSort(['userId' => 'desc'])
|
||||
(new Extend\ApiResource(DiscussionResource::class))
|
||||
->sorts(fn () => [
|
||||
SortColumn::make('userId')
|
||||
])
|
||||
->endpoint(Index::class, function (Index $endpoint): Index {
|
||||
return $endpoint->defaultSort('-userId');
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -670,11 +554,13 @@ class ApiControllerTest extends TestCase
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('firstLevelRelation', Post::class, 'user_id'),
|
||||
(new Extend\ApiController(ListUsersController::class))
|
||||
->prepareDataForSerialization(function ($controller, $data) use (&$users) {
|
||||
$users = $data;
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->endpoint(Index::class, function (Index $endpoint) use (&$users) {
|
||||
return $endpoint->after(function ($context, $data) use (&$users) {
|
||||
$users = $data;
|
||||
|
||||
return [];
|
||||
return $data;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -697,22 +583,25 @@ class ApiControllerTest extends TestCase
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('firstLevelRelation', Post::class, 'user_id'),
|
||||
(new Extend\ApiController(ListUsersController::class))
|
||||
->load('firstLevelRelation')
|
||||
->prepareDataForSerialization(function ($controller, $data) use (&$users) {
|
||||
$users = $data;
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->endpoint(Index::class, function (Index $endpoint) use (&$users) {
|
||||
return $endpoint
|
||||
->eagerLoad('firstLevelRelation')
|
||||
->after(function ($context, $data) use (&$users) {
|
||||
$users = $data;
|
||||
|
||||
return [];
|
||||
return $data;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
$this->send(
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/users', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertFalse($users->filter->relationLoaded('firstLevelRelation')->isEmpty());
|
||||
$this->assertFalse($users->filter->relationLoaded('firstLevelRelation')->isEmpty(), $response->getBody()->getContents());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -725,13 +614,14 @@ class ApiControllerTest extends TestCase
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('firstLevelRelation', Post::class, 'user_id'),
|
||||
(new Extend\Model(Post::class))
|
||||
->belongsTo('secondLevelRelation', Discussion::class),
|
||||
(new Extend\ApiController(ListUsersController::class))
|
||||
->prepareDataForSerialization(function ($controller, $data) use (&$users) {
|
||||
$users = $data;
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->endpoint(Index::class, function (Index $endpoint) use (&$users) {
|
||||
return $endpoint
|
||||
->after(function ($context, $data) use (&$users) {
|
||||
$users = $data;
|
||||
|
||||
return [];
|
||||
return $data;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -756,12 +646,15 @@ class ApiControllerTest extends TestCase
|
||||
->hasOne('firstLevelRelation', Post::class, 'user_id'),
|
||||
(new Extend\Model(Post::class))
|
||||
->belongsTo('secondLevelRelation', Discussion::class),
|
||||
(new Extend\ApiController(ListUsersController::class))
|
||||
->load(['firstLevelRelation', 'firstLevelRelation.secondLevelRelation'])
|
||||
->prepareDataForSerialization(function ($controller, $data) use (&$users) {
|
||||
$users = $data;
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->endpoint(Index::class, function (Index $endpoint) use (&$users) {
|
||||
return $endpoint
|
||||
->eagerLoad(['firstLevelRelation.secondLevelRelation'])
|
||||
->after(function ($context, $data) use (&$users) {
|
||||
$users = $data;
|
||||
|
||||
return [];
|
||||
return $data;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -784,14 +677,15 @@ class ApiControllerTest extends TestCase
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('firstLevelRelation', Post::class, 'user_id'),
|
||||
(new Extend\Model(Post::class))
|
||||
->belongsTo('secondLevelRelation', Discussion::class),
|
||||
(new Extend\ApiController(ListUsersController::class))
|
||||
->load(['firstLevelRelation.secondLevelRelation'])
|
||||
->prepareDataForSerialization(function ($controller, $data) use (&$users) {
|
||||
$users = $data;
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->endpoint(Index::class, function (Index $endpoint) use (&$users) {
|
||||
return $endpoint
|
||||
->eagerLoadWhenIncluded(['firstLevelRelation' => ['secondLevelRelation']])
|
||||
->after(function ($context, $data) use (&$users) {
|
||||
$users = $data;
|
||||
|
||||
return [];
|
||||
return $data;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -814,12 +708,15 @@ class ApiControllerTest extends TestCase
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('firstLevelRelation', Post::class, 'user_id'),
|
||||
(new Extend\ApiController(ListUsersController::class))
|
||||
->loadWhere('firstLevelRelation', function ($query, $request) {})
|
||||
->prepareDataForSerialization(function ($controller, $data) use (&$users) {
|
||||
$users = $data;
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->endpoint(Index::class, function (Index $endpoint) use (&$users) {
|
||||
return $endpoint
|
||||
->eagerLoadWhere('firstLevelRelation', function ($query, $request) {})
|
||||
->after(function ($context, $data) use (&$users) {
|
||||
$users = $data;
|
||||
|
||||
return [];
|
||||
return $data;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -844,13 +741,16 @@ class ApiControllerTest extends TestCase
|
||||
->hasOne('firstLevelRelation', Post::class, 'user_id'),
|
||||
(new Extend\Model(Post::class))
|
||||
->belongsTo('secondLevelRelation', Discussion::class),
|
||||
(new Extend\ApiController(ListUsersController::class))
|
||||
->load('firstLevelRelation')
|
||||
->loadWhere('firstLevelRelation.secondLevelRelation', function ($query, $request) {})
|
||||
->prepareDataForSerialization(function ($controller, $data) use (&$users) {
|
||||
$users = $data;
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->endpoint(Index::class, function (Index $endpoint) use (&$users) {
|
||||
return $endpoint
|
||||
->eagerLoad('firstLevelRelation')
|
||||
->eagerLoadWhere('firstLevelRelation.secondLevelRelation', function ($query, $request) {})
|
||||
->after(function ($context, $data) use (&$users) {
|
||||
$users = $data;
|
||||
|
||||
return [];
|
||||
return $data;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -862,129 +762,14 @@ class ApiControllerTest extends TestCase
|
||||
|
||||
$this->assertFalse($users->pluck('firstLevelRelation')->filter->relationLoaded('secondLevelRelation')->isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_callable_second_level_relation_is_not_loaded_when_first_level_is_not()
|
||||
{
|
||||
$users = null;
|
||||
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('firstLevelRelation', Post::class, 'user_id'),
|
||||
(new Extend\Model(Post::class))
|
||||
->belongsTo('secondLevelRelation', Discussion::class),
|
||||
(new Extend\ApiController(ListUsersController::class))
|
||||
->loadWhere('firstLevelRelation.secondLevelRelation', function ($query, $request) {})
|
||||
->prepareDataForSerialization(function ($controller, $data) use (&$users) {
|
||||
$users = $data;
|
||||
|
||||
return [];
|
||||
})
|
||||
);
|
||||
|
||||
$this->send(
|
||||
$this->request('GET', '/api/users', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertTrue($users->pluck('firstLevelRelation')->filter->relationLoaded('secondLevelRelation')->isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_callable_second_level_relation_is_loaded_when_first_level_is()
|
||||
{
|
||||
$users = null;
|
||||
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('firstLevelRelation', Post::class, 'user_id'),
|
||||
(new Extend\Model(Post::class))
|
||||
->belongsTo('secondLevelRelation', Discussion::class),
|
||||
(new Extend\ApiController(ListUsersController::class))
|
||||
->loadWhere('firstLevelRelation', function ($query, $request) {})
|
||||
->loadWhere('firstLevelRelation.secondLevelRelation', function ($query, $request) {})
|
||||
->prepareDataForSerialization(function ($controller, $data) use (&$users) {
|
||||
$users = $data;
|
||||
|
||||
return [];
|
||||
})
|
||||
);
|
||||
|
||||
$this->send(
|
||||
$this->request('GET', '/api/users', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertTrue($users->pluck('firstLevelRelation')->filter->relationLoaded('secondLevelRelation')->isNotEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
class CustomDiscussionSerializer extends DiscussionSerializer
|
||||
class CustomAfterEndpointInvokableClass
|
||||
{
|
||||
protected function getDefaultAttributes(object|array $model): array
|
||||
{
|
||||
return parent::getDefaultAttributes($model) + [
|
||||
'customSerializer' => true
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class CustomDiscussionSerializer2 extends DiscussionSerializer
|
||||
{
|
||||
protected function getDefaultAttributes(object|array $model): array
|
||||
{
|
||||
return parent::getDefaultAttributes($model) + [
|
||||
'customSerializer2' => true
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class CustomUserSerializer extends UserSerializer
|
||||
{
|
||||
protected function getDefaultAttributes(object|array $model): array
|
||||
{
|
||||
return parent::getDefaultAttributes($model) + [
|
||||
'customSerializer' => true
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class CustomPostSerializer extends PostSerializer
|
||||
{
|
||||
protected function getDefaultAttributes(object|array $model): array
|
||||
{
|
||||
return parent::getDefaultAttributes($model) + [
|
||||
'customSerializer' => true
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class CustomApiControllerInvokableClass
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class CustomPrepareDataSerializationInvokableClass
|
||||
{
|
||||
public function __invoke(ShowDiscussionController $controller, Discussion $discussion)
|
||||
public function __invoke(Context $context, Discussion $discussion): Discussion
|
||||
{
|
||||
$discussion->title = __CLASS__;
|
||||
}
|
||||
}
|
||||
|
||||
class CustomInvokableClassArgsReference
|
||||
{
|
||||
public function __invoke($controller, &$data)
|
||||
{
|
||||
$data['referenceTest2'] = User::limit(2)->get();
|
||||
return $discussion;
|
||||
}
|
||||
}
|
||||
|
@@ -10,13 +10,11 @@
|
||||
namespace Flarum\Tests\integration\extenders;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Flarum\Api\Controller\ShowUserController;
|
||||
use Flarum\Api\Serializer\AbstractSerializer;
|
||||
use Flarum\Api\Serializer\BasicUserSerializer;
|
||||
use Flarum\Api\Serializer\DiscussionSerializer;
|
||||
use Flarum\Api\Serializer\ForumSerializer;
|
||||
use Flarum\Api\Serializer\PostSerializer;
|
||||
use Flarum\Api\Serializer\UserSerializer;
|
||||
use Flarum\Api\Endpoint\Show;
|
||||
use Flarum\Api\Resource\AbstractDatabaseResource;
|
||||
use Flarum\Api\Resource\ForumResource;
|
||||
use Flarum\Api\Resource\UserResource;
|
||||
use Flarum\Api\Schema;
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Extend;
|
||||
use Flarum\Post\Post;
|
||||
@@ -74,12 +72,11 @@ class ApiSerializerTest extends TestCase
|
||||
public function custom_attributes_exist_if_added()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return [
|
||||
'customAttribute' => true
|
||||
];
|
||||
})
|
||||
(new Extend\ApiResource(ForumResource::class))
|
||||
->fields(fn () => [
|
||||
Schema\Boolean::make('customAttribute')
|
||||
->get(fn () => true),
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -101,8 +98,8 @@ class ApiSerializerTest extends TestCase
|
||||
public function custom_attributes_with_invokable_exist_if_added()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(CustomAttributesInvokableClass::class)
|
||||
(new Extend\ApiResource(ForumResource::class))
|
||||
->fields(CustomAttributesInvokableClass::class)
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -124,12 +121,11 @@ class ApiSerializerTest extends TestCase
|
||||
public function custom_attributes_exist_if_added_to_parent_class()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiSerializer(BasicUserSerializer::class))
|
||||
->attributes(function () {
|
||||
return [
|
||||
'customAttribute' => true
|
||||
];
|
||||
})
|
||||
(new Extend\ApiResource(AbstractDatabaseResource::class))
|
||||
->fields(fn () => [
|
||||
Schema\Boolean::make('customAttribute')
|
||||
->get(fn () => true),
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -151,18 +147,16 @@ class ApiSerializerTest extends TestCase
|
||||
public function custom_attributes_prioritize_child_classes()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiSerializer(BasicUserSerializer::class))
|
||||
->attributes(function () {
|
||||
return [
|
||||
'customAttribute' => 'initialValue'
|
||||
];
|
||||
}),
|
||||
(new Extend\ApiSerializer(UserSerializer::class))
|
||||
->attributes(function () {
|
||||
return [
|
||||
'customAttribute' => 'newValue'
|
||||
];
|
||||
})
|
||||
(new Extend\ApiResource(AbstractDatabaseResource::class))
|
||||
->fields(fn () => [
|
||||
Schema\Str::make('customAttribute')
|
||||
->get(fn () => 'initialValue')
|
||||
]),
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->fields(fn () => [
|
||||
Schema\Str::make('customAttribute')
|
||||
->get(fn () => 'newValue')
|
||||
]),
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -179,130 +173,27 @@ class ApiSerializerTest extends TestCase
|
||||
$this->assertEquals('newValue', $payload['data']['attributes']['customAttribute']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_single_attribute_exists_if_added()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attribute('customSingleAttribute', function () {
|
||||
return true;
|
||||
})->attribute('customSingleAttribute_0', function () {
|
||||
return 0;
|
||||
})
|
||||
);
|
||||
|
||||
$this->app();
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('customSingleAttribute', $payload['data']['attributes']);
|
||||
$this->assertArrayHasKey('customSingleAttribute_0', $payload['data']['attributes']);
|
||||
$this->assertEquals(0, $payload['data']['attributes']['customSingleAttribute_0']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_single_attribute_with_invokable_exists_if_added()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attribute('customSingleAttribute_1', CustomSingleAttributeInvokableClass::class)
|
||||
);
|
||||
|
||||
$this->app();
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('customSingleAttribute_1', $payload['data']['attributes']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_single_attribute_exists_if_added_to_parent_class()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiSerializer(BasicUserSerializer::class))
|
||||
->attribute('customSingleAttribute_2', function () {
|
||||
return true;
|
||||
})
|
||||
);
|
||||
|
||||
$this->app();
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/users/2', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('customSingleAttribute_2', $payload['data']['attributes']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_single_attribute_prioritizes_child_classes()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiSerializer(BasicUserSerializer::class))
|
||||
->attribute('customSingleAttribute_3', function () {
|
||||
return 'initialValue';
|
||||
}),
|
||||
(new Extend\ApiSerializer(UserSerializer::class))
|
||||
->attribute('customSingleAttribute_3', function () {
|
||||
return 'newValue';
|
||||
})
|
||||
);
|
||||
|
||||
$this->app();
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/users/2', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('customSingleAttribute_3', $payload['data']['attributes']);
|
||||
$this->assertEquals('newValue', $payload['data']['attributes']['customSingleAttribute_3']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_attributes_can_be_overriden()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiSerializer(BasicUserSerializer::class))
|
||||
->attribute('someCustomAttribute', function () {
|
||||
return 'newValue';
|
||||
})->attributes(function () {
|
||||
return [
|
||||
'someCustomAttribute' => 'initialValue',
|
||||
'someOtherCustomAttribute' => 'initialValue',
|
||||
];
|
||||
})->attribute('someOtherCustomAttribute', function () {
|
||||
return 'newValue';
|
||||
})
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->fields(fn () => [
|
||||
Schema\Str::make('someCustomAttribute')
|
||||
->get(fn () => 'newValue'),
|
||||
])
|
||||
->fields(fn () => [
|
||||
Schema\Str::make('someCustomAttribute')
|
||||
->get(fn () => 'secondValue'),
|
||||
Schema\Str::make('someOtherCustomAttribute')
|
||||
->get(fn () => 'secondValue'),
|
||||
])
|
||||
->fields(fn () => [
|
||||
Schema\Str::make('someOtherCustomAttribute')
|
||||
->get(fn () => 'newValue'),
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -316,7 +207,7 @@ class ApiSerializerTest extends TestCase
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('someCustomAttribute', $payload['data']['attributes']);
|
||||
$this->assertEquals('newValue', $payload['data']['attributes']['someCustomAttribute']);
|
||||
$this->assertEquals('secondValue', $payload['data']['attributes']['someCustomAttribute']);
|
||||
$this->assertArrayHasKey('someOtherCustomAttribute', $payload['data']['attributes']);
|
||||
$this->assertEquals('newValue', $payload['data']['attributes']['someOtherCustomAttribute']);
|
||||
}
|
||||
@@ -327,8 +218,10 @@ class ApiSerializerTest extends TestCase
|
||||
public function custom_relations_dont_exist_by_default()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->addInclude(['customSerializerRelation', 'postCustomRelation', 'anotherCustomRelation'])
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->endpoint(Show::class, function (Show $endpoint): Show {
|
||||
return $endpoint->addDefaultInclude(['customSerializerRelation', 'postCustomRelation', 'anotherCustomRelation']);
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -337,11 +230,7 @@ class ApiSerializerTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$responseJson = json_decode($response->getBody(), true);
|
||||
|
||||
$this->assertArrayNotHasKey('customSerializerRelation', $responseJson['data']['relationships']);
|
||||
$this->assertArrayNotHasKey('postCustomRelation', $responseJson['data']['relationships']);
|
||||
$this->assertArrayNotHasKey('anotherCustomRelation', $responseJson['data']['relationships']);
|
||||
$this->assertEquals(400, $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,10 +241,15 @@ class ApiSerializerTest extends TestCase
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasMany('customSerializerRelation', Discussion::class, 'user_id'),
|
||||
(new Extend\ApiSerializer(UserSerializer::class))
|
||||
->hasMany('customSerializerRelation', DiscussionSerializer::class),
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->addInclude('customSerializerRelation')
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->fields(fn () => [
|
||||
Schema\Relationship\ToMany::make('customSerializerRelation')
|
||||
->type('discussions')
|
||||
->includable()
|
||||
])
|
||||
->endpoint(Show::class, function (Show $endpoint) {
|
||||
return $endpoint->addDefaultInclude(['customSerializerRelation']);
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -378,64 +272,15 @@ class ApiSerializerTest extends TestCase
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('customSerializerRelation', Discussion::class, 'user_id'),
|
||||
(new Extend\ApiSerializer(UserSerializer::class))
|
||||
->hasOne('customSerializerRelation', DiscussionSerializer::class),
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->addInclude('customSerializerRelation')
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/users/2', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$responseJson = json_decode($response->getBody(), true);
|
||||
|
||||
$this->assertArrayHasKey('customSerializerRelation', $responseJson['data']['relationships']);
|
||||
$this->assertEquals('discussions', $responseJson['data']['relationships']['customSerializerRelation']['data']['type']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_relationship_exists_if_added()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('customSerializerRelation', Discussion::class, 'user_id'),
|
||||
(new Extend\ApiSerializer(UserSerializer::class))
|
||||
->relationship('customSerializerRelation', function (AbstractSerializer $serializer, $model) {
|
||||
return $serializer->hasOne($model, DiscussionSerializer::class, 'customSerializerRelation');
|
||||
}),
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->addInclude('customSerializerRelation')
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/users/2', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$responseJson = json_decode($response->getBody(), true);
|
||||
|
||||
$this->assertArrayHasKey('customSerializerRelation', $responseJson['data']['relationships']);
|
||||
$this->assertEquals('discussions', $responseJson['data']['relationships']['customSerializerRelation']['data']['type']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_relationship_with_invokable_exists_if_added()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('customSerializerRelation', Discussion::class, 'user_id'),
|
||||
(new Extend\ApiSerializer(UserSerializer::class))
|
||||
->relationship('customSerializerRelation', CustomRelationshipInvokableClass::class),
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->addInclude('customSerializerRelation')
|
||||
(new Extend\ApiResource(UserResource::class))
|
||||
->fields(fn () => [
|
||||
Schema\Relationship\ToOne::make('customSerializerRelation')
|
||||
->type('discussions')
|
||||
->includable()
|
||||
])
|
||||
->endpoint(Show::class, function (Show $endpoint) {
|
||||
return $endpoint->addDefaultInclude(['customSerializerRelation']);
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -458,10 +303,15 @@ class ApiSerializerTest extends TestCase
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasMany('anotherCustomRelation', Discussion::class, 'user_id'),
|
||||
(new Extend\ApiSerializer(BasicUserSerializer::class))
|
||||
->hasMany('anotherCustomRelation', DiscussionSerializer::class),
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->addInclude('anotherCustomRelation')
|
||||
(new Extend\ApiResource(AbstractDatabaseResource::class))
|
||||
->fields(fn () => [
|
||||
Schema\Relationship\ToMany::make('anotherCustomRelation')
|
||||
->type('discussions')
|
||||
->includable()
|
||||
])
|
||||
->endpoint(Show::class, function (Show $endpoint) {
|
||||
return $endpoint->addDefaultInclude(['anotherCustomRelation']);
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
@@ -475,62 +325,15 @@ class ApiSerializerTest extends TestCase
|
||||
$this->assertArrayHasKey('anotherCustomRelation', $responseJson['data']['relationships']);
|
||||
$this->assertCount(3, $responseJson['data']['relationships']['anotherCustomRelation']['data']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_relationship_prioritizes_child_classes()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('postCustomRelation', Post::class, 'user_id'),
|
||||
(new Extend\Model(User::class))
|
||||
->hasOne('discussionCustomRelation', Discussion::class, 'user_id'),
|
||||
(new Extend\ApiSerializer(BasicUserSerializer::class))
|
||||
->hasOne('postCustomRelation', PostSerializer::class),
|
||||
(new Extend\ApiSerializer(UserSerializer::class))
|
||||
->relationship('postCustomRelation', function (AbstractSerializer $serializer, $model) {
|
||||
return $serializer->hasOne($model, DiscussionSerializer::class, 'discussionCustomRelation');
|
||||
}),
|
||||
(new Extend\ApiController(ShowUserController::class))
|
||||
->addInclude('postCustomRelation')
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/users/2', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$responseJson = json_decode($response->getBody(), true);
|
||||
|
||||
$this->assertArrayHasKey('postCustomRelation', $responseJson['data']['relationships']);
|
||||
$this->assertEquals('discussions', $responseJson['data']['relationships']['postCustomRelation']['data']['type']);
|
||||
}
|
||||
}
|
||||
|
||||
class CustomAttributesInvokableClass
|
||||
{
|
||||
public function __invoke()
|
||||
public function __invoke(): array
|
||||
{
|
||||
return [
|
||||
'customAttributeFromInvokable' => true
|
||||
Schema\Boolean::make('customAttributeFromInvokable')
|
||||
->get(fn () => true),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class CustomSingleAttributeInvokableClass
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class CustomRelationshipInvokableClass
|
||||
{
|
||||
public function __invoke(AbstractSerializer $serializer, $model)
|
||||
{
|
||||
return $serializer->hasOne($model, DiscussionSerializer::class, 'customSerializerRelation');
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,8 @@
|
||||
namespace Flarum\Tests\integration\extenders;
|
||||
|
||||
use Exception;
|
||||
use Flarum\Api\Serializer\ForumSerializer;
|
||||
use Flarum\Api\Resource\ForumResource;
|
||||
use Flarum\Api\Schema\Boolean;
|
||||
use Flarum\Extend;
|
||||
use Flarum\Extension\ExtensionManager;
|
||||
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
|
||||
@@ -25,14 +26,13 @@ class ConditionalTest extends TestCase
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Conditional())
|
||||
->when(true, function () {
|
||||
return [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return ['customConditionalAttribute' => true];
|
||||
})
|
||||
];
|
||||
})
|
||||
->when(true, fn () => [
|
||||
(new Extend\ApiResource(ForumResource::class))
|
||||
->fields(fn () => [
|
||||
Boolean::make('customConditionalAttribute')
|
||||
->get(fn () => true)
|
||||
])
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -53,14 +53,13 @@ class ConditionalTest extends TestCase
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Conditional())
|
||||
->when(false, function () {
|
||||
return [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return ['customConditionalAttribute' => true];
|
||||
})
|
||||
];
|
||||
})
|
||||
->when(false, fn () => [
|
||||
(new Extend\ApiResource(ForumResource::class))
|
||||
->fields(fn () => [
|
||||
Boolean::make('customConditionalAttribute')
|
||||
->get(fn () => true)
|
||||
])
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -81,16 +80,13 @@ class ConditionalTest extends TestCase
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Conditional())
|
||||
->when(function () {
|
||||
return true;
|
||||
}, function () {
|
||||
return [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return ['customConditionalAttribute' => true];
|
||||
})
|
||||
];
|
||||
})
|
||||
->when(fn () => true, fn () => [
|
||||
(new Extend\ApiResource(ForumResource::class))
|
||||
->fields(fn () => [
|
||||
Boolean::make('customConditionalAttribute')
|
||||
->get(fn () => true)
|
||||
])
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -111,16 +107,13 @@ class ConditionalTest extends TestCase
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Conditional())
|
||||
->when(function () {
|
||||
return false;
|
||||
}, function () {
|
||||
return [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return ['customConditionalAttribute' => true];
|
||||
})
|
||||
];
|
||||
})
|
||||
->when(fn () => false, fn () => [
|
||||
(new Extend\ApiResource(ForumResource::class))
|
||||
->fields(fn () => [
|
||||
Boolean::make('customConditionalAttribute')
|
||||
->get(fn () => true)
|
||||
])
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -147,14 +140,13 @@ class ConditionalTest extends TestCase
|
||||
if (! $extensions) {
|
||||
throw new Exception('ExtensionManager not injected');
|
||||
}
|
||||
}, function () {
|
||||
return [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return ['customConditionalAttribute' => true];
|
||||
})
|
||||
];
|
||||
})
|
||||
}, fn () => [
|
||||
(new Extend\ApiResource(ForumResource::class))
|
||||
->fields(fn () => [
|
||||
Boolean::make('customConditionalAttribute')
|
||||
->get(fn () => true)
|
||||
])
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -294,14 +286,13 @@ class ConditionalTest extends TestCase
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Conditional())
|
||||
->when(false, function () {
|
||||
return [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return ['customConditionalAttribute' => true];
|
||||
})
|
||||
];
|
||||
})
|
||||
->when(false, fn () => [
|
||||
(new Extend\ApiResource(ForumResource::class))
|
||||
->fields(fn () => [
|
||||
Boolean::make('customConditionalAttribute')
|
||||
->get(fn () => true)
|
||||
])
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -322,14 +313,13 @@ class ConditionalTest extends TestCase
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Conditional())
|
||||
->when(true, function () {
|
||||
return [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return ['customConditionalAttribute' => true];
|
||||
})
|
||||
];
|
||||
})
|
||||
->when(true, fn () => [
|
||||
(new Extend\ApiResource(ForumResource::class))
|
||||
->fields(fn () => [
|
||||
Boolean::make('customConditionalAttribute')
|
||||
->get(fn () => true)
|
||||
])
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
@@ -370,12 +360,11 @@ class TestExtender
|
||||
public function __invoke(): array
|
||||
{
|
||||
return [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return [
|
||||
'customConditionalAttribute' => true
|
||||
];
|
||||
})
|
||||
(new Extend\ApiResource(ForumResource::class))
|
||||
->fields(fn () => [
|
||||
Boolean::make('customConditionalAttribute')
|
||||
->get(fn () => true)
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -9,33 +9,42 @@
|
||||
|
||||
namespace Flarum\Tests\integration\extenders;
|
||||
|
||||
use Flarum\Api\JsonApi;
|
||||
use Flarum\Api\Resource\GroupResource;
|
||||
use Flarum\Extend;
|
||||
use Flarum\Foundation\Application;
|
||||
use Flarum\Group\Command\CreateGroup;
|
||||
use Flarum\Group\Event\Created;
|
||||
use Flarum\Group\Group;
|
||||
use Flarum\Locale\TranslatorInterface;
|
||||
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
|
||||
use Flarum\Testing\integration\TestCase;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class EventTest extends TestCase
|
||||
{
|
||||
use RetrievesAuthorizedUsers;
|
||||
|
||||
protected function buildGroup()
|
||||
protected function buildGroup(): Group
|
||||
{
|
||||
$bus = $this->app()->getContainer()->make(BusDispatcher::class);
|
||||
/** @var JsonApi $api */
|
||||
$api = $this->app()->getContainer()->make(JsonApi::class);
|
||||
|
||||
return $bus->dispatch(
|
||||
new CreateGroup(User::find(1), ['attributes' => [
|
||||
'nameSingular' => 'test group',
|
||||
'namePlural' => 'test groups',
|
||||
'color' => '#000000',
|
||||
'icon' => 'fas fa-crown',
|
||||
]])
|
||||
);
|
||||
return $api->forResource(GroupResource::class)
|
||||
->forEndpoint('create')
|
||||
->process(
|
||||
body: [
|
||||
'data' => [
|
||||
'attributes' => [
|
||||
'nameSingular' => 'test group',
|
||||
'namePlural' => 'test groups',
|
||||
'color' => '#000000',
|
||||
'icon' => 'fas fa-crown',
|
||||
]
|
||||
],
|
||||
],
|
||||
options: ['actor' => User::find(1)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -34,7 +34,11 @@ class MailTest extends TestCase
|
||||
])
|
||||
);
|
||||
|
||||
$fields = json_decode($response->getBody()->getContents(), true)['data']['attributes']['fields'];
|
||||
$body = $response->getBody()->getContents();
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode(), $body);
|
||||
|
||||
$fields = json_decode($body, true)['data']['attributes']['fields'];
|
||||
|
||||
// The custom driver does not exist
|
||||
$this->assertArrayNotHasKey('custom', $fields);
|
||||
|
@@ -19,6 +19,13 @@ class ModelPrivateTest extends TestCase
|
||||
{
|
||||
use RetrievesAuthorizedUsers;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
Discussion::unguard();
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
@@ -28,8 +35,10 @@ class ModelPrivateTest extends TestCase
|
||||
|
||||
$user = User::find(1);
|
||||
|
||||
$discussion = Discussion::start('Some Discussion', $user);
|
||||
$discussion->save();
|
||||
$discussion = Discussion::create([
|
||||
'title' => 'Some Discussion',
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$this->assertNull($discussion->is_private);
|
||||
}
|
||||
@@ -50,10 +59,14 @@ class ModelPrivateTest extends TestCase
|
||||
|
||||
$user = User::find(1);
|
||||
|
||||
$privateDiscussion = Discussion::start('Private Discussion', $user);
|
||||
$publicDiscussion = Discussion::start('Public Discussion', $user);
|
||||
$privateDiscussion->save();
|
||||
$publicDiscussion->save();
|
||||
$privateDiscussion = Discussion::create([
|
||||
'title' => 'Private Discussion',
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
$publicDiscussion = Discussion::create([
|
||||
'title' => 'Public Discussion',
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$this->assertTrue($privateDiscussion->is_private);
|
||||
$this->assertFalse($publicDiscussion->is_private);
|
||||
@@ -73,10 +86,14 @@ class ModelPrivateTest extends TestCase
|
||||
|
||||
$user = User::find(1);
|
||||
|
||||
$privateDiscussion = Discussion::start('Private Discussion', $user);
|
||||
$publicDiscussion = Discussion::start('Public Discussion', $user);
|
||||
$privateDiscussion->save();
|
||||
$publicDiscussion->save();
|
||||
$privateDiscussion = Discussion::create([
|
||||
'title' => 'Private Discussion',
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
$publicDiscussion = Discussion::create([
|
||||
'title' => 'Public Discussion',
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$this->assertTrue($privateDiscussion->is_private);
|
||||
$this->assertFalse($publicDiscussion->is_private);
|
||||
@@ -102,10 +119,14 @@ class ModelPrivateTest extends TestCase
|
||||
|
||||
$user = User::find(1);
|
||||
|
||||
$privateDiscussion = Discussion::start('Private Discussion', $user);
|
||||
$publicDiscussion = Discussion::start('Public Discussion', $user);
|
||||
$privateDiscussion->save();
|
||||
$publicDiscussion->save();
|
||||
$privateDiscussion = Discussion::create([
|
||||
'title' => 'Private Discussion',
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
$publicDiscussion = Discussion::create([
|
||||
'title' => 'Public Discussion',
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$this->assertTrue($privateDiscussion->is_private);
|
||||
$this->assertFalse($publicDiscussion->is_private);
|
||||
|
@@ -306,11 +306,13 @@ class ModelTest extends TestCase
|
||||
|
||||
$this->app();
|
||||
|
||||
$group1 = new Group;
|
||||
$group2 = new Group;
|
||||
Group::boot();
|
||||
|
||||
$this->assertEquals(1, $group1->counter);
|
||||
$this->assertEquals(3, $group2->counter);
|
||||
$group1 = new Group();
|
||||
$group2 = new Group();
|
||||
|
||||
$this->assertEquals(3, $group1->counter);
|
||||
$this->assertEquals(4, $group2->counter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -31,19 +31,6 @@ class NotificationTest extends TestCase
|
||||
$this->assertArrayNotHasKey('customNotificationType', Notification::getSubjectModels());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function notification_serializer_doesnt_exist_by_default()
|
||||
{
|
||||
$this->app();
|
||||
|
||||
$this->assertNotContains(
|
||||
'customNotificationTypeSerializer',
|
||||
$this->app->getContainer()->make('flarum.api.notification_serializers')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
@@ -57,34 +44,13 @@ class NotificationTest extends TestCase
|
||||
*/
|
||||
public function notification_type_exists_if_added()
|
||||
{
|
||||
$this->extend((new Extend\Notification)->type(
|
||||
CustomNotificationType::class,
|
||||
'customNotificationTypeSerializer'
|
||||
));
|
||||
$this->extend((new Extend\Notification)->type(CustomNotificationType::class));
|
||||
|
||||
$this->app();
|
||||
|
||||
$this->assertArrayHasKey('customNotificationType', Notification::getSubjectModels());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function notification_serializer_exists_if_added()
|
||||
{
|
||||
$this->extend((new Extend\Notification)->type(
|
||||
CustomNotificationType::class,
|
||||
'customNotificationTypeSerializer'
|
||||
));
|
||||
|
||||
$this->app();
|
||||
|
||||
$this->assertContains(
|
||||
'customNotificationTypeSerializer',
|
||||
$this->app->getContainer()->make('flarum.api.notification_serializers')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
@@ -107,9 +73,9 @@ class NotificationTest extends TestCase
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Notification())
|
||||
->type(CustomNotificationType::class, 'customSerializer')
|
||||
->type(SecondCustomNotificationType::class, 'secondCustomSerializer', ['customDriver'])
|
||||
->type(ThirdCustomNotificationType::class, 'thirdCustomSerializer')
|
||||
->type(CustomNotificationType::class)
|
||||
->type(SecondCustomNotificationType::class, ['customDriver'])
|
||||
->type(ThirdCustomNotificationType::class)
|
||||
->driver('customDriver', CustomNotificationDriver::class, [CustomNotificationType::class])
|
||||
->driver('secondCustomDriver', SecondCustomNotificationDriver::class, [SecondCustomNotificationType::class])
|
||||
);
|
||||
@@ -132,7 +98,7 @@ class NotificationTest extends TestCase
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Notification)
|
||||
->type(CustomNotificationType::class, 'customNotificationTypeSerializer')
|
||||
->type(CustomNotificationType::class)
|
||||
->driver('customNotificationDriver', CustomNotificationDriver::class)
|
||||
->beforeSending(function ($blueprint, $users) {
|
||||
if ($blueprint instanceof CustomNotificationType) {
|
||||
|
@@ -42,13 +42,18 @@ class SearchIndexTest extends TestCase
|
||||
public static function modelProvider(): array
|
||||
{
|
||||
return [
|
||||
['discussions', Discussion::class, 'title'],
|
||||
['posts', CommentPost::class, 'content'],
|
||||
['discussions', Discussion::class, [
|
||||
'title' => 'test',
|
||||
'content' => 'test!',
|
||||
]],
|
||||
['posts', CommentPost::class, [
|
||||
'content' => 'test!!',
|
||||
]],
|
||||
];
|
||||
}
|
||||
|
||||
/** @dataProvider modelProvider */
|
||||
public function test_indexer_triggered_on_create(string $type, string $modelClass, string $attribute)
|
||||
public function test_indexer_triggered_on_create(string $type, string $modelClass, array $attributes)
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\SearchIndex())
|
||||
@@ -61,9 +66,8 @@ class SearchIndexTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'attributes' => [
|
||||
$attribute => 'test',
|
||||
],
|
||||
'type' => $type,
|
||||
'attributes' => $attributes,
|
||||
'relationships' => ($type === 'posts' ? [
|
||||
'discussion' => [
|
||||
'data' => [
|
||||
@@ -71,7 +75,7 @@ class SearchIndexTest extends TestCase
|
||||
'id' => 1,
|
||||
],
|
||||
],
|
||||
] : null),
|
||||
] : []),
|
||||
]
|
||||
],
|
||||
]),
|
||||
@@ -81,7 +85,7 @@ class SearchIndexTest extends TestCase
|
||||
}
|
||||
|
||||
/** @dataProvider modelProvider */
|
||||
public function test_indexer_triggered_on_save(string $type, string $modelClass, string $attribute)
|
||||
public function test_indexer_triggered_on_save(string $type, string $modelClass, array $attributes)
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\SearchIndex())
|
||||
@@ -94,9 +98,8 @@ class SearchIndexTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'attributes' => [
|
||||
$attribute => 'changed'
|
||||
]
|
||||
'type' => $type,
|
||||
'attributes' => $type === 'discussions' ? array_diff_key($attributes, ['content' => null]) : $attributes,
|
||||
]
|
||||
],
|
||||
]),
|
||||
@@ -106,7 +109,7 @@ class SearchIndexTest extends TestCase
|
||||
}
|
||||
|
||||
/** @dataProvider modelProvider */
|
||||
public function test_indexer_triggered_on_delete(string $type, string $modelClass, string $attribute)
|
||||
public function test_indexer_triggered_on_delete(string $type, string $modelClass, array $attributes)
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\SearchIndex())
|
||||
@@ -125,7 +128,7 @@ class SearchIndexTest extends TestCase
|
||||
}
|
||||
|
||||
/** @dataProvider modelProvider */
|
||||
public function test_indexer_triggered_on_hide(string $type, string $modelClass, string $attribute)
|
||||
public function test_indexer_triggered_on_hide(string $type, string $modelClass, array $attributes)
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\SearchIndex())
|
||||
@@ -138,6 +141,7 @@ class SearchIndexTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => $type,
|
||||
'attributes' => [
|
||||
'isHidden' => true
|
||||
]
|
||||
@@ -150,7 +154,7 @@ class SearchIndexTest extends TestCase
|
||||
}
|
||||
|
||||
/** @dataProvider modelProvider */
|
||||
public function test_indexer_triggered_on_restore(string $type, string $modelClass, string $attribute)
|
||||
public function test_indexer_triggered_on_restore(string $type, string $modelClass, array $attributes)
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\SearchIndex())
|
||||
@@ -163,6 +167,7 @@ class SearchIndexTest extends TestCase
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'data' => [
|
||||
'type' => $type,
|
||||
'attributes' => [
|
||||
'isHidden' => false
|
||||
]
|
||||
|
@@ -97,6 +97,30 @@ class SettingsTest extends TestCase
|
||||
$this->assertEquals('customValueModified', $payload['data']['attributes']['customPrefix.customSetting']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_setting_callback_can_cast_to_type()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Settings())
|
||||
->serializeToForum('customPrefix.customSetting', 'custom-prefix.custom_setting', function ($value) {
|
||||
return (bool) $value;
|
||||
})
|
||||
);
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('customPrefix.customSetting', $payload['data']['attributes']);
|
||||
$this->assertEquals(true, $payload['data']['attributes']['customPrefix.customSetting']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
|
@@ -149,7 +149,7 @@ class ThemeTest extends TestCase
|
||||
|
||||
$response = $this->send($this->request('GET', '/'));
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertEquals(200, $response->getStatusCode(), $response->getBody()->getContents());
|
||||
|
||||
$cssFilePath = $this->app()->getContainer()->make('filesystem')->disk('flarum-assets')->path('forum.css');
|
||||
$contents = file_get_contents($cssFilePath);
|
||||
|
@@ -10,16 +10,16 @@
|
||||
namespace Flarum\Tests\integration\extenders;
|
||||
|
||||
use Flarum\Extend;
|
||||
use Flarum\Group\GroupValidator;
|
||||
use Flarum\Foundation\AbstractValidator;
|
||||
use Flarum\Testing\integration\TestCase;
|
||||
use Flarum\User\UserValidator;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class ValidatorTest extends TestCase
|
||||
{
|
||||
private function extendToRequireLongPassword()
|
||||
{
|
||||
$this->extend((new Extend\Validator(UserValidator::class))->configure(function ($flarumValidator, $validator) {
|
||||
$this->extend((new Extend\Validator(CustomUserValidator::class))->configure(function ($flarumValidator, $validator) {
|
||||
$validator->setRules([
|
||||
'password' => [
|
||||
'required',
|
||||
@@ -31,7 +31,7 @@ class ValidatorTest extends TestCase
|
||||
|
||||
private function extendToRequireLongPasswordViaInvokableClass()
|
||||
{
|
||||
$this->extend((new Extend\Validator(UserValidator::class))->configure(CustomValidatorClass::class));
|
||||
$this->extend((new Extend\Validator(CustomUserValidator::class))->configure(CustomValidatorClass::class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ class ValidatorTest extends TestCase
|
||||
*/
|
||||
public function custom_validation_rule_does_not_exist_by_default()
|
||||
{
|
||||
$this->app()->getContainer()->make(UserValidator::class)->assertValid(['password' => 'simplePassword']);
|
||||
$this->app()->getContainer()->make(CustomUserValidator::class)->assertValid(['password' => 'simplePassword']);
|
||||
|
||||
// If we have gotten this far, no validation exception has been thrown, so the test is succesful.
|
||||
$this->assertTrue(true);
|
||||
@@ -54,7 +54,7 @@ class ValidatorTest extends TestCase
|
||||
|
||||
$this->expectException(ValidationException::class);
|
||||
|
||||
$this->app()->getContainer()->make(UserValidator::class)->assertValid(['password' => 'simplePassword']);
|
||||
$this->app()->getContainer()->make(CustomUserValidator::class)->assertValid(['password' => 'simplePassword']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ class ValidatorTest extends TestCase
|
||||
|
||||
$this->expectException(ValidationException::class);
|
||||
|
||||
$this->app()->getContainer()->make(UserValidator::class)->assertValid(['password' => 'simplePassword']);
|
||||
$this->app()->getContainer()->make(CustomUserValidator::class)->assertValid(['password' => 'simplePassword']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +76,7 @@ class ValidatorTest extends TestCase
|
||||
{
|
||||
$this->extendToRequireLongPassword();
|
||||
|
||||
$this->app()->getContainer()->make(GroupValidator::class)->assertValid(['password' => 'simplePassword']);
|
||||
$this->app()->getContainer()->make(CustomValidator::class)->assertValid(['password' => 'simplePassword']);
|
||||
|
||||
// If we have gotten this far, no validation exception has been thrown, so the test is succesful.
|
||||
$this->assertTrue(true);
|
||||
@@ -95,3 +95,57 @@ class CustomValidatorClass
|
||||
] + $validator->getRules());
|
||||
}
|
||||
}
|
||||
|
||||
class CustomUserValidator extends AbstractValidator
|
||||
{
|
||||
protected ?User $user = null;
|
||||
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
protected function getRules(): array
|
||||
{
|
||||
$idSuffix = $this->user ? ','.$this->user->id : '';
|
||||
|
||||
return [
|
||||
'username' => [
|
||||
'required',
|
||||
'regex:/^[a-z0-9_-]+$/i',
|
||||
'unique:users,username'.$idSuffix,
|
||||
'min:3',
|
||||
'max:30'
|
||||
],
|
||||
'email' => [
|
||||
'required',
|
||||
'email:filter',
|
||||
'unique:users,email'.$idSuffix
|
||||
],
|
||||
'password' => [
|
||||
'required',
|
||||
'min:8'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
protected function getMessages(): array
|
||||
{
|
||||
return [
|
||||
'username.regex' => $this->translator->trans('core.api.invalid_username_message')
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class CustomValidator extends AbstractValidator
|
||||
{
|
||||
protected array $rules = [
|
||||
'name_singular' => ['required'],
|
||||
'name_plural' => ['required']
|
||||
];
|
||||
}
|
||||
|
@@ -34,10 +34,11 @@ class RegisterTest extends TestCase
|
||||
$this->request('POST', '/register')
|
||||
);
|
||||
|
||||
$this->assertEquals(422, $response->getStatusCode());
|
||||
$body = (string) $response->getBody();
|
||||
|
||||
$this->assertEquals(422, $response->getStatusCode(), $body);
|
||||
|
||||
// The response body should contain details about the failed validation
|
||||
$body = (string) $response->getBody();
|
||||
$this->assertJson($body);
|
||||
$this->assertEquals([
|
||||
'errors' => [
|
||||
|
@@ -10,10 +10,10 @@
|
||||
namespace Flarum\Tests\integration\policy;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Flarum\Bus\Dispatcher;
|
||||
use Flarum\Api\JsonApi;
|
||||
use Flarum\Api\Resource\PostResource;
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Flarum\Post\Command\PostReply;
|
||||
use Flarum\Post\Post;
|
||||
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
|
||||
use Flarum\Testing\integration\TestCase;
|
||||
@@ -94,9 +94,30 @@ class DiscussionPolicyTest extends TestCase
|
||||
$this->assertTrue($user->can('rename', $discussion));
|
||||
$this->assertFalse($user->can('rename', $discussionWithReply));
|
||||
|
||||
$this->app()->getContainer()->make(Dispatcher::class)->dispatch(
|
||||
new PostReply(1, User::findOrFail(1), ['attributes' => ['content' => 'test']], null)
|
||||
);
|
||||
/** @var JsonApi $api */
|
||||
$api = $this->app()->getContainer()->make(JsonApi::class);
|
||||
|
||||
$api
|
||||
->forResource(PostResource::class)
|
||||
->forEndpoint('create')
|
||||
->process(
|
||||
body: [
|
||||
'data' => [
|
||||
'attributes' => [
|
||||
'content' => 'test'
|
||||
],
|
||||
'relationships' => [
|
||||
'discussion' => [
|
||||
'data' => [
|
||||
'type' => 'discussions',
|
||||
'id' => '1'
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
options: ['actor' => User::findOrFail(1)]
|
||||
);
|
||||
|
||||
// Date further into the future
|
||||
Carbon::setTestNow('2025-01-01 13:00:00');
|
||||
|
Reference in New Issue
Block a user