workflow CRUD complete

This commit is contained in:
Martin McKeaveney 2020-05-20 17:02:46 +01:00
parent f069c3eb4b
commit 39c894c459
8 changed files with 244 additions and 10 deletions

View File

@ -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",

View File

@ -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)
}

View File

@ -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())

View File

@ -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
}

View File

@ -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);
}

View File

@ -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);
})
})
});

View File

@ -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

View File

@ -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
};