Files
2026-04-23 17:36:31 +09:00

143 lines
4.2 KiB
PHP

<?php
namespace Tests\Unit\Support;
use App\Support\UmaskHelper;
use Illuminate\Support\Facades\File;
use Tests\TestCase;
/**
* UmaskHelper::configureForGroupSharing 단위 테스트
*
* 운영자 의도 존중 umask 조정 헬퍼. 본 테스트는 POSIX 의미의 `fileperms` 와
* `umask` 동작을 검증하므로 Linux 환경에서만 의미 있는 결과를 낸다. Windows
* 에서는 자동 스킵.
*/
class UmaskHelperTest extends TestCase
{
private string $tmpRoot;
private int $originalUmask;
protected function setUp(): void
{
parent::setUp();
$this->originalUmask = umask();
$this->tmpRoot = storage_path('app/test-umask-helper-'.uniqid());
File::ensureDirectoryExists($this->tmpRoot);
}
protected function tearDown(): void
{
// 헬퍼 호출로 변경된 umask 를 원래대로 복원 (다른 테스트 격리)
umask($this->originalUmask);
if (File::isDirectory($this->tmpRoot)) {
File::deleteDirectory($this->tmpRoot);
}
parent::tearDown();
}
private function assertPosixOrSkip(): void
{
if (DIRECTORY_SEPARATOR !== '/' || ! function_exists('posix_getuid')) {
$this->markTestSkipped('POSIX 전용 — Windows 에서는 fileperms/umask 의미 제한');
}
}
/**
* storage 디렉토리에 g+w 가 설정되어 있으면 umask 를 0002 로 조정하고
* 이전 umask 를 반환한다.
*/
public function test_sets_umask_when_storage_has_group_write(): void
{
$this->assertPosixOrSkip();
chmod($this->tmpRoot, 0775);
// 초기 umask 를 0022 로 고정해 비교 가능하게
umask(0022);
$previous = UmaskHelper::configureForGroupSharing($this->tmpRoot);
$this->assertSame(0022, $previous, '이전 umask 를 반환해야 한다');
$this->assertSame(0002, umask(), '현재 umask 는 0002 로 조정되어야 한다');
}
/**
* storage 디렉토리가 g-w 이면 운영자 의도 존중 — null 반환 + umask 변경 없음.
*/
public function test_skips_when_storage_has_no_group_write(): void
{
$this->assertPosixOrSkip();
chmod($this->tmpRoot, 0755);
umask(0022);
$result = UmaskHelper::configureForGroupSharing($this->tmpRoot);
$this->assertNull($result, 'g-w 환경에서는 null 반환 (no-op)');
$this->assertSame(0022, umask(), 'umask 는 변경되지 않아야 한다');
}
/**
* 지정한 경로가 디렉토리가 아니면 null.
*/
public function test_returns_null_when_path_is_not_a_directory(): void
{
$this->assertPosixOrSkip();
$nonExistent = $this->tmpRoot.'/does-not-exist';
umask(0022);
$result = UmaskHelper::configureForGroupSharing($nonExistent);
$this->assertNull($result);
$this->assertSame(0022, umask(), 'umask 는 변경되지 않아야 한다');
}
/**
* 조정 후 런타임이 만드는 새 디렉토리가 실제로 g+w 를 포함하는지 검증.
* umask 조정의 최종 효과를 확인.
*/
public function test_new_directory_inherits_group_write_after_adjustment(): void
{
$this->assertPosixOrSkip();
chmod($this->tmpRoot, 0775);
umask(0022);
UmaskHelper::configureForGroupSharing($this->tmpRoot);
$newDir = $this->tmpRoot.'/new-child';
mkdir($newDir, 0777);
$perms = fileperms($newDir) & 0777;
$this->assertSame(0775, $perms, '조정된 umask(0002) 기준 mkdir 결과는 0775 여야 한다');
}
/**
* 원상 복원 — 헬퍼가 이전 umask 를 반환하므로 호출자가 그 값으로 되돌릴 수 있다.
*/
public function test_caller_can_restore_previous_umask(): void
{
$this->assertPosixOrSkip();
chmod($this->tmpRoot, 0775);
umask(0022);
$previous = UmaskHelper::configureForGroupSharing($this->tmpRoot);
$this->assertSame(0022, $previous);
$this->assertSame(0002, umask());
// 호출자가 반환값으로 원상 복원
umask($previous);
$this->assertSame(0022, umask());
}
}