package tech.easyflow.common.web.jsonbody;

import org.junit.Test;
import org.springframework.core.MethodParameter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import tech.easyflow.common.web.exceptions.BusinessException;

import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;

/**
 * {@link JsonBodyArgumentResolver} 请求体错误语义回归测试。
 */
public class JsonBodyArgumentResolverTest {

    /**
     * 验证畸形 JSON 返回安全的 HTTP 400 业务异常。
     *
     * @throws Exception 构造反射参数失败时抛出
     */
    @Test
    public void shouldRejectMalformedJsonAsBadRequest() throws Exception {
        RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
        JsonBodyArgumentResolver resolver = new JsonBodyArgumentResolver(adapter);
        Method method = JsonBodyArgumentResolverTest.class.getDeclaredMethod("sampleBody", SampleRequest.class);
        MethodParameter parameter = new MethodParameter(method, 0);
        MockHttpServletRequest request = new MockHttpServletRequest("POST", "/api/v1/skill/update");
        request.setContentType("application/json");
        request.setCharacterEncoding(StandardCharsets.UTF_8.name());
        request.setContent("{\"name\":".getBytes(StandardCharsets.UTF_8));

        BusinessException exception = assertThrows(BusinessException.class,
                () -> resolver.resolveArgument(parameter, null, new ServletWebRequest(request), null));

        assertEquals(400, exception.getHttpStatus());
        assertEquals(400, exception.getErrorCode());
        assertEquals("请求参数格式不正确", exception.getMessage());
    }

    /**
     * 提供反射参数签名。
     *
     * @param request 示例请求
     */
    private static void sampleBody(@JsonBody(skipConvertError = false) SampleRequest request) {
        // 仅用于构造 MethodParameter。
    }

    private record SampleRequest(String name) {
    }
}
