package com.esv.freight.file.module.file.controller;

import com.alibaba.fastjson.JSONObject;
import com.esv.freight.file.BaseTestController;
import com.esv.freight.file.common.response.ECode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Base64;

/**
 * @description:
 * @project: freight-file-service
 * @name: com.esv.freight.file.module.upload.controller.UploadControllerTest
 * @author: 黄朝斌
 * @email: huangchaobin@esvtek.com
 * @createTime: 2020/04/14 15:11
 * @version:1.0
 */
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class UploadControllerTest extends BaseTestController {

    private static String fileId;

    private static String fileUrl;

    @Test
    public void a1_uploadSingleFile_success_test() throws Exception {
        String url = "/upload/single";
        JSONObject reqJson = new JSONObject();

        // 构造数据
        String filepath = "D:\\test\\路上飞-签名.PNG";
        File file = new File(filepath);
        InputStream input = new FileInputStream(file);
        reqJson.put("fileType", "image");
        reqJson.put("fileData", Base64.getEncoder().encodeToString(IOUtils.toByteArray(input)));
        reqJson.put("fileName", "路上飞-签名.PNG");

        MvcResult mvcResult = this.getMockMvc().perform(MockMvcRequestBuilders.post(url)
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .content(reqJson.toJSONString()))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        String responseStr = mvcResult.getResponse().getContentAsString();
        log.info(responseStr);

        JSONObject result = JSONObject.parseObject(responseStr);
        Assert.assertEquals(ECode.SUCCESS.code(), result.getIntValue("code"));
        fileId = result.getJSONObject("data").getString("id");
        fileUrl = result.getJSONObject("data").getString("url");
    }

    @Test
    public void a2_uploadSingleFile_pdf_success_test() throws Exception {
        String url = "/upload/single";
        JSONObject reqJson = new JSONObject();

        // 构造数据
        String filepath = "D:\\test\\线下合同-货主.pdf";
        File file = new File(filepath);
        InputStream input = new FileInputStream(file);
        reqJson.put("fileType", "pdf");
        reqJson.put("fileData", Base64.getEncoder().encodeToString(IOUtils.toByteArray(input)));
        reqJson.put("fileName", "线下合同-货主");

        MvcResult mvcResult = this.getMockMvc().perform(MockMvcRequestBuilders.post(url)
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .content(reqJson.toJSONString()))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        String responseStr = mvcResult.getResponse().getContentAsString();
        log.info(responseStr);

        JSONObject result = JSONObject.parseObject(responseStr);
        Assert.assertEquals(ECode.SUCCESS.code(), result.getIntValue("code"));
        fileId = result.getJSONObject("data").getString("id");
        fileUrl = result.getJSONObject("data").getString("url");
    }

    @Test
    public void a3_uploadSingleFile_word_success_test() throws Exception {
        String url = "/upload/single";
        JSONObject reqJson = new JSONObject();

        // 构造数据
        String filepath = "D:\\test\\线上合同-司机.docx";
        File file = new File(filepath);
        InputStream input = new FileInputStream(file);
        reqJson.put("fileType", "word");
        reqJson.put("fileData", Base64.getEncoder().encodeToString(IOUtils.toByteArray(input)));
        reqJson.put("fileName", "线上合同-司机");

        MvcResult mvcResult = this.getMockMvc().perform(MockMvcRequestBuilders.post(url)
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .content(reqJson.toJSONString()))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        String responseStr = mvcResult.getResponse().getContentAsString();
        log.info(responseStr);

        JSONObject result = JSONObject.parseObject(responseStr);
        Assert.assertEquals(ECode.SUCCESS.code(), result.getIntValue("code"));
        fileId = result.getJSONObject("data").getString("id");
        fileUrl = result.getJSONObject("data").getString("url");
    }

    @Test
    public void b1_uploadSingleFile_file_type_error_test() throws Exception {
        String url = "/upload/single";
        JSONObject reqJson = new JSONObject();

        // 构造数据
        String filepath = "D:\\test\\1366x768_107480_8.jpg";
        File file = new File(filepath);
        InputStream input = new FileInputStream(file);
        reqJson.put("fileType", "test");
        reqJson.put("fileData", Base64.getEncoder().encodeToString(IOUtils.toByteArray(input)));
        reqJson.put("fileName", "1366x768_107480_8.jpg");

        MvcResult mvcResult = this.getMockMvc().perform(MockMvcRequestBuilders.post(url)
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .content(reqJson.toJSONString()))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        String responseStr = mvcResult.getResponse().getContentAsString();
        log.info(responseStr);

        JSONObject result = JSONObject.parseObject(responseStr);
        Assert.assertEquals(1001, result.getIntValue("code"));
    }

    @Test
    public void b2_uploadSingleFile_file_size_error_test() throws Exception {
        String url = "/upload/single";
        JSONObject reqJson = new JSONObject();

        // 构造数据
        String filepath = "D:\\test\\方正粗黑宋简体.ttf";
        byte[] bytes = IOUtils.toByteArray(new FileInputStream(new File(filepath)));
        reqJson.put("fileType", "image");
        reqJson.put("fileData", Base64.getEncoder().encodeToString(bytes));
        reqJson.put("fileName", "方正粗黑宋简体.ttf");

        MvcResult mvcResult = this.getMockMvc().perform(MockMvcRequestBuilders.post(url)
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .content(reqJson.toJSONString()))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        String responseStr = mvcResult.getResponse().getContentAsString();
        log.info(responseStr);

        JSONObject result = JSONObject.parseObject(responseStr);
        Assert.assertEquals(1002, result.getIntValue("code"));
    }

    @Test
    public void b3_uploadSingleFile_inValid_image_error_test() throws Exception {
        String url = "/upload/single";
        JSONObject reqJson = new JSONObject();

        // 构造数据
        String filepath = "D:\\test\\test.txt";
        File file = new File(filepath);
        reqJson.put("fileType", "image");
        reqJson.put("fileData", Base64.getEncoder().encodeToString(IOUtils.toByteArray(FileUtils.openInputStream(file))));
        reqJson.put("fileName", "1366x768_107480_8.jpg");

        MvcResult mvcResult = this.getMockMvc().perform(MockMvcRequestBuilders.post(url)
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .content(reqJson.toJSONString()))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        String responseStr = mvcResult.getResponse().getContentAsString();
        log.info(responseStr);

        JSONObject result = JSONObject.parseObject(responseStr);
        Assert.assertEquals(1001, result.getIntValue("code"));
    }

    @Test
    public void c1_directDownload_success_test() throws Exception {
        String[] datas = fileUrl.split("direct");
        String dUrl = datas[1];

        String url = "/download/direct/"+dUrl;

        this.getMockMvc().perform(MockMvcRequestBuilders.get(url))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();
    }

    @Test
    public void c2_getFileData_success_test() throws Exception {
        String url = "/download/getFileData";
        JSONObject reqJson = new JSONObject();

        // 构造数据
        reqJson.put("id", fileId);

        MvcResult mvcResult = this.getMockMvc().perform(MockMvcRequestBuilders.post(url)
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .content(reqJson.toJSONString()))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        String responseStr = mvcResult.getResponse().getContentAsString();
        log.info(responseStr);

        JSONObject result = JSONObject.parseObject(responseStr);
        Assert.assertTrue(result.getJSONObject("data").containsKey("fileData"));
    }

    @Test
    public void d1_deleteSingleFile_success_test() throws Exception {
        String url = "/delete/single";
        JSONObject reqJson = new JSONObject();

        // 构造数据
        reqJson.put("id", fileId);

        MvcResult mvcResult = this.getMockMvc().perform(MockMvcRequestBuilders.post(url)
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .content(reqJson.toJSONString()))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        String responseStr = mvcResult.getResponse().getContentAsString();
        log.info(responseStr);

        JSONObject result = JSONObject.parseObject(responseStr);
        Assert.assertEquals(ECode.SUCCESS.code(), result.getIntValue("code"));
    }
}
