package com.lemon.cases;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPatch;
import com.alibaba.fastjson.JSONPath;
import com.lemon.constants.Constants;
import com.lemon.pojo.API;
import com.lemon.pojo.Case;
import com.lemon.pojo.JsonPathVaildate;
import com.lemon.pojo.WriteBackData;
import com.lemon.utils.AuthorizationUtils;
import com.lemon.utils.ExcelUtils;
import com.lemon.utils.HttpUtils;
import com.lemon.utils.SqlUtils;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.util.List;


/**
 * @program: Lemon
 * @description:
 * @author: ray
 * @create: 2022-09-23 13:57
 **/
public class LoginCase extends BaseCase {


    @Test(dataProvider = "datas1",description = "登录测试")   // DTO数据传输
    @Description("登录...xxx.xxx")
    public void testLogin(API api, Case cas) throws Exception {
        //1、参数化替换
        String params = replace(cas.getParams());
        String sql = replace(cas.getCheckSQL());
        cas.setParams(params);
        cas.setCheckSQL(sql);
        //2、数据库前置查询结果（断言必须在接口执行前后都查询）
        Object beforeSqlResult = SqlUtils.querySingle(cas.getCheckSQL());
        //3、调用接口
        String body = call(api, cas, false);
        // 3.1 将登录的token存储（仅限于登录接口特有）
        AuthorizationUtils.storeToken(body);
        //4、断言响应结果，Excel中预期响应数据与实际响应数据进行对比
        Boolean assertResponseFlag = assertResponse(cas, body);
        //5、添加接口响应回写excel内容
        addWBD(Integer.parseInt(cas.getId()), Constants.ACTURL_WRITER_BACK_CELL_NUM, body);
        //6、数据库后置查询结果
        Object afterSqlResult = SqlUtils.querySingle(cas.getCheckSQL());

        //7、数据库断言

        //8、添加断言回写内容

        //9、添加日志

        //10、报表断言

    }

    // 使用对应参数编写接口自动化
    @DataProvider(name = "datas0")
    public Object[][] datas0() {
        //Object[m][n] m代表执行次数，n代表参数个数
        Object[][] datas = {
                {"http://api.lemonban.com/fetureloan/member/register", "{\"mobile_phone\":\"15500110011\",\"pwd\":\"123456\"}"},
                {"http://api.lemonban.com/fetureloan/member/register", "{\"mobile_phone\":\"15500110012\",\"pwd\":\"123456\"}"},
                {"http://api.lemonban.com/fetureloan/member/register", "{\"mobile_phone\":\"15500110013\",\"pwd\":\"123456\"}"},
        };
        return datas;
    }


    // 使用Excel文件传输接口信息和请求信息
    @DataProvider(name = "datas1")
    public Object[][] datas1() {
        // 传参apiID
        Object[][] datas = ExcelUtils.getAPIAndCaseByApiId("2");
        return datas;
    }


    /*
     * 鉴权：token、cookie、session
     * 1、cookie：客户端（浏览器）本地缓存==>存在磁盘本地某个路径
     *      存储一些小的明文信息，不会放非常隐秘的信息
     *      cookie是如何生成的？客户端（JS脚本）和服务端（Java、Python）都能生成，一般都是服务器生成。
     *
     *      NAME=VALUE      赋予cookie的名称和其值（必填项）
     *      expires=DATE    cookie的有效期（被max-age取代）
     *      path=PATH       cookie适用路径，默认为当前路径
     *      domain=域名      cookie适用域名，默认当前域名
     *      max-age         用秒来设置cookie生存期
     *      size            大小
     *      HttpOnly        只有在http请求头中会带cookie信息，禁止通过JS访问
     *      secure          设置是否只能通过HTTPS来传递此条cookie
     *
     *  2、session：服务端缓存==>存储在内存中或者数据库中，断开了连接（关闭浏览器）session就会失效。
     *      默认失效时间为30分钟。优点：可以存储任意信息，缺点：耗内存；
     *      session是如何生成的？服务端生成，使用cookie回写到客户端（jsessionId），客户端每次发送请求时自动携带该cookie（jsessionId）。
     *
     * 3、token：票据==>存储在客户端（浏览器）对header或body中
     *      优点：不存储在服务端。一般只用来做鉴权存储用户相关信息。
     *      token是如何生成的？服务端生成，携带在header或body中回写客户端，客户端以同样的方法传递给服务端。
     *
     * 4、如何实现鉴权
     *      a、获取到对应的jsession或者对应token字符串；
     *      b、在请求的同时添加上它们；
     * token子验证过程：结果是相等的，算法是相同的。
     *
     * 5、代码鉴权逻辑：
     *      a、在获取Post请求响应之后(HttpUtils)，判断响应体中是否还有token字符；
     *      b、如果含有token存储到env环境变量中，(Map<String,String>)
     *      c、每次post、get、patch请求之前，调用添加token的方法addToken
     *      d、addToken中会判断env环境中是否有Token，如果有添加到对应的请求头中
     * */

}
