@webda/core
Version:
Expose API with Lambda
328 lines • 14.2 kB
JavaScript
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