const usageQuotaMiddleware = require("../usageQuota") const usageQuota = require("../../utilities/usageQuota") const CouchDB = require("../../db") const env = require("../../environment") jest.mock("../../db") jest.mock("../../utilities/usageQuota") jest.mock("../../environment", () => ({ isTest: () => true, isProd: () => false, isDev: () => true, _set: () => {}, })) class TestConfiguration { constructor() { this.throw = jest.fn() this.next = jest.fn() this.middleware = usageQuotaMiddleware this.ctx = { throw: this.throw, next: this.next, appId: "test", request: { body: {} }, req: { method: "POST", url: "/rows" } } } executeMiddleware() { return this.middleware(this.ctx, this.next) } setProd(bool) { if (bool) { env.isDev = () => false env.isProd = () => true this.ctx.auth = { apiKey: "test" } } else { env.isDev = () => true env.isProd = () => false } } setMethod(method) { this.ctx.req.method = method } setUrl(url) { this.ctx.req.url = url } setBody(body) { this.ctx.request.body = body } setFiles(files) { this.ctx.request.files = { file: files } } } describe("usageQuota middleware", () => { let config beforeEach(() => { config = new TestConfiguration() }) it("skips the middleware if there is no usage property or method", async () => { await config.executeMiddleware() expect(config.next).toHaveBeenCalled() }) it("passes through to next middleware if document already exists", async () => { config.setProd(true) config.setBody({ _id: "test", _rev: "test", }) CouchDB.mockImplementationOnce(() => ({ get: async () => true })) await config.executeMiddleware() expect(config.next).toHaveBeenCalled() }) it("throws if request has _id, but the document no longer exists", async () => { config.setBody({ _id: "123", _rev: "test", }) config.setProd(true) CouchDB.mockImplementationOnce(() => ({ get: async () => { throw new Error() } })) await config.executeMiddleware() expect(config.throw).toHaveBeenCalledWith(404, `${config.ctx.request.body._id} does not exist`) }) it("calculates and persists the correct usage quota for the relevant action", async () => { config.setUrl("/rows") config.setProd(true) await config.executeMiddleware() expect(usageQuota.update).toHaveBeenCalledWith("test", "rows", 1) expect(config.next).toHaveBeenCalled() }) it("calculates the correct file size from a file upload call and adds it to quota", async () => { config.setUrl("/upload") config.setProd(true) config.setFiles([ { size: 100 }, { size: 10000 }, ]) await config.executeMiddleware() expect(usageQuota.update).toHaveBeenCalledWith("test", "storage", 10100) expect(config.next).toHaveBeenCalled() }) })