package incheon.pack.map.web;

import incheon.com.security.vo.LoginVO;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.util.Collections;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;

/**
 * PackMapController MockMvc 테스트.
 * 인증 사용자/미인증 사용자별 모델 바인딩, 뷰 이름을 검증한다.
 */
@ExtendWith(MockitoExtension.class)
class PackMapControllerTest {

    @InjectMocks
    private PackMapController controller;

    private MockMvc mockMvc;

    @BeforeEach
    void setup() {
        mockMvc = MockMvcBuilders.standaloneSetup(controller)
                .setCustomArgumentResolvers(new AuthenticationPrincipalArgumentResolver())
                .build();
    }

    @AfterEach
    void clearSecurity() {
        SecurityContextHolder.clearContext();
    }

    @Test
    @DisplayName("인증 사용자 → model에 userId 바인딩")
    void mapWithAuthenticatedUser() throws Exception {
        LoginVO loginVO = new LoginVO();
        loginVO.setUserId("testUser");
        UsernamePasswordAuthenticationToken auth =
                new UsernamePasswordAuthenticationToken(loginVO, null, Collections.emptyList());
        SecurityContextHolder.getContext().setAuthentication(auth);

        mockMvc.perform(get("/pack/map.do"))
                .andExpect(status().isOk())
                .andExpect(view().name("pack/map/map"))
                .andExpect(model().attribute("userId", "testUser"));
    }

    @Test
    @DisplayName("미인증 사용자 → userId 미바인딩")
    void mapWithAnonymousUser() throws Exception {
        mockMvc.perform(get("/pack/map.do"))
                .andExpect(status().isOk())
                .andExpect(view().name("pack/map/map"))
                .andExpect(model().attributeDoesNotExist("userId"));
    }
}
