workflow CRUD complete
This commit is contained in:
parent
f069c3eb4b
commit
39c894c459
|
@ -24,7 +24,7 @@
|
|||
},
|
||||
"scripts": {
|
||||
"test": "jest routes --runInBand",
|
||||
"test:integration": "jest routes --runInBand",
|
||||
"test:integration": "jest workflow --runInBand",
|
||||
"test:watch": "jest -w",
|
||||
"initialise": "node ../cli/bin/budi init -b local -q",
|
||||
"budi": "node ../cli/bin/budi",
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -15,6 +15,7 @@ const {
|
|||
viewRoutes,
|
||||
staticRoutes,
|
||||
componentRoutes,
|
||||
workflowRoutes
|
||||
} = require("./routes")
|
||||
|
||||
const router = new Router()
|
||||
|
@ -75,6 +76,9 @@ router.use(recordRoutes.allowedMethods())
|
|||
|
||||
router.use(instanceRoutes.routes())
|
||||
router.use(instanceRoutes.allowedMethods())
|
||||
|
||||
router.use(workflowRoutes.routes())
|
||||
router.use(workflowRoutes.allowedMethods())
|
||||
// end auth routes
|
||||
|
||||
router.use(pageRoutes.routes())
|
||||
|
|
|
@ -9,6 +9,7 @@ const modelRoutes = require("./model")
|
|||
const viewRoutes = require("./view")
|
||||
const staticRoutes = require("./static")
|
||||
const componentRoutes = require("./component")
|
||||
const workflowRoutes = require("./workflow");
|
||||
|
||||
module.exports = {
|
||||
authRoutes,
|
||||
|
@ -22,4 +23,5 @@ module.exports = {
|
|||
viewRoutes,
|
||||
staticRoutes,
|
||||
componentRoutes,
|
||||
workflowRoutes
|
||||
}
|
||||
|
|
|
@ -76,14 +76,9 @@ exports.createUser = async (
|
|||
|
||||
exports.insertDocument = async (databaseId, document) => {
|
||||
const { id, ...documentFields } = document
|
||||
await new CouchDB(databaseId).put({ _id: id, ...documentFields })
|
||||
return await new CouchDB(databaseId).put({ _id: id, ...documentFields })
|
||||
}
|
||||
|
||||
exports.createSchema = async (request, instanceId, schema) => {
|
||||
for (let model of schema.models) {
|
||||
await request.post(`/api/${instanceId}/models`).send(model)
|
||||
}
|
||||
for (let view of schema.views) {
|
||||
await request.post(`/api/${instanceId}/views`).send(view)
|
||||
}
|
||||
}
|
||||
exports.destroyDocument = async (databaseId, documentId) => {
|
||||
return await new CouchDB(databaseId).destroy(documentId);
|
||||
}
|
|
@ -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