UNPKG

@webda/core

Version:

Expose API with Lambda

328 lines 14.2 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { suite, test } from "@testdeck/mocha"; import * as assert from "assert"; import { existsSync } from "fs"; import sinon from "sinon"; import { Ident, MemoryStore, User, WebdaError } from "../index.js"; import { HttpContext } from "../utils/httpcontext.js"; import { FileUtils } from "../utils/serializers.js"; import { StoreNotFoundError } from "./store.js"; import { PermissionModel, StoreTest } from "./store.spec.js"; import { WebdaQL } from "./webdaql/query.js"; let MemoryStoreTest = class MemoryStoreTest extends StoreTest { async before() { this.cleanFiles.push(".test.json"); return super.before(); } getIdentStore() { // Need to slow down the _get let store = this.getService("MemoryIdents"); // @ts-ignore let original = store._get.bind(store); // @ts-ignore store._get = async (...args) => { await this.sleep(1); return original(...args); }; return store; } getUserStore() { return this.getService("MemoryUsers"); } async getIndex() { return this.getService("MemoryAggregators").get("index"); } async recreateIndex() { let store = this.getService("MemoryAggregators"); await store.__clean(); await this.getService("MemoryIdentsIndexer").createAggregate(); } async deleteAsyncHttp() { let executor, ctx; ctx = await this.webda.newWebContext(new HttpContext("test.webda.io", "GET", "/memory/idents/ToDelete")); let identStore = this.getIdentStore(); await identStore.save({ uuid: "toDelete", test: "ok" }); await identStore.delete("toDelete"); executor = this.getExecutor(ctx, "test.webda.io", "GET", "/memory/idents/toDelete"); assert.notStrictEqual(executor, undefined); await assert.rejects(() => executor.execute(ctx), WebdaError.NotFound); executor = this.getExecutor(ctx, "test.webda.io", "PUT", "/memory/idents/toDelete"); assert.notStrictEqual(executor, undefined); await assert.rejects(() => executor.execute(ctx), WebdaError.NotFound); executor = this.getExecutor(ctx, "test.webda.io", "DELETE", "/memory/idents/toDelete"); assert.notStrictEqual(executor, undefined); await assert.rejects(() => executor.execute(ctx), WebdaError.NotFound); assert.strictEqual(identStore._getSync("notFound"), null); } async queryAdditional() { let userStore = await this.fillForQuery(); // Verify permission issue and half pagination userStore.setModel(PermissionModel); userStore.getParameters().forceModel = true; // Return undefined as filter to trigger the warning let find = userStore.find; userStore.find = async (query) => { let res = await find.bind(userStore)({ filter: new WebdaQL.AndExpression([]), continuationToken: query.continuationToken, limit: query.limit }); return { ...res, filter: undefined }; }; let context = await this.newContext(); // Verify pagination system let res, offset; let total = 0; do { res = await userStore.query(`state = 'CA' LIMIT 100 ${offset ? 'OFFSET "' + offset + '"' : ""}`, context); offset = res.continuationToken; total += res.results.length; } while (offset); assert.strictEqual(total, 100); assert.rejects(() => userStore.queryAll("state = 'CA' OFFSET 123"), /Cannot contain an OFFSET for queryAll method/); assert.strictEqual((await userStore.queryAll("state = 'CA' LIMIT 50")).length, 250); return userStore; } initRoutes() { // cov let identStore = this.getIdentStore(); identStore.getParameters().expose = undefined; identStore.initRoutes(); } getSync() { let identStore = this.getIdentStore(); assert.throws(() => identStore._getSync("plop", true), StoreNotFoundError); } async additionalModels() { const subProject = this.webda.getModel("WebdaDemo/SubProject"); const project = this.webda.getModel("WebdaDemo/Project"); let store = new MemoryStore(this.webda, "additionalModel", { model: "WebdaDemo/SubProject" }).resolve(); assert.strictEqual(store.handleModel(project), -1); assert.strictEqual(store.handleModel(subProject), 0); assert.strictEqual(store.handleModel(this.webda.getModel("WebdaDemo/AnotherSubProject")), -1); store = new MemoryStore(this.webda, "additionalModel", { model: "WebdaDemo/SubProject", additionalModels: ["WebdaDemo/Project"] }).resolve(); assert.strictEqual(store.handleModel(project), 0); assert.strictEqual(store.handleModel(subProject), 0); assert.strictEqual(store.handleModel(this.webda.getModel("WebdaDemo/AnotherSubProject")), 1); assert.strictEqual(store.handleModel(this.webda.getModel("WebdaDemo/SubSubProject")), 2); store = new MemoryStore(this.webda, "additionalModel", { model: "WebdaDemo/SubProject", additionalModels: ["WebdaDemo/Project"], strict: true }).resolve(); assert.strictEqual(store.handleModel(project), -1); assert.strictEqual(store.handleModel(subProject), 0); assert.strictEqual(store.handleModel(this.webda.getModel("WebdaDemo/AnotherSubProject")), -1); } async badActions() { let identStore = this.getIdentStore(); // @ts-ignore identStore._model = { getActions: () => { return { test: { global: true } }; } }; await assert.throws(() => identStore.initRoutes(), /Action static method test does not exist/); // @ts-ignore identStore._model = { // @ts-ignore prototype: {}, getActions: () => { return { test: { global: false } }; } }; await assert.throws(() => identStore.initRoutes(), /Action method test does not exist/); } async multiModel() { let identStore = this.getIdentStore(); identStore.getParameters().strict = false; await identStore.save(new User().setUuid("user")); await identStore.save(new Ident().load({ uuid: "ident" }, true)); assert.ok((await identStore.get("user")) instanceof User); assert.ok((await identStore.get("ident")) instanceof Ident); identStore.getParameters().defaultModel = true; identStore.storage["user"] = identStore.storage["user"].replace(/User/, "User2"); assert.ok((await identStore.get("user")).constructor.name === "Ident"); assert.ok((await identStore.get("ident")) instanceof Ident); identStore.getParameters().defaultModel = false; assert.ok((await identStore.get("user")) === undefined); assert.ok((await identStore.get("ident")) instanceof Ident); } async multiModelQuery() { const Teacher = this.webda.getModel("Teacher"); const Project = this.webda.getModel("Project"); const SubProject = this.webda.getModel("SubProject"); const AnotherSubProject = this.webda.getModel("AnotherSubProject"); const SubSubProject = this.webda.getModel("SubSubProject"); await Promise.all([Teacher, Project, SubProject, AnotherSubProject, SubSubProject].map(model => { let p = []; for (let i = 1; i < 4; i++) { p.push(model.create({ name: `${model.name} ${i}` })); } return Promise.all(p); })); assert.strictEqual((await Teacher.query("")).results.length, 3); assert.strictEqual((await Teacher.query("", false)).results.length, 3); assert.strictEqual((await Project.query("")).results.length, 12); assert.strictEqual((await Project.query("", false)).results.length, 3); assert.strictEqual((await AnotherSubProject.query("")).results.length, 6); assert.strictEqual((await AnotherSubProject.query("", false)).results.length, 3); assert.strictEqual((await SubProject.query("")).results.length, 3); assert.strictEqual((await SubProject.query("", false)).results.length, 3); } async migration() { let usersStore = this.getUserStore(); for (let i = 0; i < 1200; i++) { await usersStore.save({ uuid: `id_${i}`, id: i }); if (i % 10 === 0) { usersStore.storage[`id_${i}`] = usersStore.storage[`id_${i}`].replace(/Webda\/User/, "webda/user2"); } else if (i % 2 === 0) { usersStore.storage[`id_${i}`] = usersStore.storage[`id_${i}`].replace(/Webda\/User/, "webdademo/user"); } } await usersStore.v3Migration(); (await usersStore.getAll()).forEach(user => { if (user.id % 10 === 0) { assert.strictEqual(user.__type, "webda/user2"); assert.deepStrictEqual(user.__types, ["webda/user2"]); } else if (user.id % 2 === 0) { assert.strictEqual(user.__type, "WebdaDemo/User"); assert.deepStrictEqual(user.__types, ["User", "Webda/User"]); } else { assert.strictEqual(user.__type, "Webda/User"); assert.deepStrictEqual(user.__types, ["Webda/User"]); } }); usersStore.getParameters().modelAliases = { "webda/user2": "WebdaDemo/User" }; await usersStore.cleanModelAliases(); (await usersStore.getAll()).forEach(user => { if (user.id % 10 === 0) { assert.strictEqual(user.__type, "WebdaDemo/User"); } else if (user.id % 2 === 0) { assert.strictEqual(user.__type, "WebdaDemo/User"); } else { assert.strictEqual(user.__type, "Webda/User"); } }); await usersStore.recomputeTypeShortId(); (await usersStore.getAll()).forEach(user => { if (user.id % 10 === 0) { assert.strictEqual(user.__type, "User"); } else if (user.id % 2 === 0) { assert.strictEqual(user.__type, "User"); } else { assert.strictEqual(user.__type, "Webda/User"); } }); await usersStore.getMigration(`storeMigration.${usersStore.getName()}.typesShortId`); await usersStore.cancelMigration(`storeMigration.${usersStore.getName()}.typesShortId`); await usersStore.migration("test", async () => { return async () => { }; }); } async persistence() { this.cleanFiles.push(".test.json.gz"); let identStore = this.getIdentStore(); identStore.getParameters().persistence = { path: ".test.json.gz", delay: 10, compressionLevel: 9 }; await identStore.init(); // @ts-ignore await identStore.put("test", { label: "\n\n" }); await this.sleep(20); await identStore.persistencePromise; // Check basic persistence assert.ok(existsSync(".test.json.gz")); //assert.notStrictEqual(FileUtils.load(".test.json.gz").test, undefined); identStore.storage = {}; // Check basic load of persistence await identStore.init(); assert.notStrictEqual(identStore.storage.test, undefined); identStore.storage = {}; identStore.getParameters().persistence = { path: ".test.json" }; // Test old format non-encrypted and non-compressed FileUtils.save({ uuid: "test", test: "ok" }, ".test.json"); await identStore.init(); assert.notStrictEqual(identStore.storage.test, undefined); // Check encryption identStore.getParameters().persistence = { path: ".test.json", delay: 0, key: "test", cipher: "aes-256-ctr" }; // Should silently ignore not encrypted file await identStore.init(); await identStore.put("test", {}); await identStore.persist(); identStore.storage = {}; // Check basic load of persistence await identStore.init(); assert.notStrictEqual(identStore.storage.test, undefined); const mock = sinon.stub(identStore, "persist").returns(Promise.resolve()); await identStore.stop(); assert.strictEqual(mock.callCount, 1); } }; __decorate([ test ], MemoryStoreTest.prototype, "deleteAsyncHttp", null); __decorate([ test ], MemoryStoreTest.prototype, "queryAdditional", null); __decorate([ test ], MemoryStoreTest.prototype, "initRoutes", null); __decorate([ test ], MemoryStoreTest.prototype, "getSync", null); __decorate([ test ], MemoryStoreTest.prototype, "additionalModels", null); __decorate([ test ], MemoryStoreTest.prototype, "badActions", null); __decorate([ test ], MemoryStoreTest.prototype, "multiModel", null); __decorate([ test ], MemoryStoreTest.prototype, "multiModelQuery", null); __decorate([ test ], MemoryStoreTest.prototype, "migration", null); __decorate([ test ], MemoryStoreTest.prototype, "persistence", null); MemoryStoreTest = __decorate([ suite ], MemoryStoreTest); export { MemoryStoreTest }; //# sourceMappingURL=memory.spec.js.map