Exemple #1
0
 def __init__(self):
     self.data = get_request_json()
     self.username = redis.get_username(request.headers.get('X-Token'))
     # self.acim = ApiCompanyInfoManager()
     # self.asim = ApiSystemInfoManager()
     # self.aiim = ApiIntfInfoManager()
     # self.atim = ApiTestcaseInfoManager()
     self.aplm = ApiProductLineManager()
     self.atmm = ApiTestcaseMainManager()
Exemple #2
0
 def __init__(self):
     self.data = get_request_json()
     self.username = redis.get_username(request.headers.get('X-Token'))
     self.atmtrm = ApiTestcaseMainTagRelationManager()
     self.aplm = ApiProductLineManager()
     self.atmm = ApiTestcaseMainManager()
     self.aiim = ApiIntfInfoManager()
     self.atsm = ApiTestcaseSubManager()
     self.atrqm = ApiTestcaseRequestQllManager()
     self.ttm = TestcaseTagManager()
     if self.username:
         self.data["userName"] = self.username
Exemple #3
0
    def query_related_cases_by_sub_id(self):
        try:
            sub_id = self.data.pop("subId")
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验错误"})

        sub_obj = ApiTestcaseSubManager.get_testcase_sub(id=sub_id)
        if not sub_obj or not sub_obj.main_list or not json_loads(
                sub_obj.main_list):
            return make_response({"code": "101", "desc": "没有关联的用例信息"})

        main_id_list = json_loads(sub_obj.main_list)
        main_objs = ApiTestcaseMainManager.get_testcases_in_id_list(
            main_id_list)
        data_list = []
        for main_obj in main_objs:
            p_obj = ApiProductLineManager.get_product_line(
                id=main_obj.api_product_line_id)
            data_dic = {
                "testcaseId": main_obj.id,
                "testcaseName": main_obj.testcase_name,
                "productLineDesc": get_full_product_line_name(p_obj)
            }
            data_list.append(data_dic)

        return make_response({"code": "000", "data": data_list})
Exemple #4
0
def get_full_product_line_name(p_obj, tail_name=''):
    """获取全链路用例完整节点信息"""
    full_product_line_name = '{0} -> {1}'.format(p_obj.product_line_name, tail_name)
    if not p_obj.parent_id:
        return full_product_line_name.strip(' ->')
    else:
        parent_p_obj = ApiProductLineManager.get_product_line(id=p_obj.parent_id)
        return get_full_product_line_name(parent_p_obj, tail_name=full_product_line_name)
Exemple #5
0
def add_memo(summary):
    """增加一些备注,并且记录生成的公共变量"""

    details = summary['details']
    for detail_dic in details:
        # 每条用例
        in_out = detail_dic.pop('in_out', None)
        # 全链路用例增加信息
        if detail_dic['is_main']:
            case_id = 'M' + str(detail_dic['case_id'])
            if 'testcase_main_id' not in summary:
                # summary['testcase_main_id'] = detail_dic['case_id']
                testcase_main_obj = ApiTestcaseMainManager.get_testcase_main(id=detail_dic['case_id'])
                # summary['testcase_main_name'] = testcase_main_obj.testcase_name
                p_obj = ApiProductLineManager.get_product_line(id=testcase_main_obj.api_product_line_id)
                summary['product_line_id'] = p_obj.id
                summary['product_line_name'] = get_full_product_line_name(p_obj)
        # 接口用例增加信息
        else:
            case_id = str(detail_dic['case_id'])
            if 'intf_id' not in summary:
                summary['intf_id'] = detail_dic['intf_id']
                intf_obj = ApiIntfInfoManager.get_intf(id=detail_dic['intf_id'])
                summary['intf_name'] = '{0}-{1}'.format(intf_obj.intf_desc, intf_obj.intf_name)
                system_obj = ApiSystemInfoManager.get_system(id=intf_obj.api_system_id)
                summary['system_id'] = system_obj.id
                summary['system_name'] = system_obj.system_name
        # 记录随机生成的数据,方便追溯和定时清理数据
        if in_out:
            record_keys = ['MOBILE_NO', 'ID_NO', 'BANK_CARD_NO_CREDIT', 'BANK_CARD_NO_DEBIT']
            mobile_no, id_no, bank_card_no_credit, bank_card_no_debit = '', '', '', ''
            is_found = False
            for var, var_value in in_out['in'].items():
                for key in record_keys:
                    if key == var:
                        is_found = True
                        if var == 'MOBILE_NO':
                            mobile_no = var_value
                        elif var == 'ID_NO':
                            id_no = var_value
                        elif var == 'BANK_CARD_NO_CREDIT':
                            bank_card_no_credit = var_value
                        elif var == 'BANK_CARD_NO_DEBIT':
                            bank_card_no_debit = var_value
                        break
            if is_found:
                GenerateDataRecordManager.insert_record(
                    case_id=case_id, mobile_no=mobile_no, id_no=id_no, bank_card_no_credit=bank_card_no_credit,
                    bank_card_no_debit=bank_card_no_debit)

    return summary
Exemple #6
0
    def product_line_subtree(self):
        """根据公司id查询配置在该公司下的产品线-目录-目录-...-全链路用例"""
        try:
            company_id = self.data.pop('companyId')
            with_sub = self.data.pop('withSub', None)
            tag_id_list = self.data.pop('tagIdList', None)
            without_testcase = self.data.pop('withoutTestcase', None)
        except KeyError:
            return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]})

        if not (isinstance(tag_id_list, list) and len(tag_id_list) in [1, 2]):
            tag_id_list = None

        self.all_sub_objs = ApiTestcaseSubManager.get_testcase_subs()

        subtree = []
        index = 0

        pl_objs = ApiProductLineManager.get_product_lines(
            api_company_id=company_id)
        for pl_obj in pl_objs:
            index += 1
            top_tree = {
                'id': index,
                'label': pl_obj.product_line_name,
                'productLineId': pl_obj.id,
                'children': []
            }
            index = get_under_node(pl_obj.id, top_tree['children'], index,
                                   with_sub, tag_id_list, without_testcase,
                                   self.all_sub_objs)
            subtree.append(top_tree)

        if tag_id_list:
            # 过滤去除没有用例的节点
            remove_no_case_node(subtree)

        return make_response({"code": "000", "data": subtree})
