fix: update test & move constants

This commit is contained in:
niunai 2017-09-19 18:16:42 +08:00
parent 485452cc97
commit 3ba8b84d08
6 changed files with 205 additions and 50 deletions

View File

@ -15,6 +15,10 @@ export default {
goods: goods, goods: goods,
quota: data.quota, quota: data.quota,
quotaUsed: data.quota_used, quotaUsed: data.quota_used,
initialSku: {
s1: '30349',
s2: '1193'
}
} }
}, },
@ -85,6 +89,7 @@ Vue.component(Sku.name, Sku);
:quota="quota" :quota="quota"
:quota-used="quotaUsed" :quota-used="quotaUsed"
:reset-stepper-on-hide="true" :reset-stepper-on-hide="true"
:initial-sku="initialSku"
@buy-clicked="handleBuyClicked" @buy-clicked="handleBuyClicked"
@add-cart="handleAddCartClicked" @add-cart="handleAddCartClicked"
> >
@ -201,6 +206,11 @@ skuData: {
message_1:"", message_1:"",
... // 有几个留言就有几条 ... // 有几个留言就有几条
}, },
// 另一种格式的留言key不同
cartMessages: {
'留言1': 'xxxx',
... // key是message的name
},
// 选择的商品数量 // 选择的商品数量
selectedNum:1, selectedNum:1,
// 选择的sku组合 // 选择的sku组合

View File

