mirror of
https://github.com/YMFE/yapi.git
synced 2025-01-30 13:20:24 +08:00
Merge branch 'dev' of gitlab.corp.qunar.com:mfe/yapi into dev
This commit is contained in:
commit
394acf8522
@ -11,6 +11,7 @@ const MockExtra = require('common/mock-extra.js')
|
||||
import './Postman.scss';
|
||||
import json5 from 'json5'
|
||||
import { handleMockWord, isJson } from '../../common.js'
|
||||
import _ from "underscore"
|
||||
|
||||
function json_parse(data) {
|
||||
try {
|
||||
@ -197,7 +198,7 @@ export default class Run extends Component {
|
||||
return;
|
||||
}
|
||||
const { headers, bodyForm, pathParam, bodyOther, caseEnv, domains, method, pathname, query, bodyType } = this.state;
|
||||
const urlObj = URL.parse(domains.find(item => item.name === caseEnv).domain);
|
||||
const urlObj = URL.parse(_.find(domains, item => item.name === caseEnv).domain);
|
||||
let path = pathname
|
||||
pathParam.forEach(item => {
|
||||
path = path.replace(`:${item.name}`, item.value || `:${item.name}`);
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
setGroupList,
|
||||
fetchGroupMsg
|
||||
} from '../../../reducer/modules/group.js'
|
||||
import _ from 'underscore'
|
||||
|
||||
import './GroupList.scss';
|
||||
|
||||
@ -185,7 +186,8 @@ export default class GroupList extends Component {
|
||||
@autobind
|
||||
selectGroup(e) {
|
||||
const groupId = e.key;
|
||||
const currGroup = this.props.groupList.find((group) => { return +group._id === +groupId });
|
||||
//const currGroup = this.props.groupList.find((group) => { return +group._id === +groupId });
|
||||
const currGroup = _.find(this.props.groupList, (group) => { return +group._id === +groupId });
|
||||
this.props.setCurrGroup(currGroup);
|
||||
this.props.history.replace(`${currGroup._id}`);
|
||||
this.props.fetchNewsData(groupId, "group", 1, 10)
|
||||
|
@ -76,8 +76,8 @@ export default class InterfaceCaseContent extends Component {
|
||||
let currColId = this.getColId(result.payload.data.data, currCaseId);
|
||||
this.props.history.push('/project/' + params.id + '/interface/case/' + currCaseId)
|
||||
await this.props.fetchCaseData(currCaseId)
|
||||
this.props.setColData({currCaseId: +currCaseId, currColId, isShowCol: false})
|
||||
this.setState({editCasename: this.props.currCase.casename})
|
||||
this.props.setColData({ currCaseId: +currCaseId, currColId, isShowCol: false })
|
||||
this.setState({ editCasename: this.props.currCase.casename })
|
||||
}
|
||||
|
||||
async componentWillReceiveProps(nextProps) {
|
||||
@ -87,8 +87,8 @@ export default class InterfaceCaseContent extends Component {
|
||||
let currColId = this.getColId(interfaceColList, newCaseId);
|
||||
if (oldCaseId !== newCaseId) {
|
||||
await this.props.fetchCaseData(newCaseId);
|
||||
this.props.setColData({currCaseId: +newCaseId, currColId, isShowCol: false})
|
||||
this.setState({editCasename: this.props.currCase.casename})
|
||||
this.props.setColData({ currCaseId: +newCaseId, currColId, isShowCol: false })
|
||||
this.setState({ editCasename: this.props.currCase.casename })
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ export default class InterfaceCaseContent extends Component {
|
||||
}
|
||||
|
||||
updateCase = async () => {
|
||||
|
||||
|
||||
const {
|
||||
caseEnv: case_env,
|
||||
pathname: path,
|
||||
@ -110,9 +110,9 @@ export default class InterfaceCaseContent extends Component {
|
||||
bodyOther: req_body_other,
|
||||
resMockTest: mock_verify
|
||||
} = this.postman.state;
|
||||
|
||||
const {editCasename: casename} = this.state;
|
||||
const {_id: id} = this.props.currCase;
|
||||
|
||||
const { editCasename: casename } = this.state;
|
||||
const { _id: id } = this.props.currCase;
|
||||
let params = {
|
||||
id,
|
||||
casename,
|
||||
@ -127,15 +127,15 @@ export default class InterfaceCaseContent extends Component {
|
||||
req_body_other,
|
||||
mock_verify
|
||||
};
|
||||
if(this.postman.state.test_status !== 'error'){
|
||||
if (this.postman.state.test_status !== 'error') {
|
||||
params.test_res_body = this.postman.state.res;
|
||||
params.test_report = this.postman.state.validRes;
|
||||
params.test_status = this.postman.state.test_status;
|
||||
params.test_res_header = this.postman.state.resHeader;
|
||||
}
|
||||
|
||||
|
||||
if(params.test_res_body && typeof params.test_res_body === 'object'){
|
||||
|
||||
if (params.test_res_body && typeof params.test_res_body === 'object') {
|
||||
params.test_res_body = JSON.stringify(params.test_res_body, null, ' ');
|
||||
}
|
||||
|
||||
@ -167,30 +167,18 @@ export default class InterfaceCaseContent extends Component {
|
||||
render() {
|
||||
const { currCase, currProject } = this.props;
|
||||
const { isEditingCasename, editCasename } = this.state;
|
||||
const data = Object.assign({}, currCase, currProject, {_id: currCase._id});
|
||||
const data = Object.assign({}, currCase, currProject, { _id: currCase._id });
|
||||
return (
|
||||
<div style={{padding: '6px 0'}} className="case-content">
|
||||
<div style={{ padding: '6px 0' }} className="case-content">
|
||||
<div className="case-title">
|
||||
{!isEditingCasename && <Tooltip title="点击编辑" placement="bottom"><div className="case-name" onClick={this.triggerEditCasename}>
|
||||
{currCase.casename}
|
||||
</div></Tooltip>}
|
||||
|
||||
{isEditingCasename && <div className="edit-case-name">
|
||||
<Input value={editCasename} onChange={e => this.setState({editCasename: e.target.value})} style={{fontSize: 18}} />
|
||||
{/*<Button
|
||||
title="Enter"
|
||||
onClick={this.saveCasename}
|
||||
type="primary"
|
||||
style={{ marginLeft: 8 }}
|
||||
>保存</Button>
|
||||
<Button
|
||||
title="Esc"
|
||||
onClick={this.cancelEditCasename}
|
||||
type="primary"
|
||||
style={{ marginLeft: 8 }}
|
||||
>取消</Button>*/}
|
||||
<Input value={editCasename} onChange={e => this.setState({ editCasename: e.target.value })} style={{ fontSize: 18 }} />
|
||||
</div>}
|
||||
<span className="inter-link" style={{margin: '0px 8px 0px 6px', fontSize: 12}}>
|
||||
<span className="inter-link" style={{ margin: '0px 8px 0px 6px', fontSize: 12 }}>
|
||||
<Link className="text" to={`/project/${currProject._id}/interface/api/${currCase.interface_id}`}>对应接口</Link>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -4,11 +4,12 @@ import PropTypes from 'prop-types'
|
||||
import { withRouter } from 'react-router'
|
||||
import { Link } from 'react-router-dom'
|
||||
import constants from '../../../../constants/variable.js'
|
||||
import { Tooltip, Icon, Button, Spin, Modal, message ,Select} from 'antd'
|
||||
import { Tooltip, Icon, Button, Spin, Modal, message, Select, Switch } from 'antd'
|
||||
import { fetchInterfaceColList, fetchCaseList, setColData } from '../../../../reducer/modules/interfaceCol'
|
||||
import HTML5Backend from 'react-dnd-html5-backend';
|
||||
import { DragDropContext } from 'react-dnd';
|
||||
import { isJson, handleMockWord, simpleJsonPathParse } from '../../../../common.js'
|
||||
import mockEditor from '../InterfaceList/mockEditor';
|
||||
import * as Table from 'reactabular-table';
|
||||
import * as dnd from 'reactabular-dnd';
|
||||
import * as resolve from 'table-resolver';
|
||||
@ -17,6 +18,8 @@ import URL from 'url';
|
||||
import Mock from 'mockjs'
|
||||
import json5 from 'json5'
|
||||
import CaseReport from './CaseReport.js'
|
||||
import _ from 'underscore'
|
||||
|
||||
const MockExtra = require('common/mock-extra.js')
|
||||
const Option = Select.Option;
|
||||
function json_parse(data) {
|
||||
@ -74,7 +77,10 @@ class InterfaceColContent extends Component {
|
||||
visible: false,
|
||||
curCaseid: null,
|
||||
hasPlugin: false,
|
||||
currColEnv: ''
|
||||
currColEnv: '',
|
||||
advVisible: false,
|
||||
curScript: '',
|
||||
enableScript: false
|
||||
};
|
||||
this.onRow = this.onRow.bind(this);
|
||||
this.onMoveRow = this.onMoveRow.bind(this);
|
||||
@ -85,8 +91,7 @@ class InterfaceColContent extends Component {
|
||||
let { currColId } = this.props;
|
||||
const params = this.props.match.params;
|
||||
const { actionId } = params;
|
||||
currColId = +actionId ||
|
||||
result.payload.data.data.find(item => +item._id === +currColId) && +currColId ||
|
||||
this.currColId = currColId = +actionId ||
|
||||
result.payload.data.data[0]._id;
|
||||
this.props.history.push('/project/' + params.id + '/interface/col/' + currColId)
|
||||
if (currColId && currColId != 0) {
|
||||
@ -112,6 +117,7 @@ class InterfaceColContent extends Component {
|
||||
})
|
||||
}
|
||||
}, 500)
|
||||
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@ -161,20 +167,20 @@ class InterfaceColContent extends Component {
|
||||
status = 'error';
|
||||
result = e;
|
||||
}
|
||||
|
||||
|
||||
let query = this.arrToObj(curitem.req_query);
|
||||
if(!query || typeof query !== 'object'){
|
||||
if (!query || typeof query !== 'object') {
|
||||
query = {};
|
||||
}
|
||||
let body = {};
|
||||
if(HTTP_METHOD[curitem.method].request_body){
|
||||
if(curitem.req_body_type === 'form'){
|
||||
if (HTTP_METHOD[curitem.method].request_body) {
|
||||
if (curitem.req_body_type === 'form') {
|
||||
body = this.arrToObj(curitem.req_body_form);
|
||||
}else {
|
||||
} else {
|
||||
body = isJson(curitem.req_body_other);
|
||||
}
|
||||
|
||||
if(!body || typeof body !== 'object'){
|
||||
|
||||
if (!body || typeof body !== 'object') {
|
||||
body = {};
|
||||
}
|
||||
}
|
||||
@ -195,7 +201,7 @@ class InterfaceColContent extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleTest = (interfaceData) => {
|
||||
handleTest = async (interfaceData) => {
|
||||
const { currProject } = this.props;
|
||||
const { case_env } = interfaceData;
|
||||
let path = URL.resolve(currProject.basepath, interfaceData.path);
|
||||
@ -204,13 +210,13 @@ class InterfaceColContent extends Component {
|
||||
path = path.replace(`:${item.name}`, item.value || `:${item.name}`);
|
||||
});
|
||||
const domains = currProject.env.concat();
|
||||
let currDomain = domains.find(item => item.name === case_env);
|
||||
if(!currDomain){
|
||||
let currDomain = _.find(domains, item => item.name === case_env);
|
||||
if (!currDomain) {
|
||||
currDomain = domains[0];
|
||||
}
|
||||
const urlObj = URL.parse(currDomain.domain);
|
||||
if(urlObj.pathname){
|
||||
if(urlObj.pathname[urlObj.pathname.length - 1] !== '/'){
|
||||
if (urlObj.pathname) {
|
||||
if (urlObj.pathname[urlObj.pathname.length - 1] !== '/') {
|
||||
urlObj.pathname += '/'
|
||||
}
|
||||
}
|
||||
@ -222,89 +228,132 @@ class InterfaceColContent extends Component {
|
||||
query: this.getQueryObj(interfaceData.req_query)
|
||||
});
|
||||
|
||||
let result = { code: 400, msg: '数据异常', validRes: [] };
|
||||
let that = this;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let result = { code: 400, msg: '数据异常', validRes: [] };
|
||||
let that = this;
|
||||
|
||||
result.url = href;
|
||||
result.method = interfaceData.method;
|
||||
result.headers = that.getHeadersObj(interfaceData.req_headers);
|
||||
if(interfaceData.req_body_type === 'form'){
|
||||
result.body = that.arrToObj(interfaceData.req_body_form)
|
||||
}else{
|
||||
let reqBody = isJson(interfaceData.req_body_other);
|
||||
if(reqBody === false){
|
||||
result.body = this.handleValue(interfaceData.req_body_other)
|
||||
}else{
|
||||
result.body = JSON.stringify(this.handleJson(reqBody))
|
||||
}
|
||||
|
||||
result.url = href;
|
||||
result.method = interfaceData.method;
|
||||
result.headers = that.getHeadersObj(interfaceData.req_headers);
|
||||
if (interfaceData.req_body_type === 'form') {
|
||||
result.body = that.arrToObj(interfaceData.req_body_form)
|
||||
} else {
|
||||
let reqBody = isJson(interfaceData.req_body_other);
|
||||
if (reqBody === false) {
|
||||
result.body = this.handleValue(interfaceData.req_body_other)
|
||||
} else {
|
||||
result.body = JSON.stringify(this.handleJson(reqBody))
|
||||
}
|
||||
|
||||
window.crossRequest({
|
||||
|
||||
}
|
||||
try{
|
||||
let data =await this.crossRequest({
|
||||
url: href,
|
||||
method: interfaceData.method,
|
||||
headers: that.getHeadersObj(interfaceData.req_headers),
|
||||
data: result.body,
|
||||
success: (res, header) => {
|
||||
res = json_parse(res);
|
||||
result.res_header = header;
|
||||
result.res_body = res;
|
||||
if (res && typeof res === 'object') {
|
||||
let tpl = MockExtra(json_parse(interfaceData.res_body), {
|
||||
query: interfaceData.req_query,
|
||||
body: interfaceData.req_body_form
|
||||
})
|
||||
|
||||
let validRes = [];
|
||||
if (interfaceData.mock_verify) {
|
||||
validRes = Mock.valid(tpl, res);
|
||||
}
|
||||
if (validRes.length === 0) {
|
||||
result.code = 0;
|
||||
result.validRes = [{ message: '验证通过' }];
|
||||
resolve(result);
|
||||
} else if (validRes.length > 0) {
|
||||
result.code = 1;
|
||||
result.validRes = validRes;
|
||||
resolve(result)
|
||||
}
|
||||
} else {
|
||||
reject(result)
|
||||
}
|
||||
},
|
||||
error: (err, header) => {
|
||||
try {
|
||||
err = json_parse(err);
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
|
||||
err = err || '请求异常';
|
||||
result.code = 400;
|
||||
result.res_header = header;
|
||||
result.res_body = err;
|
||||
reject(result)
|
||||
}
|
||||
data: result.body
|
||||
})
|
||||
let res = data.res.body = json_parse(data.res.body);
|
||||
let header = data.res.header;
|
||||
result.res_header = header;
|
||||
result.res_body = res;
|
||||
let validRes = [];
|
||||
if (res && typeof res === 'object') {
|
||||
if (interfaceData.mock_verify) {
|
||||
let tpl = MockExtra(json_parse(interfaceData.res_body), {
|
||||
query: interfaceData.req_query,
|
||||
body: interfaceData.req_body_form
|
||||
})
|
||||
validRes = Mock.valid(tpl, res);
|
||||
}
|
||||
}
|
||||
let responseData = Object.assign({}, {
|
||||
status:data.res.status,
|
||||
body: res,
|
||||
header: data.res.header,
|
||||
statusText: data.res.statusText
|
||||
})
|
||||
await that.handleScriptTest(interfaceData, responseData, validRes);
|
||||
if (validRes.length === 0) {
|
||||
result.code = 0;
|
||||
result.validRes = [{ message: '验证通过' }];
|
||||
} else if (validRes.length > 0) {
|
||||
result.code = 1;
|
||||
result.validRes = validRes;
|
||||
}
|
||||
return result;
|
||||
|
||||
}catch(data){
|
||||
if(data.err){
|
||||
data.err = data.err || '请求异常';
|
||||
try {
|
||||
data.err = json_parse( data.err);
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
result.res_body = data.err;
|
||||
result.res_header = data.header;
|
||||
}else{
|
||||
result.res_body = data.message;
|
||||
}
|
||||
|
||||
result.code = 400;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
crossRequest = (options)=>{
|
||||
return new Promise((resolve, reject)=>{
|
||||
options.success = function(res, header, data){
|
||||
resolve(data);
|
||||
}
|
||||
options.error = function(err, header){
|
||||
reject({
|
||||
err,
|
||||
header
|
||||
})
|
||||
}
|
||||
window.crossRequest(options);
|
||||
})
|
||||
}
|
||||
|
||||
handleJson = (data)=>{
|
||||
if(!data){
|
||||
//response, validRes
|
||||
handleScriptTest =async (interfaceData,response, validRes)=>{
|
||||
if(interfaceData.enable_script !== true){
|
||||
return null;
|
||||
}
|
||||
try{
|
||||
let test = await axios.post('/api/col/run_script', {
|
||||
response: response,
|
||||
records: this.records,
|
||||
script: interfaceData.test_script
|
||||
})
|
||||
if(test.data.errcode !== 0){
|
||||
validRes.push({
|
||||
message: test.data.data[0]
|
||||
})
|
||||
}
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
validRes.push({
|
||||
message: err.message
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handleJson = (data) => {
|
||||
if (!data) {
|
||||
return data;
|
||||
}
|
||||
if(typeof data === 'string'){
|
||||
if (typeof data === 'string') {
|
||||
return this.handleValue(data);
|
||||
}else if(typeof data === 'object'){
|
||||
for(let i in data){
|
||||
} else if (typeof data === 'object') {
|
||||
for (let i in data) {
|
||||
data[i] = this.handleJson(data[i]);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
return data;
|
||||
return data;
|
||||
}
|
||||
|
||||
handleValue = (val) => {
|
||||
@ -329,7 +378,7 @@ class InterfaceColContent extends Component {
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
getQueryObj = (query) => {
|
||||
query = query || [];
|
||||
@ -378,18 +427,29 @@ class InterfaceColContent extends Component {
|
||||
}
|
||||
|
||||
async componentWillReceiveProps(nextProps) {
|
||||
const { interfaceColList } = nextProps;
|
||||
const { actionId: oldColId, id } = this.props.match.params
|
||||
//const { interfaceColList } = nextProps;
|
||||
//const { actionId: oldColId, id } = this.props.match.params
|
||||
let newColId = nextProps.match.params.actionId
|
||||
if (!interfaceColList.find(item => +item._id === +newColId)&&interfaceColList[0]._id) {
|
||||
this.props.history.push('/project/' + id + '/interface/col/' + interfaceColList[0]._id)
|
||||
} else if ((oldColId !== newColId) || interfaceColList !== this.props.interfaceColList) {
|
||||
|
||||
if(newColId !== this.currColId){
|
||||
this.currColId = newColId;
|
||||
if (newColId && newColId != 0) {
|
||||
await this.props.fetchCaseList(newColId);
|
||||
this.props.setColData({ currColId: +newColId, isShowCol: true })
|
||||
this.handleColdata(this.props.currCaseList)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if (!interfaceColList.find(item => +item._id === +newColId) && interfaceColList[0]._id) {
|
||||
// this.props.history.push('/project/' + id + '/interface/col/' + interfaceColList[0]._id)
|
||||
// } else if ((oldColId !== newColId) || interfaceColList !== this.props.interfaceColList) {
|
||||
// if (newColId && newColId != 0) {
|
||||
// await this.props.fetchCaseList(newColId);
|
||||
// this.props.setColData({ currColId: +newColId, isShowCol: true })
|
||||
// this.handleColdata(this.props.currCaseList)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
openReport = (id) => {
|
||||
@ -400,7 +460,60 @@ class InterfaceColContent extends Component {
|
||||
visible: true,
|
||||
curCaseid: id
|
||||
})
|
||||
}
|
||||
|
||||
openAdv = (id) => {
|
||||
let findCase = _.find(this.props.currCaseList, item=> item.id === id)
|
||||
|
||||
this.setState({
|
||||
enableScript: findCase.enable_script,
|
||||
curScript: findCase.test_script,
|
||||
advVisible: true,
|
||||
curCaseid: id
|
||||
}, () => {
|
||||
let that = this;
|
||||
if(that.Editor){
|
||||
that.Editor.setValue(this.state.curScript);
|
||||
}else{
|
||||
that.Editor = mockEditor({
|
||||
container: 'case-script',
|
||||
data: this.state.curScript,
|
||||
onChange: function (d) {
|
||||
that.setState({
|
||||
curScript: d.text
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
handleAdvCancel = () => {
|
||||
this.setState({
|
||||
advVisible: false
|
||||
});
|
||||
}
|
||||
|
||||
handleAdvOk = async () => {
|
||||
const {curCaseid, enableScript, curScript} = this.state;
|
||||
const res = await axios.post('/api/col/up_case', {
|
||||
id: curCaseid,
|
||||
test_script: curScript,
|
||||
enable_script: enableScript
|
||||
});
|
||||
if(res.data.errcode === 0){
|
||||
message.success('更新成功');
|
||||
}
|
||||
this.setState({
|
||||
advVisible: false
|
||||
});
|
||||
let currColId = this.currColId;
|
||||
await this.props.fetchCaseList(currColId);
|
||||
this.props.setColData({ currColId: +currColId, isShowCol: true })
|
||||
this.handleColdata(this.props.currCaseList)
|
||||
}
|
||||
|
||||
handleCancel = () => {
|
||||
@ -411,7 +524,7 @@ class InterfaceColContent extends Component {
|
||||
|
||||
colEnvChange = (envName) => {
|
||||
let rows = [...this.state.rows];
|
||||
for(var i in rows){
|
||||
for (var i in rows) {
|
||||
rows[i].case_env = envName;
|
||||
}
|
||||
this.setState({
|
||||
@ -501,22 +614,29 @@ class InterfaceColContent extends Component {
|
||||
}
|
||||
]
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
header: {
|
||||
label: '测试报告'
|
||||
label: '操作'
|
||||
|
||||
},
|
||||
props: {
|
||||
style: {
|
||||
width: '100px'
|
||||
width: '200px'
|
||||
}
|
||||
},
|
||||
cell: {
|
||||
formatters: [(text, { rowData }) => {
|
||||
if (!this.reports[rowData.id]) {
|
||||
return null;
|
||||
let reportFun = () => {
|
||||
if (!this.reports[rowData.id]) {
|
||||
return null;
|
||||
}
|
||||
return <Button onClick={() => this.openReport(rowData.id)}>测试报告</Button>
|
||||
}
|
||||
return <Button onClick={() => this.openReport(rowData.id)}>报告</Button>
|
||||
return <div className="interface-col-table-action">
|
||||
<Button onClick={() => this.openAdv(rowData.id)} type="primary">高级</Button>
|
||||
{reportFun()}
|
||||
</div>
|
||||
}]
|
||||
}
|
||||
}
|
||||
@ -544,14 +664,14 @@ class InterfaceColContent extends Component {
|
||||
<div style={{ display: 'inline-block', margin: 0, marginBottom: '16px' }}>
|
||||
<Select value={currColEnv} style={{ width: "320px" }} onChange={this.colEnvChange}>
|
||||
{
|
||||
colEnv.map((item)=>{
|
||||
return <Option key={item._id} value={item.name}>{item.name+": "+item.domain}</Option>;
|
||||
colEnv.map((item) => {
|
||||
return <Option key={item._id} value={item.name}>{item.name + ": " + item.domain}</Option>;
|
||||
})
|
||||
}
|
||||
</Select>
|
||||
</div>
|
||||
{this.state.hasPlugin?
|
||||
<Button type="primary" style={{ float: 'right' }} onClick={this.executeTests}>开始测试</Button>:
|
||||
{this.state.hasPlugin ?
|
||||
<Button type="primary" style={{ float: 'right' }} onClick={this.executeTests}>开始测试</Button> :
|
||||
<Tooltip title="请安装 cross-request Chrome 插件">
|
||||
<Button disabled type="primary" style={{ float: 'right' }} >开始测试</Button>
|
||||
</Tooltip>
|
||||
@ -584,6 +704,21 @@ class InterfaceColContent extends Component {
|
||||
>
|
||||
<CaseReport {...this.reports[this.state.curCaseid]} />
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="自定义测试脚本"
|
||||
width="660px"
|
||||
style={{ minHeight: '500px' }}
|
||||
visible={this.state.advVisible}
|
||||
onCancel={this.handleAdvCancel}
|
||||
onOk={this.handleAdvOk}
|
||||
>
|
||||
<h3>
|
||||
是否开启:
|
||||
<Switch checked={this.state.enableScript} onChange={e=>this.setState({enableScript: e})} />
|
||||
</h3>
|
||||
<div className="case-script" id="case-script" style={{ minHeight: 500 }}></div>
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -115,4 +115,14 @@
|
||||
.interface-col-table-body td{
|
||||
padding-left:5px;
|
||||
}
|
||||
|
||||
.interface-col-table-action button{
|
||||
margin-right: 5px;
|
||||
padding: 5px 10px;
|
||||
max-width: 90px;
|
||||
}
|
||||
}
|
||||
|
||||
.case-script{
|
||||
margin: 10px
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
var strRegex = /\${([a-zA-Z0-9_\.]+)\}/g;
|
||||
var strRegex = /\${(body|query)([a-zA-Z0-9_\.]*)\}/i;
|
||||
var varSplit = '.';
|
||||
var mockSplit = '|';
|
||||
var Mock = require('mockjs');
|
||||
@ -33,7 +33,7 @@ function mock(mockJSON, context) {
|
||||
c[i] = (p[i].constructor === Array) ? [] : {};
|
||||
parse(p[i], c[i]);
|
||||
} else if(p[i] && typeof p[i] === 'string'){
|
||||
p[i] = handleStr(p[i]);
|
||||
p[i] = handleStr(p[i]);
|
||||
var filters = i.split(mockSplit), newFilters = [].concat(filters);
|
||||
c[i] = p[i];
|
||||
if (filters.length > 1) {
|
||||
@ -63,7 +63,11 @@ function mock(mockJSON, context) {
|
||||
if (typeof str !== 'string' || str.indexOf('{') === -1 || str.indexOf('}') === -1 || str.indexOf('$') === -1) {
|
||||
return str;
|
||||
}
|
||||
str = str.replace(strRegex, function (matchs, name) {
|
||||
|
||||
let matchs = str.match(strRegex);
|
||||
if(matchs){
|
||||
let name = matchs[1] + matchs[2];
|
||||
if(!name) return str;
|
||||
var names = name.split(varSplit);
|
||||
var data = context;
|
||||
names.forEach(function (n) {
|
||||
@ -75,7 +79,7 @@ function mock(mockJSON, context) {
|
||||
}
|
||||
});
|
||||
return data;
|
||||
});
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
@ -334,10 +334,6 @@ class interfaceColController extends baseController{
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '用例id不能为空');
|
||||
}
|
||||
|
||||
// if(!params.casename){
|
||||
// return ctx.body = yapi.commons.resReturn(null, 400, '用例名称不能为空');
|
||||
// }
|
||||
|
||||
let caseData = await this.caseModel.get(params.id);
|
||||
let auth = await this.checkAuth(caseData.project_id, 'project', 'edit');
|
||||
if (!auth) {
|
||||
@ -346,9 +342,9 @@ class interfaceColController extends baseController{
|
||||
|
||||
params.uid = this.getUid();
|
||||
|
||||
//不允许修改接口id和项目id
|
||||
delete params.interface_id;
|
||||
delete params.project_id;
|
||||
// delete params.col_id;
|
||||
|
||||
let result = await this.caseModel.up(params.id, params);
|
||||
let username = this.getUsername();
|
||||
@ -595,6 +591,28 @@ class interfaceColController extends baseController{
|
||||
}
|
||||
}
|
||||
|
||||
async runCaseScript(ctx){
|
||||
let params = ctx.request.body;
|
||||
let script = params.script;
|
||||
if(!script){
|
||||
return ctx.body = yapi.commons.resReturn('ok');
|
||||
}
|
||||
|
||||
try{
|
||||
let a = yapi.commons.sandbox({
|
||||
assert: require('assert'),
|
||||
status: params.response.status,
|
||||
body: params.response.body,
|
||||
header: params.response.header,
|
||||
records: params.records
|
||||
}, script);
|
||||
return ctx.body = yapi.commons.resReturn('ok');
|
||||
}catch(err){
|
||||
let errArr = err.stack.split("\n");
|
||||
return ctx.body = yapi.commons.resReturn(errArr, 400, err.message)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,9 @@ class interfaceCase extends baseModel {
|
||||
test_status: {type: String, enum: ['ok', 'invalid', 'error', '']},
|
||||
test_report: [],
|
||||
test_res_header: Schema.Types.Mixed,
|
||||
mock_verify: {type: Boolean, default: false}
|
||||
|
||||
mock_verify: {type: Boolean, default: false},
|
||||
enable_script: {type: Boolean, default: false},
|
||||
test_script: String
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -366,6 +366,10 @@ let routerConfig = {
|
||||
action: "delCase",
|
||||
path: "del_case",
|
||||
method: "get"
|
||||
},{
|
||||
action: "runCaseScript",
|
||||
path: "run_script",
|
||||
method: "post"
|
||||
}
|
||||
],
|
||||
"test": [{
|
||||
|
Loading…
Reference in New Issue
Block a user