Exemple #7
0
class ApiTestcaseMain(Resource):
    def __init__(self):
        self.data = get_request_json()
        self.username = redis.get_username(request.headers.get('X-Token'))
        self.atmtrm = ApiTestcaseMainTagRelationManager()
        self.aplm = ApiProductLineManager()
        self.atmm = ApiTestcaseMainManager()
        self.aiim = ApiIntfInfoManager()
        self.atsm = ApiTestcaseSubManager()
        self.atrqm = ApiTestcaseRequestQllManager()
        self.ttm = TestcaseTagManager()
        if self.username:
            self.data["userName"] = self.username

    @timer
    def post(self, action):
        if action == 'add':
            return self.add_testcase_main(action)

        elif action == 'edit':
            return self.edit_testcase_main(action)

        elif action == 'delete':
            return self.delete_testcase_main()

        elif action == 'queryByProductLine':
            return self.query_by_product_line()

        elif action == 'queryByIntfId':
            return self.query_by_intf_id()

        elif action == 'detail':
            return self.testcase_detail()

        elif action == 'changeStatus':
            return self.change_status()

        elif action == 'copy':
            return self.copy_testcase()

        elif action == 'setTag':
            return self.set_tag()

        elif action == 'changeParent':
            return self.change_parent()

        elif action == 'queryRelatedCasesBySubId':
            return self.query_related_cases_by_sub_id()

        elif action == 'getCustomFlows':
            return self.get_custom_flows()

        elif action == 'saveCustomFlows':
            return self.save_custom_flows()

        else:
            return make_response({
                "code":
                "100",
                "desc":
                "url错误,不存在的接口动作<{action}>".format(action=action)
            })

    @developer_check
    def add_testcase_main(self, action):
        try:
            handle_api_testcase_main(action, **self.data)
        except LoadCaseError:
            return make_response({"code": "201", "desc": "新增用例时出错"})
        return make_response({"code": "000", "desc": "用例新增成功"})

    @developer_with_limit_check
    def edit_testcase_main(self, action):
        try:
            handle_api_testcase_main(action, **self.data)
        except LoadCaseError:
            return make_response({"code": "201", "desc": "保存用例时出错"})
        return make_response({"code": "000", "desc": "用例保存成功"})

    @developer_with_limit_check
    def delete_testcase_main(self):
        try:
            testcase_id = int(self.data.pop('testcaseId'))
        except KeyError:
            return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]})

        tm_obj = self.atmm.get_testcase_main(id=testcase_id)
        if not tm_obj:
            return make_response({
                "code":
                "200",
                "desc":
                "用例id\"{}\"不存在, 请刷新后重试".format(testcase_id)
            })

        sub_list = json_loads(tm_obj.sub_list)
        if tm_obj.case_type == 2:
            for sub_id in sub_list:
                sub_obj = self.atsm.get_testcase_sub(id=sub_id)
                main_list = json_loads(
                    sub_obj.main_list) if sub_obj.main_list else []
                if testcase_id in main_list:
                    main_list.remove(testcase_id)
                    self.atsm.update_testcase_sub(
                        sub_id, main_list=json_dumps(main_list))
                # self.atsm.delete_testcase_sub(sub_id)
        else:
            for sub_id in sub_list:
                sub_obj = self.atsm.get_testcase_sub(id=sub_id)
                if sub_obj.api_intf_id == tm_obj.api_intf_id:
                    main_list = json_loads(
                        sub_obj.main_list) if sub_obj.main_list else []
                    if testcase_id in main_list:
                        main_list.remove(testcase_id)
                        self.atsm.update_testcase_sub(
                            sub_id, main_list=json_dumps(main_list))
                    # self.atsm.delete_testcase_sub(sub_id)

        self.atmm.delete_testcase_main(testcase_id)

        # 删除tag关系
        relation_objs = self.atmtrm.get_relations(api_testcase_id=testcase_id)
        for relation_obj in relation_objs:
            self.atmtrm.delete_relation(relation_obj.id)

        return make_response({"code": "000", "desc": "测试用例删除成功"})

    @login_check
    def query_by_product_line(self):
        """
        根据product_line查找该套件下的所有测试用例:
        分页展示,支持用例名称搜索
        """
        try:
            product_line_id = self.data.pop('productLineId')
            page_no = int(self.data.pop('pageNo'))
            page_size = int(self.data.pop('pageSize'))
            testcase_name = self.data.pop('testcaseName', None)
        except KeyError:
            return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]})

        if not self.aplm.get_product_line(id=product_line_id):
            return make_response({
                "code":
                "201",
                "desc":
                "产品线id\"{}\"不存在, 请刷新后重试".format(product_line_id)
            })

        # 查询所有标签{类别-场景}MAP
        tag_base_map = self.get_tag_base_map()

        case_obj = self.atmm.paging_query_testcase_by_product_line_id(
            product_line_id, page_no, page_size, testcase_name=testcase_name)
        desc_list = []
        for i in case_obj.items:
            case_status = map_number_to_case_status(i.case_status)
            last_run = map_number_to_last_run(i.last_run)

            tag_relations = self.atmtrm.get_relations(api_testcase_id=i.id)
            tag_map = {}
            for base_category in tag_base_map:
                tag_map[base_category] = []
            for relation in tag_relations:
                for category, tag_list in tag_base_map.items():
                    for tag_dic in tag_list:
                        if tag_dic['tagId'] == relation.tag_id:
                            tag_map[category].append(tag_dic)

            testcases_dict = {
                "id":
                i.id,
                "testcase_name":
                "{0}__{1}".format(i.testcase_name, i.expect_result),
                "testcase_desc":
                i.simple_desc,
                "expectResult":
                i.expect_result,
                "status":
                case_status,
                "creator":
                username_to_nickname(i.creator),
                "last_modifier":
                username_to_nickname(i.last_modifier),
                "last_run":
                last_run,
                "tags":
                tag_map,
                "createTime":
                format(i.create_time) if i.create_time else '',
                "updateTime":
                format(i.update_time) if i.update_time else '',
                "lastRunTime":
                format(i.last_run_time) if i.last_run_time else '',
            }
            desc_list.append(testcases_dict)
        return make_response({
            "code": "000",
            "desc": desc_list,
            "totalNum": case_obj.total
        })

    @login_check
    def query_by_intf_id(self):
        """
        根据intf_id查找该套件下的所有测试用例:
        分页展示,支持用例名称搜索
        """
        try:
            intf_id = self.data.pop('intfId')
            page_no = int(self.data.pop('pageNo'))
            page_size = int(self.data.pop('pageSize'))
            testcase_name = self.data.pop('testcaseName', None)
        except KeyError:
            return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]})

        if not self.aiim.get_intf(id=intf_id):
            return make_response({
                "code":
                "201",
                "desc":
                "接口id\"{}\"不存在, 请刷新后重试".format(intf_id)
            })

        # 查询所有标签{类别-场景}MAP
        tag_base_map = self.get_tag_base_map()

        case_obj = self.atmm.paging_query_testcase_by_intf_id(
            intf_id, page_no, page_size, testcase_name=testcase_name)
        desc_list = []
        for i in case_obj.items:
            case_status = map_number_to_case_status(i.case_status)
            last_run = map_number_to_last_run(i.last_run)

            tag_relations = self.atmtrm.get_relations(api_testcase_id=i.id)
            tag_map = {}
            for base_category in tag_base_map:
                tag_map[base_category] = []
            for relation in tag_relations:
                for category, tag_list in tag_base_map.items():
                    for tag_dic in tag_list:
                        if tag_dic['tagId'] == relation.tag_id:
                            tag_map[category].append(tag_dic)

            testcases_dict = {
                "id": i.id,
                "testcase_name": i.testcase_name,
                "testcase_desc": i.simple_desc,
                "expectResult": i.expect_result,
                "status": case_status,
                "creator": username_to_nickname(i.creator),
                "last_modifier": username_to_nickname(i.last_modifier),
                "last_run": last_run,
                "tags": tag_map,
                "createTime": format(i.create_time) if i.create_time else '',
                "updateTime": format(i.update_time) if i.update_time else '',
                "lastRunTime":
                format(i.last_run_time) if i.last_run_time else '',
            }
            desc_list.append(testcases_dict)
        return make_response({
            "code": "000",
            "desc": desc_list,
            "totalNum": case_obj.total
        })

    @developer_check
    def testcase_detail(self):
        try:
            testcase_id = self.data.pop("testcaseId")
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验错误"})
        tm_obj = self.atmm.get_testcase_main(id=testcase_id)

        if not tm_obj:
            return make_response({
                "code":
                "101",
                "desc":
                "用例id\"{}\"不存在, 请刷新后重试".format(testcase_id)
            })

        testcase_detail = get_api_testcase_main_detail(tm_obj)
        return make_response({"code": "000", "data": testcase_detail})

    @developer_check
    def change_status(self):
        try:
            testcase_id = self.data.pop("id")
        except KeyError:
            return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]})

        obj = self.atmm.get_testcase_main(id=testcase_id)

        case_status = 1 if obj.case_status == 0 else 0

        self.atmm.update_testcase_main(id_=testcase_id,
                                       case_status=case_status)
        return make_response({"code": "000", "desc": "操作成功"})

    @developer_check
    def copy_testcase(self):
        try:
            testcase_id = self.data.pop('id')
            copy_num = int(self.data.pop('copyNum'))
            copy_type = int(self.data.pop('copyType',
                                          1))  # 1:复制主用例,引用子用例 2:复制主用例和子用例
        except (KeyError, ValueError):
            return make_response({"code": "100", "desc": "入参校验失败"})

        tm_obj = self.atmm.get_testcase_main(id=testcase_id)
        if tm_obj.case_type == 2:
            product_line_id = tm_obj.api_product_line_id
            pre_obj = self.atmm.get_last_obj_by_product_line(product_line_id)
        else:
            intf_id = tm_obj.api_intf_id
            pre_obj = self.atmm.get_last_obj_by_intf(intf_id)

        index = pre_obj.index + 1 if pre_obj else 0
        table_last_obj = self.atmm.get_last_obj()
        insert_id = table_last_obj.id + 1 if table_last_obj else 1

        if copy_type == 2:
            from_sub_list = json_loads(tm_obj.sub_list)
            sub_info_list = []
            for from_sub_id in from_sub_list:
                t_sub_obj = self.atsm.get_testcase_sub(id=from_sub_id)
                tr_obj = self.atrqm.get_request(api_testcase_id=from_sub_id)

                sub_info_list.append({
                    'request': tr_obj.request,
                    'sub_name': t_sub_obj.sub_name,
                    'request_type': t_sub_obj.request_type,
                    'include': t_sub_obj.include,
                    'simple_desc': t_sub_obj.simple_desc,
                    'case_type': t_sub_obj.case_type,
                    'api_intf_id': t_sub_obj.api_intf_id,
                    'creator': self.username,
                    'expect_result': t_sub_obj.expect_result,
                })

            testcase_insert_list = []
            testcase_id_list = []
            for i in range(copy_num):
                update_list = copy.deepcopy(sub_info_list)
                to_sub_list = ApiTestcaseSubManager.batch_update_testcase_sub(
                    update_list)

                case_name = tm_obj.testcase_name + '_copy_{0}_{1}'.format(
                    testcase_id, i + 1)
                testcase_insert_list.append({
                    'id':
                    insert_id + i,
                    'testcase_name':
                    case_name,
                    'simple_desc':
                    tm_obj.simple_desc,
                    'case_type':
                    tm_obj.case_type,
                    'case_status':
                    tm_obj.case_status,
                    'api_intf_id':
                    tm_obj.api_intf_id,
                    'api_product_line_id':
                    tm_obj.api_product_line_id,
                    'sub_list':
                    json_dumps(to_sub_list),
                    'creator':
                    self.username,
                    'expect_result':
                    tm_obj.expect_result,
                    'index':
                    index + i,
                    'setup_flow_list':
                    tm_obj.setup_flow_list,
                    'main_teardown_hooks':
                    tm_obj.main_teardown_hooks,
                })
                testcase_id_list.append(insert_id + i)
            self.atmm.batch_insert_testcase_main(testcase_insert_list)

            # 复制tag
            tag_relation_objs = self.atmtrm.get_relations(
                api_testcase_id=testcase_id)
            tag_id_list = [str(obj.tag_id) for obj in tag_relation_objs]
            tag_relation_insert_list = []
            for i in range(copy_num):
                for tag_id in tag_id_list:
                    tag_relation_insert_list.append({
                        'api_testcase_id':
                        testcase_id_list[i],
                        'tag_id':
                        tag_id
                    })
            self.atmtrm.batch_insert_relation(tag_relation_insert_list)

        elif copy_type == 1:
            to_sub_list = json_loads(tm_obj.sub_list)
            testcase_insert_list = []
            testcase_id_list = []
            for i in range(copy_num):
                case_name = tm_obj.testcase_name + '_copy_{0}_{1}'.format(
                    testcase_id, i + 1)
                testcase_insert_list.append({
                    'id':
                    insert_id + i,
                    'testcase_name':
                    case_name,
                    'simple_desc':
                    tm_obj.simple_desc,
                    'case_type':
                    tm_obj.case_type,
                    'case_status':
                    tm_obj.case_status,
                    'api_intf_id':
                    tm_obj.api_intf_id,
                    'api_product_line_id':
                    tm_obj.api_product_line_id,
                    'sub_list':
                    json_dumps(to_sub_list),
                    'creator':
                    self.username,
                    'expect_result':
                    tm_obj.expect_result,
                    'index':
                    index + i,
                    'setup_flow_list':
                    tm_obj.setup_flow_list,
                    'main_teardown_hooks':
                    tm_obj.main_teardown_hooks,
                })
                testcase_id_list.append(insert_id + i)
            self.atmm.batch_insert_testcase_main(testcase_insert_list)

            # 复制tag
            tag_relation_objs = self.atmtrm.get_relations(
                api_testcase_id=testcase_id)
            tag_id_list = [str(obj.tag_id) for obj in tag_relation_objs]
            tag_relation_insert_list = []
            for i in range(copy_num):
                for tag_id in tag_id_list:
                    tag_relation_insert_list.append({
                        'api_testcase_id':
                        testcase_id_list[i],
                        'tag_id':
                        tag_id
                    })
            self.atmtrm.batch_insert_relation(tag_relation_insert_list)

        else:
            return make_response({
                "code": "101",
                "desc": "错误的copy_type:{0}".format(copy_type)
            })

        return make_response({
            "code":
            "000",
            "desc":
            "用例{0}复制成功, 数量{1}".format(testcase_id, copy_num)
        })

    @developer_with_limit_check
    def set_tag(self):
        try:
            testcase_id = self.data.pop("testcaseId")
            tag_id_list = self.data.pop("tagIdList")
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验错误"})

        for tag_id in tag_id_list:
            if not self.ttm.get_testcase_tag(tag_id):
                return make_response({
                    "code":
                    "200",
                    "desc":
                    "标签id\"{}\"不存在, 请刷新后重试".format(tag_id)
                })

        set_testcase_tag(testcase_id, tag_id_list, is_main=True)

        return make_response({"code": "000", "desc": "设置标签成功"})

    @login_check
    def query_related_cases_by_sub_id(self):
        try:
            sub_id = self.data.pop("subId")
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验错误"})

        sub_obj = ApiTestcaseSubManager.get_testcase_sub(id=sub_id)
        if not sub_obj or not sub_obj.main_list or not json_loads(
                sub_obj.main_list):
            return make_response({"code": "101", "desc": "没有关联的用例信息"})

        main_id_list = json_loads(sub_obj.main_list)
        main_objs = ApiTestcaseMainManager.get_testcases_in_id_list(
            main_id_list)
        data_list = []
        for main_obj in main_objs:
            p_obj = ApiProductLineManager.get_product_line(
                id=main_obj.api_product_line_id)
            data_dic = {
                "testcaseId": main_obj.id,
                "testcaseName": main_obj.testcase_name,
                "productLineDesc": get_full_product_line_name(p_obj)
            }
            data_list.append(data_dic)

        return make_response({"code": "000", "data": data_list})

    @login_check
    def get_custom_flows(self):
        try:
            testcase_id = self.data.pop('testcaseId')
        except KeyError:
            return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]})

        flow_objs = ApiTestcaseMainCustomFlowManager.get_flows(
            testcase_id=testcase_id)
        data_list = [{
            'flowId': obj.id,
            'flowName': obj.flow_name,
            'flowIndexList': json_loads(obj.flow_index_list)
        } for obj in flow_objs]
        return make_response({"code": "000", "flowList": data_list})

    @developer_check
    def save_custom_flows(self):
        try:
            testcase_id = self.data.pop('testcaseId')
            flow_list = self.data.pop('flowList')
        except KeyError:
            return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]})

        save_flow(testcase_id, flow_list)

        return make_response({"code": "000", "desc": "保存成功"})

    @developer_check
    def change_parent(self):
        try:
            testcase_id = self.data.pop('testcaseId')
            parent_id = self.data.pop('newParentId')
        except KeyError:
            return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]})

        tm_obj = self.atmm.get_testcase_main(id=testcase_id)
        if tm_obj.case_type == 2:
            pl_obj = self.aplm.get_product_line(id=parent_id)
            if not pl_obj:
                return make_response({
                    "code": "202",
                    "desc": "不存在的目录id, 请刷新后重试"
                })
            sub_obj = self.aplm.get_product_line(parent_id=pl_obj.id)
            if sub_obj:
                return make_response({
                    "code": "500",
                    "desc": "移动失败,新目录下包含其他目录,请移动到最后一层目录中"
                })
            pre_tm_obj = self.atmm.get_last_obj_by_product_line(parent_id)
        else:
            intf_obj = self.aiim.get_intf(id=parent_id)
            if not intf_obj:
                return make_response({
                    "code": "201",
                    "desc": "不存在的接口id, 请刷新后重试"
                })
            pre_tm_obj = self.atmm.get_last_obj_by_intf(parent_id)

        # 更新原产品线/原接口其他用例的index
        self.atmm.index_update_while_remove_testcase(id_=testcase_id)

        # 获取新产品线/新接口的用例index
        index = pre_tm_obj.index + 1 if pre_tm_obj else 0

        # 更新
        if tm_obj.case_type == 2:
            self.atmm.update_testcase_main(id_=testcase_id,
                                           api_product_line_id=parent_id,
                                           index=index)
        else:
            self.atmm.update_testcase_main(id_=testcase_id,
                                           api_intf_id=parent_id,
                                           index=index)
        return make_response({"code": "000", "desc": "移动成功"})

    def get_tag_base_map(self):
        # 查询所有标签{类别-场景}MAP
        tag_objs = self.ttm.query_testcase_tag()
        tag_base_map = {}
        for tag_obj in tag_objs:
            if tag_obj.tag_category not in tag_base_map:
                tag_base_map[tag_obj.tag_category] = [{
                    "tagId":
                    tag_obj.id,
                    "tagName":
                    tag_obj.tag_name
                }]
            else:
                tag_base_map[tag_obj.tag_category].append({
                    "tagId":
                    tag_obj.id,
                    "tagName":
                    tag_obj.tag_name
                })
        return tag_base_map
