@noggin/elastic-noggin-sdk
Version:
Elastic Noggin SDK
328 lines (302 loc) • 9.46 kB
text/typescript
import { EnSrv } from "./ensrv";
import { IEnSrvOptions } from "./IEnSrvOptions";
import { EnoFactory } from "./EnoFactory";
import { Eno } from "./models/Eno";
import { IQueryOption } from "./query";
import { firstValueFrom, of } from "rxjs";
describe("EnSrv", () => {
let enSrvOptions: IEnSrvOptions;
let enSrv: EnSrv;
beforeEach(() => {
enSrvOptions = {
enSrvUrl: "https://services.dev.elasticnoggin.com/ensrv/",
namespace: "my-namespace",
};
enSrv = new EnSrv(enSrvOptions);
});
it("Should read an eno", async () => {
const enoFactory = new EnoFactory("my-type", "my-security");
const eno = enoFactory.makeEno();
const readSpy = spyOn(enSrv.fn, "read").and.returnValue(of(eno));
const result = await firstValueFrom(
enSrv.read("my-tip", { branch: "my-branch" }, { bulk: true })
);
expect(readSpy).toHaveBeenCalledWith(
"my-tip",
{
enSrvUrl: "https://services.dev.elasticnoggin.com/ensrv/",
namespace: "my-namespace",
bulk: true,
},
{ branch: "my-branch" }
);
expect(result).toEqual(eno);
});
it("Should send a batch", async () => {
const enoFactory = new EnoFactory("my-type", "my-security");
const eno = enoFactory.makeEno();
const sendSpy = spyOn(enSrv.fn, "send").and.returnValue(of([eno]));
const result = await firstValueFrom(enSrv.send([eno], { bulk: true }));
expect(sendSpy).toHaveBeenCalledWith([eno], {
enSrvUrl: "https://services.dev.elasticnoggin.com/ensrv/",
namespace: "my-namespace",
bulk: true,
});
expect(result).toEqual([eno]);
});
it("Should start a process", async () => {
const processResponse = {
operationTip: "my-response-op-tip",
responseTip: "my-response-tip",
isFinished: true,
};
const startProcessSpy = spyOn(enSrv.fn, "startProcess").and.returnValue(
of(processResponse)
);
const result = await firstValueFrom(
enSrv.startProcess(
"my-process-tip",
{ waitForFinish: true },
{ bulk: true }
)
);
expect(startProcessSpy).toHaveBeenCalledWith(
"my-process-tip",
{
enSrvUrl: "https://services.dev.elasticnoggin.com/ensrv/",
namespace: "my-namespace",
bulk: true,
},
{ waitForFinish: true }
);
expect(result).toEqual(processResponse);
});
it("Should pull a batch", async () => {
const enoFactory = new EnoFactory("my-type", "my-security");
const eno = enoFactory.makeEno();
const pullSpy = spyOn(enSrv.fn, "pull").and.returnValue(of([eno]));
const result = await firstValueFrom(
enSrv.pull(["my-tip"], { branch: "my-branch" }, { bulk: true })
);
expect(pullSpy).toHaveBeenCalledWith(
["my-tip"],
{
enSrvUrl: "https://services.dev.elasticnoggin.com/ensrv/",
namespace: "my-namespace",
bulk: true,
},
{ branch: "my-branch" }
);
expect(result).toEqual([eno]);
});
it("Should mutate the sessionToken in options", async () => {
const processResponse = {
operationTip: "my-response-op-tip",
responseTip: "my-response-tip",
isFinished: true,
};
spyOn(enSrv.fn, "startProcess").and.callFake(
(processTip, myEnSrvOptions, processOptions) => {
myEnSrvOptions.sessionToken = "my-new-session-token";
return of(processResponse);
}
);
await firstValueFrom(
enSrv.startProcess(
"my-process-tip",
{ waitForFinish: true },
{ bulk: true }
)
);
expect(enSrvOptions.sessionToken).toBe("my-new-session-token");
});
});
xdescribe("End-to-end EnSrv tests", () => {
let enSrvOptions: IEnSrvOptions;
beforeEach(() => {
enSrvOptions = {
enSrvUrl: "https://services.dev.elasticnoggin.com/ensrv/",
namespace:
"29686d9379c22c17d177cafc364a8b5a5774407b3bfd3b142a59b57a88e16e0",
sessionToken: "<enter token here>",
};
});
it("Should read an eno", async () => {
const enSrv = new EnSrv(enSrvOptions);
const eno = await firstValueFrom(enSrv.read("root"));
expect(eno.tip).toBe("root");
});
it("Should error when read not found", async () => {
const enSrv = new EnSrv(enSrvOptions);
try {
await firstValueFrom(enSrv.read("does-not-exist"));
fail();
} catch (err) {
const errEno = new Eno(JSON.parse(err.message));
expect(errEno.getFieldStringValue("error/message/tip")).toBe(
"error/message/eno/not-found"
);
}
});
it("Should error when read not permitted", async () => {
const enSrv = new EnSrv(enSrvOptions);
try {
await firstValueFrom(enSrv.read("test/user/1"));
fail();
} catch (err) {
const errEno = new Eno(JSON.parse(err.message));
expect(errEno.getFieldStringValue("error/message/tip")).toBe(
"error/message/security/access-denied"
);
}
});
it("Should error when write not permitted", async () => {
const enSrv = new EnSrv(enSrvOptions);
const oldEno = await firstValueFrom(enSrv.read("root"));
const enoFactory = new EnoFactory();
enoFactory.setProtoToPatch(oldEno);
enoFactory.setSecurity("security/policy/op");
const newEno = enoFactory.makeEno();
try {
await firstValueFrom(enSrv.write(newEno));
fail();
} catch (err) {
const errEno = new Eno(JSON.parse(err.message));
expect(errEno.getFieldStringValue("error/message/tip")).toBe(
"error/message/security/access-denied"
);
}
});
it("Should error when process does not exist", async () => {
const enSrv = new EnSrv(enSrvOptions);
try {
await firstValueFrom(enSrv.startProcess("does-not-exist"));
fail();
} catch (err) {
const errEno = new Eno(JSON.parse(err.message));
expect(errEno.getFieldStringValue("error/message/tip")).toBe(
"error/message/reference/not-found"
);
}
});
it("Should evaluate a formula", async () => {
const enSrv = new EnSrv(enSrvOptions);
const formulaOptions = {
context: "root",
vars: { myVar: "alpha" },
};
const results = await firstValueFrom(
enSrv.evalFormula('ARRAY(TIP(),VAR("myVar"))', formulaOptions)
);
expect(results).toEqual(["root", "alpha"]);
});
it("Should error when formula invalid", async () => {
const enSrv = new EnSrv(enSrvOptions);
const results = await firstValueFrom(enSrv.evalFormula("bad-syntax"));
expect(results).toEqual(["bad-syntax"]);
});
it("Should get locale", async () => {
const enSrv = new EnSrv(enSrvOptions);
const results = await firstValueFrom(enSrv.locale());
expect(results).toEqual({
lang: "en-us",
timezone: "Australia/Sydney",
dateFormat: "DD MMM YYYY",
datetimeFormat: "DD MMM YYYY HH:mm",
});
});
it("Should execute a query", async () => {
const enSrv = new EnSrv(enSrvOptions);
const queryOptions: IQueryOption = {
extraAttributes: [{ label: "runtimeAttr1", formula: "TIP()" }],
extraFilters: [
{ label: "runtimeFilter1", formula: "EQUALS(TIP(), TIP())" },
],
vars: {
varKey1: ["varVal1a", "varVal1b"],
varKey2: ["varVal2a", "varVal2b"],
},
dimensionOptions: [
{
label: "runtimeDim1",
formula: "TIP()",
sortby: ["TITLE()"],
sortdir: ["asc"],
limit: 1,
},
],
};
const results = await firstValueFrom(
enSrv.executeQuery("eim/query/get-all-modules", queryOptions)
);
expect(results).toEqual({
attributes: [
{
tip: "eim/query/attr/tip",
label: "$tip",
formula: "TIP()",
},
{
label: "$tip",
formula: "TIP()",
},
{
label: "name",
formula: 'FIELD("app/module:name")',
},
{
label: "description",
formula: 'FIELD("app/module:description")',
},
{
label: "solutionNames",
formula:
'FIELD_VALUES("app/solution:name", FIELD("app/module:solution"))',
},
{
label: "solutionColors",
formula:
'FIELD_VALUES("app/solution:color", FIELD("app/module:solution"))',
},
{
label: "runtimeAttr1",
formula: "TIP()",
},
],
dimensions: [
{
label: "runtimeDim1",
values: [jasmine.stringMatching(/.+/)],
},
],
results: jasmine.any(Array),
execTime: jasmine.any(Number),
});
});
it("Should execute a 1d query", async () => {
const enSrv = new EnSrv(enSrvOptions);
const queryOptions: IQueryOption = {
extraAttributes: [{ label: "runtimeAttr1", formula: "TIP()" }],
extraFilters: [
{ label: "runtimeFilter1", formula: "EQUALS(TIP(), TIP())" },
],
vars: {
varKey1: ["varVal1a", "varVal1b"],
varKey2: ["varVal2a", "varVal2b"],
},
dimensionOptions: [
{
label: "runtimeDim1",
formula: "TIP()",
sortby: ["TITLE()"],
sortdir: ["asc"],
limit: 1,
},
],
};
const results = await firstValueFrom(
enSrv.executeQuery1d("eim/query/get-all-modules", queryOptions)
);
expect(results).toEqual(jasmine.any(Array));
});
});