package com.zsc.edu.gateway.rest.system;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.edu.gateway.MockMvcConfigBase;
import com.zsc.edu.gateway.domain.system.RoleBuilder;
import com.zsc.edu.gateway.modules.system.controller.RoleController;
import com.zsc.edu.gateway.modules.system.dto.RoleDto;
import com.zsc.edu.gateway.modules.system.entity.Role;
import com.zsc.edu.gateway.modules.system.service.RoleAuthService;
import com.zsc.edu.gateway.modules.system.service.RoleService;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.Spy;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;

import java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(RoleController.class)
public class RoleControllerTest extends MockMvcConfigBase {
    @Spy
    private static Role role1;

    private static Role role2;

    @MockBean
    private RoleService service;
    @MockBean
    private RoleAuthService authService;

    @BeforeAll
    static void beforeAll() {
        role1 = RoleBuilder.aRole().name("管理员").build();
        role1.setId(1L);
        role2 = RoleBuilder.aRole().name("普通用户").build();
        role2.setId(2L);
    }

    @Test
    void create() throws Exception {
        RoleDto dto = new RoleDto();
        dto.setName(role1.getName());
        when(service.create(any())).thenReturn(role1);
        mockMvc.perform(post("/api/rest/role")
                .with(csrf().asHeader())
                .with(user(userDetails))
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(dto))
        ).andExpect(status().isOk()).andDo(print());
        verify(service).create(any());
    }

    @Test
    void list() throws Exception {
        List<Role> roles = Lists.newArrayList(role1, role2);
        Page<Role> pageResult = new Page<>();
        pageResult.setRecords(roles);
        pageResult.setTotal((long) roles.size());

        when(service.page(any(Page.class), any())).thenReturn(pageResult);
        mockMvc.perform(get("/api/rest/role")
                        .with(user(userDetails))
                ).andExpect(status().isOk())
                .andDo(print());
        verify(service).page(any(Page.class), any());
    }

    @Test
    void update() throws Exception {
        RoleDto dto = new RoleDto();
        dto.setName(role1.getName());
//        when(service.edit(any(), any())).thenReturn(true);
        mockMvc.perform(patch("/api/rest/role/{id}", role1.getId())
                .with(csrf().asHeader())
                .with(user(userDetails))
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(dto))
        ).andExpect(status().isOk()).andDo(print());
        verify(service).edit(any(), any());
    }
}
