383 lines
16 KiB
JavaScript
383 lines
16 KiB
JavaScript
import {setupApphierarchy, basicAppHierarchyCreator_WithFields,
|
|
getNewFieldAndAdd, stubEventHandler} from "./specHelpers";
|
|
import {events, isNonEmptyString} from "../src/common";
|
|
import { isBoolean } from "util";
|
|
import {permission} from "../src/authApi/permissions";
|
|
import { _getNew } from "../src/recordApi/getNew";
|
|
|
|
describe("recordApi > getNew", () => {
|
|
|
|
it("should get object with generated id and key (full path)", async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
|
|
expect(record.id).toBeDefined();
|
|
expect(isNonEmptyString(record.id)).toBeTruthy();
|
|
|
|
expect(record.key).toBeDefined();
|
|
expect(isNonEmptyString(record.key)).toBeTruthy();
|
|
expect(record.key).toBe(`/customers/${record.id}`);
|
|
});
|
|
|
|
it("should create object with all declared fields, using default values", async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
|
|
const newRecord = recordApi.getNew("/customers", "customer")
|
|
|
|
expect(newRecord.surname).toBe(null);
|
|
expect(newRecord.isalive).toBe(true);
|
|
expect(newRecord.createddate).toBe(null);
|
|
expect(newRecord.age).toBe(null);
|
|
});
|
|
|
|
it("should create object with all declared fields, and use inital values", async () => {
|
|
const {recordApi} = await setupApphierarchy(templateApi => {
|
|
const hierarchy = basicAppHierarchyCreator_WithFields(templateApi);
|
|
const {customerRecord} = hierarchy;
|
|
|
|
customerRecord.fields = [];
|
|
|
|
const newField = getNewFieldAndAdd(templateApi, customerRecord);
|
|
newField("surname", "string", "hello");
|
|
newField("isalive", "bool", "true");
|
|
newField("age", "number", "999");
|
|
|
|
return hierarchy;
|
|
});
|
|
|
|
const newRecord = recordApi.getNew("/customers", "customer")
|
|
|
|
expect(newRecord.surname).toBe("hello");
|
|
expect(newRecord.isalive).toBe(true);
|
|
expect(newRecord.age).toBe(999);
|
|
});
|
|
|
|
it("should add a function 'isNew' which always returns true", async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
|
|
expect(record.isNew).toBeDefined();
|
|
expect(isBoolean(record.isNew)).toBeTruthy();
|
|
expect(record.isNew).toBeTruthy();
|
|
});
|
|
|
|
it("should add a function 'type' returns type", async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
|
|
expect(record.type).toBeDefined();
|
|
expect(isNonEmptyString(record.type)).toBeTruthy();
|
|
expect(record.type).toBe("customer");
|
|
});
|
|
|
|
it("should throw error, user user does not have permission", async () => {
|
|
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
app.removePermission(permission.createRecord.get(appHierarchy.customerRecord.nodeKey()));
|
|
expect(() => recordApi.getNew("/customers", "customer")).toThrow(/Unauthorized/);
|
|
});
|
|
|
|
it("should not depend on having any other permissions", async () => {
|
|
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
app.withOnlyThisPermission(permission.createRecord.get(appHierarchy.customerRecord.nodeKey()));
|
|
recordApi.getNew("/customers", "customer");
|
|
});
|
|
|
|
it("for 'single record' type, should create with key ending in node name", async () => {
|
|
const {appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const {settingsRecord} = appHierarchy;
|
|
const result = _getNew(settingsRecord, "");
|
|
expect(result.key).toBe("/settings")
|
|
})
|
|
});
|
|
|
|
describe('recordApi > save then load', () => {
|
|
|
|
it('should save all field values on create new record', async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
|
|
record.surname = "Ledog";
|
|
record.isalive = true;
|
|
record.age = 9;
|
|
record.createddate = new Date();
|
|
|
|
await recordApi.save(record);
|
|
|
|
const saved = await recordApi.load(record.key);
|
|
|
|
expect(saved.surname).toBe(record.surname);
|
|
expect(saved.isalive).toBe(record.isalive);
|
|
expect(saved.age).toBe(record.age);
|
|
expect(saved.createddate).toEqual(record.createddate);
|
|
|
|
});
|
|
|
|
it('should create values for fields when undefined', async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
|
|
record.age = 9;
|
|
record.createddate = new Date();
|
|
|
|
await recordApi.save(record);
|
|
|
|
const saved = await recordApi.load(record.key);
|
|
|
|
expect(saved.surname).toBe(null);
|
|
expect(saved.isalive).toBe(true);
|
|
expect(saved.age).toBe(record.age);
|
|
expect(saved.createddate).toEqual(record.createddate);
|
|
|
|
});
|
|
|
|
it('loaded record isNew() always return false', async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
|
|
record.age = 9;
|
|
record.createddate = new Date();
|
|
|
|
await recordApi.save(record);
|
|
|
|
const saved = await recordApi.load(record.key);
|
|
|
|
expect(saved.isNew).toBeDefined();
|
|
expect(saved.isNew).toBe(false);
|
|
});
|
|
|
|
it('loaded record id() and key() should work', async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
|
|
record.age = 9;
|
|
record.createddate = new Date();
|
|
|
|
await recordApi.save(record);
|
|
|
|
const saved = await recordApi.load(record.key);
|
|
|
|
expect(saved.id).toBeDefined();
|
|
expect(saved.id).toBe(record.id);
|
|
|
|
expect(saved.key).toBeDefined();
|
|
expect(saved.key).toBe(saved.key);
|
|
});
|
|
|
|
|
|
it('loaded record type() should be a function', async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
|
|
record.age = 9;
|
|
record.createddate = new Date();
|
|
|
|
await recordApi.save(record);
|
|
|
|
const saved = await recordApi.load(record.key);
|
|
|
|
expect(isNonEmptyString(saved.type)).toBeTruthy()
|
|
expect(saved.type).toBe("customer");
|
|
});
|
|
|
|
it('update existing should update field', async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
|
|
record.surname = "Ledog";
|
|
record.isalive = true;
|
|
record.age = 9;
|
|
record.createddate = new Date();
|
|
|
|
await recordApi.save(record);
|
|
|
|
const saved = await recordApi.load(record.key);
|
|
|
|
saved.surname = "Zeedog";
|
|
await recordApi.save(saved);
|
|
const savedAgain = await recordApi.load(saved.key);
|
|
expect(savedAgain.surname).toBe(saved.surname);
|
|
});
|
|
|
|
it("should maintain referential integrity", async () => {
|
|
const {recordApi} =
|
|
await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
|
|
const referredByCustomer = recordApi.getNew("/customers", "customer");
|
|
referredByCustomer.surname = "Ledog";
|
|
referredByCustomer.age = 9;
|
|
referredByCustomer.isalive = true,
|
|
referredByCustomer.createdDate = new Date();
|
|
const savedReferredBy = await recordApi.save(referredByCustomer);
|
|
|
|
const referredCustomer = recordApi.getNew("/customers", "customer");
|
|
referredCustomer.surname = "Zeecat";
|
|
referredCustomer.age = 9;
|
|
referredCustomer.isalive = true,
|
|
referredCustomer.createdDate = new Date();
|
|
referredCustomer.referredBy = referredByCustomer;
|
|
await recordApi.save(referredCustomer);
|
|
|
|
savedReferredBy.surname = "Zeedog";
|
|
await recordApi.save(savedReferredBy);
|
|
|
|
const loadedReferredTo = await recordApi.load(referredCustomer.key);
|
|
expect(loadedReferredTo.referredBy.surname).toBe("Zeedog");
|
|
});
|
|
});
|
|
|
|
describe("save", () => {
|
|
|
|
it("IsNew() should return false after save", async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
record.surname = "Ledog";
|
|
|
|
const savedRecord = await recordApi.save(record);
|
|
expect(savedRecord.isNew).toBe(false);
|
|
});
|
|
|
|
it("should publish onbegin and oncomplete events", async () => {
|
|
const {recordApi, subscribe} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const handler = stubEventHandler();
|
|
subscribe(events.recordApi.save.onBegin, handler.handle);
|
|
subscribe(events.recordApi.save.onComplete, handler.handle);
|
|
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
record.surname = "Ledog";
|
|
|
|
await recordApi.save(record);
|
|
|
|
const onBegin = handler.getEvents(events.recordApi.save.onBegin);
|
|
const onComplete = handler.getEvents(events.recordApi.save.onComplete);
|
|
expect(onBegin.length).toBe(1);
|
|
expect(onComplete.length).toBe(1);
|
|
expect(onBegin[0].context.record).toBeDefined();
|
|
expect(onBegin[0].context.record.key).toBe(record.key);
|
|
expect(onComplete[0].context.record).toBeDefined();
|
|
expect(onComplete[0].context.record.key).toBe(record.key);
|
|
|
|
});
|
|
|
|
it("should publish create on create and update on update", async () => {
|
|
const {recordApi, subscribe} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const handler = stubEventHandler();
|
|
subscribe(events.recordApi.save.onRecordCreated, handler.handle);
|
|
subscribe(events.recordApi.save.onRecordUpdated, handler.handle);
|
|
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
record.surname = "Ledog";
|
|
|
|
const savedRecord =await recordApi.save(record);
|
|
const onCreate = handler.getEvents(events.recordApi.save.onRecordCreated);
|
|
expect(onCreate.length).toBe(1);
|
|
expect(onCreate[0].context.record).toBeDefined();
|
|
expect(onCreate[0].context.record.key).toBe(record.key);
|
|
|
|
savedRecord.surname = "Zeecat";
|
|
await recordApi.save(savedRecord);
|
|
|
|
const onUpdate = handler.getEvents(events.recordApi.save.onRecordUpdated);
|
|
expect(onUpdate.length).toBe(1);
|
|
expect(onUpdate[0].context.old).toBeDefined();
|
|
expect(onUpdate[0].context.old.key).toBe(record.key);
|
|
expect(onUpdate[0].context.old.surname).toBe("Ledog");
|
|
expect(onUpdate[0].context.new).toBeDefined();
|
|
expect(onUpdate[0].context.new.key).toBe(record.key);
|
|
expect(onUpdate[0].context.new.surname).toBe("Zeecat");
|
|
|
|
});
|
|
|
|
it("should create folder and index for subcollection", async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
record.surname = "Ledog";
|
|
|
|
const savedRecord = await recordApi.save(record);
|
|
expect(await recordApi._storeHandle.exists(`${record.key}/invoice_index/index.csv`)).toBeTruthy()
|
|
expect(await recordApi._storeHandle.exists(`${record.key}/invoice_index`)).toBeTruthy()
|
|
expect(await recordApi._storeHandle.exists(`${record.key}/invoices`)).toBeTruthy()
|
|
});
|
|
|
|
it("should create index folder and shardMap for sharded reverse reference index", async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
record.surname = "Ledog";
|
|
|
|
await recordApi.save(record);
|
|
expect(await recordApi._storeHandle.exists(`${record.key}/referredToCustomers/shardMap.json`)).toBeTruthy();
|
|
expect(await recordApi._storeHandle.exists(`${record.key}/referredToCustomers`)).toBeTruthy();
|
|
});
|
|
|
|
it("should create folder for record", async () => {
|
|
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
record.surname = "Ledog";
|
|
|
|
const savedRecord = await recordApi.save(record);
|
|
expect(await recordApi._storeHandle.exists(`${record.key}`)).toBeTruthy();
|
|
expect(await recordApi._storeHandle.exists(`${record.key}/record.json`)).toBeTruthy();
|
|
});
|
|
|
|
it("should create allids file", async () => {
|
|
const {recordApi, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
record.surname = "Ledog";
|
|
|
|
await recordApi.save(record);
|
|
|
|
const allIdsPath = `/customers/allids/${appHierarchy.customerRecord.nodeId}/${record.id[2]}`;
|
|
expect(await recordApi._storeHandle.exists(allIdsPath)).toBeTruthy();
|
|
|
|
});
|
|
|
|
it("create should throw error, user user does not have permission", async () => {
|
|
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
app.removePermission(permission.createRecord.get(appHierarchy.customerRecord.nodeKey()));
|
|
expect(recordApi.save(record)).rejects.toThrow(/Unauthorized/);
|
|
});
|
|
|
|
it("create should not depend on having any other permissions", async () => {
|
|
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
app.withOnlyThisPermission(permission.createRecord.get(appHierarchy.customerRecord.nodeKey()));
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
await recordApi.save(record);
|
|
});
|
|
|
|
it("update should throw error, user user does not have permission", async () => {
|
|
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
app.removePermission(permission.updateRecord.get(appHierarchy.customerRecord.nodeKey()));
|
|
const created = await recordApi.save(record);
|
|
expect(recordApi.save(created)).rejects.toThrow(/Unauthorized/);
|
|
});
|
|
|
|
it("update should not depend on having any other permissions", async () => {
|
|
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
const saved = await recordApi.save(record);
|
|
app.withOnlyThisPermission(permission.updateRecord.get(appHierarchy.customerRecord.nodeKey()));
|
|
await recordApi.save(saved);
|
|
});
|
|
})
|
|
|
|
describe("recordApi > load", () => {
|
|
|
|
it("should throw error when user user does not have permission", async () => {
|
|
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
const created = await recordApi.save(record);
|
|
app.removePermission(permission.readRecord.get(appHierarchy.customerRecord.nodeKey()));
|
|
expect(recordApi.load(created.key)).rejects.toThrow(/Unauthorized/);
|
|
});
|
|
|
|
it("should not depend on having any other permissions", async () => {
|
|
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
|
const record = recordApi.getNew("/customers", "customer");
|
|
const saved = await recordApi.save(record);
|
|
app.withOnlyThisPermission(permission.readRecord.get(appHierarchy.customerRecord.nodeKey()));
|
|
await recordApi.load(saved.key);
|
|
});
|
|
|
|
});
|