Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f343f12645 | ||
|
|
1032631318 | ||
|
|
f9f79479e8 |
No files matched your search
@@ -49,11 +49,11 @@
|
|||||||
/* 快应用特有相关 */
|
/* 快应用特有相关 */
|
||||||
"quickapp" : {},
|
"quickapp" : {},
|
||||||
/* 小程序特有相关 */
|
/* 小程序特有相关 */
|
||||||
/* 当前:测试 AppID;切生产时把 appid 改为下方生产值 */
|
/* 当前:生产 AppID;切测试时把 appid 改为下方测试值 */
|
||||||
/* 生产 AppID:wx2b139581f4c855e4 */
|
/* 生产 AppID:wx2b139581f4c855e4 */
|
||||||
/* 测试 AppID:wxa261ad85f2c99b26 */
|
/* 测试 AppID:wxa261ad85f2c99b26 */
|
||||||
"mp-weixin" : {
|
"mp-weixin" : {
|
||||||
"appid" : "wxa261ad85f2c99b26",
|
"appid" : "wx2b139581f4c855e4",
|
||||||
"setting" : {
|
"setting" : {
|
||||||
"urlCheck" : false,
|
"urlCheck" : false,
|
||||||
"es6" : true
|
"es6" : true
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* 微信公众平台须为对应环境配置 request / 业务域名(HTTPS)
|
* 微信公众平台须为对应环境配置 request / 业务域名(HTTPS)
|
||||||
*/
|
*/
|
||||||
export const APP_ENV = 'test' // 'local' | 'test' | 'prod'
|
export const APP_ENV = 'prod' // 'local' | 'test' | 'prod'
|
||||||
|
|
||||||
const ENV_PRESETS = {
|
const ENV_PRESETS = {
|
||||||
local: {
|
local: {
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
import test from 'node:test'
|
||||||
|
import assert from 'node:assert/strict'
|
||||||
|
import { readFileSync } from 'node:fs'
|
||||||
|
import vm from 'node:vm'
|
||||||
|
import * as Vue from 'vue'
|
||||||
|
import { compile } from '@vue/compiler-dom'
|
||||||
|
import { projectValidation } from './project-assignment.js'
|
||||||
|
|
||||||
|
const source = readFileSync(new URL('../views/market/MarketModuleForm.vue', import.meta.url), 'utf8')
|
||||||
|
// Render the real loop/slot/ref structure; native host nodes need no browser or service.
|
||||||
|
const template = source.slice(source.indexOf('<template v-for="section in leadingSections"'), source.indexOf('\n\n <section'))
|
||||||
|
const render = new Function('Vue', compile(template, { prefixIdentifiers: true }).code)(Vue)
|
||||||
|
const submitSource = source.slice(source.indexOf('async function submit()'), source.indexOf('\nasync function confirmLeave()'))
|
||||||
|
const renderer = Vue.createRenderer({
|
||||||
|
createElement: () => ({}), createText: () => ({}), createComment: () => ({}),
|
||||||
|
insert(node, parent, anchor = null) {
|
||||||
|
parent.children ||= []
|
||||||
|
node.parent = parent
|
||||||
|
const index = parent.children.indexOf(anchor)
|
||||||
|
parent.children.splice(index < 0 ? parent.children.length : index, 0, node)
|
||||||
|
},
|
||||||
|
remove(node) {
|
||||||
|
const siblings = node.parent?.children || []
|
||||||
|
const index = siblings.indexOf(node)
|
||||||
|
if (index >= 0) siblings.splice(index, 1)
|
||||||
|
},
|
||||||
|
setText() {}, setElementText() {}, patchProp() {},
|
||||||
|
parentNode: (node) => node.parent,
|
||||||
|
nextSibling: (node) => {
|
||||||
|
const siblings = node.parent?.children || []
|
||||||
|
return siblings[siblings.indexOf(node) + 1] || null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
async function mountForm({ role, mode = 'create', projectId = 'project-1', loading = false, error = '' }) {
|
||||||
|
const projectAssignment = Vue.ref(null)
|
||||||
|
const formData = Vue.ref({ source: 'research_donation', projectId })
|
||||||
|
const messages = [], requests = []
|
||||||
|
let validations = 0
|
||||||
|
const ProjectAssignmentField = {
|
||||||
|
setup(_, { expose }) {
|
||||||
|
expose({ validate() {
|
||||||
|
validations++
|
||||||
|
return projectValidation({ editing: mode === 'edit', required: true, projectId, loading, error })
|
||||||
|
} })
|
||||||
|
return () => Vue.h('div')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const Section = { setup: (_, { slots }) => () => slots.insert?.() }
|
||||||
|
const context = Vue.ref({ module: 'protocol', marketRole: role })
|
||||||
|
const app = renderer.createApp({
|
||||||
|
components: { MarketFormSection: Section, ProjectAssignmentField },
|
||||||
|
setup: () => ({
|
||||||
|
projectAssignment, context, formData, mode,
|
||||||
|
leadingSections: [{ key: 'customer' }, { key: 'protocol' }],
|
||||||
|
formOptions: {}, fieldsLocked: false, dirty: false,
|
||||||
|
sectionValue: () => ({}), searchProtocolCustomers() {}, setSectionValue() {},
|
||||||
|
uploadField() {}, handleFieldChange() {}, handleCustomerSelect() {}
|
||||||
|
}), render
|
||||||
|
})
|
||||||
|
app.mount({})
|
||||||
|
await Vue.nextTick()
|
||||||
|
const scope = {
|
||||||
|
projectAssignment, context, formData, mode: Vue.ref(mode),
|
||||||
|
submitting: Vue.ref(false), uploadPending: Vue.ref(0), isProtocolV2: Vue.ref(false),
|
||||||
|
isProtocolV1: Vue.ref(false), id: Vue.ref(mode === 'edit' ? 'record-1' : ''),
|
||||||
|
action: Vue.ref(mode), visibleSections: Vue.ref([]), dirty: Vue.ref(true),
|
||||||
|
showToast: (text) => messages.push(text), showSuccessToast: (text) => messages.push(text),
|
||||||
|
validateRequiredFields: () => '', buildMarketActionPayload: (_module, _action, data) => data,
|
||||||
|
sanitizeMarketPayload: (data) => data, buildPayload: () => formData.value,
|
||||||
|
AbortController, submitController: null, allowLeave: false,
|
||||||
|
saveMarketRecord: async (...args) => { requests.push(args); return { id: 'saved' } },
|
||||||
|
mountGuard: { isCurrent: () => true }, mountToken: 1,
|
||||||
|
resolveMarketSavedDetailId: () => 'saved', router: { replace: async () => {} },
|
||||||
|
route: { query: {} }, marketRecordNavigationQuery: () => ({}),
|
||||||
|
marketErrorMessage: (cause) => cause.message
|
||||||
|
}
|
||||||
|
const submit = vm.runInNewContext(`${submitSource}\nsubmit`, scope)
|
||||||
|
return { submit, messages, requests, app, validations: () => validations }
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const role of ['specialist', 'manager']) {
|
||||||
|
for (const mode of ['create', 'edit']) {
|
||||||
|
test(`${role} ${mode}: a valid project reaches the save request`, async () => {
|
||||||
|
const form = await mountForm({ role, mode })
|
||||||
|
try {
|
||||||
|
await form.submit()
|
||||||
|
assert.equal(form.validations(), 1)
|
||||||
|
assert.equal(form.requests.length, 1)
|
||||||
|
assert.equal(form.requests[0][0].marketRole, role)
|
||||||
|
assert.deepEqual(form.messages, ['保存成功'])
|
||||||
|
} finally { form.app.unmount() }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for (const [state, message] of [
|
||||||
|
[{ projectId: '' }, '请选择所属项目'],
|
||||||
|
[{ loading: true }, '项目选项加载中,请稍后保存'],
|
||||||
|
[{ error: 'network' }, '项目选项加载失败,请重试后保存']
|
||||||
|
]) {
|
||||||
|
test(`${role}: ${message}`, async () => {
|
||||||
|
const form = await mountForm({ role, ...state })
|
||||||
|
try {
|
||||||
|
await form.submit()
|
||||||
|
assert.equal(form.validations(), 1)
|
||||||
|
assert.equal(form.requests.length, 0)
|
||||||
|
assert.deepEqual(form.messages, [message])
|
||||||
|
} finally { form.app.unmount() }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
>
|
>
|
||||||
<template #insert>
|
<template #insert>
|
||||||
<ProjectAssignmentField
|
<ProjectAssignmentField
|
||||||
ref="projectAssignment"
|
:ref="(instance) => (projectAssignment = instance)"
|
||||||
embedded
|
embedded
|
||||||
v-model="formData.projectId"
|
v-model="formData.projectId"
|
||||||
:biz-type="formData.source"
|
:biz-type="formData.source"
|
||||||
|
|||||||
Reference in new issue
Block a user