검색 — 이 코어에 추가한 BOOLEAN MODE 정제기가 게시판에는 도달하지 않아 원문 키워드가 그대로 바인딩되고 있었다. + - * " < > 를 넣으면 오류 화면이 떴다. 코어 정제기 경유로 옮겼고, 같은 술어를 count 와 get 으로 두 번 실행하던 것을 페이지네이터 한 번으로 합쳤다. 구체 엔진 직접 호출도 해석기 경유로 바꿔 플러그인 검색엔진이 게시글·신고 검색에 적용된다. 상세 — 같은 글을 3회, 같은 게시판을 5회 읽고 있었다. 조회한 인스턴스를 넘겨 글 1회·게시판 1회로 줄였고, 조회수 증가를 권한 확인 뒤로 옮겨 열람 권한이 없는 요청이 조회수를 올리지 않게 했다. 목록 — 답변 트리의 무제한 조회에 상한과 순환 가드를 두고, O(n²) 병합을 한 패스로 바꿨다. 댓글도 무제한 조회에 상한을 두되 잘렸다는 사실과 전체 건수를 함께 알린다. 조용히 잘리면 "댓글이 그만큼뿐" 으로 보인다. 원댓글 단위 페이지네이션을 더해 답글이 부모와 떨어지지 않게 했다. 관리자 화면 — 총 건수가 잘린 목록에서 페이저가 "1페이지뿐" 으로 접히던 자리를 고쳤다. 저장소가 상한을 붙인 목록인데 화면이 그 값을 1 로 채우고 있어, 기록이 상한을 넘으면 2페이지에 도달할 방법이 없었다. 같은 파일에서 드러난 사전 결함도 함께 처리했다 — 반복 렌더 안의 정적 HTML id, Icon 의 박스 크기 지정, 단색 버튼의 다크 모드 대비.
105 lines
3.4 KiB
PHP
105 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace Modules\Sirsoft\Board\Tests\Feature;
|
|
|
|
use Modules\Sirsoft\Board\Models\Comment;
|
|
use Modules\Sirsoft\Board\Models\Post;
|
|
use Modules\Sirsoft\Board\Repositories\Contracts\CommentRepositoryInterface;
|
|
use Modules\Sirsoft\Board\Repositories\Contracts\PostRepositoryInterface;
|
|
use Modules\Sirsoft\Board\Tests\BoardTestCase;
|
|
use Tests\Concerns\CountsQueries;
|
|
|
|
/**
|
|
* 게시판 목록 조회의 쿼리 수 회귀 테스트 (#519)
|
|
*
|
|
* 행 수를 늘려도 쿼리 수가 늘지 않는지 단언한다 — 그것이 N+1 의 정의이고,
|
|
* 정상적인 구조 변경(관계 추가 등)에는 반응하지 않는다.
|
|
*
|
|
* @scenario case=list_query_count
|
|
*
|
|
* @effects post_list_query_count_stable,
|
|
* comment_tree_query_count_stable
|
|
*/
|
|
class ListQueryCountRegressionTest extends BoardTestCase
|
|
{
|
|
use CountsQueries;
|
|
|
|
/**
|
|
* 게시글을 원하는 수만큼 만듭니다.
|
|
*
|
|
* @param int $count 생성할 수
|
|
* @param string $prefix 제목 접두
|
|
*/
|
|
private function seedPosts(int $count, string $prefix): void
|
|
{
|
|
for ($i = 0; $i < $count; $i++) {
|
|
Post::create([
|
|
'board_id' => $this->board->id,
|
|
'title' => $prefix.' '.$i,
|
|
'content' => '본문',
|
|
'author_name' => '작성자',
|
|
'status' => 'published',
|
|
'ip_address' => '127.0.0.1',
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 게시글 목록: 글 수가 늘어도 쿼리 수가 늘지 않는지 확인
|
|
*
|
|
* @effects post_list_query_count_stable
|
|
*/
|
|
public function test_post_list_query_count_is_stable(): void
|
|
{
|
|
$repository = app(PostRepositoryInterface::class);
|
|
$this->seedPosts(5, '초기');
|
|
|
|
$this->assertQueryCountStableAsDataGrows(
|
|
measure: fn () => $repository->paginate($this->board->slug, [], 50, false, $this->board),
|
|
grow: fn () => $this->seedPosts(10, '추가'),
|
|
context: '게시글 목록',
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 댓글 트리: 댓글 수가 늘어도 쿼리 수가 늘지 않는지 확인
|
|
*
|
|
* 종전에는 부모 댓글을 관계로 다시 불러 같은 집합을 한 번 더 가져왔다.
|
|
*
|
|
* @effects comment_tree_query_count_stable
|
|
*/
|
|
public function test_comment_tree_query_count_is_stable(): void
|
|
{
|
|
$repository = app(CommentRepositoryInterface::class);
|
|
|
|
$post = Post::create([
|
|
'board_id' => $this->board->id,
|
|
'title' => '댓글 트리',
|
|
'content' => '본문',
|
|
'author_name' => '작성자',
|
|
'status' => 'published',
|
|
'ip_address' => '127.0.0.1',
|
|
]);
|
|
|
|
$seedComments = function (int $count, string $prefix) use ($post) {
|
|
for ($i = 0; $i < $count; $i++) {
|
|
Comment::create([
|
|
'board_id' => $this->board->id,
|
|
'post_id' => $post->id,
|
|
'content' => $prefix.' '.$i,
|
|
'author_name' => '댓글쓴이',
|
|
'ip_address' => '127.0.0.1',
|
|
]);
|
|
}
|
|
};
|
|
|
|
$seedComments(5, '초기');
|
|
|
|
$this->assertQueryCountStableAsDataGrows(
|
|
measure: fn () => $repository->getByPostId($this->board->slug, $post->id, boardId: $this->board->id),
|
|
grow: fn () => $seedComments(10, '추가'),
|
|
context: '댓글 트리',
|
|
);
|
|
}
|
|
}
|