fix: 提示打包提交并重置表单

This commit is contained in:
shenlei 2026-07-20 15:28:02 +09:00
parent 9b77441ec7
commit 51d7374f2d
2 changed files with 58 additions and 17 deletions

View File

@ -1,5 +1,6 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { mount, flushPromises } from '@vue/test-utils'
import { createMemoryHistory, createRouter } from 'vue-router'
import BuildView from '../views/BuildView.vue'
global.fetch = vi.fn()
@ -11,12 +12,25 @@ class MockWebSocket {
}
global.WebSocket = MockWebSocket
const mountBuildView = () => {
const router = createRouter({
history: createMemoryHistory(),
routes: [{ path: '/', component: BuildView }],
})
return mount(BuildView, {
global: {
plugins: [router],
provide: { getToken: () => '' },
},
})
}
describe('BuildView.vue', () => {
beforeEach(() => {
vi.clearAllMocks()
fetch.mockImplementation((url) => {
const responses = {
'/api/apps': { '1': { name: '测试App', server: '测试环境' } },
'/api/apps': { '1': { name: '测试App', server: '测试环境', certificates: { Ad_Hoc: {} } } },
'/api/schemes': { '1': { name: 'testScheme' } },
'/api/branches': ['main', 'dev'],
'/api/tasks': [],
@ -28,7 +42,7 @@ describe('BuildView.vue', () => {
})
it('显示打包配置面板', async () => {
const wrapper = mount(BuildView)
const wrapper = mountBuildView()
await flushPromises()
expect(wrapper.text()).toContain('打包配置')
@ -39,15 +53,17 @@ describe('BuildView.vue', () => {
})
it('加载 apps 和 schemes', async () => {
const wrapper = mount(BuildView)
const wrapper = mountBuildView()
await flushPromises()
const appOptions = wrapper.findAll('select')[0].findAll('option')
wrapper.vm.selectedServer = '测试环境'
await wrapper.vm.$nextTick()
const appOptions = wrapper.findAll('select')[1].findAll('option')
expect(appOptions.length).toBeGreaterThan(1)
})
it('加载分支列表并显示下拉', async () => {
const wrapper = mount(BuildView)
const wrapper = mountBuildView()
await flushPromises()
const branchSelect = wrapper.findAll('select').find(s => {
@ -58,10 +74,10 @@ describe('BuildView.vue', () => {
})
it('默认值正确', async () => {
const wrapper = mount(BuildView)
const wrapper = mountBuildView()
await flushPromises()
expect(wrapper.vm.form.build_type).toBe('Ad_Hoc')
expect(wrapper.vm.form.build_type).toBe('')
expect(wrapper.vm.form.obfuscation).toBe(false)
expect(wrapper.vm.form.branch).toBe('main')
})
@ -75,7 +91,7 @@ describe('BuildView.vue', () => {
})
}
const responses = {
'/api/apps': { '1': { name: '测试App', server: '测试环境' } },
'/api/apps': { '1': { name: '测试App', server: '测试环境', certificates: { Ad_Hoc: {} } } },
'/api/schemes': { '1': { name: 'testScheme' } },
'/api/branches': ['main', 'dev'],
'/api/tasks': [],
@ -85,21 +101,28 @@ describe('BuildView.vue', () => {
})
})
const wrapper = mount(BuildView)
const wrapper = mountBuildView()
await flushPromises()
await wrapper.setData({ form: { ...wrapper.vm.form, app_id: '1' } })
wrapper.vm.selectedServer = '测试环境'
await wrapper.vm.$nextTick()
wrapper.vm.form.app_id = '1'
await wrapper.vm.$nextTick()
await wrapper.find('.btn-primary').trigger('click')
await flushPromises()
expect(fetch).toHaveBeenCalledWith('/api/tasks', expect.objectContaining({
method: 'POST',
}))
expect(wrapper.text()).toContain('打包任务已创建,正在排队,请勿重复点击。')
expect(wrapper.vm.form.app_id).toBe('')
expect(wrapper.vm.form.build_type).toBe('')
expect(wrapper.vm.form.scheme_id).toBe('')
})
it('未选择 App 时提示', async () => {
window.alert = vi.fn()
const wrapper = mount(BuildView)
const wrapper = mountBuildView()
await flushPromises()
await wrapper.find('.btn-primary').trigger('click')
@ -109,7 +132,7 @@ describe('BuildView.vue', () => {
it('显示任务队列', async () => {
fetch.mockImplementation((url) => {
const responses = {
'/api/apps': { '1': { name: '测试App', server: '测试环境' } },
'/api/apps': { '1': { name: '测试App', server: '测试环境', certificates: { Ad_Hoc: {} } } },
'/api/schemes': { '1': { name: 'testScheme' } },
'/api/branches': ['main', 'dev'],
'/api/tasks': [
@ -122,7 +145,7 @@ describe('BuildView.vue', () => {
})
})
const wrapper = mount(BuildView)
const wrapper = mountBuildView()
await flushPromises()
const taskItems = wrapper.findAll('.task-item')
@ -130,7 +153,7 @@ describe('BuildView.vue', () => {
})
it('状态文本正确', async () => {
const wrapper = mount(BuildView)
const wrapper = mountBuildView()
await flushPromises()
expect(wrapper.vm.statusText('pending')).toBe('等待中')

View File

@ -53,6 +53,7 @@
<label for="obfuscation">启用混淆</label>
</div>
</div>
<p v-if="submitNotice" class="submit-notice" role="status" aria-live="polite">{{ submitNotice }}</p>
<button class="btn btn-primary" @click="submitTask" :disabled="submitting">
{{ submitting ? '提交中...' : '开始打包' }}
</button>
@ -193,6 +194,7 @@ const form = ref({
branch: 'main',
})
const submitting = ref(false)
const submitNotice = ref('')
const currentTaskId = ref(null)
const completedTask = ref(null)
const logs = ref([])
@ -294,7 +296,12 @@ watch(selectedServer, () => {
form.value.app_id = ''
})
watch(() => form.value.app_id, () => {
watch(() => form.value.app_id, (appId) => {
if (!appId) {
form.value.scheme_id = ''
form.value.build_type = ''
return
}
form.value.scheme_id = filteredSchemes.value[0]?.[0] || ''
form.value.build_type = availableBuildTypes.value[0] || ''
})
@ -347,6 +354,7 @@ onMounted(async () => {
})
const submitTask = async () => {
if (submitting.value) return
if (!form.value.app_id) {
alert('请选择 App')
return
@ -362,11 +370,20 @@ const submitTask = async () => {
const task = await res.json()
currentTaskId.value = task.id
tasks.value.unshift(task)
submitNotice.value = '打包任务已创建,正在排队,请勿重复点击。'
selectedServer.value = ''
form.value = {
app_id: '',
build_type: '',
scheme_id: '',
obfuscation: false,
branch: branches.value[0] || 'main',
}
} else {
alert('提交失败')
submitNotice.value = '提交失败,请检查配置后重试。'
}
} catch (e) {
alert('提交失败')
submitNotice.value = '提交失败,请检查网络后重试。'
} finally {
submitting.value = false
}
@ -443,6 +460,7 @@ const errorCategoryHint = (cat) => {
.btn-primary { background: #1890ff; color: white; }
.btn-primary:hover { background: #40a9ff; }
.btn-primary:disabled { background: #d9d9d9; cursor: not-allowed; }
.submit-notice { margin: 0 0 12px; padding: 9px 12px; border-radius: 6px; background: #e6f7ff; color: #096dd9; font-size: 13px; line-height: 1.5; }
.btn-danger { background: #ff4d4f; color: white; }
.right-panel { display: flex; flex-direction: column; gap: 16px; height: calc(100vh - 120px); overflow: hidden; }