package com.ga.common.menu;

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.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class PermissionCheckerTest {

    @Mock MenuMapper menuMapper;
    @InjectMocks PermissionChecker checker;

    @Test
    @DisplayName("userId null 이면 즉시 false 반환 (DB 조회 안함)")
    void nullUser_returnsFalse() {
        boolean ok = checker.hasPermission(null, "MENU", "READ");

        assertThat(ok).isFalse();
        verify(menuMapper, never()).hasPermission(any(), any(), any());
    }

    @Test
    @DisplayName("Mapper 가 1 이상 반환 → true")
    void hasPermission_grant() {
        when(menuMapper.hasPermission(1L, "AGENT", "READ")).thenReturn(1);

        assertThat(checker.hasPermission(1L, "AGENT", "READ")).isTrue();
    }

    @Test
    @DisplayName("Mapper 가 0 반환 → false")
    void hasPermission_deny() {
        when(menuMapper.hasPermission(1L, "AGENT", "DELETE")).thenReturn(0);

        assertThat(checker.hasPermission(1L, "AGENT", "DELETE")).isFalse();
    }

    @Test
    @DisplayName("Mapper 호출 인자가 그대로 전달됨")
    void argumentsForwarded() {
        when(menuMapper.hasPermission(anyLong(), any(), any())).thenReturn(1);

        checker.hasPermission(42L, "SETTLE", "APPROVE");

        verify(menuMapper).hasPermission(42L, "SETTLE", "APPROVE");
    }
}
