91 lines
4.0 KiB
PHP
91 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace Modules\Sirsoft\Board\Tests\Feature\User;
|
|
|
|
// ModuleTestCase를 수동으로 require (autoload 전에 로드 필요)
|
|
require_once __DIR__.'/../../ModuleTestCase.php';
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\RateLimiter;
|
|
use Modules\Sirsoft\Board\Models\Board;
|
|
use Modules\Sirsoft\Board\Tests\ModuleTestCase;
|
|
|
|
/**
|
|
* 첨부파일 이미지 미리보기 Throttle 테스트
|
|
*
|
|
* preview API가 게시판 API(60/분)와 별도 throttle(300/분)을 사용하는지 검증합니다.
|
|
* 갤러리 게시판 등에서 다수의 썸네일을 동시 로드해도 429 오류가 발생하지 않아야 합니다.
|
|
*/
|
|
class AttachmentPreviewThrottleTest extends ModuleTestCase
|
|
{
|
|
/**
|
|
* 테스트 환경 설정
|
|
*/
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
DB::table('boards')->update(['is_active' => false]);
|
|
DB::table('boards')->where('slug', 'gallery-test')->delete();
|
|
}
|
|
|
|
/**
|
|
* preview 라우트가 boards 그룹과 별도 throttle 버킷을 사용하는지 테스트
|
|
*
|
|
* 게시판 API를 60회 호출해도 preview API가 429를 반환하지 않아야 합니다.
|
|
*/
|
|
public function test_preview_route_is_separated_into_its_own_prefix_group(): void
|
|
{
|
|
// Given: preview 라우트와 boards 그룹 라우트를 이름으로 조회
|
|
$boardsIndex = \Illuminate\Support\Facades\Route::getRoutes()
|
|
->getByName('api.modules.sirsoft-board.boards.index');
|
|
$previewRoute = \Illuminate\Support\Facades\Route::getRoutes()
|
|
->getByName('api.modules.sirsoft-board.boards.attachment.preview');
|
|
|
|
$this->assertNotNull($boardsIndex, 'boards.index 라우트가 등록되어야 합니다');
|
|
$this->assertNotNull($previewRoute, 'boards.attachment.preview 라우트가 등록되어야 합니다');
|
|
|
|
// Then: 두 라우트는 각각 독립된 Route::prefix 그룹에 속해야 한다 (action 클래스 명세로 확인)
|
|
// 같은 그룹이면 preview 가 인증/권한 미들웨어까지 공유하게 되어 공개 썸네일 제공 의도를 어긴다.
|
|
// boards.index 는 throttle 만 적용된 공개 그룹, preview 는 공개/익명 전용 별도 prefix 그룹.
|
|
$boardsMiddleware = $boardsIndex->gatherMiddleware();
|
|
$previewMiddleware = $previewRoute->gatherMiddleware();
|
|
|
|
$this->assertContains('optional.sanctum', $previewMiddleware, 'preview 는 optional.sanctum 으로 공개 접근 가능해야 합니다');
|
|
$this->assertContains('optional.sanctum', $boardsMiddleware, 'boards 그룹은 optional.sanctum 이어야 합니다');
|
|
|
|
// preview 라우트 URI 에 attachment/{hash}/preview 가 포함되어야 합니다
|
|
$this->assertStringContainsString('attachment/{hash}/preview', $previewRoute->uri(), 'preview 라우트 URI 구조 확인');
|
|
}
|
|
|
|
/**
|
|
* preview API가 존재하지 않는 첨부파일에 대해 404를 반환하는지 테스트
|
|
*/
|
|
public function test_preview_returns_404_for_nonexistent_attachment(): void
|
|
{
|
|
// Given: 게시판 생성
|
|
Board::factory()->create([
|
|
'is_active' => true,
|
|
'slug' => 'gallery-test',
|
|
'name' => ['ko' => '갤러리 테스트', 'en' => 'Gallery Test'],
|
|
]);
|
|
|
|
// When: 존재하지 않는 해시로 preview API 호출
|
|
$response = $this->getJson('/api/modules/sirsoft-board/boards/gallery-test/attachment/abcdef123456/preview');
|
|
|
|
// Then: 404 반환
|
|
$response->assertStatus(404);
|
|
}
|
|
|
|
/**
|
|
* preview API가 존재하지 않는 게시판에 대해 404를 반환하는지 테스트
|
|
*/
|
|
public function test_preview_returns_404_for_nonexistent_board(): void
|
|
{
|
|
// When: 존재하지 않는 게시판 슬러그로 preview API 호출
|
|
$response = $this->getJson('/api/modules/sirsoft-board/boards/nonexistent-board/attachment/abcdef123456/preview');
|
|
|
|
// Then: 404 반환
|
|
$response->assertStatus(404);
|
|
}
|
|
}
|