Merge pull request #4447 from Budibase/merge/4414
Fix for query preview validation
This commit is contained in:
commit
04118fb26a
|
@ -1,6 +1,16 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/buttongroup/dist/index-vars.css"
|
import "@spectrum-css/buttongroup/dist/index-vars.css"
|
||||||
export let vertical = false
|
export let vertical = false
|
||||||
|
export let gap = ""
|
||||||
|
|
||||||
|
$: gapStyle =
|
||||||
|
gap === "L"
|
||||||
|
? "var(--spacing-l)"
|
||||||
|
: gap === "M"
|
||||||
|
? "var(--spacing-m)"
|
||||||
|
: gap === "S"
|
||||||
|
? "var(--spacing-s)"
|
||||||
|
: null
|
||||||
|
|
||||||
function group(element) {
|
function group(element) {
|
||||||
const buttons = Array.from(element.getElementsByTagName("button"))
|
const buttons = Array.from(element.getElementsByTagName("button"))
|
||||||
|
@ -14,6 +24,7 @@
|
||||||
use:group
|
use:group
|
||||||
class="spectrum-ButtonGroup"
|
class="spectrum-ButtonGroup"
|
||||||
class:spectrum-ButtonGroup--vertical={vertical}
|
class:spectrum-ButtonGroup--vertical={vertical}
|
||||||
|
style={gapStyle ? `gap: ${gapStyle};` : null}
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
$: datasource = $datasources.list.find(ds => ds._id === query.datasourceId)
|
$: datasource = $datasources.list.find(ds => ds._id === query.datasourceId)
|
||||||
$: query.schema = fieldsToSchema(fields)
|
$: query.schema = fieldsToSchema(fields)
|
||||||
$: datasourceType = datasource?.source
|
$: datasourceType = datasource?.source
|
||||||
$: integrationInfo = $integrations[datasourceType]
|
$: integrationInfo = datasourceType ? $integrations[datasourceType] : null
|
||||||
$: queryConfig = integrationInfo?.query
|
$: queryConfig = integrationInfo?.query
|
||||||
$: shouldShowQueryConfig = queryConfig && query.queryVerb
|
$: shouldShowQueryConfig = queryConfig && query.queryVerb
|
||||||
$: readQuery = query.queryVerb === "read" || query.readable
|
$: readQuery = query.queryVerb === "read" || query.readable
|
||||||
|
@ -160,7 +160,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="viewer-controls">
|
<div class="viewer-controls">
|
||||||
<Heading size="S">Results</Heading>
|
<Heading size="S">Results</Heading>
|
||||||
<ButtonGroup>
|
<ButtonGroup gap="M">
|
||||||
<Button cta disabled={queryInvalid} on:click={saveQuery}>
|
<Button cta disabled={queryInvalid} on:click={saveQuery}>
|
||||||
Save Query
|
Save Query
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
const joiValidator = require("../../../middleware/joi-validator")
|
const joiValidator = require("../../../middleware/joi-validator")
|
||||||
const Joi = require("joi")
|
const Joi = require("joi")
|
||||||
|
|
||||||
|
const OPTIONAL_STRING = Joi.string().optional().allow(null).allow("")
|
||||||
|
|
||||||
exports.queryValidation = () => {
|
exports.queryValidation = () => {
|
||||||
return Joi.object({
|
return Joi.object({
|
||||||
_id: Joi.string(),
|
_id: Joi.string(),
|
||||||
|
@ -18,7 +20,7 @@ exports.queryValidation = () => {
|
||||||
queryVerb: Joi.string().allow().required(),
|
queryVerb: Joi.string().allow().required(),
|
||||||
extra: Joi.object().optional(),
|
extra: Joi.object().optional(),
|
||||||
schema: Joi.object({}).required().unknown(true),
|
schema: Joi.object({}).required().unknown(true),
|
||||||
transformer: Joi.string().optional(),
|
transformer: OPTIONAL_STRING,
|
||||||
flags: Joi.object().optional(),
|
flags: Joi.object().optional(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -31,12 +33,18 @@ exports.generateQueryValidation = () => {
|
||||||
exports.generateQueryPreviewValidation = () => {
|
exports.generateQueryPreviewValidation = () => {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.body(Joi.object({
|
return joiValidator.body(Joi.object({
|
||||||
|
_id: OPTIONAL_STRING,
|
||||||
|
_rev: OPTIONAL_STRING,
|
||||||
|
readable: Joi.boolean().optional(),
|
||||||
fields: Joi.object().required(),
|
fields: Joi.object().required(),
|
||||||
queryVerb: Joi.string().allow().required(),
|
queryVerb: Joi.string().required(),
|
||||||
|
name: OPTIONAL_STRING,
|
||||||
|
flags: Joi.object().optional(),
|
||||||
|
schema: Joi.object().optional(),
|
||||||
extra: Joi.object().optional(),
|
extra: Joi.object().optional(),
|
||||||
datasourceId: Joi.string().required(),
|
datasourceId: Joi.string().required(),
|
||||||
transformer: Joi.string().optional(),
|
transformer: OPTIONAL_STRING,
|
||||||
parameters: Joi.object({}).required().unknown(true),
|
parameters: Joi.object({}).required().unknown(true),
|
||||||
queryId: Joi.string().optional(),
|
queryId: OPTIONAL_STRING,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,7 @@ describe("/queries", () => {
|
||||||
parameters: {},
|
parameters: {},
|
||||||
fields: {},
|
fields: {},
|
||||||
queryVerb: "read",
|
queryVerb: "read",
|
||||||
|
name: datasource.name,
|
||||||
})
|
})
|
||||||
.set(config.defaultHeaders())
|
.set(config.defaultHeaders())
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
|
@ -261,9 +262,13 @@ describe("/queries", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("check that it automatically retries on fail with cached dynamics", async () => {
|
it("check that it automatically retries on fail with cached dynamics", async () => {
|
||||||
const { datasource, query: base } = await config.dynamicVariableDatasource()
|
const { datasource, query: base } =
|
||||||
|
await config.dynamicVariableDatasource()
|
||||||
// preview once to cache
|
// preview once to cache
|
||||||
await preview(datasource, { path: "www.google.com", queryString: "test={{ variable3 }}" })
|
await preview(datasource, {
|
||||||
|
path: "www.google.com",
|
||||||
|
queryString: "test={{ variable3 }}",
|
||||||
|
})
|
||||||
// check its in cache
|
// check its in cache
|
||||||
const contents = await checkCacheForDynamicVariable(base._id, "variable3")
|
const contents = await checkCacheForDynamicVariable(base._id, "variable3")
|
||||||
expect(contents.rows.length).toEqual(1)
|
expect(contents.rows.length).toEqual(1)
|
||||||
|
@ -276,9 +281,13 @@ describe("/queries", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("deletes variables when linked query is deleted", async () => {
|
it("deletes variables when linked query is deleted", async () => {
|
||||||
const { datasource, query: base } = await config.dynamicVariableDatasource()
|
const { datasource, query: base } =
|
||||||
|
await config.dynamicVariableDatasource()
|
||||||
// preview once to cache
|
// preview once to cache
|
||||||
await preview(datasource, { path: "www.google.com", queryString: "test={{ variable3 }}" })
|
await preview(datasource, {
|
||||||
|
path: "www.google.com",
|
||||||
|
queryString: "test={{ variable3 }}",
|
||||||
|
})
|
||||||
// check its in cache
|
// check its in cache
|
||||||
let contents = await checkCacheForDynamicVariable(base._id, "variable3")
|
let contents = await checkCacheForDynamicVariable(base._id, "variable3")
|
||||||
expect(contents.rows.length).toEqual(1)
|
expect(contents.rows.length).toEqual(1)
|
||||||
|
|
|
@ -393,6 +393,7 @@ class TestConfiguration {
|
||||||
parameters: {},
|
parameters: {},
|
||||||
fields,
|
fields,
|
||||||
queryVerb: "read",
|
queryVerb: "read",
|
||||||
|
name: datasource.name,
|
||||||
})
|
})
|
||||||
.set(config.defaultHeaders())
|
.set(config.defaultHeaders())
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
|
|
Loading…
Reference in New Issue