mirror of https://github.com/Budibase/budibase.git
8 changed files with 244 additions and 10 deletions
@ -0,0 +1,68 @@ |
|||||
|
const CouchDB = require("../../db") |
||||
|
const Ajv = require("ajv") |
||||
|
const newid = require("../../db/newid") |
||||
|
|
||||
|
const ajv = new Ajv() |
||||
|
|
||||
|
exports.create = async function(ctx) { |
||||
|
const db = new CouchDB(ctx.params.instanceId) |
||||
|
const workflow = ctx.request.body |
||||
|
|
||||
|
workflow._id = newid() |
||||
|
|
||||
|
// TODO: Possibly validate the workflow against a schema
|
||||
|
|
||||
|
// // validation with ajv
|
||||
|
// const model = await db.get(record.modelId)
|
||||
|
// const validate = ajv.compile({
|
||||
|
// properties: model.schema,
|
||||
|
// })
|
||||
|
// const valid = validate(record)
|
||||
|
|
||||
|
// if (!valid) {
|
||||
|
// ctx.status = 400
|
||||
|
// ctx.body = {
|
||||
|
// status: 400,
|
||||
|
// errors: validate.errors,
|
||||
|
// }
|
||||
|
// return
|
||||
|
// }
|
||||
|
|
||||
|
|
||||
|
workflow.type = "workflow" |
||||
|
const response = await db.post(workflow) |
||||
|
workflow._rev = response.rev |
||||
|
|
||||
|
ctx.status = 200 |
||||
|
ctx.body = { |
||||
|
message: "Workflow created successfully", |
||||
|
workflow: { |
||||
|
...workflow, |
||||
|
...response |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
exports.update = async function(ctx) { |
||||
|
const db = new CouchDB(ctx.params.instanceId) |
||||
|
ctx.body = await db.get(ctx.params.recordId) |
||||
|
} |
||||
|
|
||||
|
exports.fetch = async function(ctx) { |
||||
|
const db = new CouchDB(ctx.params.instanceId) |
||||
|
const response = await db.query(`database/by_type`, { |
||||
|
type: "workflow", |
||||
|
include_docs: true, |
||||
|
}) |
||||
|
ctx.body = response.rows.map(row => row.doc) |
||||
|
} |
||||
|
|
||||
|
exports.find = async function(ctx) { |
||||
|
const db = new CouchDB(ctx.params.instanceId) |
||||
|
ctx.body = await db.get(ctx.params.id) |
||||
|
} |
||||
|
|
||||
|
exports.destroy = async function(ctx) { |
||||
|
const db = new CouchDB(ctx.params.instanceId) |
||||
|
ctx.body = await db.remove(ctx.params.id, ctx.params.rev) |
||||
|
} |
||||
@ -0,0 +1,114 @@ |
|||||
|
const { |
||||
|
createClientDatabase, |
||||
|
createApplication, |
||||
|
createInstance, |
||||
|
defaultHeaders, |
||||
|
supertest, |
||||
|
insertDocument, |
||||
|
destroyDocument |
||||
|
} = require("./couchTestUtils") |
||||
|
|
||||
|
const TEST_WORKFLOW = { |
||||
|
_id: "Test Workflow", |
||||
|
name: "My Workflow", |
||||
|
pageId: "123123123", |
||||
|
screenId: "kasdkfldsafkl", |
||||
|
live: true, |
||||
|
uiTree: { |
||||
|
|
||||
|
}, |
||||
|
definition: { |
||||
|
triggers: [ |
||||
|
|
||||
|
], |
||||
|
next: { |
||||
|
actionId: "abc123", |
||||
|
type: "SERVER", |
||||
|
conditions: { |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
describe("/workflows", () => { |
||||
|
let request |
||||
|
let server |
||||
|
let app |
||||
|
let instance |
||||
|
let workflow |
||||
|
|
||||
|
beforeAll(async () => { |
||||
|
({ request, server } = await supertest()) |
||||
|
await createClientDatabase(request) |
||||
|
app = await createApplication(request) |
||||
|
}) |
||||
|
|
||||
|
beforeEach(async () => { |
||||
|
instance = await createInstance(request, app._id) |
||||
|
if (workflow) await destroyDocument(workflow.id); |
||||
|
}) |
||||
|
|
||||
|
afterAll(async () => { |
||||
|
server.close() |
||||
|
}) |
||||
|
|
||||
|
const createWorkflow = async () => { |
||||
|
workflow = await insertDocument(instance._id, { |
||||
|
type: "workflow", |
||||
|
...TEST_WORKFLOW |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
describe("create", () => { |
||||
|
it("returns a success message when the workflow is successfully created", async () => { |
||||
|
const res = await request |
||||
|
.post(`/api/${instance._id}/workflows`) |
||||
|
.set(defaultHeaders) |
||||
|
.send(TEST_WORKFLOW) |
||||
|
.expect('Content-Type', /json/) |
||||
|
.expect(200) |
||||
|
|
||||
|
expect(res.body.message).toEqual("Workflow created successfully"); |
||||
|
expect(res.body.workflow.name).toEqual("My Workflow"); |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
describe("fetch", () => { |
||||
|
it("return all the workflows for an instance", async () => { |
||||
|
await createWorkflow(); |
||||
|
const res = await request |
||||
|
.get(`/api/${instance._id}/workflows`) |
||||
|
.set(defaultHeaders) |
||||
|
.expect('Content-Type', /json/) |
||||
|
.expect(200) |
||||
|
|
||||
|
expect(res.body[0]).toEqual(expect.objectContaining(TEST_WORKFLOW)); |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
describe("find", () => { |
||||
|
it("returns a workflow when queried by ID", async () => { |
||||
|
await createWorkflow(); |
||||
|
const res = await request |
||||
|
.get(`/api/${instance._id}/workflows/${workflow.id}`) |
||||
|
.set(defaultHeaders) |
||||
|
.expect('Content-Type', /json/) |
||||
|
.expect(200) |
||||
|
|
||||
|
expect(res.body).toEqual(expect.objectContaining(TEST_WORKFLOW)); |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
describe("destroy", () => { |
||||
|
it("deletes a workflow by its ID", async () => { |
||||
|
await createWorkflow(); |
||||
|
const res = await request |
||||
|
.delete(`/api/${instance._id}/workflows/${workflow.id}/${workflow.rev}`) |
||||
|
.set(defaultHeaders) |
||||
|
.expect('Content-Type', /json/) |
||||
|
.expect(200) |
||||
|
|
||||
|
expect(res.body.id).toEqual(TEST_WORKFLOW._id); |
||||
|
}) |
||||
|
}) |
||||
|
}); |
||||
@ -0,0 +1,13 @@ |
|||||
|
const Router = require("@koa/router") |
||||
|
const controller = require("../controllers/workflow") |
||||
|
|
||||
|
const router = Router() |
||||
|
|
||||
|
router |
||||
|
.get("/api/:instanceId/workflows", controller.fetch) |
||||
|
.get("/api/:instanceId/workflows/:id", controller.find) |
||||
|
.post("/api/:instanceId/workflows", controller.create) |
||||
|
.put("/api/:instanceId/workflows/:id", controller.update) |
||||
|
.delete("/api/:instanceId/workflows/:id/:rev", controller.destroy) |
||||
|
|
||||
|
module.exports = router |
||||
@ -0,0 +1,38 @@ |
|||||
|
const WORKFLOW_SCHEMA = { |
||||
|
properties: { |
||||
|
type: "workflow", |
||||
|
pageId: { |
||||
|
type: "string" |
||||
|
}, |
||||
|
screenId: { |
||||
|
type: "string" |
||||
|
}, |
||||
|
live: { |
||||
|
type: "boolean" |
||||
|
}, |
||||
|
uiTree: { |
||||
|
type: "object" |
||||
|
}, |
||||
|
definition: { |
||||
|
type: "object", |
||||
|
properties: { |
||||
|
triggers: { type: "array" }, |
||||
|
next: { |
||||
|
type: "object", |
||||
|
properties: { |
||||
|
type: { type: "string" }, |
||||
|
actionId: { type: "string" }, |
||||
|
args: { type: "object" }, |
||||
|
conditions: { type: "array" }, |
||||
|
errorHandling: { type: "object" }, |
||||
|
next: { type: "object" } |
||||
|
} |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
module.exports = { |
||||
|
WORKFLOW_SCHEMA |
||||
|
}; |
||||
Loading…
Reference in new issue