feat: ui
This commit is contained in:
+298
-120
@@ -199,6 +199,10 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.picker-card--full {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
.picker-card .q-card__section--vert {
|
.picker-card .q-card__section--vert {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 16px 18px;
|
padding: 16px 18px;
|
||||||
@@ -590,6 +594,20 @@
|
|||||||
background: rgba(25, 54, 61, 0.03);
|
background: rgba(25, 54, 61, 0.03);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.test-mock-item-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 12px;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.test-mock-item-json {
|
||||||
|
min-height: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.test-mock-item-full {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
.detail-label {
|
.detail-label {
|
||||||
color: var(--studio-muted);
|
color: var(--studio-muted);
|
||||||
font-size: 0.74rem;
|
font-size: 0.74rem;
|
||||||
@@ -888,18 +906,78 @@
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.function-tabs {
|
||||||
|
margin-bottom: 14px;
|
||||||
|
border-radius: 18px;
|
||||||
|
background: rgba(22, 32, 40, 0.04);
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.function-tabs .q-tab {
|
||||||
|
flex: 1 1 0;
|
||||||
|
min-width: 0;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 48px;
|
||||||
|
border-radius: 12px;
|
||||||
|
color: var(--q-primary);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.function-tabs .q-tab__content {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.function-tabs .q-tab--active {
|
||||||
|
background: var(--q-primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.function-tabs .q-tab--active,
|
||||||
|
.function-tabs .q-tab--active .q-tab__label,
|
||||||
|
.function-tabs .q-tab--active .text-weight-bold,
|
||||||
|
.function-tabs .q-tab--active .text-caption {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.function-content {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.function-content-header {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.test-type-layout {
|
||||||
|
display: grid;
|
||||||
|
gap: 18px;
|
||||||
|
grid-template-columns: minmax(220px, 260px) minmax(0, 1fr);
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
.test-type-tabs {
|
.test-type-tabs {
|
||||||
margin-top: 8px;
|
|
||||||
border-radius: 18px;
|
border-radius: 18px;
|
||||||
background: rgba(22, 32, 40, 0.04);
|
background: rgba(22, 32, 40, 0.04);
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.test-type-tabs .q-tab {
|
.test-type-tabs .q-tab {
|
||||||
flex: 1 1 0;
|
justify-content: flex-start;
|
||||||
min-width: 0;
|
min-height: 48px;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
color: var(--q-primary);
|
color: var(--q-primary);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.test-type-tabs .q-tab__content {
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.test-type-tabs .q-tab--active {
|
.test-type-tabs .q-tab--active {
|
||||||
@@ -914,9 +992,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.test-type-panels {
|
.test-type-panels {
|
||||||
margin-top: 14px;
|
|
||||||
background: transparent;
|
background: transparent;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.test-type-panel {
|
.test-type-panel {
|
||||||
@@ -1110,8 +1188,13 @@
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.test-type-layout {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
.mock-source-grid,
|
.mock-source-grid,
|
||||||
.test-detail-grid,
|
.test-detail-grid,
|
||||||
|
.test-mock-item-grid,
|
||||||
.settings-row-grid,
|
.settings-row-grid,
|
||||||
.settings-table-grid {
|
.settings-table-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
@@ -1226,7 +1309,7 @@
|
|||||||
|
|
||||||
<main class="workspace-grid">
|
<main class="workspace-grid">
|
||||||
<section class="primary-row">
|
<section class="primary-row">
|
||||||
<q-card flat class="studio-card picker-card">
|
<q-card flat class="studio-card picker-card picker-card--full">
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<div class="section-title">
|
<div class="section-title">
|
||||||
<div>
|
<div>
|
||||||
@@ -1280,39 +1363,34 @@
|
|||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
<q-card flat class="studio-card picker-card" v-if="currentDataset.analysis">
|
</section>
|
||||||
|
|
||||||
|
<q-card flat class="studio-card" v-if="currentFundingSource && currentDataset.analysis">
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<div class="section-title">
|
<q-tabs
|
||||||
<div>
|
v-if="functionOptions.length"
|
||||||
<h2>Function</h2>
|
|
||||||
<div class="section-caption">
|
|
||||||
Choose the wallet interface method to inspect for the selected funding source.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<label class="native-select-label" for="function-select">
|
|
||||||
Function
|
|
||||||
</label>
|
|
||||||
<div class="picker-action-row">
|
|
||||||
<q-select
|
|
||||||
id="function-select"
|
|
||||||
v-model="selectedFunctionByDataset[selectedDatasetKey]"
|
v-model="selectedFunctionByDataset[selectedDatasetKey]"
|
||||||
:options="functionOptions"
|
|
||||||
emit-value
|
|
||||||
map-options
|
|
||||||
outlined
|
|
||||||
dense
|
dense
|
||||||
options-dense
|
active-color="white"
|
||||||
behavior="menu"
|
indicator-color="transparent"
|
||||||
hide-dropdown-icon
|
align="justify"
|
||||||
class="fixture-select picker-select"
|
class="function-tabs text-primary"
|
||||||
>
|
>
|
||||||
<template v-slot:append>
|
<q-tab
|
||||||
<span class="fixture-select-icon" aria-hidden="true">expand_more</span>
|
v-for="fn in currentDataset.analysis.functions"
|
||||||
</template>
|
:key="fn.name"
|
||||||
</q-select>
|
:name="fn.name"
|
||||||
|
>
|
||||||
|
<div class="text-left">
|
||||||
|
<div class="text-weight-bold">{{ fn.name }}</div>
|
||||||
|
<div class="text-caption">{{ fn.tests.length }} tests</div>
|
||||||
|
</div>
|
||||||
|
</q-tab>
|
||||||
|
</q-tabs>
|
||||||
|
|
||||||
|
<div v-if="functionOptions.length">
|
||||||
|
<div class="function-content">
|
||||||
|
<div class="function-content-header" v-if="currentFunction">
|
||||||
<q-btn
|
<q-btn
|
||||||
color="primary"
|
color="primary"
|
||||||
outline
|
outline
|
||||||
@@ -1321,29 +1399,14 @@
|
|||||||
@click="functionMocksDialog = true"
|
@click="functionMocksDialog = true"
|
||||||
></q-btn>
|
></q-btn>
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<q-card flat class="studio-card" v-if="currentFunction && currentFundingSource">
|
|
||||||
<q-card-section>
|
|
||||||
<div class="section-title">
|
|
||||||
<div>
|
|
||||||
<h2>Tests For Selected Function</h2>
|
|
||||||
<div class="section-caption">
|
|
||||||
Browse the raw test types for this function, then inspect the call params, expected result, and selected funding source mocks.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div v-if="currentFunctionTestTypeGroups.length" class="test-type-layout">
|
||||||
<q-tabs
|
<q-tabs
|
||||||
v-if="currentFunctionTestTypeGroups.length"
|
|
||||||
v-model="currentSelectedTestTypeKey"
|
v-model="currentSelectedTestTypeKey"
|
||||||
|
vertical
|
||||||
dense
|
dense
|
||||||
active-color="white"
|
active-color="white"
|
||||||
indicator-color="transparent"
|
indicator-color="transparent"
|
||||||
align="justify"
|
|
||||||
class="test-type-tabs text-primary"
|
class="test-type-tabs text-primary"
|
||||||
>
|
>
|
||||||
<q-tab
|
<q-tab
|
||||||
@@ -1518,9 +1581,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="test-mock-item-list" v-if="binding.itemTexts.length">
|
<div class="test-mock-item-list" v-if="binding.items.length">
|
||||||
<div
|
<div
|
||||||
v-for="(item, itemIndex) in binding.itemTexts"
|
v-for="(item, itemIndex) in binding.items"
|
||||||
:key="`${mockSet.path}-binding-${bindingIndex}-item-${itemIndex}`"
|
:key="`${mockSet.path}-binding-${bindingIndex}-item-${itemIndex}`"
|
||||||
class="test-mock-item-card"
|
class="test-mock-item-card"
|
||||||
>
|
>
|
||||||
@@ -1547,13 +1610,100 @@
|
|||||||
></q-checkbox>
|
></q-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="test-mock-item-grid">
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
class="field-label"
|
||||||
|
:for="`test-mock-item-description-${group.key}-${testEntry.index}-${mockSetIndex}-${bindingIndex}-${itemIndex}`"
|
||||||
|
>
|
||||||
|
Description
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
:id="`test-mock-item-description-${group.key}-${testEntry.index}-${mockSetIndex}-${bindingIndex}-${itemIndex}`"
|
||||||
|
v-model="item.descriptionText"
|
||||||
|
class="native-input"
|
||||||
|
type="text"
|
||||||
|
placeholder="Optional label"
|
||||||
|
spellcheck="false"
|
||||||
|
@blur="persistTestMockSet(testEntry, mockSet)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
class="field-label"
|
||||||
|
:for="`test-mock-item-request-type-${group.key}-${testEntry.index}-${mockSetIndex}-${bindingIndex}-${itemIndex}`"
|
||||||
|
>
|
||||||
|
Request Type
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
:id="`test-mock-item-request-type-${group.key}-${testEntry.index}-${mockSetIndex}-${bindingIndex}-${itemIndex}`"
|
||||||
|
v-model="item.requestType"
|
||||||
|
class="native-input"
|
||||||
|
type="text"
|
||||||
|
placeholder="json"
|
||||||
|
spellcheck="false"
|
||||||
|
@blur="persistTestMockSet(testEntry, mockSet)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
class="field-label"
|
||||||
|
:for="`test-mock-item-request-body-${group.key}-${testEntry.index}-${mockSetIndex}-${bindingIndex}-${itemIndex}`"
|
||||||
|
>
|
||||||
|
Request Body
|
||||||
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
:id="`test-mock-definition-${group.key}-${testEntry.index}-${mockSetIndex}-${bindingIndex}-${itemIndex}`"
|
:id="`test-mock-item-request-body-${group.key}-${testEntry.index}-${mockSetIndex}-${bindingIndex}-${itemIndex}`"
|
||||||
v-model="item.text"
|
v-model="item.requestBodyText"
|
||||||
class="native-textarea test-mock-editor"
|
class="native-textarea test-mock-item-json"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
@blur="persistTestMockSet(testEntry, mockSet)"
|
@blur="persistTestMockSet(testEntry, mockSet)"
|
||||||
></textarea>
|
></textarea>
|
||||||
|
<div v-if="item.requestBodyError" class="settings-error q-mt-sm">
|
||||||
|
{{ item.requestBodyError }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
class="field-label"
|
||||||
|
:for="`test-mock-item-response-type-${group.key}-${testEntry.index}-${mockSetIndex}-${bindingIndex}-${itemIndex}`"
|
||||||
|
>
|
||||||
|
Response Type
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
:id="`test-mock-item-response-type-${group.key}-${testEntry.index}-${mockSetIndex}-${bindingIndex}-${itemIndex}`"
|
||||||
|
v-model="item.responseType"
|
||||||
|
class="native-input"
|
||||||
|
type="text"
|
||||||
|
placeholder="json"
|
||||||
|
spellcheck="false"
|
||||||
|
@blur="persistTestMockSet(testEntry, mockSet)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-mock-item-full">
|
||||||
|
<label
|
||||||
|
class="field-label"
|
||||||
|
:for="`test-mock-item-response-${group.key}-${testEntry.index}-${mockSetIndex}-${bindingIndex}-${itemIndex}`"
|
||||||
|
>
|
||||||
|
Response
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
:id="`test-mock-item-response-${group.key}-${testEntry.index}-${mockSetIndex}-${bindingIndex}-${itemIndex}`"
|
||||||
|
v-model="item.responseText"
|
||||||
|
class="native-textarea test-mock-item-json"
|
||||||
|
spellcheck="false"
|
||||||
|
@blur="persistTestMockSet(testEntry, mockSet)"
|
||||||
|
></textarea>
|
||||||
|
<div v-if="item.responseError" class="settings-error q-mt-sm">
|
||||||
|
{{ item.responseError }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="item.error" class="settings-error q-mt-sm">
|
<div v-if="item.error" class="settings-error q-mt-sm">
|
||||||
{{ item.error }}
|
{{ item.error }}
|
||||||
</div>
|
</div>
|
||||||
@@ -1598,10 +1748,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
</q-tab-panels>
|
</q-tab-panels>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="!currentFunctionTestTypeGroups.length" class="empty-state">
|
<div v-else-if="currentFunction" class="empty-state">
|
||||||
No tests are defined for this function.
|
No tests are defined for this function.
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else class="empty-state">
|
||||||
|
No functions are defined for this fixture file.
|
||||||
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</main>
|
</main>
|
||||||
@@ -2473,6 +2630,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createTestMockItemDraftState(item = {}) {
|
||||||
|
const source = isPlainObject(item) ? item : {}
|
||||||
|
|
||||||
|
return {
|
||||||
|
descriptionText:
|
||||||
|
typeof source.description === 'string' ? source.description : '',
|
||||||
|
skip: typeof source.skip === 'boolean' ? source.skip : false,
|
||||||
|
hasSkipField: typeof source.skip === 'boolean',
|
||||||
|
requestType:
|
||||||
|
typeof source.request_type === 'string' ? source.request_type : '',
|
||||||
|
requestBodyText:
|
||||||
|
source.request_body !== undefined
|
||||||
|
? safeStringify(source.request_body)
|
||||||
|
: '',
|
||||||
|
requestBodyError: '',
|
||||||
|
responseType:
|
||||||
|
typeof source.response_type === 'string' ? source.response_type : '',
|
||||||
|
responseText:
|
||||||
|
source.response !== undefined ? safeStringify(source.response) : '',
|
||||||
|
responseError: '',
|
||||||
|
error: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function inferDatasetKeyFromData(data) {
|
function inferDatasetKeyFromData(data) {
|
||||||
let rpcHint = false
|
let rpcHint = false
|
||||||
|
|
||||||
@@ -2757,11 +2938,8 @@
|
|||||||
.filter(([key]) => key !== 'description')
|
.filter(([key]) => key !== 'description')
|
||||||
.map(([key, value]) => ({
|
.map(([key, value]) => ({
|
||||||
selectedMockName: key,
|
selectedMockName: key,
|
||||||
itemTexts: (Array.isArray(value) ? value : [value]).map(
|
items: (Array.isArray(value) ? value : [value]).map(item =>
|
||||||
item => ({
|
createTestMockItemDraftState(item)
|
||||||
text: safeStringify(item),
|
|
||||||
error: ''
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
})),
|
})),
|
||||||
error: ''
|
error: ''
|
||||||
@@ -3003,10 +3181,7 @@
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
selectedMockName: mockName,
|
selectedMockName: mockName,
|
||||||
itemTexts: normalizedItems.map(item => ({
|
items: normalizedItems.map(item => createTestMockItemDraftState(item))
|
||||||
text: safeStringify(item),
|
|
||||||
error: ''
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
testMockBindingOptions(selectedMockName = '') {
|
testMockBindingOptions(selectedMockName = '') {
|
||||||
@@ -3037,8 +3212,7 @@
|
|||||||
return availableName?.value || ''
|
return availableName?.value || ''
|
||||||
},
|
},
|
||||||
testMockItemTitle(item, itemIndex) {
|
testMockItemTitle(item, itemIndex) {
|
||||||
const parsed = parseJsonText(item?.text || '')
|
const description = item?.descriptionText || ''
|
||||||
const description = parsed.ok ? parsed.data?.description : ''
|
|
||||||
|
|
||||||
if (typeof description === 'string' && description.trim() !== '') {
|
if (typeof description === 'string' && description.trim() !== '') {
|
||||||
return description.trim()
|
return description.trim()
|
||||||
@@ -3047,48 +3221,15 @@
|
|||||||
return `Test Mock Definition ${itemIndex + 1}`
|
return `Test Mock Definition ${itemIndex + 1}`
|
||||||
},
|
},
|
||||||
testMockItemHasSkip(item) {
|
testMockItemHasSkip(item) {
|
||||||
const parsed = parseJsonText(item?.text || '')
|
return Boolean(item?.hasSkipField || item?.skip === true)
|
||||||
|
|
||||||
return (
|
|
||||||
parsed.ok &&
|
|
||||||
isPlainObject(parsed.data) &&
|
|
||||||
typeof parsed.data.skip === 'boolean'
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
testMockItemSkip(item) {
|
testMockItemSkip(item) {
|
||||||
const parsed = parseJsonText(item?.text || '')
|
return Boolean(item?.skip)
|
||||||
|
|
||||||
if (
|
|
||||||
!parsed.ok ||
|
|
||||||
!isPlainObject(parsed.data) ||
|
|
||||||
typeof parsed.data.skip !== 'boolean'
|
|
||||||
) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return parsed.data.skip
|
|
||||||
},
|
},
|
||||||
setTestMockItemSkip(testEntry, mockSet, item, value) {
|
setTestMockItemSkip(testEntry, mockSet, item, value) {
|
||||||
const parsed = parseJsonText(item?.text || '')
|
|
||||||
|
|
||||||
if (
|
|
||||||
!parsed.ok ||
|
|
||||||
!isPlainObject(parsed.data) ||
|
|
||||||
typeof parsed.data.skip !== 'boolean'
|
|
||||||
) {
|
|
||||||
item.error =
|
|
||||||
'Could not update skip because this mock definition is not valid JSON with a boolean skip field.'
|
|
||||||
this.notify(
|
|
||||||
'Could not save mock skip flag.',
|
|
||||||
'negative',
|
|
||||||
item.error
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
item.error = ''
|
item.error = ''
|
||||||
parsed.data.skip = Boolean(value)
|
item.hasSkipField = true
|
||||||
item.text = safeStringify(parsed.data)
|
item.skip = Boolean(value)
|
||||||
this.persistTestMockSet(testEntry, mockSet)
|
this.persistTestMockSet(testEntry, mockSet)
|
||||||
},
|
},
|
||||||
addTestMockBinding(testEntry, mockSet) {
|
addTestMockBinding(testEntry, mockSet) {
|
||||||
@@ -3101,14 +3242,11 @@
|
|||||||
this.persistTestMockSet(testEntry, mockSet)
|
this.persistTestMockSet(testEntry, mockSet)
|
||||||
},
|
},
|
||||||
addTestMockBindingItem(testEntry, mockSet, binding) {
|
addTestMockBindingItem(testEntry, mockSet, binding) {
|
||||||
binding.itemTexts.push({
|
binding.items.push(createTestMockItemDraftState({}))
|
||||||
text: safeStringify({}),
|
|
||||||
error: ''
|
|
||||||
})
|
|
||||||
this.persistTestMockSet(testEntry, mockSet)
|
this.persistTestMockSet(testEntry, mockSet)
|
||||||
},
|
},
|
||||||
removeTestMockBindingItem(testEntry, mockSet, binding, itemIndex) {
|
removeTestMockBindingItem(testEntry, mockSet, binding, itemIndex) {
|
||||||
binding.itemTexts.splice(itemIndex, 1)
|
binding.items.splice(itemIndex, 1)
|
||||||
this.persistTestMockSet(testEntry, mockSet)
|
this.persistTestMockSet(testEntry, mockSet)
|
||||||
},
|
},
|
||||||
getSettingsDraftRows(datasetKey, fundingSourceName) {
|
getSettingsDraftRows(datasetKey, fundingSourceName) {
|
||||||
@@ -3374,8 +3512,10 @@
|
|||||||
|
|
||||||
mockSet.error = ''
|
mockSet.error = ''
|
||||||
;(mockSet.bindings || []).forEach(binding => {
|
;(mockSet.bindings || []).forEach(binding => {
|
||||||
;(binding.itemTexts || []).forEach(item => {
|
;(binding.items || []).forEach(item => {
|
||||||
item.error = ''
|
item.error = ''
|
||||||
|
item.requestBodyError = ''
|
||||||
|
item.responseError = ''
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -3385,7 +3525,7 @@
|
|||||||
const mockName = (binding.selectedMockName || '').trim()
|
const mockName = (binding.selectedMockName || '').trim()
|
||||||
|
|
||||||
if (!mockName) {
|
if (!mockName) {
|
||||||
if ((binding.itemTexts || []).length) {
|
if ((binding.items || []).length) {
|
||||||
mockSet.error = 'Select a function mock before editing its overrides.'
|
mockSet.error = 'Select a function mock before editing its overrides.'
|
||||||
this.notify(
|
this.notify(
|
||||||
'Could not save test mock definition.',
|
'Could not save test mock definition.',
|
||||||
@@ -3410,20 +3550,32 @@
|
|||||||
|
|
||||||
const parsedItems = []
|
const parsedItems = []
|
||||||
|
|
||||||
for (let itemIndex = 0; itemIndex < (binding.itemTexts || []).length; itemIndex += 1) {
|
for (let itemIndex = 0; itemIndex < (binding.items || []).length; itemIndex += 1) {
|
||||||
const item = binding.itemTexts[itemIndex]
|
const item = binding.items[itemIndex]
|
||||||
|
const nextItem = {}
|
||||||
|
|
||||||
|
if ((item.descriptionText || '').trim() !== '') {
|
||||||
|
nextItem.description = item.descriptionText.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.hasSkipField || item.skip === true) {
|
||||||
|
nextItem.skip = Boolean(item.skip)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((item.requestType || '').trim() !== '') {
|
||||||
|
nextItem.request_type = item.requestType.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((item.requestBodyText || '').trim() !== '') {
|
||||||
try {
|
try {
|
||||||
parsedItems.push(
|
nextItem.request_body = this.parseEditableTestJson(
|
||||||
this.parseEditableTestJson(
|
item.requestBodyText,
|
||||||
item.text,
|
`${mockName} request_body ${itemIndex + 1}`
|
||||||
`${mockName} item ${itemIndex + 1}`
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
item.error =
|
item.requestBodyError =
|
||||||
error instanceof Error ? error.message : String(error)
|
error instanceof Error ? error.message : String(error)
|
||||||
mockSet.error = item.error
|
mockSet.error = item.requestBodyError
|
||||||
this.notify(
|
this.notify(
|
||||||
'Could not save test mock definition.',
|
'Could not save test mock definition.',
|
||||||
'negative',
|
'negative',
|
||||||
@@ -3433,6 +3585,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((item.responseType || '').trim() !== '') {
|
||||||
|
nextItem.response_type = item.responseType.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((item.responseText || '').trim() !== '') {
|
||||||
|
try {
|
||||||
|
nextItem.response = this.parseEditableTestJson(
|
||||||
|
item.responseText,
|
||||||
|
`${mockName} response ${itemIndex + 1}`
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
item.responseError =
|
||||||
|
error instanceof Error ? error.message : String(error)
|
||||||
|
mockSet.error = item.responseError
|
||||||
|
this.notify(
|
||||||
|
'Could not save test mock definition.',
|
||||||
|
'negative',
|
||||||
|
mockSet.error
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedItems.push(nextItem)
|
||||||
|
}
|
||||||
|
|
||||||
nextValue[mockName] = parsedItems
|
nextValue[mockName] = parsedItems
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user