Exemple #8
0
def get_under_node(parent_id, tree_list, index, with_sub, tag_id_list,
                   without_testcase, all_sub_objs):
    pl_objs = ApiProductLineManager.get_product_lines(parent_id=parent_id)
    for pl_obj in pl_objs:
        index += 1
        tree = {
            'id': index,
            'label': pl_obj.product_line_name,
            'productLineId': pl_obj.id,
            'children': []
        }
        index = get_under_node(pl_obj.id, tree['children'], index, with_sub,
                               tag_id_list, without_testcase, all_sub_objs)
        tree_list.append(tree)

    if without_testcase:
        return index

    # tm_objs = ApiTestcaseMainManager.get_testcase_mains(api_product_line_id=parent_id)
    res = ApiTestcaseMainManager.get_testcase_mains_in_tag(
        api_product_line_id=parent_id, tag_id_list=tag_id_list)

    for row in res:
        index += 1
        tree = {
            'id': index,
            'label': str(row[0]) + '_' + row[1],
            'testcaseId': row[0],
            'children': []
        }
        # 是否需要添加到子用例层
        if with_sub:
            sub_list = json.loads(row[2])

            # sub_objs = ApiTestcaseSubManager.get_testcase_subs_in_id_list(sub_list)
            # for sub_obj in sub_objs:
            #     sub_tree = {
            #         'id': index,
            #         'label': sub_obj.sub_name,
            #         'subId': sub_obj.id,
            #     }
            #     tree['children'].append(sub_tree)

            # for sub_id in sub_list:
            #     sub_obj = ApiTestcaseSubManager.get_testcase_sub(id=sub_id)
            #     sub_tree = {
            #         'id': index,
            #         'label': sub_obj.sub_name,
            #         'subId': sub_id,
            #         'children': []
            #     }
            #     tree['children'].append(sub_tree)

            for sub_id in sub_list:
                for sub_obj in all_sub_objs:
                    if sub_id == sub_obj.id:
                        sub_tree = {
                            'id': index,
                            'label': sub_obj.sub_name,
                            'subId': sub_obj.id,
                        }
                        tree['children'].append(sub_tree)
                        break

        tree_list.append(tree)
    return index
