Files
sam-api/tests/Feature/Account/AccountApiTest.php
hskwon a27b1b2091 feat: Phase 5.1-1 사용자 초대 + Phase 5.2 알림 설정 API 연동
- 사용자 초대 API: role 문자열 지원 추가 (React 호환)
- 알림 설정 API: 그룹 기반 계층 구조 구현
  - notification_setting_groups 테이블 추가
  - notification_setting_group_items 테이블 추가
  - notification_setting_group_states 테이블 추가
  - GET/PUT /api/v1/settings/notifications 엔드포인트 추가
- Pint 코드 스타일 정리
2025-12-22 17:42:59 +09:00

258 lines
7.8 KiB
PHP

<?php
namespace Tests\Feature\Account;
use App\Models\Members\User;
use App\Models\Members\UserTenant;
use App\Models\Tenants\Tenant;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;
class AccountApiTest 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);
}
// ==================== Agreements Tests ====================
public function test_can_get_agreements(): void
{
$response = $this->authenticatedRequest('get', '/api/v1/account/agreements');
$response->assertStatus(200)
->assertJsonStructure([
'success',
'message',
'data',
]);
}
public function test_can_update_agreements(): void
{
$response = $this->authenticatedRequest('put', '/api/v1/account/agreements', [
'marketing_agreed' => true,
'privacy_agreed' => true,
]);
// 200 또는 422 (검증 규칙에 따라)
$this->assertContains($response->status(), [200, 422]);
}
// ==================== Suspend Tests ====================
public function test_can_suspend_account_from_tenant(): void
{
// 추가 사용자 생성 후 테스트 (원본 사용자 유지)
$newUserId = 'suspendtest'.uniqid();
$newUser = User::create([
'user_id' => $newUserId,
'name' => 'Suspend Test User',
'email' => $newUserId.'@example.com',
'password' => bcrypt('password123'),
]);
UserTenant::create([
'user_id' => $newUser->id,
'tenant_id' => $this->tenant->id,
'is_active' => true,
'is_default' => true,
]);
// 새 사용자로 로그인
$loginResponse = $this->withHeaders([
'X-API-KEY' => $this->apiKey,
'Accept' => 'application/json',
])->postJson('/api/v1/login', [
'user_id' => $newUser->user_id,
'user_pwd' => 'password123',
]);
$newToken = $loginResponse->json('access_token');
// 사용 중지 요청
$response = $this->withHeaders([
'X-API-KEY' => $this->apiKey,
'Authorization' => 'Bearer '.$newToken,
'Accept' => 'application/json',
])->postJson('/api/v1/account/suspend');
// 성공 또는 구현에 따른 응답
$this->assertContains($response->status(), [200, 400, 422]);
}
// ==================== Withdraw Tests ====================
public function test_withdraw_requires_password_confirmation(): void
{
$response = $this->authenticatedRequest('post', '/api/v1/account/withdraw', [
// 비밀번호 없이 요청
]);
// 검증 실패 예상
$response->assertStatus(422);
}
public function test_withdraw_with_wrong_password_fails(): void
{
$response = $this->authenticatedRequest('post', '/api/v1/account/withdraw', [
'password' => 'wrongpassword',
'reason' => '테스트 탈퇴',
]);
// 비밀번호 불일치 - 401 또는 422
$this->assertContains($response->status(), [400, 401, 422]);
}
public function test_can_withdraw_with_correct_password(): void
{
// 탈퇴 테스트용 새 사용자 생성
$withdrawUserId = 'withdrawtest'.uniqid();
$withdrawUser = User::create([
'user_id' => $withdrawUserId,
'name' => 'Withdraw Test User',
'email' => $withdrawUserId.'@example.com',
'password' => bcrypt('password123'),
]);
UserTenant::create([
'user_id' => $withdrawUser->id,
'tenant_id' => $this->tenant->id,
'is_active' => true,
'is_default' => true,
]);
// 새 사용자로 로그인
$loginResponse = $this->withHeaders([
'X-API-KEY' => $this->apiKey,
'Accept' => 'application/json',
])->postJson('/api/v1/login', [
'user_id' => $withdrawUser->user_id,
'user_pwd' => 'password123',
]);
$newToken = $loginResponse->json('access_token');
// 회원 탈퇴 요청
$response = $this->withHeaders([
'X-API-KEY' => $this->apiKey,
'Authorization' => 'Bearer '.$newToken,
'Accept' => 'application/json',
])->postJson('/api/v1/account/withdraw', [
'password' => 'password123',
'reason' => '테스트 탈퇴입니다.',
]);
// 성공 또는 구현에 따른 응답
$this->assertContains($response->status(), [200, 400, 422]);
}
// ==================== Authentication Tests ====================
public function test_cannot_access_agreements_without_authentication(): void
{
$response = $this->withHeaders([
'X-API-KEY' => $this->apiKey,
'Accept' => 'application/json',
])->getJson('/api/v1/account/agreements');
$response->assertStatus(401);
}
public function test_cannot_suspend_without_authentication(): void
{
$response = $this->withHeaders([
'X-API-KEY' => $this->apiKey,
'Accept' => 'application/json',
])->postJson('/api/v1/account/suspend');
$response->assertStatus(401);
}
public function test_cannot_withdraw_without_authentication(): void
{
$response = $this->withHeaders([
'X-API-KEY' => $this->apiKey,
'Accept' => 'application/json',
])->postJson('/api/v1/account/withdraw', [
'password' => 'password123',
]);
$response->assertStatus(401);
}
}