- 사용자 초대 API: role 문자열 지원 추가 (React 호환) - 알림 설정 API: 그룹 기반 계층 구조 구현 - notification_setting_groups 테이블 추가 - notification_setting_group_items 테이블 추가 - notification_setting_group_states 테이블 추가 - GET/PUT /api/v1/settings/notifications 엔드포인트 추가 - Pint 코드 스타일 정리
381 lines
12 KiB
PHP
381 lines
12 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Popup;
|
|
|
|
use App\Models\Members\User;
|
|
use App\Models\Members\UserTenant;
|
|
use App\Models\Popups\Popup;
|
|
use App\Models\Tenants\Tenant;
|
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
|
use Tests\TestCase;
|
|
|
|
class PopupApiTest extends TestCase
|
|
{
|
|
use DatabaseTransactions;
|
|
|
|
private Tenant $tenant;
|
|
|
|
private User $user;
|
|
|
|
private string $apiKey;
|
|
|
|
private string $token;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
// 테스트용 API Key 생성
|
|
$this->apiKey = 'test-api-key-'.uniqid();
|
|
\DB::table('api_keys')->insert([
|
|
'key' => $this->apiKey,
|
|
'description' => 'Test API Key',
|
|
'is_active' => true,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
// Tenant 생성 또는 기존 사용
|
|
$this->tenant = Tenant::first() ?? Tenant::withoutEvents(function () {
|
|
return Tenant::create([
|
|
'company_name' => 'Test Company',
|
|
'code' => 'TEST'.uniqid(),
|
|
'email' => 'test@example.com',
|
|
'phone' => '010-1234-5678',
|
|
]);
|
|
});
|
|
|
|
// User 생성
|
|
$testUserId = 'testuser'.uniqid();
|
|
$this->user = User::create([
|
|
'user_id' => $testUserId,
|
|
'name' => 'Test User',
|
|
'email' => $testUserId.'@example.com',
|
|
'password' => bcrypt('password123'),
|
|
]);
|
|
|
|
// UserTenant 관계 생성
|
|
UserTenant::create([
|
|
'user_id' => $this->user->id,
|
|
'tenant_id' => $this->tenant->id,
|
|
'is_active' => true,
|
|
'is_default' => true,
|
|
]);
|
|
|
|
// 로그인 및 토큰 획득
|
|
$this->loginAndGetToken();
|
|
}
|
|
|
|
protected function loginAndGetToken(): void
|
|
{
|
|
$response = $this->withHeaders([
|
|
'X-API-KEY' => $this->apiKey,
|
|
'Accept' => 'application/json',
|
|
])->postJson('/api/v1/login', [
|
|
'user_id' => $this->user->user_id,
|
|
'user_pwd' => 'password123',
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$this->token = $response->json('access_token');
|
|
}
|
|
|
|
protected function authenticatedRequest(string $method, string $uri, array $data = [])
|
|
{
|
|
return $this->withHeaders([
|
|
'X-API-KEY' => $this->apiKey,
|
|
'Authorization' => 'Bearer '.$this->token,
|
|
'Accept' => 'application/json',
|
|
])->{$method.'Json'}($uri, $data);
|
|
}
|
|
|
|
// ==================== Popup CRUD Tests ====================
|
|
|
|
public function test_can_list_popups(): void
|
|
{
|
|
Popup::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'title' => 'Test Popup 1',
|
|
'content' => 'Test content 1',
|
|
'target_type' => 'all',
|
|
'status' => 'active',
|
|
'started_at' => now()->subDay(),
|
|
'ended_at' => now()->addWeek(),
|
|
'created_by' => $this->user->id,
|
|
'updated_by' => $this->user->id,
|
|
]);
|
|
|
|
$response = $this->authenticatedRequest('get', '/api/v1/popups');
|
|
|
|
$response->assertStatus(200)
|
|
->assertJsonStructure([
|
|
'success',
|
|
'message',
|
|
'data',
|
|
]);
|
|
}
|
|
|
|
public function test_can_create_popup(): void
|
|
{
|
|
$response = $this->authenticatedRequest('post', '/api/v1/popups', [
|
|
'title' => 'New Popup',
|
|
'content' => '<h1>Welcome!</h1><p>This is a new popup.</p>',
|
|
'target_type' => 'all',
|
|
'status' => 'active',
|
|
'started_at' => now()->format('Y-m-d H:i:s'),
|
|
'ended_at' => now()->addMonth()->format('Y-m-d H:i:s'),
|
|
]);
|
|
|
|
$response->assertStatus(201)
|
|
->assertJsonStructure([
|
|
'success',
|
|
'message',
|
|
'data' => [
|
|
'id',
|
|
'title',
|
|
'content',
|
|
'target_type',
|
|
'status',
|
|
],
|
|
]);
|
|
|
|
$this->assertDatabaseHas('popups', [
|
|
'title' => 'New Popup',
|
|
'target_type' => 'all',
|
|
'tenant_id' => $this->tenant->id,
|
|
]);
|
|
}
|
|
|
|
public function test_can_show_popup(): void
|
|
{
|
|
$popup = Popup::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'title' => 'Show Test Popup',
|
|
'content' => 'Show test content',
|
|
'target_type' => 'all',
|
|
'status' => 'active',
|
|
'started_at' => now()->subDay(),
|
|
'ended_at' => now()->addWeek(),
|
|
'created_by' => $this->user->id,
|
|
'updated_by' => $this->user->id,
|
|
]);
|
|
|
|
$response = $this->authenticatedRequest('get', "/api/v1/popups/{$popup->id}");
|
|
|
|
$response->assertStatus(200)
|
|
->assertJsonStructure([
|
|
'success',
|
|
'message',
|
|
'data' => [
|
|
'id',
|
|
'title',
|
|
'content',
|
|
],
|
|
])
|
|
->assertJson([
|
|
'data' => [
|
|
'title' => 'Show Test Popup',
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function test_can_update_popup(): void
|
|
{
|
|
$popup = Popup::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'title' => 'Original Popup',
|
|
'content' => 'Original content',
|
|
'target_type' => 'all',
|
|
'status' => 'active',
|
|
'started_at' => now()->subDay(),
|
|
'ended_at' => now()->addWeek(),
|
|
'created_by' => $this->user->id,
|
|
'updated_by' => $this->user->id,
|
|
]);
|
|
|
|
$response = $this->authenticatedRequest('put', "/api/v1/popups/{$popup->id}", [
|
|
'title' => 'Updated Popup',
|
|
'content' => 'Updated content',
|
|
'status' => 'inactive',
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
|
|
$this->assertDatabaseHas('popups', [
|
|
'id' => $popup->id,
|
|
'title' => 'Updated Popup',
|
|
'status' => 'inactive',
|
|
]);
|
|
}
|
|
|
|
public function test_can_delete_popup(): void
|
|
{
|
|
$popup = Popup::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'title' => 'Delete Test Popup',
|
|
'content' => 'Delete test content',
|
|
'target_type' => 'all',
|
|
'status' => 'active',
|
|
'started_at' => now()->subDay(),
|
|
'ended_at' => now()->addWeek(),
|
|
'created_by' => $this->user->id,
|
|
'updated_by' => $this->user->id,
|
|
]);
|
|
|
|
$response = $this->authenticatedRequest('delete', "/api/v1/popups/{$popup->id}");
|
|
|
|
$response->assertStatus(200);
|
|
|
|
$this->assertSoftDeleted('popups', [
|
|
'id' => $popup->id,
|
|
]);
|
|
}
|
|
|
|
// ==================== Active Popups Tests ====================
|
|
|
|
public function test_can_get_active_popups(): void
|
|
{
|
|
// 활성 팝업 (현재 기간 내)
|
|
Popup::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'title' => 'Active Popup',
|
|
'content' => 'Active content',
|
|
'target_type' => 'all',
|
|
'status' => 'active',
|
|
'started_at' => now()->subDay(),
|
|
'ended_at' => now()->addWeek(),
|
|
'created_by' => $this->user->id,
|
|
'updated_by' => $this->user->id,
|
|
]);
|
|
|
|
// 비활성 팝업
|
|
Popup::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'title' => 'Inactive Popup',
|
|
'content' => 'Inactive content',
|
|
'target_type' => 'all',
|
|
'status' => 'inactive',
|
|
'started_at' => now()->subDay(),
|
|
'ended_at' => now()->addWeek(),
|
|
'created_by' => $this->user->id,
|
|
'updated_by' => $this->user->id,
|
|
]);
|
|
|
|
// 기간 만료된 팝업
|
|
Popup::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'title' => 'Expired Popup',
|
|
'content' => 'Expired content',
|
|
'target_type' => 'all',
|
|
'status' => 'active',
|
|
'started_at' => now()->subMonth(),
|
|
'ended_at' => now()->subWeek(),
|
|
'created_by' => $this->user->id,
|
|
'updated_by' => $this->user->id,
|
|
]);
|
|
|
|
$response = $this->authenticatedRequest('get', '/api/v1/popups/active');
|
|
|
|
$response->assertStatus(200);
|
|
|
|
$data = $response->json('data');
|
|
$this->assertIsArray($data);
|
|
|
|
// 활성 팝업만 반환되어야 함
|
|
$titles = collect($data)->pluck('title')->toArray();
|
|
$this->assertContains('Active Popup', $titles);
|
|
$this->assertNotContains('Inactive Popup', $titles);
|
|
$this->assertNotContains('Expired Popup', $titles);
|
|
}
|
|
|
|
public function test_active_popups_respects_date_range(): void
|
|
{
|
|
// 아직 시작 안 된 팝업
|
|
Popup::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'title' => 'Future Popup',
|
|
'content' => 'Future content',
|
|
'target_type' => 'all',
|
|
'status' => 'active',
|
|
'started_at' => now()->addWeek(),
|
|
'ended_at' => now()->addMonth(),
|
|
'created_by' => $this->user->id,
|
|
'updated_by' => $this->user->id,
|
|
]);
|
|
|
|
$response = $this->authenticatedRequest('get', '/api/v1/popups/active');
|
|
|
|
$response->assertStatus(200);
|
|
|
|
$data = $response->json('data');
|
|
$titles = collect($data)->pluck('title')->toArray();
|
|
$this->assertNotContains('Future Popup', $titles);
|
|
}
|
|
|
|
// ==================== Target Type Tests ====================
|
|
|
|
public function test_can_create_popup_with_department_target(): void
|
|
{
|
|
// TODO: FormRequest 유효성 검사 규칙에 따라 target_id 검증 필요
|
|
// 현재 API는 target_type=department일 때 추가 검증이 있을 수 있음
|
|
$this->markTestSkipped('Department target validation rules need to be verified');
|
|
|
|
$response = $this->authenticatedRequest('post', '/api/v1/popups', [
|
|
'title' => 'Department Popup',
|
|
'content' => 'For specific department',
|
|
'target_type' => 'department',
|
|
'target_id' => 1,
|
|
'status' => 'active',
|
|
'started_at' => now()->format('Y-m-d H:i:s'),
|
|
'ended_at' => now()->addMonth()->format('Y-m-d H:i:s'),
|
|
]);
|
|
|
|
$response->assertStatus(201);
|
|
|
|
$this->assertDatabaseHas('popups', [
|
|
'title' => 'Department Popup',
|
|
'target_type' => 'department',
|
|
'target_id' => 1,
|
|
]);
|
|
}
|
|
|
|
// ==================== Validation Tests ====================
|
|
|
|
public function test_cannot_create_popup_without_required_fields(): void
|
|
{
|
|
$response = $this->authenticatedRequest('post', '/api/v1/popups', [
|
|
// title 누락
|
|
'content' => 'Some content',
|
|
]);
|
|
|
|
$response->assertStatus(422);
|
|
}
|
|
|
|
public function test_cannot_create_popup_with_invalid_date_range(): void
|
|
{
|
|
$response = $this->authenticatedRequest('post', '/api/v1/popups', [
|
|
'title' => 'Invalid Date Popup',
|
|
'content' => 'Content',
|
|
'target_type' => 'all',
|
|
'status' => 'active',
|
|
'started_at' => now()->addMonth()->format('Y-m-d H:i:s'),
|
|
'ended_at' => now()->format('Y-m-d H:i:s'), // 시작일보다 이전
|
|
]);
|
|
|
|
// 유효성 검사 실패 예상
|
|
$response->assertStatus(422);
|
|
}
|
|
|
|
// ==================== Authentication Tests ====================
|
|
|
|
public function test_cannot_access_popups_without_authentication(): void
|
|
{
|
|
$response = $this->withHeaders([
|
|
'X-API-KEY' => $this->apiKey,
|
|
'Accept' => 'application/json',
|
|
])->getJson('/api/v1/popups');
|
|
|
|
$response->assertStatus(401);
|
|
}
|
|
}
|