diff --git a/packages/server/src/api/controllers/record.js b/packages/server/src/api/controllers/record.js index 4685079f68..296f40e326 100644 --- a/packages/server/src/api/controllers/record.js +++ b/packages/server/src/api/controllers/record.js @@ -2,6 +2,40 @@ const CouchDB = require("../../db") const validateJs = require("validate.js") const newid = require("../../db/newid") +exports.patch = async function(ctx) { + const db = new CouchDB(ctx.user.instanceId) + const record = await db.get(ctx.params._id) + const model = await db.get(record.modelId) + const patchfields = ctx.request.body + + for (let key in patchfields) { + if (!model.schema[key]) continue + record[key] = patchfields[key] + } + + const validateResult = await validate({ + record, + model, + }) + + if (!validateResult.valid) { + ctx.status = 400 + ctx.body = { + status: 400, + errors: validateResult.errors, + } + return + } + + const response = await db.put(record) + record._rev = response.rev + record.type = "record" + ctx.body = record + ctx.status = 200 + ctx.message = `${model.name} updated successfully.` + return +} + exports.save = async function(ctx) { const db = new CouchDB(ctx.user.instanceId) const record = ctx.request.body diff --git a/packages/server/src/api/routes/record.js b/packages/server/src/api/routes/record.js index deba513aa9..15fbe29503 100644 --- a/packages/server/src/api/routes/record.js +++ b/packages/server/src/api/routes/record.js @@ -22,6 +22,11 @@ router authorized(WRITE_MODEL, ctx => ctx.params.modelId), recordController.save ) + .patch( + "/api/:modelId/records/:id", + authorized(WRITE_MODEL, ctx => ctx.params.modelId), + recordController.save + ) .post( "/api/:modelId/records/validate", authorized(WRITE_MODEL, ctx => ctx.params.modelId), diff --git a/packages/server/src/api/routes/tests/couchTestUtils.js b/packages/server/src/api/routes/tests/couchTestUtils.js index 594c4a3121..513e1d3f03 100644 --- a/packages/server/src/api/routes/tests/couchTestUtils.js +++ b/packages/server/src/api/routes/tests/couchTestUtils.js @@ -50,6 +50,12 @@ exports.createModel = async (request, appId, instanceId, model) => { constraints: { type: "string", }, + description: { + type: "text", + constraints: { + type: "string", + }, + }, }, }, } @@ -61,18 +67,6 @@ exports.createModel = async (request, appId, instanceId, model) => { return res.body } -exports.createView = async (request, appId, instanceId, view) => { - view = view || { - map: "function(doc) { emit(doc[doc.key], doc._id); } ", - } - - const res = await request - .post(`/api/views`) - .set(exports.defaultHeaders(appId, instanceId)) - .send(view) - return res.body -} - exports.createClientDatabase = async id => await create(id || TEST_CLIENT_ID) exports.createApplication = async (request, name = "test_application") => { diff --git a/packages/server/src/api/routes/tests/record.spec.js b/packages/server/src/api/routes/tests/record.spec.js index 62cf205b1c..68e9f8758f 100644 --- a/packages/server/src/api/routes/tests/record.spec.js +++ b/packages/server/src/api/routes/tests/record.spec.js @@ -30,20 +30,30 @@ describe("/records", () => { model = await createModel(request, app._id, instance._id) record = { name: "Test Contact", + description: "original description", status: "new", modelId: model._id } }) + const createRecord = async r => + await request + .post(`/api/${model._id}/records`) + .send(r || record) + .set(defaultHeaders(app._id, instance._id)) + .expect('Content-Type', /json/) + .expect(200) + + const loadRecord = async id => + await request + .get(`/api/${model._id}/records/${id}`) + .set(defaultHeaders(app._id, instance._id)) + .expect('Content-Type', /json/) + .expect(200) + + describe("save, load, update, delete", () => { - const createRecord = async r => - await request - .post(`/api/${model._id}/records`) - .send(r || record) - .set(defaultHeaders(app._id, instance._id)) - .expect('Content-Type', /json/) - .expect(200) it("returns a success message when the record is created", async () => { const res = await createRecord() @@ -144,6 +154,35 @@ describe("/records", () => { }) }) + describe("patch", () => { + it("should update only the fields that are supplied", async () => { + const rec = await createRecord() + const existing = rec.body + + const res = await request + .patch(`/api/${model._id}/records/${rec._id}`) + .send({ + _id: existing._id, + _rev: existing._rev, + modelId: model._id, + name: "Updated Name", + }) + .set(defaultHeaders(app._id, instance._id)) + .expect('Content-Type', /json/) + .expect(200) + + expect(res.res.statusMessage).toEqual(`${model.name} updated successfully.`) + expect(res.body.name).toEqual("Updated Name") + expect(res.body.description).toEqual(rec.description) + + const savedRecord = await loadRecord(res.body._id) + + expect(savedRecord.body.description).toEqual(rec.description) + expect(savedRecord.body.name).toEqual("Updated Name") + + }) + }) + describe("validate", () => { it("should return no errors on valid record", async () => { const result = await request