feat: case add resBody cache

This commit is contained in:
suxiaoxin 2017-09-20 11:45:18 +08:00
parent 26e9e487ce
commit 65c17e565f
5 changed files with 106 additions and 56 deletions

View File

@ -10,7 +10,7 @@ import URL from 'url';
const MockExtra = require('common/mock-extra.js')
import './Postman.scss';
import json5 from 'json5'
import {handleMockWord} from '../../common.js'
import { handleMockWord } from '../../common.js'
function json_parse(data) {
try {
@ -76,8 +76,9 @@ export default class Run extends Component {
bodyType: '',
bodyOther: '',
loading: false,
validRes: null,
hasPlugin: true
validRes: [],
hasPlugin: true,
test_status: null
}
constructor(props) {
@ -137,8 +138,13 @@ export default class Run extends Component {
req_body_form = [],
basepath = '',
env = [],
case_env = ''
case_env = '',
test_status = '',
test_res_body = '',
test_report = [],
test_res_header=''
} = data;
// case 任意编辑 pathname不管项目的 basepath
const pathname = (type === 'inter' ? (basepath + url) : url).replace(/\/+/g, '/');
@ -169,12 +175,21 @@ export default class Run extends Component {
bodyOther: req_body_other,
caseEnv: case_env || (env[0] && env[0].name),
bodyType: req_body_type || 'form',
loading: false
loading: false,
test_status: test_status,
validRes: test_report,
res: test_res_body,
resHeader: test_res_header
}, () => {
if (req_body_type && req_body_type !== 'file' && req_body_type !== 'form') {
this.loadBodyEditor()
}
if(test_res_body){
this.bindAceEditor();
}
});
}
@autobind
@ -193,7 +208,7 @@ export default class Run extends Component {
const href = URL.format({
protocol: urlObj.protocol || 'http',
host: urlObj.host,
pathname: urlObj.pathname ? urlObj.pathname + path : path,
pathname: urlObj.pathname ? URL.resolve(urlObj.pathname, path) : path,
query: this.getQueryObj(query)
});
@ -213,7 +228,7 @@ export default class Run extends Component {
}
const { res_body, res_body_type } = that.props.data;
let validRes = '';
let validRes = [];
let query = {};
that.state.query.forEach(item => {
query[item.name] = item.value;
@ -234,8 +249,17 @@ export default class Run extends Component {
validRes = Mock.valid(tpl, res)
}
message.success('请求完成')
that.setState({ res, resHeader: header, validRes })
if (Array.isArray(validRes) && validRes.length > 0) {
message.warn('请求完成, 返回数据跟接口定义不匹配');
validRes = validRes.map(item => {
return item.message
})
that.setState({ res, resHeader: header, validRes, test_status: 'invalid' })
} else if (Array.isArray(validRes) && validRes.length === 0) {
message.success('请求完成');
that.setState({ res, resHeader: header, validRes: ['验证通过'], test_status: 'ok' })
}
that.setState({ loading: false })
that.bindAceEditor()
} catch (e) {
@ -251,7 +275,7 @@ export default class Run extends Component {
message.error(e.message)
}
message.error('请求异常')
that.setState({ res: err || '请求失败', resHeader: header, validRes: null })
that.setState({ res: err || '请求失败', resHeader: header, validRes: [], test_status: 'error' })
that.setState({ loading: false })
that.bindAceEditor()
}
@ -504,7 +528,6 @@ export default class Run extends Component {
HTTP_METHOD[method] = HTTP_METHOD[method] || {}
const hasPlugin = this.state.hasPlugin;
let isResJson = isJsonData(resHeader, res);
let path = pathname;
pathParam.forEach(item => {
path = path.replace(`:${item.name}`, item.value || `:${item.name}`);
@ -512,16 +535,10 @@ export default class Run extends Component {
const search = decodeURIComponent(URL.format({ query: this.getQueryObj(query) }));
let validResView;
if (!validRes) {
validResView = '请定义返回json'
}
if (Array.isArray(validRes) && validRes.length > 0) {
validResView = validRes.map((item, index) => {
return <div key={index}>{item.message}</div>
})
} else if (Array.isArray(validRes)) {
validResView = <p>验证通过</p>
}
validResView = validRes.map((item, index) => {
return <div key={index}>{item}</div>
})
@ -571,7 +588,7 @@ export default class Run extends Component {
domains.map((item, index) => (<Option value={item.name} key={index}>{item.name + '' + item.domain}</Option>))
}
</Select>
<Input disabled value={path + search} onChange={this.changePath} spellCheck="false" style={{ flexBasis: 180, flexGrow: 1 }} />
</InputGroup>

View File

@ -96,6 +96,7 @@ export default class InterfaceCaseContent extends Component {
}
updateCase = async () => {
const {
caseEnv: case_env,
pathname: path,
@ -107,9 +108,10 @@ export default class InterfaceCaseContent extends Component {
bodyForm: req_body_form,
bodyOther: req_body_other
} = this.postman.state;
const {editCasename: casename} = this.state;
const {_id: id} = this.props.currCase;
const res = await axios.post('/api/col/up_case', {
let params = {
id,
casename,
case_env,
@ -121,7 +123,20 @@ export default class InterfaceCaseContent extends Component {
req_body_type,
req_body_form,
req_body_other
});
};
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'){
params.test_res_body = JSON.stringify(params.test_res_body, null, ' ');
}
const res = await axios.post('/api/col/up_case', params);
if (this.props.currCase.casename !== casename) {
this.props.fetchInterfaceColList(this.props.match.params.id);
}

View File

@ -75,13 +75,14 @@ class InterfaceColContent extends Component {
}
handleColdata = (rows)=>{
handleColdata = (rows) => {
console.log(rows);
rows = rows.map((item) => {
item.id = item._id;
return item;
})
rows = rows.sort((n, o)=>{
return n.index>o.index
rows = rows.sort((n, o) => {
return n.index > o.index
})
this.setState({
rows: rows
@ -102,7 +103,7 @@ class InterfaceColContent extends Component {
targetRowId
})(this.state.rows);
let changes = [];
rows.forEach((item, index)=>{
rows.forEach((item, index) => {
changes.push({
id: item._id,
index: index
@ -115,7 +116,7 @@ class InterfaceColContent extends Component {
}
}
componentWillReceiveProps(nextProps) {
async componentWillReceiveProps(nextProps) {
const { interfaceColList } = nextProps;
const { actionId: oldColId, id } = this.props.match.params
let newColId = nextProps.match.params.actionId
@ -123,7 +124,7 @@ class InterfaceColContent extends Component {
this.props.history.push('/project/' + id + '/interface/col/' + interfaceColList[0]._id)
} else if (oldColId !== newColId) {
if (newColId && newColId != 0) {
this.props.fetchCaseList(newColId);
await this.props.fetchCaseList(newColId);
this.props.setColData({ currColId: +newColId, isShowCol: true })
this.handleColdata(this.props.currCaseList)
}
@ -139,12 +140,26 @@ class InterfaceColContent extends Component {
},
cell: {
formatters: [
(text,{rowData}) => {
(text, { rowData }) => {
let record = rowData;
return <Link to={"/project/" + record.project_id + "/interface/case/" + record._id}>{record.casename}</Link>
}
}
]
}
}, {
header: {
label: 'key',
formatters: [() => {
return <Tooltip title="每个用例都有一个独一无二的key可用来获取匹配的接口响应数据">
Key</Tooltip>
}]
},
cell: {
formatters: [
(value, { rowData }) => {
return <span>{rowData._id}</span>
}]
}
}, {
property: 'path',
header: {
@ -152,7 +167,7 @@ class InterfaceColContent extends Component {
},
cell: {
formatters: [
(text,{rowData}) => {
(text, { rowData }) => {
let record = rowData;
return (
<Tooltip title="跳转到对应接口">
@ -162,17 +177,9 @@ class InterfaceColContent extends Component {
}
]
}
}, {
header: {
label: '请求方法'
},
property: 'method'
}
];
const { rows } = this.state;
if (rows.length === 0) {
return null;
}
const components = {
header: {
cell: dnd.Header
@ -195,10 +202,10 @@ class InterfaceColContent extends Component {
<Table.Provider
components={components}
columns={resolvedColumns}
style={{width:'100%', lineHeight: '30px'}}
style={{ width: '100%', lineHeight: '30px' }}
>
<Table.Header
style={{textAlign: 'left'}}
style={{ textAlign: 'left' }}
headerRows={resolve.headerRows({ columns })}
/>

View File

@ -59,7 +59,8 @@ export default class Run extends Component {
bodyForm: req_body_form,
bodyOther: req_body_other
} = this.postman.state;
const res = await axios.post('/api/col/add_case', {
let params = {
interface_id,
casename: caseName,
col_id: colId,
@ -73,7 +74,20 @@ export default class Run extends Component {
req_body_type,
req_body_form,
req_body_other
});
};
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'){
params.test_res_body = JSON.stringify(params.test_res_body, null, ' ');
}
const res = await axios.post('/api/col/add_case', params);
if (res.data.errcode) {
message.error(res.data.errmsg)
} else {
@ -85,7 +99,6 @@ export default class Run extends Component {
render () {
const { currInterface, currProject } = this.props;
const data = Object.assign({}, currInterface, currProject, {_id: currInterface._id})
return (
<div>
<Postman data={data} type="inter" saveTip="保存到集合" save={() => this.setState({saveCaseModalVisible: true})} ref={this.savePostmanRef} />

View File

@ -1,5 +1,7 @@
const yapi = require('../yapi.js');
const baseModel = require('./base.js');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
class interfaceCase extends baseModel {
getName() {
@ -17,25 +19,21 @@ class interfaceCase extends baseModel {
add_time: Number,
up_time: Number,
case_env: { type: String },
// path: { type: String },
// method: { type: String },
req_params: [{
name: String, value: String
}],
req_query: [{
name: String, value: String
}],
// req_headers: [{
// name: String, value: String
// }],
// req_body_type: {
// type: String,
// enum: ['form', 'json', 'text', 'xml']
// },
req_body_form: [{
name: String, value: String
}],
req_body_other: String
req_body_other: String,
test_res_body: String,
test_status: {type: String, enum: ['ok', 'invalid', 'error', '']},
test_report: [],
test_res_header: Schema.Types.Mixed
};
}