package com.zsc.bill.rest;

import com.zsc.bill.MockMvcConfigBase;
import com.zsc.bill.domain.AuthorityBuilder;
import com.zsc.bill.modules.system.controller.AuthorityController;
import com.zsc.bill.modules.system.dto.AuthorityDto;
import com.zsc.bill.modules.system.entity.Authority;
import com.zsc.bill.modules.system.service.AuthorityService;
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(AuthorityController.class)
public class AuthorityControllerTest extends MockMvcConfigBase {

    @Spy
    private static Authority aut1;

    private static Authority aut2;

    @MockBean
    private AuthorityService service;


    @BeforeAll
    static void beforeAll() {
        aut1 = AuthorityBuilder.aAuthority().name("AUTHORITY_ONE").build();
        aut1.setId(1L);
        aut2 = AuthorityBuilder.aAuthority().name("AUTHORITY_TWO").build();
    }

    @Test
    void create() throws Exception {
        AuthorityDto dto = new AuthorityDto();
        dto.name=aut1.getName();
        when(service.create(any())).thenReturn(aut1);
        mockMvc.perform(post("/api/rest/auth")
                .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<Authority> authorities = Lists.newArrayList(aut1, aut2);
        when(service.list()).thenReturn(authorities);
        mockMvc.perform(get("/api/rest/auth").with(user(userDetails))
        ).andExpect(status().isOk()).andDo(print());
        verify(service).list();
    }


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