package tech.easyflow.publicapi.interceptor;

import org.junit.Assert;
import org.junit.Test;
import org.slf4j.MDC;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import tech.easyflow.common.web.error.RequestErrorProfile;
import tech.easyflow.common.web.error.RequestIdContext;

/**
 * {@link PublicApiRequestContextFilter} 请求上下文测试。
 */
public class PublicApiRequestContextFilterTest {

    /**
     * 验证合法客户端请求 ID 会进入响应头，且请求结束后清理 MDC。
     *
     * @throws Exception 过滤器执行失败
     */
    @Test
    public void shouldKeepValidRequestIdAndClearMdc() throws Exception {
        MockHttpServletRequest request = new MockHttpServletRequest(
                "POST",
                "/public-api/workflow/runAsync");
        request.addHeader(RequestIdContext.HEADER_NAME, "client-123");
        MockHttpServletResponse response =
                new MockHttpServletResponse();

        new PublicApiRequestContextFilter().doFilter(
                request,
                response,
                new MockFilterChain());

        Assert.assertEquals(
                "client-123",
                response.getHeader(RequestIdContext.HEADER_NAME));
        Assert.assertEquals(
                "client-123",
                request.getAttribute(RequestIdContext.ATTRIBUTE_NAME));
        Assert.assertNotNull(request.getAttribute(
                RequestErrorProfile.ATTRIBUTE_NAME));
        Assert.assertNull(MDC.get(RequestIdContext.MDC_KEY));
    }

    /**
     * 验证非法请求 ID 会被替换，避免响应头注入。
     *
     * @throws Exception 过滤器执行失败
     */
    @Test
    public void shouldReplaceInvalidRequestId() throws Exception {
        MockHttpServletRequest request = new MockHttpServletRequest(
                "POST",
                "/public-api/workflow/runAsync");
        request.addHeader(
                RequestIdContext.HEADER_NAME,
                "bad\r\nX-Injected: yes");
        MockHttpServletResponse response =
                new MockHttpServletResponse();

        new PublicApiRequestContextFilter().doFilter(
                request,
                response,
                new MockFilterChain());

        String generated = response.getHeader(
                RequestIdContext.HEADER_NAME);
        Assert.assertNotNull(generated);
        Assert.assertFalse(generated.contains("\r"));
        Assert.assertFalse(generated.contains("\n"));
        Assert.assertNotEquals("bad\r\nX-Injected: yes", generated);
    }

    /**
     * 验证后续工作流接口也会注册稳定业务错误翻译规则。
     *
     * @throws Exception 过滤器执行失败
     */
    @Test
    public void shouldAttachErrorProfileToWorkflowStatusApi()
            throws Exception {
        MockHttpServletRequest request = new MockHttpServletRequest(
                "POST",
                "/public-api/workflow/getChainStatus");
        MockHttpServletResponse response =
                new MockHttpServletResponse();

        new PublicApiRequestContextFilter().doFilter(
                request,
                response,
                new MockFilterChain());

        Assert.assertNotNull(request.getAttribute(
                RequestErrorProfile.ATTRIBUTE_NAME));
    }
}
