package cn.novalon.gym.manage.gateway.audit;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpMethod;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;

import java.net.InetSocketAddress;

import static org.junit.jupiter.api.Assertions.*;

/**
 * AuditLogService单元测试
 * 
 * 文件定义：测试审计日志服务的核心功能
 * 涉及业务：请求日志记录、响应日志记录、安全事件记录
 * 
 * @author 张翔
 * @date 2026-03-26
 */
@ExtendWith(MockitoExtension.class)
class AuditLogServiceTest {

    private AuditLogService auditLogService;

    @BeforeEach
    void setUp() {
        auditLogService = new AuditLogService();
    }

    @Test
    void testLogRequest() {
        MockServerHttpRequest request = MockServerHttpRequest
                .method(HttpMethod.GET, "/api/users")
                .header("X-Request-Id", "test-request-123")
                .header("User-Agent", "TestAgent")
                .remoteAddress(new InetSocketAddress("192.168.1.1", 8080))
                .build();

        assertDoesNotThrow(() -> auditLogService.logRequest(request, "user123"));
    }

    @Test
    void testLogResponse() {
        MockServerHttpRequest request = MockServerHttpRequest
                .method(HttpMethod.GET, "/api/users")
                .header("X-Request-Id", "test-request-456")
                .build();

        auditLogService.logRequest(request, "user123");

        assertDoesNotThrow(() -> auditLogService.logResponse("test-request-456", 200, 150));
    }

    @Test
    void testLogSecurityEvent() {
        MockServerHttpRequest request = MockServerHttpRequest
                .method(HttpMethod.GET, "/api/admin")
                .header("X-Request-Id", "test-request-789")
                .build();

        auditLogService.logRequest(request, "user123");

        assertDoesNotThrow(() -> 
                auditLogService.logSecurityEvent("test-request-789", "UNAUTHORIZED_ACCESS", "User attempted to access admin resource"));
    }

    @Test
    void testLogError() {
        MockServerHttpRequest request = MockServerHttpRequest
                .method(HttpMethod.POST, "/api/data")
                .header("X-Request-Id", "test-request-error")
                .build();

        auditLogService.logRequest(request, "user123");

        assertDoesNotThrow(() -> 
                auditLogService.logError("test-request-error", "INTERNAL_ERROR", "Database connection failed"));
    }

    @Test
    void testLogRequestWithoutRequestId() {
        MockServerHttpRequest request = MockServerHttpRequest
                .method(HttpMethod.GET, "/api/test")
                .remoteAddress(new InetSocketAddress("10.0.0.1", 8080))
                .build();

        assertDoesNotThrow(() -> auditLogService.logRequest(request, "user456"));
    }

    @Test
    void testLogResponseWithNonExistentRequestId() {
        assertDoesNotThrow(() -> auditLogService.logResponse("non-existent-id", 404, 50));
    }
}
