test set creation endpoint
This commit is contained in:
parent
737ad430f7
commit
50df56a0cb
1 changed files with 122 additions and 0 deletions
|
|
@ -2,11 +2,20 @@
|
||||||
|
|
||||||
namespace Tests\Feature;
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use App\Auth\CreateSessionDto;
|
||||||
|
use App\Auth\SessionRepository;
|
||||||
use App\Element\CreateElementDto;
|
use App\Element\CreateElementDto;
|
||||||
use App\Element\ElementRepository;
|
use App\Element\ElementRepository;
|
||||||
use App\Set\CreateSetDto;
|
use App\Set\CreateSetDto;
|
||||||
use App\Set\SetRepository;
|
use App\Set\SetRepository;
|
||||||
|
use App\Shared\ValueObject\EmailAddress;
|
||||||
|
use App\User\CreateUserDto;
|
||||||
|
use App\User\UserRepository;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use DateTimeZone;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Illuminate\Http\UploadedFile;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
class SetsEndpointTest extends TestCase
|
class SetsEndpointTest extends TestCase
|
||||||
|
|
@ -63,4 +72,117 @@ class SetsEndpointTest extends TestCase
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCreateSetRequiresAuthentication(): void
|
||||||
|
{
|
||||||
|
$response = $this->postJson('/api/sets', [
|
||||||
|
'name' => 'New Series',
|
||||||
|
'description' => 'A new learning series',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertUnauthorized();
|
||||||
|
$response->assertExactJson([
|
||||||
|
'error' => 'unauthenticated',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAuthenticatedCreateSetCreatesRootElement(): void
|
||||||
|
{
|
||||||
|
Storage::fake('public');
|
||||||
|
$setRepository = app(SetRepository::class);
|
||||||
|
$elementRepository = app(ElementRepository::class);
|
||||||
|
$this->createSession('valid-token');
|
||||||
|
|
||||||
|
$response = $this->withCredentials()
|
||||||
|
->withUnencryptedCookie('auth_token', 'valid-token')
|
||||||
|
->post('/api/sets', [
|
||||||
|
'name' => 'New Series',
|
||||||
|
'description' => 'A new learning series',
|
||||||
|
'iconImage' => $this->iconImageUpload(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertCreated();
|
||||||
|
$body = $response->json();
|
||||||
|
$setId = $body['set']['id'];
|
||||||
|
$rootElementId = $body['set']['rootElementId'];
|
||||||
|
$this->assertIsInt($setId);
|
||||||
|
$this->assertIsInt($rootElementId);
|
||||||
|
$this->assertSame('New Series', $body['set']['name']);
|
||||||
|
$this->assertSame(
|
||||||
|
'A new learning series',
|
||||||
|
$body['set']['description'],
|
||||||
|
);
|
||||||
|
$this->assertStringContainsString(
|
||||||
|
'/storage/set-icons/',
|
||||||
|
$body['set']['iconImageUrl'],
|
||||||
|
);
|
||||||
|
|
||||||
|
$createdSet = $setRepository->find($setId);
|
||||||
|
$this->assertNotNull($createdSet);
|
||||||
|
$rootElement = $elementRepository->findRootBySet($createdSet);
|
||||||
|
$this->assertNotNull($rootElement);
|
||||||
|
$this->assertSame($rootElementId, $rootElement->getId());
|
||||||
|
$this->assertSame('New Series', $rootElement->getTitle());
|
||||||
|
$this->assertSame(
|
||||||
|
'A new learning series',
|
||||||
|
$rootElement->getDescription(),
|
||||||
|
);
|
||||||
|
$storedIconPath = $createdSet->getIconImageUrl();
|
||||||
|
$this->assertStringStartsWith('set-icons/', $storedIconPath);
|
||||||
|
$this->assertSame($storedIconPath, $rootElement->getIconImageUrl());
|
||||||
|
Storage::disk('public')->assertExists($storedIconPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateSetRequiresIconImage(): void
|
||||||
|
{
|
||||||
|
$this->createSession('valid-token');
|
||||||
|
|
||||||
|
$response = $this->withCredentials()
|
||||||
|
->withUnencryptedCookie('auth_token', 'valid-token')
|
||||||
|
->post('/api/sets', [
|
||||||
|
'name' => 'New Series',
|
||||||
|
'description' => 'A new learning series',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertBadRequest();
|
||||||
|
$response->assertExactJson([
|
||||||
|
'error' => 'icon image is required',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createSession(string $token): void
|
||||||
|
{
|
||||||
|
$userRepository = app(UserRepository::class);
|
||||||
|
$sessionRepository = app(SessionRepository::class);
|
||||||
|
$user = $userRepository->create(new CreateUserDto(
|
||||||
|
email: new EmailAddress('admin@example.com'),
|
||||||
|
passwordHash: 'password-hash',
|
||||||
|
));
|
||||||
|
$now = new DateTimeImmutable(
|
||||||
|
'2026-05-01T00:00:00',
|
||||||
|
new DateTimeZone('UTC'),
|
||||||
|
);
|
||||||
|
$sessionRepository->create(new CreateSessionDto(
|
||||||
|
token: $token,
|
||||||
|
user: $user,
|
||||||
|
createdAt: $now,
|
||||||
|
expiresAt: new DateTimeImmutable(
|
||||||
|
'2099-01-01T00:00:00',
|
||||||
|
new DateTimeZone('UTC'),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function iconImageUpload(): UploadedFile
|
||||||
|
{
|
||||||
|
$fixturePath = __DIR__ . '/../fixtures/icon.png';
|
||||||
|
|
||||||
|
return new UploadedFile(
|
||||||
|
$fixturePath,
|
||||||
|
'icon.png',
|
||||||
|
'image/png',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue