feat: better fields
This commit is contained in:
+92
-19
@@ -720,13 +720,22 @@
|
|||||||
.function-mocks-table-grid {
|
.function-mocks-table-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.function-mocks-table-grid--rest {
|
||||||
grid-template-columns:
|
grid-template-columns:
|
||||||
minmax(150px, 1fr)
|
minmax(150px, 1fr)
|
||||||
minmax(240px, 1.3fr)
|
minmax(240px, 1.3fr)
|
||||||
minmax(220px, 1.2fr)
|
minmax(220px, 1.2fr)
|
||||||
minmax(180px, 1fr)
|
minmax(180px, 1fr);
|
||||||
minmax(260px, 1.3fr);
|
}
|
||||||
align-items: stretch;
|
|
||||||
|
.function-mocks-table-grid--rpc {
|
||||||
|
grid-template-columns:
|
||||||
|
minmax(150px, 1fr)
|
||||||
|
minmax(280px, 1.35fr)
|
||||||
|
minmax(320px, 1.65fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
.function-mocks-header {
|
.function-mocks-header {
|
||||||
@@ -1567,7 +1576,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div v-if="activeTestMockBindingMode(mockSet) === 'rest'">
|
||||||
<label
|
<label
|
||||||
class="field-label"
|
class="field-label"
|
||||||
:for="`test-mock-item-request-type-${group.key}-${testEntry.index}-${mockSetIndex}-${activeTestMockBindingName(mockSet)}-${itemIndex}`"
|
:for="`test-mock-item-request-type-${group.key}-${testEntry.index}-${mockSetIndex}-${activeTestMockBindingName(mockSet)}-${itemIndex}`"
|
||||||
@@ -1585,7 +1594,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div v-if="activeTestMockBindingMode(mockSet) === 'rest'">
|
||||||
<label
|
<label
|
||||||
class="field-label"
|
class="field-label"
|
||||||
:for="`test-mock-item-request-body-${group.key}-${testEntry.index}-${mockSetIndex}-${activeTestMockBindingName(mockSet)}-${itemIndex}`"
|
:for="`test-mock-item-request-body-${group.key}-${testEntry.index}-${mockSetIndex}-${activeTestMockBindingName(mockSet)}-${itemIndex}`"
|
||||||
@@ -1918,12 +1927,19 @@
|
|||||||
<div class="settings-editor" v-if="currentFunctionMockRows.length">
|
<div class="settings-editor" v-if="currentFunctionMockRows.length">
|
||||||
<div class="function-mocks-table-wrap">
|
<div class="function-mocks-table-wrap">
|
||||||
<div class="function-mocks-table">
|
<div class="function-mocks-table">
|
||||||
<div class="function-mocks-header function-mocks-table-grid">
|
<div
|
||||||
|
class="function-mocks-header function-mocks-table-grid"
|
||||||
|
:class="`function-mocks-table-grid--${currentFunctionMockEditorMode}`"
|
||||||
|
>
|
||||||
<div class="function-mocks-heading">Mock Name</div>
|
<div class="function-mocks-heading">Mock Name</div>
|
||||||
<div class="function-mocks-heading">Method</div>
|
<div class="function-mocks-heading">Method</div>
|
||||||
|
<template v-if="currentFunctionMockEditorMode === 'rest'">
|
||||||
<div class="function-mocks-heading">Headers JSON</div>
|
<div class="function-mocks-heading">Headers JSON</div>
|
||||||
<div class="function-mocks-heading">Query Params JSON</div>
|
<div class="function-mocks-heading">Query Params JSON</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
<div class="function-mocks-heading">Response</div>
|
<div class="function-mocks-heading">Response</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -1931,7 +1947,10 @@
|
|||||||
:key="mockRow.id"
|
:key="mockRow.id"
|
||||||
class="function-mocks-row"
|
class="function-mocks-row"
|
||||||
>
|
>
|
||||||
<div class="function-mocks-table-grid">
|
<div
|
||||||
|
class="function-mocks-table-grid"
|
||||||
|
:class="`function-mocks-table-grid--${functionMockRowMode(mockRow)}`"
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
:id="`function-mock-name-${mockRow.id}`"
|
:id="`function-mock-name-${mockRow.id}`"
|
||||||
@@ -2015,6 +2034,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<template v-if="functionMockRowMode(mockRow) === 'rest'">
|
||||||
<div class="function-mock-json-cell">
|
<div class="function-mock-json-cell">
|
||||||
<textarea
|
<textarea
|
||||||
:id="`function-mock-headers-${mockRow.id}`"
|
:id="`function-mock-headers-${mockRow.id}`"
|
||||||
@@ -2042,7 +2062,9 @@
|
|||||||
Query Params JSON: JSON object of expected query-string parameters.
|
Query Params JSON: JSON object of expected query-string parameters.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
<div class="function-mock-cell-stack">
|
<div class="function-mock-cell-stack">
|
||||||
<div class="function-mock-subfield">
|
<div class="function-mock-subfield">
|
||||||
<input
|
<input
|
||||||
@@ -2050,14 +2072,16 @@
|
|||||||
v-model="mockRow.responseType"
|
v-model="mockRow.responseType"
|
||||||
class="native-input"
|
class="native-input"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="json"
|
placeholder="data"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
@input="persistFunctionMocks({ silent: true })"
|
@input="persistFunctionMocks({ silent: true })"
|
||||||
/>
|
/>
|
||||||
<div class="settings-hint">
|
<div class="settings-hint">
|
||||||
Response Type: Optional response mode such as
|
Response Type: Optional RPC return mode such as
|
||||||
<code>json</code>,
|
|
||||||
<code>data</code>,
|
<code>data</code>,
|
||||||
|
<code>function</code>,
|
||||||
|
<code>async-function</code>,
|
||||||
|
<code>json</code>,
|
||||||
or
|
or
|
||||||
<code>exception</code>.
|
<code>exception</code>.
|
||||||
</div>
|
</div>
|
||||||
@@ -2068,15 +2092,16 @@
|
|||||||
:id="`function-mock-response-${mockRow.id}`"
|
:id="`function-mock-response-${mockRow.id}`"
|
||||||
v-model="mockRow.responseText"
|
v-model="mockRow.responseText"
|
||||||
class="native-textarea"
|
class="native-textarea"
|
||||||
placeholder='{"field":"value"}'
|
placeholder='{"method_name":{"request_type":"function","response_type":"json","response":{}}}'
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
@input="persistFunctionMocks({ silent: true })"
|
@input="persistFunctionMocks({ silent: true })"
|
||||||
></textarea>
|
></textarea>
|
||||||
<div class="settings-hint">
|
<div class="settings-hint">
|
||||||
Response Body: JSON payload, data object, or exception body returned by the mock.
|
Response: RPC mock object returned by the patched function.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="mockRow.error" class="settings-error function-mocks-note">
|
<div v-if="mockRow.error" class="settings-error function-mocks-note">
|
||||||
@@ -2859,6 +2884,13 @@
|
|||||||
this.currentTestFundingSourceName
|
this.currentTestFundingSourceName
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
currentFunctionMockEditorMode() {
|
||||||
|
if (this.currentFunctionMockRows.length) {
|
||||||
|
return this.functionMockRowMode(this.currentFunctionMockRows[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.selectedDatasetKey === 'rpc' ? 'rpc' : 'rest'
|
||||||
|
},
|
||||||
currentFunctionMockNameOptions() {
|
currentFunctionMockNameOptions() {
|
||||||
const seen = new Set()
|
const seen = new Set()
|
||||||
|
|
||||||
@@ -3763,6 +3795,32 @@
|
|||||||
) || null
|
) || null
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
functionMockRowMode(row) {
|
||||||
|
return row?.requestType === 'function' ? 'rpc' : 'rest'
|
||||||
|
},
|
||||||
|
functionMockModeByName(mockName) {
|
||||||
|
const normalizedName = (mockName || '').trim()
|
||||||
|
if (!normalizedName) {
|
||||||
|
return this.selectedDatasetKey === 'rpc' ? 'rpc' : 'rest'
|
||||||
|
}
|
||||||
|
|
||||||
|
const draftRow = this.currentFunctionMockRows.find(
|
||||||
|
row => (row.name || '').trim() === normalizedName
|
||||||
|
)
|
||||||
|
if (draftRow) {
|
||||||
|
return this.functionMockRowMode(draftRow)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockValue =
|
||||||
|
this.datasets[this.selectedDatasetKey].data?.functions?.[
|
||||||
|
this.currentFunctionName
|
||||||
|
]?.mocks?.[this.currentTestFundingSourceName]?.[normalizedName] || {}
|
||||||
|
|
||||||
|
return mockValue?.request_type === 'function' ? 'rpc' : 'rest'
|
||||||
|
},
|
||||||
|
activeTestMockBindingMode(mockSet) {
|
||||||
|
return this.functionMockModeByName(this.activeTestMockBindingName(mockSet))
|
||||||
|
},
|
||||||
nextAvailableTestMockName(mockSet) {
|
nextAvailableTestMockName(mockSet) {
|
||||||
const usedNames = new Set(
|
const usedNames = new Set(
|
||||||
(mockSet.bindings || [])
|
(mockSet.bindings || [])
|
||||||
@@ -4004,20 +4062,22 @@
|
|||||||
},
|
},
|
||||||
parseFunctionMockRowBody(row) {
|
parseFunctionMockRowBody(row) {
|
||||||
const mock = {}
|
const mock = {}
|
||||||
|
const mode = this.functionMockRowMode(row)
|
||||||
|
|
||||||
const name = row.name.trim()
|
const name = row.name.trim()
|
||||||
if (!name) {
|
if (!name) {
|
||||||
throw new Error('Mock name cannot be empty.')
|
throw new Error('Mock name cannot be empty.')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row.uri.trim() !== '') {
|
|
||||||
mock.uri = row.uri
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row.method.trim() !== '') {
|
if (row.method.trim() !== '') {
|
||||||
mock.method = row.method
|
mock.method = row.method
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode === 'rest') {
|
||||||
|
if (row.uri.trim() !== '') {
|
||||||
|
mock.uri = row.uri
|
||||||
|
}
|
||||||
|
|
||||||
if (row.headersText.trim() !== '') {
|
if (row.headersText.trim() !== '') {
|
||||||
const parsedHeaders = JSON.parse(row.headersText)
|
const parsedHeaders = JSON.parse(row.headersText)
|
||||||
if (!isPlainObject(parsedHeaders)) {
|
if (!isPlainObject(parsedHeaders)) {
|
||||||
@@ -4033,7 +4093,7 @@
|
|||||||
}
|
}
|
||||||
mock.query_params = parsedQueryParams
|
mock.query_params = parsedQueryParams
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (row.requestType.trim() !== '') {
|
if (row.requestType.trim() !== '') {
|
||||||
mock.request_type = row.requestType
|
mock.request_type = row.requestType
|
||||||
}
|
}
|
||||||
@@ -4045,6 +4105,7 @@
|
|||||||
if (row.responseText.trim() !== '') {
|
if (row.responseText.trim() !== '') {
|
||||||
mock.response = JSON.parse(row.responseText)
|
mock.response = JSON.parse(row.responseText)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return mock
|
return mock
|
||||||
},
|
},
|
||||||
@@ -4060,6 +4121,11 @@
|
|||||||
|
|
||||||
if (row.requestType === 'function') {
|
if (row.requestType === 'function') {
|
||||||
row.uri = ''
|
row.uri = ''
|
||||||
|
row.headersText = ''
|
||||||
|
row.queryParamsText = ''
|
||||||
|
} else {
|
||||||
|
row.responseType = ''
|
||||||
|
row.responseText = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
this.persistFunctionMocks({ silent: true })
|
this.persistFunctionMocks({ silent: true })
|
||||||
@@ -4167,6 +4233,7 @@
|
|||||||
|
|
||||||
for (const binding of mockSet.bindings || []) {
|
for (const binding of mockSet.bindings || []) {
|
||||||
const mockName = (binding.selectedMockName || '').trim()
|
const mockName = (binding.selectedMockName || '').trim()
|
||||||
|
const bindingMode = this.functionMockModeByName(mockName)
|
||||||
|
|
||||||
if (!mockName) {
|
if (!mockName) {
|
||||||
if ((binding.items || []).length) {
|
if ((binding.items || []).length) {
|
||||||
@@ -4210,11 +4277,17 @@
|
|||||||
nextItem.skip = Boolean(item.skip)
|
nextItem.skip = Boolean(item.skip)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((item.requestType || '').trim() !== '') {
|
if (
|
||||||
|
bindingMode === 'rest' &&
|
||||||
|
(item.requestType || '').trim() !== ''
|
||||||
|
) {
|
||||||
nextItem.request_type = item.requestType.trim()
|
nextItem.request_type = item.requestType.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((item.requestBodyText || '').trim() !== '') {
|
if (
|
||||||
|
bindingMode === 'rest' &&
|
||||||
|
(item.requestBodyText || '').trim() !== ''
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
nextItem.request_body = this.parseEditableTestJson(
|
nextItem.request_body = this.parseEditableTestJson(
|
||||||
item.requestBodyText,
|
item.requestBodyText,
|
||||||
|
|||||||
Reference in New Issue
Block a user