Exemple #9
0
def get_api_testcase_main_detail(tm_obj):
    """
    新版-获取主测试用例详情
    :param tm_obj:
    :return:
    """
    custom = read_custom()
    pvim = ApiPublicVariableInfoManager()
    public_v_objs = pvim.get_variables()

    case_type = tm_obj.case_type

    main_teardown_info = []
    if tm_obj.main_teardown_hooks:
        main_teardown_hooks = json.loads(tm_obj.main_teardown_hooks)
        for teardown in main_teardown_hooks:
            teardown = teardown.replace("||$DB_CONNECT", "",
                                        1).replace("||$DISCONF_HOST", "", 1)
            teardown_func_name = teardown.split("${")[1].split("(")[0]
            teardown_func_args = teardown[:-2].split("(", 1)[-1]
            for teardown_hook in custom["teardown-hooks"]:
                if teardown_hook["name"] == teardown_func_name:
                    args_dict = {}
                    for a, p in zip(teardown_func_args.split('||'),
                                    teardown_hook["parameters"]):
                        args_dict[p] = a
                    main_teardown_info.append({
                        "name":
                        teardown_func_name,
                        "desc":
                        teardown_hook["description"],
                        "args":
                        args_dict
                    })

    # # 返回自定义flow信息
    # custom_flow_objs = ApiTestcaseMainCustomFlowManager.get_flows(testcase_id=tm_obj.id)
    # custom_flow_list = [
    #     {
    #         "flowId": obj.id,
    #         "flowName": obj.flow_name,
    #         "startEnd": [obj.start_sub_index, obj.end_sub_index]
    #     }
    #     for obj in custom_flow_objs
    # ]

    response = {
        "base": {
            "testcaseName": tm_obj.testcase_name,
            "testcaseDesc": tm_obj.simple_desc if tm_obj.simple_desc else '',
            "creator": tm_obj.creator,
            "last_modifier": tm_obj.last_modifier,
            "expectResult":
            tm_obj.expect_result if tm_obj.expect_result else '',
            "mainTeardownInfo": main_teardown_info,
        },
        "steps": [],
    }
    _all_main_case_objs = None
    if case_type == 1:
        response["base"].update({
            "caseType": case_type,
            "intfId": tm_obj.api_intf_id,
        })
        response["setupFlow"] = []
        setup_flow_id_list = json.loads(tm_obj.setup_flow_list)
        for setup_flow_id in setup_flow_id_list:
            flow_obj = ApiTestcaseMainManager.get_testcase_main(
                id=setup_flow_id)
            pl_obj = ApiProductLineManager.get_product_line(
                id=flow_obj.api_product_line_id)
            product_line_name = pl_obj.product_line_name if pl_obj else ""
            response["setupFlow"].append({
                "flowCaseId":
                setup_flow_id,
                "flowName":
                flow_obj.testcase_name,
                "productLineName":
                product_line_name,
                "productLineId":
                flow_obj.api_product_line_id,
            })

        _all_main_case_objs = ApiTestcaseMainManager.get_testcase_mains()

    sub_id_list = json.loads(tm_obj.sub_list)

    ts_objs = ApiTestcaseSubManager.get_testcase_subs_in_id_list(sub_id_list)
    tr_objs = ApiTestcaseRequestQllManager.get_requests_in_case_id_list(
        sub_id_list)
    intf_id_list = [ts_obj.api_intf_id for ts_obj in ts_objs]
    intf_objs = ApiIntfInfoManager.get_intfs_in_id_list(intf_id_list)

    for sub_id in sub_id_list:
        sub_dic = {
            "base": {},
            "setupInfo": [],
            "teardownInfo": [],
            "requestTeardownInfo": [],
            "requestInfo": {},
            "validateInfo": [],
            "extractInfo": [],
            "variableInfo": []
        }

        # ts_obj = ApiTestcaseSubManager.get_testcase_sub(id=sub_id)
        # tr_obj = ApiTestcaseRequestQllManager.get_request(api_testcase_id=sub_id)
        # intf_obj = ApiIntfInfoManager.get_intf(id=ts_obj.api_intf_id)
        ts_obj = None
        tr_obj = None
        intf_obj = None
        for obj in ts_objs:
            if obj.id == sub_id:
                ts_obj = obj
                break
        for obj in tr_objs:
            if obj.api_testcase_id == sub_id:
                tr_obj = obj
                break

        if not ts_obj or not tr_obj:
            continue
        for obj in intf_objs:
            if obj.id == ts_obj.api_intf_id:
                intf_obj = obj
                break

        request = tr_obj.request
        include = ts_obj.include
        request_type = ts_obj.request_type

        # 返回base
        sub_dic["base"]["intfId"] = ts_obj.api_intf_id
        sub_dic["base"]["intfName"] = intf_obj.intf_name
        sub_dic["base"][
            "intfNameInChinese"] = intf_obj.intf_desc if intf_obj.intf_desc else ''
        sub_dic["base"]["subId"] = sub_id
        sub_dic["base"]["subName"] = ts_obj.sub_name
        sub_dic["base"][
            "subDesc"] = ts_obj.simple_desc if ts_obj.simple_desc else ''
        sub_dic["base"][
            "subExpectResult"] = ts_obj.expect_result if ts_obj.expect_result else ''
        sub_dic["base"][
            "isMultiQuote"] = True if ts_obj.main_list and json.loads(
                ts_obj.main_list) and len(json.loads(
                    ts_obj.main_list)) > 1 else False
        sub_dic["base"]["requestType"] = map_number_to_testcase_type(
            request_type)
        if case_type == 1:
            sub_dic["base"][
                "isSelf"] = True if ts_obj.api_intf_id == tm_obj.api_intf_id else False

        # testcase_request = json.loads(request.replace("'", "\""))
        testcase_request = json.loads(request)
        last_teststeps = len(testcase_request["teststeps"]) - 1

        # 返回variableInfo
        for variable in testcase_request["teststeps"][last_teststeps][
                "variables"]:
            for variable_key, variable_value in variable.items():

                if 1 == 0:
                    pass
                else:
                    variable_dict = {}
                    # variable_value = str(variable_value)
                    save_as_type = get_save_as_type(variable_value)
                    variable_value = str(variable_value)

                    # 自定义变量-db
                    if variable_value.startswith("${variable_db_operation("):
                        variable_dict["name"] = variable_key
                        variable_dict["type"] = "db"
                        variable_dict["value"] = variable_value.replace(
                            "${variable_db_operation(", "",
                            1).replace("||$DB_CONNECT)}", "", 1)

                    # 变量类型-function
                    elif variable_value.startswith(
                            '${') and variable_value.endswith('}'):
                        func_name = variable_value.split('${')[-1].split(
                            '(')[0]
                        if 'variable_db_operation' == func_name:
                            continue
                        args_list = variable_value[:-2].split(
                            '(', 1)[-1].split('||')
                        args_dict = {}
                        for func in custom["functions"]:
                            if func["name"] == func_name:
                                for a, p in zip(args_list, func["parameters"]):
                                    args_dict[p] = a
                                break

                        variable_dict["name"] = variable_key
                        variable_dict["type"] = "function"
                        variable_dict["value"] = func_name
                        variable_dict["args"] = args_dict

                    # 变量类型-constant
                    else:
                        variable_dict["saveAs"] = save_as_type
                        variable_dict["name"] = variable_key
                        variable_dict["type"] = "constant"
                        variable_dict["value"] = variable_value
                    sub_dic["variableInfo"].append(variable_dict)

        # 返回setupInfo
        testcase_setup_hooks = testcase_request["teststeps"][last_teststeps][
            "setup_hooks"]
        for setup in testcase_setup_hooks:
            setup_func_name = setup.split("${")[1].split("(")[0]
            setup_func_args = setup[:-2].split("(", 1)[-1]
            # setup_func_args = re.findall(r'[^()]+', setup.split("{")[-1].split('}')[0])[1]
            # setup_func_args = re.findall(r'[(](.*?)[)]', setup,re.S)[0]
            '''判断request字段里面的setup_hooks里面是否有前置操作,有则返回至detail的setupInfo'''
            for setup_hook in custom["setup-hooks"]:
                if setup_hook["name"] == setup_func_name:
                    if setup_func_name == "setup_db_operation":
                        sub_dic["setupInfo"].append({
                            "name":
                            setup_func_name,
                            "desc":
                            setup_hook["description"],
                            "args": {
                                "sql":
                                setup_func_args.replace(
                                    "||$DB_CONNECT", "", 1)
                            }
                        })
                    elif setup_func_name == "setup_wait_until_db_result_succeed":
                        args_dict = {}
                        for a, p in zip(setup_func_args.split('||'),
                                        setup_hook["parameters"]):
                            if p == "sql":
                                args_dict[p] = a.replace(
                                    "||$DB_CONNECT", "", 1)
                            else:
                                args_dict[p] = a
                        sub_dic["setupInfo"].append({
                            "name":
                            setup_func_name,
                            "desc":
                            setup_hook["description"],
                            "args":
                            args_dict
                        })
                    else:
                        '''
                                # {
                                #     "name": "execution_testcase",
                                #     "args": {
                                #         "用例编号": "4173",
                                #         "请求参数": "{\"phone\":\"18260037329\"}"
                                #     }
                                # }
                                #
                            '''
                        args_dict = {}
                        for a, p in zip(setup_func_args.split('||'),
                                        setup_hook["parameters"]):
                            args_dict[p] = a
                        sub_dic["setupInfo"].append({
                            "name":
                            setup_func_name,
                            "desc":
                            setup_hook["description"],
                            "args":
                            args_dict
                        })
            '''判断request字段里面的setup_hooks里面是否有加签函数,有则返回至detail的requestInfo'''
            for setup_hook in custom["sign"]:
                if setup_hook["name"] == setup_func_name:
                    if "sign" in setup_func_name:
                        '''setup_hooks中是否有加签函数'''
                        sub_dic["requestInfo"]["sign"] = {
                            "name": setup_func_name,
                            "desc": setup_hook["description"]
                        }

        # 返回teardownInfo
        testcase_teardown_hooks = testcase_request["teststeps"][
            last_teststeps]["teardown_hooks"]
        for teardown in testcase_teardown_hooks:
            teardown_func_name = teardown.split("${")[1].split("(")[0]
            teardown_func_args = teardown[:-2].split("(", 1)[-1]
            for teardown_hook in custom["teardown-hooks"]:
                if teardown_hook["name"] == teardown_func_name:
                    if teardown_func_name == "teardown_db_operation":
                        sub_dic["teardownInfo"].append({
                            "name":
                            teardown_func_name,
                            "desc":
                            teardown_hook["description"],
                            "args": {
                                "sql":
                                teardown_func_args.replace(
                                    "||$DB_CONNECT", "", 1)
                            }
                        })
                    elif teardown_func_name == "teardown_wait_until_db_result_succeed":
                        args_dict = {}
                        for a, p in zip(teardown_func_args.split('||'),
                                        teardown_hook["parameters"]):
                            if p == "sql":
                                args_dict[p] = a.replace(
                                    "||$DB_CONNECT", "", 1)
                            else:
                                args_dict[p] = a
                        sub_dic["teardownInfo"].append({
                            "name":
                            teardown_func_name,
                            "desc":
                            teardown_hook["description"],
                            "args":
                            args_dict
                        })
                    else:
                        """如果args是列表,返回args列表"""

                        args_dict = {}
                        for a, p in zip(teardown_func_args.split('||'),
                                        teardown_hook["parameters"]):
                            args_dict[p] = a
                        sub_dic["teardownInfo"].append({
                            "name":
                            teardown_func_name,
                            "desc":
                            teardown_hook["description"],
                            "args":
                            args_dict
                        })

        # 返回requestTeardownInfo
        request_teardown_hooks = testcase_request["teststeps"][
            last_teststeps].get("request_teardown_hooks", [])
        for teardown in request_teardown_hooks:
            teardown_func_name = teardown.split("${")[1].split("(")[0]
            teardown_func_args = teardown[:-2].split("(", 1)[-1]
            for teardown_hook in custom["teardown-hooks"]:
                if teardown_hook["name"] == teardown_func_name:
                    """如果args是列表,返回args列表"""
                    args_dict = {}
                    for a, p in zip(teardown_func_args.split('||'),
                                    teardown_hook["parameters"]):
                        args_dict[p] = a
                    sub_dic["requestTeardownInfo"].append({
                        "name":
                        teardown_func_name,
                        "desc":
                        teardown_hook["description"],
                        "args":
                        args_dict
                    })

        # 返回requestInfo[json]
        requests_dict = testcase_request["teststeps"][last_teststeps][
            "request"]
        is_merge = requests_dict.pop("isMerge", True)
        if request_type == 1:

            for json_value in requests_dict.values():
                sub_dic["requestInfo"]["json"] = json_value

            # 增加入参校验
            include_li = json.loads(include)

            if len(include_li) >= 3:
                param_check_dic = include_li[2]["param_check"]
                for item, p_list in param_check_dic.items():
                    if item == 'empty':
                        sub_dic["requestInfo"]["emptyCheckParamList"] = p_list

        elif request_type == 2:
            for args_value in requests_dict.values():
                sub_dic["requestInfo"] = args_value

        elif request_type == 3:

            for msg_value in requests_dict.values():
                sub_dic["requestInfo"] = msg_value

        sub_dic["requestInfo"]["isMerge"] = is_merge
        sub_dic["requestInfo"]["type"] = request_type

        # 返回extractInfo

        for extract in testcase_request["teststeps"][last_teststeps][
                "extract"]:
            for extract_key, extract_value in extract.items():
                sub_dic["extractInfo"].append({
                    "saveAs": extract_key,
                    "check": extract_value
                })

        # 返回validateInfo
        for validate in testcase_request["teststeps"][last_teststeps][
                "validate"]:
            for comparator, veirfy in validate.items():
                if comparator == 'db_validate' and veirfy[0].endswith(
                        '$DB_CONNECT'):
                    veirfy[0] = veirfy[0].split("$DB_")[0]
                sub_dic["validateInfo"].append({
                    "comparator":
                    comparator,
                    "desc":
                    comparator,
                    "check":
                    veirfy[0],
                    "expect":
                    veirfy[1],
                    "comment":
                    veirfy[2] if len(veirfy) >= 3 else '',
                })

        # 返回include
        if not (include is None or len(include) < 3):
            testcase_include = json.loads(include)
            include_list = [{"public_variables": []}]
            for pv_id in testcase_include[0]["public_variables"]:
                # obj = pvim.get_variable(id=pv_id)
                obj = None
                for public_v_obj in public_v_objs:
                    if public_v_obj.id == pv_id:
                        obj = public_v_obj
                        break
                if not obj:
                    continue
                id_, name, type_name, desc = obj.id, obj.variable_name, obj.type, obj.simple_desc
                value = [v.strip()
                         for v in obj.value.strip('##').split('##')][0]
                include_list[0]["public_variables"].append({
                    "id": id_,
                    "name": name,
                    "value": value,
                    "type": type_name,
                    "desc": desc
                })
            sub_dic["include"] = include_list

        # 返回relatedMainCases
        if case_type == 1:
            sub_dic.update({"relatedCases": []})
            for main_case_obj in _all_main_case_objs:
                if main_case_obj.case_type == 2:
                    continue
                other_case_sub_list = json.loads(main_case_obj.sub_list)
                if sub_id in other_case_sub_list:
                    sub_dic["relatedCases"].append({
                        "testcaseId":
                        main_case_obj.id,
                        "testcaseName":
                        main_case_obj.testcase_name
                    })

        response["steps"].append(sub_dic)

    return response