@ -1,12 +1,12 @@
<template> <template>
<van-cell-group> <van-cell-group class="van-sku-messages">
<template v-for="(message, index) in internalMessages"> <template v-for="(message, index) in internalMessages">
<template v-if="message.type === 'image'"></template> <template v-if="message.type === 'image'"></template>
<van-field v-else-if="message.multiple == '1'" <van-field v-else-if="message.multiple == '1'"
:key="index" :key="index"
:required="message.required == '1'" :required="message.required == '1'"
:label="message.name" :label="message.name"
placeholder="点击填写段落文本" :placeholder="placeholderMap.textarea"
type="textarea" type="textarea"
v-model="messageValues[index]"> v-model="messageValues[index]">
</van-field> </van-field>
@ -14,7 +14,7 @@
:key="index" :key="index"
:required="message.required == '1'" :required="message.required == '1'"
:label="message.name" :label="message.name"
:placeholder="PLACEHOLDER_MAP[message.type]" :placeholder="placeholderMap[message.type]"
:type="getType(message)" :type="getType(message)"
v-model="messageValues[index]"> v-model="messageValues[index]">
</van-field> </van-field>
@ -27,15 +27,7 @@ import Field from '../../field';
import CellGroup from '../../cell-group'; import CellGroup from '../../cell-group';
import validateEmail from 'zan-utils/validate/email'; import validateEmail from 'zan-utils/validate/email';
import validateNumber from 'zan-utils/validate/number'; import validateNumber from 'zan-utils/validate/number';
import { DEFAULT_PLACEHOLDER_MAP } from '../constants';
const PLACEHOLDER_MAP = {
'id_no': '输入18位身份证号码',
text: '输入文本',
tel: '输入数字',
email: '输入邮箱',
date: '点击选择日期',
time: '点击选择时间'
};
export default { export default {
name: 'van-sku-messages', name: 'van-sku-messages',
@ -46,12 +38,13 @@ export default {
}, },
props: { props: {
messages: Array messages: Array,
messagePlaceholderMap: Object
}, },
data() { data() {
return { return {
PLACEHOLDER_MAP placeholderMap: Object.assign({}, DEFAULT_PLACEHOLDER_MAP, this.messagePlaceholderMap)
}; };
}, },
@ -127,12 +120,6 @@ export default {
} }
} }
} else { } else {
// if (message.type == 'image') {
// loaded = _this.$el.find('#ipt-' + j).data('uploaded');
// if (loaded == 'false' || !loaded) {
// return '';
// }
// }
if (message.type === 'tel' && !validateNumber(value)) { if (message.type === 'tel' && !validateNumber(value)) {
return '请填写正确的数字格式留言'; return '请填写正确的数字格式留言';
} }

View File

@ -11,7 +11,7 @@
<script> <script>
import Stepper from '../../stepper'; import Stepper from '../../stepper';
import { LIMIT_TYPE } from '../constants'; import { LIMIT_TYPE, DEFAULT_BUY_TEXT } from '../constants';
const { QUOTA_LIMIT, STOCK_LIMIT } = LIMIT_TYPE; const { QUOTA_LIMIT, STOCK_LIMIT } = LIMIT_TYPE;
@ -24,7 +24,7 @@ export default {
props: { props: {
skuEventBus: Object, skuEventBus: Object,
sku: Object, skuStockNum: Number,
selectedSku: Object, selectedSku: Object,
selectedSkuComb: Object, selectedSkuComb: Object,
selectedNum: Number, selectedNum: Number,
@ -36,7 +36,7 @@ export default {
}, },
stepperTitle: { stepperTitle: {
type: String, type: String,
default: '购买数量' default: DEFAULT_BUY_TEXT
} }
}, },
@ -64,7 +64,7 @@ export default {
if (this.selectedSkuComb) { if (this.selectedSkuComb) {
return this.selectedSkuComb.stock_num; return this.selectedSkuComb.stock_num;
} }
return this.sku.stock_num; return this.skuStockNum;
}, },
stepperLimit() { stepperLimit() {
const quotaLimit = this.quota - this.quotaUsed; const quotaLimit = this.quota - this.quotaUsed;

View File

@ -2,3 +2,17 @@ export const LIMIT_TYPE = {
QUOTA_LIMIT: 0, QUOTA_LIMIT: 0,
STOCK_LIMIT: 1 STOCK_LIMIT: 1
}; };
export const DEFAULT_BUY_TEXT = '立即购买';
export const DEFAULT_STEPPER_TITLE = '购买数量';
export const DEFAULT_PLACEHOLDER_MAP = {
'id_no': '输入18位身份证号码',
text: '输入文本',
tel: '输入数字',
email: '输入邮箱',
date: '点击选择日期',
time: '点击选择时间',
textarea: '点击填写段落文本'
};

View File

@ -1,5 +1,5 @@
<template> <template>
<van-popup v-model="show" position="bottom" :lock-scroll="true"> <van-popup v-model="show" v-if="!isSkuEmpty" position="bottom" :lock-scroll="true">
<div class="van-sku-container"> <div class="van-sku-container">
<div class="van-sku-layout"> <div class="van-sku-layout">
<slot name="sku-header" :skuEventBus="skuEventBus" :selectedSku="selectedSku" :selectedSkuComb="selectedSkuComb"> <slot name="sku-header" :skuEventBus="skuEventBus" :selectedSku="selectedSku" :selectedSkuComb="selectedSkuComb">
@ -42,7 +42,7 @@
:selectedSkuComb="selectedSkuComb" :selectedSkuComb="selectedSkuComb"
:selectedNum="selectedNum" :selectedNum="selectedNum"
:stepperTitle="stepperTitle" :stepperTitle="stepperTitle"
:sku="sku" :skuStockNum="sku.stock_num"
:quota="quota" :quota="quota"
:quotaUsed="quotaUsed" :quotaUsed="quotaUsed"
:hideStock="hideStock"> :hideStock="hideStock">
@ -51,17 +51,18 @@
<slot name="sku-messages"> <slot name="sku-messages">
<van-sku-messages <van-sku-messages
ref="skuMessages" ref="skuMessages"
:messagePlaceholderMap="messagePlaceholderMap"
:messages="sku.messages"> :messages="sku.messages">
</van-sku-messages> </van-sku-messages>
</slot> </slot>
<slot name="sku-actions" :skuEventBus="skuEventBus">
<van-sku-actions
:skuEventBus="skuEventBus"
:buyText="buyText"
:showAddCartBtn="showAddCartBtn">
</van-sku-actions>
</slot>
</div> </div>
<slot name="sku-actions" :skuEventBus="skuEventBus">
<van-sku-actions
:skuEventBus="skuEventBus"
:buyText="buyText"
:showAddCartBtn="showAddCartBtn">
</van-sku-actions>
</slot>
</div> </div>
</div> </div>
</van-popup> </van-popup>
@ -78,7 +79,7 @@ import SkuStepper from '../components/SkuStepper';
import SkuMessages from '../components/SkuMessages'; import SkuMessages from '../components/SkuMessages';
import SkuActions from '../components/SkuActions'; import SkuActions from '../components/SkuActions';
import { isAllSelected, getSkuComb, getSelectedSkuValues } from '../utils/skuHelper'; import { isAllSelected, getSkuComb, getSelectedSkuValues } from '../utils/skuHelper';
import { LIMIT_TYPE } from '../constants'; import { LIMIT_TYPE, DEFAULT_STEPPER_TITLE } from '../constants';
const { QUOTA_LIMIT } = LIMIT_TYPE; const { QUOTA_LIMIT } = LIMIT_TYPE;
@ -123,13 +124,19 @@ export default {
buyText: String, buyText: String,
stepperTitle: { stepperTitle: {
type: String, type: String,
default: '购买数量' default: DEFAULT_STEPPER_TITLE
}, },
bodyOffsetTop: { bodyOffsetTop: {
type: Number, type: Number,
default: 150 default: 200
}, },
resetStepperOnHide: Boolean, resetStepperOnHide: Boolean,
messagePlaceholderMap: {
type: Object,
default() {
return {};
}
},
value: Boolean value: Boolean
}, },
@ -169,7 +176,7 @@ export default {
computed: { computed: {
bodyStyle() { bodyStyle() {
const windowHeight = window.innerHeight; const windowHeight = window.innerHeight;
// header82px // header82px, sku actions50pxbodyOffsetTop
const maxHeight = windowHeight - this.bodyOffsetTop; const maxHeight = windowHeight - this.bodyOffsetTop;
return { return {
@ -179,6 +186,13 @@ export default {
isSkuCombSelected() { isSkuCombSelected() {
return isAllSelected(this.sku.tree, this.selectedSku); return isAllSelected(this.sku.tree, this.selectedSku);
}, },
// sku
isSkuEmpty() {
for (var key in this.sku) {
if (Object.prototype.hasOwnProperty.call(this.sku, key)) return false;
}
return true;
},
hasSku() { hasSku() {
return !this.sku.none_sku; return !this.sku.none_sku;
}, },
@ -250,7 +264,7 @@ export default {
if (this.isSkuCombSelected) { if (this.isSkuCombSelected) {
const error = this.validateSkuMessages(); const error = this.validateSkuMessages();
// sku // sku
return error ? error : ''; return error;
} else { } else {
return '请选择完整的规格'; return '请选择完整的规格';
} }

View File

@ -2,9 +2,14 @@ import Sku from 'packages/sku';
import { mount } from 'avoriaz'; import { mount } from 'avoriaz';
import { DOMChecker } from '../utils'; import { DOMChecker } from '../utils';
import data from '../mock/sku'; import data from '../mock/sku';
import repeat from 'lodash/repeat';
const { skuHelper } = Sku; const { skuHelper } = Sku;
const goods = data.goods_info; const goods = data.goods_info;
const initialSku = {
s1: '30349',
s2: '1193'
};
goods.picture = goods.picture[0]; goods.picture = goods.picture[0];
describe('Sku', (done) => { describe('Sku', (done) => {
@ -41,18 +46,29 @@ describe('Sku', (done) => {
const selectedSku = skuHelper.getSelectedSkuValues(data.sku.tree, wrapper.vm.selectedSku); const selectedSku = skuHelper.getSelectedSkuValues(data.sku.tree, wrapper.vm.selectedSku);
expect(selectedSku[0].id).to.equal('30349'); expect(selectedSku[0].id).to.equal('30349');
// 关闭sku弹层 // 测试sku图片
const closeCallback = sinon.spy(); const firstSku = wrapper.find('.van-sku-row__item')[0];
const closeIcon = wrapper.find('.van-sku__close-icon')[0]; firstSku.trigger('click');
wrapper.vm.$on('sku-close', closeCallback);
closeIcon.trigger('click');
wrapper.vm.$nextTick(() => { wrapper.vm.$nextTick(() => {
expect(closeCallback.calledOnce).to.be.true; DOMChecker(wrapper, {
done(); src: {
'.van-sku__goods-img': 'https://img.yzcdn.cn/upload_files/2017/03/16/Fs_OMbSFPa183sBwvG_94llUYiLa.jpeg?imageView2/2/w/100/h/100/q/75/format/jpg'
}
});
// 关闭sku弹层
const closeCallback = sinon.spy();
const closeIcon = wrapper.find('.van-sku__close-icon')[0];
wrapper.vm.$on('sku-close', closeCallback);
closeIcon.trigger('click');
wrapper.vm.$nextTick(() => {
expect(closeCallback.calledOnce).to.be.true;
done();
});
}); });
}); });
it('click buy and addCart', (done) => { it('should trigger an event or toast error when click buy and addCart', (done) => {
wrapper = mount(Sku, { wrapper = mount(Sku, {
attachToDocument: true, attachToDocument: true,
propsData: { propsData: {
@ -98,7 +114,7 @@ describe('Sku', (done) => {
}); });
}); });
it('change step value', (done) =>{ it('should modify current num or toast error when change step value', (done) => {
wrapper = mount(Sku, { wrapper = mount(Sku, {
attachToDocument: true, attachToDocument: true,
propsData: { propsData: {
@ -135,14 +151,15 @@ describe('Sku', (done) => {
}); });
}); });
it('test none sku', (done) => { it('should not render sku group when none_sku is true', (done) => {
data.sku.none_sku = true; // eslint-disable-line const newData = Object.assign({}, data);
newData.sku.none_sku = true; // eslint-disable-line
wrapper = mount(Sku, { wrapper = mount(Sku, {
attachToDocument: true, attachToDocument: true,
propsData: { propsData: {
value: false, value: false,
sku: data.sku, sku: newData.sku,
goods: goods goods: goods
} }
}); });
@ -153,4 +170,117 @@ describe('Sku', (done) => {
done(); done();
}); });
}); });
it('should toast error when sku messages fail to pass validation', (done) => {
wrapper = mount(Sku, {
attachToDocument: true,
propsData: {
initialSku,
value: true,
sku: data.sku,
goods: goods
}
});
const buyBtn = wrapper.find('.van-sku__buy-btn')[0];
const skuMessages = wrapper.find('.van-sku-messages')[0];
const inputs = skuMessages.find('input');
const textarea = skuMessages.find('textarea')[0];
// 修改留言内容
inputs[0].element.value = 123;
// 测试身份证号
inputs[1].element.value = 234;
inputs[0].trigger('input');
inputs[1].trigger('input');
wrapper.vm.$nextTick(() => {
// 点击购买
buyBtn.trigger('click');
wrapper.vm.$nextTick(() => {
const toastText = document.querySelector('.van-toast__text');
expect(toastText.textContent).to.equal('请填写正确的身份证号码');
inputs[1].element.value = 330101198801012211;
// 测试textarea字数限制
textarea.element.value = repeat('*', 201);
inputs[1].trigger('input');
textarea.trigger('input');
wrapper.vm.$nextTick(() => {
buyBtn.trigger('click');
wrapper.vm.$nextTick(() => {
expect(toastText.textContent).to.equal('留言4 写的太多了<br/>不要超过200字');
textarea.element.value = '';
// 测试数字留言
inputs[2].element.value = 'abc';
textarea.trigger('input');
inputs[2].trigger('input');
wrapper.vm.$nextTick(() => {
buyBtn.trigger('click');
wrapper.vm.$nextTick(() => {
expect(toastText.textContent).to.equal('请填写正确的数字格式留言');
inputs[2].element.value = 0;
inputs[3].element.value = 345;
inputs[2].trigger('input');
inputs[3].trigger('input');
wrapper.vm.$nextTick(() => {
buyBtn.trigger('click');
wrapper.vm.$nextTick(() => {
expect(toastText.textContent).to.equal('请填写正确的邮箱');
done();
});
});
});
});
});
});
});
});
});
it('should toast error when there is no stock', (done) => {
/* eslint-disable */
const newData = Object.assign({}, data);
newData.sku.stock_num = 0;
newData.sku.messages = [];
newData.sku.list.forEach((item) => {
item.stock_num = 0;
});
/* eslint-enable */
wrapper = mount(Sku, {
attachToDocument: true,
propsData: {
initialSku,
value: true,
sku: newData.sku,
goods: goods
}
});
const buyBtn = wrapper.find('.van-sku__buy-btn')[0];
wrapper.vm.$nextTick(() => {
buyBtn.trigger('click');
wrapper.vm.$nextTick(() => {
const toastText = document.querySelector('.van-toast__text');
expect(toastText.textContent).to.equal('商品已经无法购买啦');
const plusBtn = wrapper.find('.van-stepper__plus')[0];
plusBtn.trigger('click');
wrapper.vm.$nextTick(() => {
expect(toastText.textContent).to.equal('库存不足');
done();
});
});
});
});
}); });