diff --git a/packages/server/middleware/controllers/view.js b/packages/server/middleware/controllers/view.js index ada3fb384c..4edc92745b 100644 --- a/packages/server/middleware/controllers/view.js +++ b/packages/server/middleware/controllers/view.js @@ -2,13 +2,26 @@ const couchdb = require("../../db"); const controller = { fetch: async ctx => { - const database = couchdb.db.use(ctx.params.databaseId); - ctx.body = await database.list({ include_docs: true }); + const db = couchdb.db.use(ctx.params.instanceId); + const designDoc = await db.get("_design/database"); + ctx.body = designDoc.views; }, create: async ctx => { - const clientDb = couchdb.db.use(ctx.params.clientId); - clientDb.insert(); - ctx.body = await database.insert(ctx.request.body); + const db = couchdb.db.use(ctx.params.instanceId); + const { name, ...viewDefinition } = ctx.request.body; + + const designDoc = await db.get("_design/database"); + designDoc.views = { + ...designDoc.views, + [name]: viewDefinition + }; + const newView = await db.insert(designDoc, designDoc._id); + + ctx.body = { + ...newView, + message: `View ${name} created successfully.`, + status: 200, + } }, destroy: async ctx => { const database = couchdb.db.use(ctx.params.databaseId); diff --git a/packages/server/middleware/routers.js b/packages/server/middleware/routers.js index 88bff2133e..4f640ff549 100644 --- a/packages/server/middleware/routers.js +++ b/packages/server/middleware/routers.js @@ -21,6 +21,7 @@ const neoUserRoutes = require("./routes/neo/user"); const clientRoutes = require("./routes/neo/client"); const applicationRoutes = require("./routes/neo/application"); const modelsRoutes = require("./routes/neo/model"); +const viewsRoutes = require("./routes/neo/view"); const builderPath = resolve(__dirname, "../builder") @@ -134,6 +135,9 @@ module.exports = (config, app) => { } }); + router.use(viewsRoutes.routes()); + router.use(viewsRoutes.allowedMethods()); + router.use(modelsRoutes.routes()); router.use(modelsRoutes.allowedMethods()); diff --git a/packages/server/middleware/routes/neo/tests/__snapshots__/view.spec.js.snap b/packages/server/middleware/routes/neo/tests/__snapshots__/view.spec.js.snap new file mode 100644 index 0000000000..60a0a6cfcd --- /dev/null +++ b/packages/server/middleware/routes/neo/tests/__snapshots__/view.spec.js.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`/views fetch returns a list of all the views that exist in the instance database 1`] = ` +Object { + "by_type": Object { + "map": "function (doc) { + emit([doc.type], doc._id); + }", + }, +} +`; diff --git a/packages/server/middleware/routes/neo/tests/application.spec.js b/packages/server/middleware/routes/neo/tests/application.spec.js index 015436d2a3..f08637c530 100644 --- a/packages/server/middleware/routes/neo/tests/application.spec.js +++ b/packages/server/middleware/routes/neo/tests/application.spec.js @@ -8,20 +8,21 @@ const CLIENT_DB_ID = "client-testing"; describe("/applications", () => { let request; + let server; beforeAll(async () => { - const server = await app({ + server = await app({ config: { port: 3000 } }); request = supertest(server); - createClientDatabase(); + await createClientDatabase(); }); afterAll(async () => { await couchdb.db.destroy(CLIENT_DB_ID) - app.close(); + server.close(); }) describe("create", () => { diff --git a/packages/server/middleware/routes/neo/tests/view.spec.js b/packages/server/middleware/routes/neo/tests/view.spec.js new file mode 100644 index 0000000000..8e6f8ed473 --- /dev/null +++ b/packages/server/middleware/routes/neo/tests/view.spec.js @@ -0,0 +1,80 @@ +const supertest = require("supertest"); +const app = require("../../../../app"); +const { createInstanceDatabase, createModel, destroyDatabase } = require("./couchTestUtils"); + + +const TEST_INSTANCE_ID = "testing-123"; + +describe("/views", () => { + let request; + let server; + + beforeAll(async () => { + server = await app({ + config: { + port: 3000 + } + }); + request = supertest(server); + }); + + afterAll(async () => { + server.close(); + }) + + describe("create", () => { + beforeEach(async () => { + await createInstanceDatabase(TEST_INSTANCE_ID); + }); + + afterEach(async () => { + await destroyDatabase(TEST_INSTANCE_ID); + }); + + it("returns a success message when the view is successfully created", done => { + request + .post(`/api/${TEST_INSTANCE_ID}/views`) + .send({ + name: "TestView", + map: `function(doc) { + if (doc.id) { + emit(doc.name, doc._id); + } + }`, + reduce: `function(keys, values) { }` + }) + .set("Accept", "application/json") + .expect('Content-Type', /json/) + .expect(200) + .end(async (err, res) => { + expect(res.body.message).toEqual("View TestView created successfully."); + expect(res.body.id).toEqual("_design/database"); + done(); + }); + }) + }); + + describe("fetch", () => { + beforeEach(async () => { + await createInstanceDatabase(TEST_INSTANCE_ID); + await createModel(TEST_INSTANCE_ID); + }); + + afterEach(async () => { + await destroyDatabase(TEST_INSTANCE_ID); + }); + + it("returns a list of all the views that exist in the instance database", done => { + request + .get(`/api/${TEST_INSTANCE_ID}/views`) + .set("Accept", "application/json") + .expect('Content-Type', /json/) + .expect(200) + .end(async (_, res) => { + expect(res.body.by_type).toBeDefined(); + expect(res.body).toMatchSnapshot(); + done(); + }); + }) + }); +}); diff --git a/packages/server/middleware/routes/neo/view.js b/packages/server/middleware/routes/neo/view.js index 15e7911f1b..22fdcee518 100644 --- a/packages/server/middleware/routes/neo/view.js +++ b/packages/server/middleware/routes/neo/view.js @@ -4,8 +4,8 @@ const controller = require("../../controllers/view"); const router = Router(); router - .get("/api/:databaseId/views", controller.fetch) - .post("/api/:databaseId/views", controller.create) - .patch("/api/:databaseId/views", controller.update); + .get("/api/:instanceId/views", controller.fetch) + .post("/api/:instanceId/views", controller.create); + // .patch("/api/:databaseId/views", controller.update); module.exports = router; \ No newline at end of file