Exemple #10
0
class ApiProductLine(Resource):
    def __init__(self):
        self.data = get_request_json()
        self.username = redis.get_username(request.headers.get('X-Token'))
        # self.acim = ApiCompanyInfoManager()
        # self.asim = ApiSystemInfoManager()
        # self.aiim = ApiIntfInfoManager()
        # self.atim = ApiTestcaseInfoManager()
        self.aplm = ApiProductLineManager()
        self.atmm = ApiTestcaseMainManager()

    @timer
    def post(self, action):
        if action == 'add':
            return self.add_product_line()

        elif action == 'edit':
            return self.edit_product_line()

        elif action == 'delete':
            return self.delete_product_line()

        elif action == 'changeParent':
            return self.change_folder_parent()

        else:
            return make_response({
                "code":
                "100",
                "desc":
                "url错误,不存在的接口动作<{action}>".format(action=action)
            })

    @developer_check
    def add_product_line(self):
        try:
            product_line_name = self.data.pop('productLineName')
            company_id = self.data.pop('companyId', None)
            parent_id = self.data.pop('parentId', None)
            if not company_id and not parent_id:
                raise KeyError
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        product_line_name = str(product_line_name).strip()

        if company_id:
            # 判断产品线是否已存在,存在无法添加
            if self.aplm.get_product_line(product_line_name=product_line_name,
                                          api_company_id=company_id):
                return make_response({
                    "code":
                    "201",
                    "desc":
                    "产品线\"{}\"已存在".format(product_line_name)
                })

            self.aplm.insert_product_line(product_line_name=product_line_name,
                                          api_company_id=company_id,
                                          creator=self.username)
            return make_response({
                "code":
                "000",
                "desc":
                "产品线\"{}\"增加成功".format(product_line_name)
            })
        else:
            # 判断目录是否已存在,存在无法添加
            if self.aplm.get_product_line(product_line_name=product_line_name,
                                          parent_id=parent_id):
                return make_response({
                    "code":
                    "201",
                    "desc":
                    "目录\"{}\"已存在".format(product_line_name)
                })

            self.aplm.insert_folder(product_line_name=product_line_name,
                                    parent_id=parent_id,
                                    creator=self.username)
            return make_response({
                "code":
                "000",
                "desc":
                "目录\"{}\"增加成功".format(product_line_name)
            })

    @developer_check
    def edit_product_line(self):
        try:
            product_line_id = self.data.pop('productLineId')
            product_line_name = self.data.pop('productLineName')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        pl_obj = self.aplm.get_product_line(id=product_line_id)
        if pl_obj.api_company_id:
            if not pl_obj:
                return make_response({
                    "code":
                    "202",
                    "desc":
                    "产品线id\"{}\"不存在, 请刷新后重试".format(product_line_id)
                })
            elif self.aplm.get_product_line(
                    product_line_name=product_line_name,
                    api_company_id=pl_obj.api_company_id):
                return make_response({
                    "code":
                    "201",
                    "desc":
                    "产品线\"{}\"已存在, 无法修改".format(product_line_name)
                })

            self.aplm.update_product_line(product_line_id,
                                          product_line_name=product_line_name,
                                          last_modifier=self.username)
            return make_response({
                "code":
                "000",
                "desc":
                "产品线\"{}\"修改成功".format(product_line_name)
            })

        else:
            if not pl_obj:
                return make_response({
                    "code":
                    "202",
                    "desc":
                    "目录id\"{}\"不存在, 请刷新后重试".format(product_line_id)
                })
            elif self.aplm.get_product_line(
                    product_line_name=product_line_name,
                    parent_id=pl_obj.parent_id):
                return make_response({
                    "code":
                    "201",
                    "desc":
                    "目录\"{}\"已存在, 无法修改".format(product_line_name)
                })

            self.aplm.update_product_line(product_line_id,
                                          product_line_name=product_line_name,
                                          last_modifier=self.username)
            return make_response({
                "code":
                "000",
                "desc":
                "目录\"{}\"修改成功".format(product_line_name)
            })

    @developer_check
    def delete_product_line(self):
        try:
            product_line_id = self.data.pop('productLineId')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        pl_obj = self.aplm.get_product_line(id=product_line_id)

        if pl_obj.api_company_id:
            if not pl_obj:
                return make_response({
                    "code":
                    "202",
                    "desc":
                    "产品线id\"{}\"不存在, 请刷新后重试".format(product_line_id)
                })

            sub_folder_objs = self.aplm.get_product_lines(
                parent_id=product_line_id)
            if sub_folder_objs:
                return make_response({
                    "code":
                    "300",
                    "desc":
                    "产品线下已配置{}个目录,无法直接删除".format(len(sub_folder_objs))
                })

            tm_objs = self.atmm.get_testcase_mains(
                api_product_line_id=product_line_id)
            if tm_objs:
                return make_response({
                    "code":
                    "300",
                    "desc":
                    "产品线下已配置{}个全链路用例,无法直接删除".format(len(tm_objs))
                })

            self.aplm.delete_product_line(product_line_id)
            return make_response({"code": "000", "desc": "产品线删除成功"})

        else:
            if not pl_obj:
                return make_response({
                    "code":
                    "202",
                    "desc":
                    "目录id\"{}\"不存在, 请刷新后重试".format(product_line_id)
                })

            sub_folder_objs = self.aplm.get_product_lines(
                parent_id=product_line_id)
            if sub_folder_objs:
                return make_response({
                    "code":
                    "300",
                    "desc":
                    "节点下已配置{}个目录,无法直接删除".format(len(sub_folder_objs))
                })

            tm_objs = self.atmm.get_testcase_mains(
                api_product_line_id=product_line_id)
            if tm_objs:
                return make_response({
                    "code":
                    "300",
                    "desc":
                    "节点下已配置{}个全链路用例,无法直接删除".format(len(tm_objs))
                })

            self.aplm.delete_folder(product_line_id)
            return make_response({"code": "000", "desc": "目录删除成功"})

    @developer_check
    def change_folder_parent(self):
        try:
            folder_id = self.data.pop('productLineId')
            new_parent_id = self.data.pop('newParentId')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        folder_obj = self.aplm.get_product_line(id=folder_id)
        if not folder_obj:
            return make_response({
                "code":
                "202",
                "desc":
                "目录id\"{}\"不存在, 请刷新后重试".format(folder_id)
            })

        parent_obj = self.aplm.get_product_line(id=new_parent_id)
        if not parent_obj:
            return make_response({
                "code":
                "203",
                "desc":
                "目录id\"{}\"不存在, 请刷新后重试".format(new_parent_id)
            })

        kwargs = {
            'id': folder_obj.id,
            'product_line_name': folder_obj.product_line_name,
            'simple_desc': folder_obj.simple_desc,
            # 'api_company_id': folder_obj.api_company_id,
            'creator': folder_obj.creator,
            'last_modifier': self.username,
            'parent_id': new_parent_id,
        }
        self.aplm.delete_folder(folder_id)
        self.aplm.insert_folder(**kwargs)
        return make_response({"code": "000", "desc": "成功"})