@noggin/elastic-noggin-sdk
Version:
Elastic Noggin SDK
671 lines (524 loc) • 20.6 kB
text/typescript
import { EnoFactory } from "./EnoFactory";
import dataConstants from "./constants";
import { IEno } from "./models/types";
describe("Basic functionality - EnoFactory", () => {
const testFactory = new EnoFactory();
beforeEach(() => {
testFactory.reset();
});
it("should create an eno", () => {
testFactory
.setType("type")
.setSecurity("security")
.setFields([
{ tip: "field tip1", value: ["field value1"] },
{ tip: "field tip2", value: ["field value2"] },
]);
const microEno = testFactory.makeEno();
expect(microEno.source.type).toBe("type");
expect(microEno.source.security).toBe("security");
expect(microEno.tip).toBe(microEno.sid);
expect(microEno.clientT.branch).toBe(dataConstants.BRANCH_MASTER);
expect(microEno.clientT.sequence).toBe(1);
expect(microEno.source.field[0].tip).toBe("field tip1");
expect(microEno.source.field[0].value).toEqual(["field value1"]);
expect(microEno.source.field[1].tip).toBe("field tip2");
expect(microEno.source.field[1].value).toEqual(["field value2"]);
});
it("should correctly calculate the sid", () => {
testFactory
.setType("type")
.setSecurity("security")
.useEmptyNonce()
.setFields([
{ tip: "field tip1", value: ["field value1"] },
{ tip: "field tip2", value: ["field value2"] },
]);
const eno = testFactory.makeEno();
expect(eno.tip).toBe(eno.sid);
expect(eno.tip).toBe(
"cc25fab5d2732cbdfc3dbbdcf3c7c45e005cba4fc7b6a6ae10ebe95b2a7c961c"
);
});
it("should create a new eno when the factory is re-used", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({ tip: "tip", value: ["value1"] });
testFactory.setField({ tip: "tip", value: ["value2"] });
const microEno1 = testFactory.makeEno();
const microEno2 = testFactory.makeEno();
expect(microEno1.tip).not.toBe(microEno2.tip);
expect(microEno1.source.nonce).not.toBe(microEno2.source.nonce);
expect(microEno2.clientT.sequence).toBe(1);
});
it("should patch the previously made eno when the factory is re-used if cleanEno is not called", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({ tip: "tip", value: ["value1"] });
testFactory.setField({ tip: "tip", value: ["value2"] });
const microEno1 = testFactory.makeEno();
const microEno1Patched = testFactory.setProtoToPatch(microEno1).makeEno();
expect(microEno1Patched.tip).toBe(microEno1.tip);
expect(microEno1Patched.sid).not.toBe(microEno1.sid);
expect(microEno1Patched.source.parent[0]).toBe(microEno1.sid);
expect(microEno1Patched.source.nonce).not.toBe(microEno1.source.nonce);
expect(microEno1Patched.clientT.sequence).toBe(
microEno1.clientT.sequence + 1
);
});
it("can't set proto to patch from an eno that has source", () => {
expect(() => {
testFactory.setProtoToPatch({ tip: "tip", sid: "sid" });
}).toThrow();
});
it("should patch the previously made eno without clientT", () => {
const patchedEno = testFactory
.setProtoToPatch({
tip: "tip",
sid: "sid",
source: {
deleted: true,
type: "type",
security: "security",
nonce: "",
field: [],
},
})
.makeEno();
expect(patchedEno.clientT.sequence).toBe(1);
});
it("should set a field on the existing field value", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({ tip: "tip", value: ["value1"] });
testFactory.setField({ tip: "tip", value: ["value2"] });
const microEno = testFactory.makeEno();
expect(microEno.source.field[0].tip).toBe("tip");
expect(microEno.source.field[0].value).toEqual(["value2"]);
});
it("should set a field formula on a new field while there are other fields", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField("tip1", ["val1"])
.setFieldFormula("tip2", "ARRAY()");
const microEno = testFactory.makeEno();
expect(microEno.source.field[1].tip).toBe("tip2");
expect(microEno.source.field[1].value).toBeUndefined();
expect(microEno.source.field[1].formula).toEqual(["ARRAY()"]);
});
it("should set a field formula on the existing field", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({ tip: "tip", value: ["value1"] });
testFactory.setFieldFormula("tip", "ARRAY()");
const microEno = testFactory.makeEno();
expect(microEno.source.field[0].tip).toBe("tip");
expect(microEno.source.field[0].value).not.toEqual(["value2"]);
expect(microEno.source.field[0].formula).toEqual(["ARRAY()"]);
});
it("should set a field by tip and value", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField("tip", ["value1"]);
const microEno = testFactory.makeEno();
expect(microEno.source.field[0].tip).toBe("tip");
expect(microEno.source.field[0].value[0]).toBe("value1");
});
it("should set a field by tip and formula", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setFieldFormula("tip", "ARRAY()");
const microEno = testFactory.makeEno();
expect(microEno.source.field[0].tip).toBe("tip");
expect(microEno.source.field[0].formula).toEqual(["ARRAY()"]);
});
it("should filter out undefined or null when setting a field", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({ tip: "tip", value: ["0", null, undefined] });
const microEno = testFactory.makeEno();
expect(microEno.source.field[0].tip).toBe("tip");
expect(microEno.source.field[0].value).toEqual(["0"]);
});
it("should filter out empty value fields", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({ tip: "tip", value: [] });
const microEno = testFactory.makeEno();
expect(microEno.source.field).toEqual([]);
});
it("should normalize the given value", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({ tip: "tip1", value: null })
.setField({ tip: "tip2", value: undefined });
const microEno = testFactory.makeEno();
expect(microEno.source.field).toEqual([]);
});
it("should normalize the given i18n value", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({ tip: "tip1", i18n: [{ lang: "en-us", value: null }] })
.setField({ tip: "tip2", i18n: [{ lang: "en-us", value: undefined }] });
const microEno = testFactory.makeEno();
expect(microEno.source.field).toEqual([]);
});
it("should filter out empty value fields (i18n)", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({
tip: "tip",
i18n: [
{ lang: "en-us", value: [] },
{ lang: "en-gb", value: [] },
],
});
const microEno = testFactory.makeEno();
expect(microEno.source.field).toEqual([]);
});
it("should set a i18n field on a non-existing field tip", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({ tip: "tip1", value: ["val1-1"] });
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setI18nValue("tip2", "en-us", ["val2-1"]);
const microEno = testFactory.makeEno();
expect(microEno.source.field[0]).toEqual({
tip: "tip1",
value: ["val1-1"],
});
expect(microEno.source.field[1]).toEqual({
tip: "tip2",
i18n: [{ lang: "en-us", value: ["val2-1"] }],
});
});
it("should set a i18n field on an existing field tip and existing lang", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setI18nValue("tip", "en-us", ["val1"]);
testFactory.setI18nValue("tip", "en-us", ["val2"]);
const microEno = testFactory.makeEno();
expect(microEno.source.field[0]).toEqual({
tip: "tip",
i18n: [{ lang: "en-us", value: ["val2"] }],
});
});
it("should set a i18n field on an existing field tip and non-existing lang", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setI18nValue("tip", "en-us", ["val1"]);
testFactory.setI18nValue("tip", "en-gb", ["val2"]);
const microEno = testFactory.makeEno();
expect(microEno.source.field[0]).toEqual({
tip: "tip",
i18n: [
{ lang: "en-us", value: ["val1"] },
{ lang: "en-gb", value: ["val2"] },
],
});
});
it(
'#setI18nValue should create "i18n" values and remove legacy "value" values when an i18n value is set and a legacy "value" ' +
"value exists",
() => {
const eno = testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({ tip: "field-1", value: ["value-1"] })
.setI18nValue("field-1", dataConstants.LANG_DEFAULT, ["value-2"])
.makeEno();
expect(eno.source.field[0]).toEqual({
tip: "field-1",
i18n: [{ lang: dataConstants.LANG_DEFAULT, value: ["value-2"] }],
});
}
);
it("#setI18nValue remove the lang entry if [] is passed as value", () => {
const eno = testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setI18nValue("field-1", "zh", ["value-1"])
.setI18nValue("field-1", "fr", ["value-2"])
.setI18nValue("field-1", "fr", [])
.makeEno();
expect(eno.source.field[0]).toEqual({
tip: "field-1",
i18n: [{ lang: "zh", value: ["value-1"] }],
});
});
it("should filter out undefined or null when setting a i18n field", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({
tip: "tip",
i18n: [{ lang: "en-us", value: ["0", null, undefined] }],
});
const microEno = testFactory.makeEno();
expect(microEno.source.field[0].tip).toBe("tip");
expect(microEno.source.field[0].i18n[0].value).toEqual(["0"]);
});
it("should set a field on the existing field value", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.OP)
.setField({ tip: "tip", value: ["value1"] });
testFactory.setField({ tip: "tip", value: ["value2"] });
const microEno = testFactory.makeEno();
expect(microEno.source.field[0].tip).toBe("tip");
expect(microEno.source.field[0].value).toEqual(["value2"]);
});
it("should create an eno with empty nonce on a certain type", () => {
testFactory
.setType("op/query")
.setSecurity(dataConstants.SECURITY.EVERYONE)
.setField({ tip: "tip", value: ["value"] });
const microEno = testFactory.makeEno();
expect(microEno.source.nonce).toBe("");
});
it("should create an eno with empty nonce when told to", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.EVERYONE)
.setField({ tip: "tip", value: ["value"] });
testFactory.useEmptyNonce();
const microEno = testFactory.makeEno();
expect(microEno.source.nonce).toBe("");
});
it("should create an eno with tip nonce when told to", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.EVERYONE)
.setField({ tip: "tip", value: ["value"] });
testFactory.setWellKnownTip("test tip").useTipNonce();
const microEno = testFactory.makeEno();
expect(microEno.source.nonce).toBe("test tip");
});
it("should create an eno with random nonce when told to", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.EVERYONE)
.setField({ tip: "tip", value: ["value"] });
testFactory.useEmptyNonce().useRandomNonce();
const microEno = testFactory.makeEno();
expect(microEno.source.nonce).not.toBe("");
});
it("should normally create an eno with a random nonce", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.EVERYONE)
.setField({ tip: "tip", value: ["value"] });
const microEno = testFactory.makeEno();
expect(microEno.source.nonce).not.toBe("");
});
it("should create an eno with known nonce when told to", () => {
testFactory
.setType("type")
.setSecurity(dataConstants.SECURITY.EVERYONE)
.setField({ tip: "tip", value: ["value"] });
testFactory.setWellKnownTip("test tip").useKnownNonce('my-nonce');
const microEno = testFactory.makeEno();
expect(microEno.source.nonce).toBe("my-nonce");
});
it("should create an eno by cloning an existing eno", () => {
testFactory
.setType("type")
.setSecurity("security")
.setField({ tip: "tip", value: ["value"] });
const microEno = testFactory.makeEno();
testFactory.setProto(microEno);
const clonedEno = testFactory.makeEno();
expect(clonedEno.source.field).toEqual(microEno.source.field);
expect(clonedEno.source.parent).toEqual(microEno.source.parent);
expect(clonedEno.source.type).toBe(microEno.source.type);
expect(clonedEno.source.security).toBe(microEno.source.security);
expect(clonedEno.source.deleted).toBe(microEno.source.deleted);
expect(clonedEno.clientT).not.toBeNull();
});
it("should reset all the fields", () => {
testFactory
.setType("type")
.setSecurity("security")
.setField({ tip: "tip", value: ["value"] });
testFactory.resetFields();
const microEno = testFactory.makeEno();
expect(microEno.source.field).toEqual([]);
});
it("should empty field when setting a different type", () => {
testFactory
.setType("type1")
.setSecurity("security")
.setField({ tip: "tip", value: ["value"] })
.setType("type2");
const microEno = testFactory.makeEno();
expect(microEno.source.field).toEqual([]);
});
it("should not empty field when setting a same type", () => {
testFactory
.setType("type1")
.setSecurity("security")
.setField({ tip: "tip", value: ["value"] })
.setType("type1");
const microEno = testFactory.makeEno();
expect(microEno.source.field[0].tip).toBe("tip");
expect(microEno.source.field[0].value).toEqual(["value"]);
});
it("should delete the given eno", () => {
testFactory
.setType("type")
.setSecurity("security")
.setField({ tip: "field", value: ["val"] })
.setDeleted(true);
const microEno = testFactory.makeEno();
expect(microEno.source.deleted).toBeTruthy();
expect(microEno.source.field).toEqual([]);
});
it("should set the tip when asked", () => {
testFactory.setType("type").setSecurity("security").setWellKnownTip("tip");
const microEno = testFactory.makeEno();
expect(microEno.tip).toBe("tip");
});
it("should set the tip to the sid", () => {
testFactory.setType("type").setSecurity("security");
const microEno = testFactory.makeEno();
expect(microEno.tip).toBe(microEno.sid);
});
it("should set a branch", () => {
testFactory.setType("type").setSecurity("security").setBranch("branch");
const microEno = testFactory.makeEno();
expect(microEno.clientT.branch).toBe("branch");
});
it("should set a default branch", () => {
testFactory.setType("type").setSecurity("security").setBranch();
const microEno = testFactory.makeEno();
expect(microEno.clientT.branch).toBe(dataConstants.BRANCH_MASTER);
});
it("should set a branch on the existing ClientT", () => {
testFactory.setType("type").setSecurity("security").setBranch("branch1");
testFactory.setBranch("branch2");
const microEno = testFactory.makeEno();
expect(microEno.clientT.branch).toBe("branch2");
});
it("should set a sequence", () => {
testFactory.setType("type").setSecurity("security").setSequence(3);
const microEno = testFactory.makeEno();
expect(microEno.clientT.sequence).toBe(3);
});
it("should set a sequence when the clientT already exists", () => {
testFactory
.setType("type")
.setSecurity("security")
.setSequence(3)
.setSequence(2);
const microEno = testFactory.makeEno();
expect(microEno.clientT.sequence).toBe(2);
});
it("should not affect on the previous eno when the factory is reused.", () => {
testFactory
.setType("type")
.setSecurity("security")
.setField({ tip: "tip", value: ["true"] });
const microEno1 = testFactory.makeEno();
const microEno2 = testFactory
.setProto(microEno1)
.setField({ tip: "tip", value: ["false"] })
.makeEno();
expect(microEno1.getFieldBooleanValue("tip")).toBeTruthy();
expect(microEno2.getFieldBooleanValue("tip")).toBeFalsy();
});
it("should reset useTipNonce state when factory is reset", () => {
testFactory.setType("type").setSecurity("security").setWellKnownTip("test-tip").useTipNonce();
const eno1 = testFactory.makeEno();
testFactory.reset("type", "security");
const eno2 = testFactory.setProtoToPatch(eno1).makeEno();
// First eno should use tip nonce, second should use random nonce (default nonce)
expect(eno1.source.nonce).toBe("test-tip");
expect(eno2.source.nonce).not.toBe("test-tip");
expect(eno2.source.nonce).not.toBe("");
});
it("should reset useKnownNonce state when factory is reset", () => {
testFactory.setType("type").setSecurity("security").useKnownNonce("known-nonce");
const eno1 = testFactory.makeEno();
testFactory.reset("type", "security");
const eno2 = testFactory.makeEno();
// First eno should use known nonce, second should use random nonce (default nonce)
expect(eno1.source.nonce).toBe("known-nonce");
expect(eno2.source.nonce).not.toBe("known-nonce");
expect(eno2.source.nonce).not.toBe("");
});
it("should reset useKnownNonce state when useRandomNonce is called", () => {
testFactory.setType("type").setSecurity("security").useKnownNonce("known-nonce");
const eno1 = testFactory.makeEno();
testFactory.useRandomNonce();
const eno2 = testFactory.makeEno();
// First eno should use known nonce, second should use random nonce
expect(eno1.source.nonce).toBe("known-nonce");
expect(eno2.source.nonce).not.toBe("known-nonce");
expect(eno2.source.nonce).not.toBe("");
});
it("should throw an error when proto information is not sufficient", () => {
expect(function () {
testFactory.makeEno();
}).toThrow();
});
});
describe("With type and security on constructor - EnoFactory", () => {
const testFactory = new EnoFactory("type", "security");
it("should create an eno", () => {
const microEno = testFactory.makeEno();
expect(microEno.source.type).toBe("type");
expect(microEno.source.security).toBe("security");
expect(microEno.tip).toBe(microEno.sid);
expect(microEno.clientT.branch).toBe(dataConstants.BRANCH_MASTER);
expect(microEno.clientT.sequence).toBe(1);
});
});
describe("With initial eno given - EnoFactory", () => {
let tempFactory = null;
beforeEach(() => {
tempFactory = new EnoFactory("type", "security");
});
it("should create an eno", () => {
const eno = tempFactory
.setField({ tip: "field", value: ["val"] })
.makeEno();
const testFactory = new EnoFactory(eno);
const microEno = testFactory.makeEno();
expect(microEno.source.type).toBe("type");
expect(microEno.source.security).toBe("security");
expect(microEno.tip).toBe(microEno.sid);
expect(microEno.clientT.branch).toBe(dataConstants.BRANCH_MASTER);
expect(microEno.clientT.sequence).toBe(1);
expect(microEno.source.field[0].tip).toBe("field");
expect(microEno.source.field[0].value).toEqual(["val"]);
});
it("should create an eno (empty source and empty clientT)", () => {
const eno: IEno = tempFactory.makeEno().toJson();
eno.clientT = null;
eno.source = null;
const testFactory = new EnoFactory(eno);
const microEno = testFactory
.setType("type")
.setSecurity("security")
.makeEno();
expect(microEno.clientT).not.toBeNull();
expect(microEno.source.field).toEqual([]);
});
});