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); } }