test text controller scoping and ownership

add failing tests for getMyTexts (own-only), getAllTexts
(admin), getText 403 for non-owner, and admin bypass on
getText. existing test_get_one_text updated to pass the
session user via the new request signature.
This commit is contained in:
Yisroel Baum 2026-05-02 21:41:52 +03:00
parent cbbbc80326
commit ea6d65a77d
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9

View file

@ -25,6 +25,10 @@ class TextControllerTest extends TestCase
private User $user; private User $user;
private User $otherUser;
private User $admin;
public function setUp(): void public function setUp(): void
{ {
$this->textRepo = new FakeTextRepository(); $this->textRepo = new FakeTextRepository();
@ -34,6 +38,16 @@ class TextControllerTest extends TestCase
passwordHash: '', passwordHash: '',
isAdmin: false, isAdmin: false,
)); ));
$this->otherUser = $this->userRepo->create(new CreateUserDto(
email: new EmailAddress('other@b.com'),
passwordHash: '',
isAdmin: false,
));
$this->admin = $this->userRepo->create(new CreateUserDto(
email: new EmailAddress('admin@b.com'),
passwordHash: '',
isAdmin: true,
));
$this->textRepo->create(new CreateTextDto( $this->textRepo->create(new CreateTextDto(
name: 'test text', name: 'test text',
user: $this->user, user: $this->user,
@ -41,9 +55,20 @@ class TextControllerTest extends TestCase
$this->controller = new TextController($this->textRepo); $this->controller = new TextController($this->textRepo);
} }
private function makeRequest(?User $user): \Psr\Http\Message\ServerRequestInterface
{
$request = new ServerRequestFactory()
->createServerRequest('GET', 'http://localhost/texts');
if ($user !== null) {
$request = $request->withAttribute('user', $user);
}
return $request;
}
public function test_get_one_text(): void public function test_get_one_text(): void
{ {
$response = $this->controller->getText( $response = $this->controller->getText(
$this->makeRequest($this->user),
new Response(), new Response(),
0, 0,
); );
@ -56,13 +81,50 @@ class TextControllerTest extends TestCase
); );
} }
public function test_get_all_texts(): void public function test_get_text_returns_404_when_not_found(): void
{
$response = $this->controller->getText(
$this->makeRequest($this->user),
new Response(),
99,
);
$this->assertEquals(404, $response->getStatusCode());
}
public function test_get_text_returns_403_when_not_owner(): void
{
$response = $this->controller->getText(
$this->makeRequest($this->otherUser),
new Response(),
0,
);
$this->assertEquals(403, $response->getStatusCode());
}
public function test_get_text_allows_admin_to_read_any_text(): void
{
$response = $this->controller->getText(
$this->makeRequest($this->admin),
new Response(),
0,
);
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals(
json_encode([
'id' => 0,
'name' => 'test text',
]),
$response->getBody()
);
}
public function test_get_all_texts_returns_every_text(): void
{ {
$this->textRepo->create(new CreateTextDto( $this->textRepo->create(new CreateTextDto(
name: 'test text 2', name: 'other users text',
user: $this->user, user: $this->otherUser,
)); ));
$response = $this->controller->getTexts(new Response()); $response = $this->controller->getAllTexts(new Response());
$this->assertEquals( $this->assertEquals(
json_encode([ json_encode([
[ [
@ -71,13 +133,51 @@ class TextControllerTest extends TestCase
], ],
[ [
'id' => 1, 'id' => 1,
'name' => 'test text 2', 'name' => 'other users text',
], ],
]), ]),
$response->getBody() $response->getBody()
); );
} }
public function test_get_my_texts_returns_only_own_texts(): void
{
$this->textRepo->create(new CreateTextDto(
name: 'other users text',
user: $this->otherUser,
));
$this->textRepo->create(new CreateTextDto(
name: 'second of mine',
user: $this->user,
));
$response = $this->controller->getMyTexts(
$this->makeRequest($this->user),
new Response(),
);
$this->assertEquals(
json_encode([
[
'id' => 0,
'name' => 'test text',
],
[
'id' => 2,
'name' => 'second of mine',
],
]),
$response->getBody()
);
}
public function test_get_my_texts_returns_empty_when_user_has_none(): void
{
$response = $this->controller->getMyTexts(
$this->makeRequest($this->otherUser),
new Response(),
);
$this->assertEquals(json_encode([]), $response->getBody());
}
public function test_create_text(): void public function test_create_text(): void
{ {
$request = new ServerRequestFactory() $request = new ServerRequestFactory()
@ -149,16 +249,11 @@ class TextControllerTest extends TestCase
public function test_create_text_ignores_user_id_in_body(): void public function test_create_text_ignores_user_id_in_body(): void
{ {
$otherUser = $this->userRepo->create(new CreateUserDto(
email: new EmailAddress('other@b.com'),
passwordHash: '',
isAdmin: false,
));
$request = new ServerRequestFactory() $request = new ServerRequestFactory()
->createServerRequest('POST', 'http://localhost/texts') ->createServerRequest('POST', 'http://localhost/texts')
->withParsedBody([ ->withParsedBody([
'name' => 'my new text', 'name' => 'my new text',
'userId' => $otherUser->getId(), 'userId' => $this->otherUser->getId(),
]) ])
->withAttribute('user', $this->user); ->withAttribute('user', $this->user);