@noggin/elastic-noggin-sdk
Version:
Elastic Noggin SDK
830 lines (710 loc) • 27.6 kB
text/typescript
import { IEnSrvOptions } from "./IEnSrvOptions";
import { updateRequestOptions, send } from "./send";
import { EnoFactory } from "./EnoFactory";
import { switchMap, tap } from "rxjs/operators";
import nock from "nock";
import { firstValueFrom } from "rxjs";
import { OptionsOfTextResponseBody } from "got/dist/source";
import { ResponseHeaders } from "./models/types";
import { IQueryOption } from "./query";
import { AbortController } from "node-abort-controller";
describe("send", () => {
let nockedSend: nock.Interceptor;
beforeEach(() => {
nock.cleanAll();
nockedSend = nock("http://example.com")
.post("/ensrv/")
.query({ ns: "myNameSpace" });
});
it("should cancel the send on abort signal", (done) => {
const enoFactory = new EnoFactory("mytype");
enoFactory.setSecurity("security/policy/local");
const eno = enoFactory.makeEno();
nockedSend.reply(200, [eno]);
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
abortController: new AbortController(),
};
send([], testOptions).subscribe({
next: () => {
fail();
done();
},
error: (err) => {
expect(err?.message).toBe('Request aborted');
done();
},
});
testOptions.abortController?.abort();
});
it("should not attempt the send if already cancelled", (done) => {
const enoFactory = new EnoFactory("mytype");
enoFactory.setSecurity("security/policy/local");
const eno = enoFactory.makeEno();
nockedSend.reply(200, [eno]);
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
abortController: new AbortController(),
};
testOptions.abortController?.abort();
send([], testOptions).subscribe({
next: () => {
fail();
done();
},
error: (err) => {
expect(err?.message).toBe('Request aborted');
done();
},
});
});
it("should cancel the send on unsubscribe", () => {
const enoFactory = new EnoFactory("mytype");
enoFactory.setSecurity("security/policy/local");
const eno = enoFactory.makeEno();
nockedSend.times(1).reply(200, [eno]);
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
};
const obs = send([], testOptions);
const sub1 = obs.subscribe({
next: () => fail(),
error: () => fail(),
});
const sub2 = obs.subscribe({
next: () => fail(),
error: () => fail(),
});
sub1.unsubscribe();
sub2.unsubscribe();
});
it("should return enos", (done) => {
const enoFactory = new EnoFactory("mytype");
enoFactory.setSecurity("security/policy/local");
const eno = enoFactory.makeEno();
nockedSend.reply(200, [eno]);
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
};
send([], testOptions).subscribe({
next: (batch) => {
expect(batch.length).toBe(1);
expect(batch[0].tip).toBe(eno.tip);
done();
},
error: () => {
fail();
done();
}
});
});
it("should return error", (done) => {
const enoFactory = new EnoFactory("mytype");
enoFactory.setSecurity("security/policy/local");
const eno = enoFactory.makeEno();
nockedSend.reply(400, "Some return content");
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
};
send([], testOptions).subscribe({
next: (batch) => {
expect(batch.length).toBe(1);
expect(batch[0].tip).toBe(eno.tip);
fail();
},
error: (err) => {
expect(err.message).toBe("Some return content");
expect(err.code).toBe(400);
done();
},
});
});
it("should set session token", (done) => {
const enoFactory = new EnoFactory("mytype");
enoFactory.setSecurity("security/policy/local");
const eno = enoFactory.makeEno();
nockedSend.reply(200, [eno], { "session-token": ["mynewtoken"] });
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
sessionToken: "myoldtoken",
useCurrentSession: false,
};
send([], testOptions).subscribe({
next: (_) => {
expect(testOptions.sessionToken).toBe("mynewtoken");
done();
},
});
});
it("should set session id", (done) => {
const enoFactory = new EnoFactory("mytype");
enoFactory.setSecurity("security/policy/local");
const eno = enoFactory.makeEno();
nockedSend.reply(function () {
expect(this.req.getHeader("Session-Id")).toBe("sample");
return [200, [eno], { "Session-Id": [this.req.getHeader("Session-Id")] }];
});
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
sessionToken:
"ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKSVV6STFOaUo5LmV5SnpaWE56YVc5dVZHOXJaVzRpT2lKMFpYTjBMM05sYzNOcGIyNVViMnRsYmlJc0luTmxjM05wYjI1SlpDSTZJbk5oYlhCc1pTSXNJbTVoYldWemNHRmpaU0k2SW5SbGMzUXZibUZ0WlhOd1lXTmxJaXdpWTNWemRHOXRVR0Y1Ykc5aFpDSTZleUoxYzJWeVZHbHdJam9pZEdWemRDOTFjMlZ5THpFaUxDSndjbTltYVd4bFZHbHdJam9pWVhCd0wzQnliMlpwYkdVdllXUnRhVzVwYzNSeVlYUnZjaUo5ZlEuUFQ1TnFSbHZvREZLcnlYYUVXakd6ZFJDbUNid01ONmdMOTJ6Y2MyQURJOA==",
};
send([], testOptions).subscribe({ next: () => done(), error: () => fail() });
});
it("should should use shared anonymous session", (done) => {
nock("http://first")
.post("/ensrv/")
.query({ ns: "myNameSpace" })
.reply(function (url) {
// Expect no session token
expect(this.req.getHeader("Session-Token")).toBeUndefined();
return [200, [], { "Session-Token": "myFirstToken" }];
});
nock("http://second")
.post("/ensrv/")
.query({ ns: "myNameSpace" })
.reply(function (url) {
// Expect reuse of anonymous token because same namespace
expect(this.req.getHeader("Session-Token")).toEqual("myFirstToken");
return [
200,
[],
{ "Session-Token": this.req.getHeader("Session-Token") },
];
});
nock("http://third")
.post("/ensrv/")
.query({ ns: "anotherNameSpace" })
.reply(function (url) {
// Expect no session token because different namespace
expect(this.req.getHeader("Session-Token")).toBeUndefined();
return [200, [], { "Session-Token": "mySecondToken" }];
});
const testOptions: { [key: string]: IEnSrvOptions } = {
first: {
enSrvUrl: "http://first/ensrv/",
namespace: "myNameSpace",
useSharedAnonymousSession: true,
useCurrentSession: false,
},
second: {
enSrvUrl: "http://second/ensrv/",
namespace: "myNameSpace",
useSharedAnonymousSession: true,
useCurrentSession: false,
},
third: {
enSrvUrl: "http://third/ensrv/",
namespace: "anotherNameSpace",
useSharedAnonymousSession: true,
useCurrentSession: false,
},
};
send([], testOptions.first)
.pipe(
tap((_) => expect(testOptions.first.sessionToken).toBeUndefined()),
switchMap((_) => send([], testOptions.second)),
tap((_) => expect(testOptions.second.sessionToken).toBeUndefined()),
switchMap((_) => send([], testOptions.third)),
tap((_) => expect(testOptions.third.sessionToken).toBeUndefined())
)
.subscribe({ next: () => done(), error: () => fail() });
});
it("should send client ip and via headers", async () => {
const enoFactory = new EnoFactory("mytype", "security/policy/local");
const eno = enoFactory.makeEno();
let calledHeaders: any;
nockedSend.reply(function () {
calledHeaders = this.req.headers;
return [200, [eno], {}];
});
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
clientIp: "1.2.3.4",
clientVia: "my-via",
};
await firstValueFrom(send([], testOptions));
expect(calledHeaders).toEqual(
jasmine.objectContaining({
"encloud-clientip": ["1.2.3.4"],
"encloud-via": ["my-via"],
})
);
});
it("should use keep alives", async () => {
const enoFactory = new EnoFactory("mytype", "security/policy/local");
const eno = enoFactory.makeEno();
let req: any;
nockedSend.reply(function () {
req = this.req;
return [200, [eno], {}];
});
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
};
await firstValueFrom(send([], testOptions));
expect(req.options.agent.keepAlive).toBe(true);
});
it('should reuse agents', async () => {
const enoFactory = new EnoFactory("mytype", "security/policy/local");
const eno = enoFactory.makeEno();
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
};
let req1: any;
nockedSend.reply(function () {
req1 = this.req;
return [200, [eno], {}];
});
await firstValueFrom(send([], testOptions));
let req2: any;
nockedSend.reply(function () {
req2 = this.req;
return [200, [eno], {}];
});
await firstValueFrom(send([], testOptions));
expect(req1.options.agent).toBe(req2.options.agent);
});
it('should retry twice', async () => {
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
bulk: true,
};
let numCalled = 0;
// console.log(new Date().valueOf());
nockedSend.times(3).reply(() => {
// console.log(new Date().valueOf());
numCalled++;
return [502];
});
try {
await firstValueFrom(send([], testOptions));
} catch (err) {
expect(err.code).toBe(502);
}
expect(numCalled).toBe(3);
});
it("should send the bulk header", async () => {
const enoFactory = new EnoFactory("mytype", "security/policy/local");
const eno = enoFactory.makeEno();
let calledHeaders: any;
nockedSend.reply(function () {
calledHeaders = this.req.headers;
return [200, [eno], {}];
});
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
bulk: true,
};
await firstValueFrom(send([], testOptions));
expect(calledHeaders).toEqual(
jasmine.objectContaining({
"encloud-bulk": ["true"],
})
);
});
it("should send additional headers", async () => {
const enoFactory = new EnoFactory("mytype", "security/policy/local");
const eno = enoFactory.makeEno();
let calledHeaders: any;
nockedSend.reply(function () {
calledHeaders = this.req.headers;
return [200, [eno], {}];
});
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
additionalHeaders: {
key1: ["value1"],
key2: ["value2a", "value2b"],
key3: [],
},
};
await firstValueFrom(send([], testOptions));
expect(calledHeaders).toEqual(
jasmine.objectContaining({
key1: ["value1"],
key2: ["value2a", "value2b"],
key3: [],
})
);
});
it("should send additional query string parameters", async () => {
const enoFactory = new EnoFactory("mytype", "security/policy/local");
const eno = enoFactory.makeEno();
let calledUrl: string = '';
nock("http://example.com")
.post("/ensrv/")
.query({
ns: "myNameSpace",
key1: "value1",
"ke&y2": "val&ue2",
key3: "",
})
.reply(function (url) {
calledUrl = url;
return [200, [eno], {}];
});
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
additionalQueryString: {
key1: "value1",
"ke&y2": "val&ue2",
key3: "",
},
};
await firstValueFrom(send([], testOptions));
expect(calledUrl).toBe(
"/ensrv/?ns=myNameSpace&key1=value1&ke%26y2=val%26ue2&key3="
);
});
it("should update headers values", (done) => {
const enoFactory = new EnoFactory("mytype");
enoFactory.setSecurity("security/policy/local");
const eno = enoFactory.makeEno();
nockedSend.reply(200, [eno], {
'en_query_nextpage': "searchAfterToken",
'header2': "header2Value",
'session-token': ["mynewtoken"],
});
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
sessionToken: "myoldtoken",
useCurrentSession: false,
};
const queryOptions: IQueryOption = {
extraAttributes: [{ label: "runtimeAttr1", formula: "TIP()" }],
extraFilters: [{ label: "runtimeFilter1", formula: "TIP()" }],
vars: {
varKey1: ["varVal1a", "varVal1b"],
varKey2: ["varVal2a", "varVal2b"],
},
dimensionOptions: [
{
label: "runtimeDim1",
formula: "TIP()",
sortby: ["TITLE()"],
sortdir: ["asc"],
limit: 1,
},
],
responseHeadersToInclude: ['en_query_nextpage', 'header2', 'header3']
};
send([], testOptions, queryOptions).subscribe({
next: (_) => {
expect(queryOptions.responseHeadersToInclude).toEqual([
{ en_query_nextpage: "searchAfterToken" },
{ header2: "header2Value" },
{ header3: null },
] as ResponseHeaders);
done();
},
});
});
describe('#updateRequestOptions', () => {
it('should use the query service', () => {
const enoFactory = new EnoFactory("op/query", "security/policy/local");
const eno = enoFactory.makeEno();
const testOptions: IEnSrvOptions = { enSrvUrl: "http://example.com/ensrv/", namespace: "myNameSpace", useQueryService: true };
let requestOptions: OptionsOfTextResponseBody = { json: [eno] };
updateRequestOptions([eno], testOptions, requestOptions);
expect(requestOptions.url).toBe('http://example.com/query/ensrv');
});
it('should not use the query service', () => {
const enoFactory = new EnoFactory("op/query", "security/policy/local");
const eno = enoFactory.makeEno();
const testOptions: IEnSrvOptions = { enSrvUrl: "http://example.com/ensrv/", namespace: "myNameSpace" };
let requestOptions: OptionsOfTextResponseBody = { json: [eno] };
updateRequestOptions([eno], testOptions, requestOptions);
expect(requestOptions.url).toBe('http://example.com/ensrv/op/query?ns=myNameSpace');
});
it('should use a thin dispatcher', () => {
const enoFactory = new EnoFactory("op/pull", "security/policy/local");
const eno = enoFactory.makeEno();
const testOptions: IEnSrvOptions = { enSrvUrl: "http://example.com/ensrv/", namespace: "myNameSpace" };
let requestOptions: OptionsOfTextResponseBody = { json: [eno] };
updateRequestOptions([eno], testOptions, requestOptions);
expect(requestOptions.url).toBe('http://example.com/ensrv/op/pull?ns=myNameSpace');
});
it('should use the fat dispatcher', () => {
const enoFactory = new EnoFactory("op/process", "security/policy/local");
const eno = enoFactory.makeEno();
const testOptions: IEnSrvOptions = { enSrvUrl: "http://example.com/ensrv/", namespace: "myNameSpace" };
let requestOptions: OptionsOfTextResponseBody = { json: [eno] };
updateRequestOptions([eno], testOptions, requestOptions);
expect(requestOptions.url).toBe('http://example.com/ensrv/?ns=myNameSpace');
});
it('should use the fat dispatcher because there is multiple enos in the batch', () => {
const enoFactory = new EnoFactory("op/query", "security/policy/local");
const eno = enoFactory.makeEno();
const testOptions: IEnSrvOptions = { enSrvUrl: "http://example.com/ensrv/", namespace: "myNameSpace" };
let requestOptions: OptionsOfTextResponseBody = { json: [eno, eno] };
updateRequestOptions([eno, eno], testOptions, requestOptions);
expect(requestOptions.url).toBe('http://example.com/ensrv/?ns=myNameSpace');
});
});
describe("initial session token management", () => {
let enoFactory: EnoFactory;
let eno: any;
beforeEach(() => {
enoFactory = new EnoFactory("mytype", "security/policy/local");
eno = enoFactory.makeEno();
});
describe("maintainInitialSessionToken flag", () => {
it("should handle all session token scenarios", async () => {
const testCases = [
{
description: "maintainInitialSessionToken is undefined (explicit)",
inputOptions: {
sessionToken: "existing-token",
maintainInitialSessionToken: undefined,
},
responseHeaders: { "session-token": ["response-token"] },
expectedInitialSessionToken: undefined,
expectedSessionToken: "response-token",
},
{
description: "maintainInitialSessionToken is undefined (implicit)",
inputOptions: {
sessionToken: "existing-token",
},
responseHeaders: { "session-token": ["response-token"] },
expectedInitialSessionToken: undefined,
expectedSessionToken: "response-token",
},
{
description: "maintainInitialSessionToken is false",
inputOptions: {
sessionToken: "existing-token",
maintainInitialSessionToken: false,
},
responseHeaders: { "session-token": ["response-token"] },
expectedInitialSessionToken: undefined,
expectedSessionToken: "response-token",
},
{
description: "maintainInitialSessionToken is true with explicit sessionToken",
inputOptions: {
sessionToken: "existing-token",
maintainInitialSessionToken: true,
},
responseHeaders: { "session-token": ["response-token"] },
expectedInitialSessionToken: "existing-token",
expectedSessionToken: "response-token",
},
{
description: "populate from response header when no sessionToken",
inputOptions: {
maintainInitialSessionToken: true,
},
responseHeaders: { "session-token": ["response-token"] },
expectedInitialSessionToken: "response-token",
expectedSessionToken: "response-token",
},
{
description: "preserve existing initialSessionToken (explicit sessionToken)",
inputOptions: {
sessionToken: "new-token",
maintainInitialSessionToken: true,
initialSessionToken: "preserved-token",
},
responseHeaders: { "session-token": ["response-token"] },
expectedInitialSessionToken: "preserved-token",
expectedSessionToken: "response-token",
},
{
description: "preserve existing initialSessionToken (response only)",
inputOptions: {
maintainInitialSessionToken: true,
initialSessionToken: "preserved-token",
},
responseHeaders: { "session-token": ["response-token"] },
expectedInitialSessionToken: "preserved-token",
expectedSessionToken: "response-token",
},
{
description: "populate from response header (string format)",
inputOptions: {
maintainInitialSessionToken: true,
},
responseHeaders: { "session-token": "string-response-token" },
expectedInitialSessionToken: "string-response-token",
expectedSessionToken: "string-response-token",
},
{
description: "populate from response header (array format)",
inputOptions: {
maintainInitialSessionToken: true,
},
responseHeaders: { "session-token": ["token1"] },
expectedInitialSessionToken: "token1",
expectedSessionToken: "token1",
},
// Edge Cases
{
description: "handle undefined sessionToken",
inputOptions: {
sessionToken: undefined,
maintainInitialSessionToken: true,
},
responseHeaders: {},
expectedInitialSessionToken: undefined,
expectedSessionToken: undefined,
},
{
description: "handle empty array response headers",
inputOptions: {
maintainInitialSessionToken: true,
},
responseHeaders: { "session-token": [] },
expectedInitialSessionToken: undefined,
expectedSessionToken: undefined,
},
];
for (const testCase of testCases) {
// Setup fresh nock for each test case
nock.cleanAll();
const testNock = nock("http://example.com")
.post("/ensrv/")
.query({ ns: "myNameSpace" })
.reply(200, [eno], testCase.responseHeaders);
// Create test options by merging base options with test case input
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
...testCase.inputOptions,
};
await firstValueFrom(send([], testOptions));
// Assert both initialSessionToken and sessionToken values
expect(testOptions.initialSessionToken)
.withContext(`${testCase.description} - initialSessionToken`)
.toBe(testCase.expectedInitialSessionToken);
expect(testOptions.sessionToken)
.withContext(`${testCase.description} - sessionToken`)
.toBe(testCase.expectedSessionToken);
}
});
it("should handle shared anonymous session scenarios", async () => {
const sessionTokenCache = require("./sessionTokenCache");
// Test case: populate from cached token with shared anonymous session
spyOn(sessionTokenCache, "hasToken").and.returnValue(true);
spyOn(sessionTokenCache, "getToken").and.returnValue("cached-token");
spyOn(sessionTokenCache, "setToken");
nock.cleanAll();
nock("http://example.com")
.post("/ensrv/")
.query({ ns: "myNameSpace" })
.reply(200, [eno], { "session-token": ["response-token"] });
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
maintainInitialSessionToken: true,
useSharedAnonymousSession: true,
};
await firstValueFrom(send([], testOptions));
expect(testOptions.initialSessionToken).toBe("cached-token");
expect(testOptions.sessionToken).toBeUndefined(); // sessionToken stays undefined with useSharedAnonymousSession
expect(sessionTokenCache.setToken).toHaveBeenCalledWith("myNameSpace", "response-token");
});
it("should ignore cache when maintainInitialSessionToken is false", async () => {
const sessionTokenCache = require("./sessionTokenCache");
spyOn(sessionTokenCache, "hasToken").and.returnValue(true);
spyOn(sessionTokenCache, "getToken").and.returnValue("cached-token");
spyOn(sessionTokenCache, "setToken");
nock.cleanAll();
nock("http://example.com")
.post("/ensrv/")
.query({ ns: "myNameSpace" })
.reply(200, [eno], { "session-token": ["response-token"] });
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
maintainInitialSessionToken: false,
useSharedAnonymousSession: true,
};
await firstValueFrom(send([], testOptions));
expect(testOptions.initialSessionToken).toBeUndefined();
expect(testOptions.sessionToken).toBeUndefined(); // sessionToken stays undefined with useSharedAnonymousSession
expect(sessionTokenCache.setToken).toHaveBeenCalledWith("myNameSpace", "response-token");
});
});
describe("Specialized Scenarios", () => {
let sessionTokenCache: any;
beforeEach(() => {
sessionTokenCache = require("./sessionTokenCache");
spyOn(sessionTokenCache, "hasToken").and.returnValue(false);
spyOn(sessionTokenCache, "getToken");
spyOn(sessionTokenCache, "setToken");
});
it("should preserve initialSessionToken across multiple requests", async () => {
// First request
nockedSend.reply(200, [eno], { "session-token": ["first-response-token"] });
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
sessionToken: "initial-token",
useCurrentSession: false,
maintainInitialSessionToken: true,
};
await firstValueFrom(send([], testOptions));
expect(testOptions.initialSessionToken).toBe("initial-token");
// Second request with different response token
nockedSend.reply(200, [eno], { "session-token": ["second-response-token"] });
await firstValueFrom(send([], testOptions));
expect(testOptions.initialSessionToken).toBe("initial-token");
expect(sessionTokenCache.getToken).not.toHaveBeenCalled();
expect(sessionTokenCache.setToken).not.toHaveBeenCalled();
});
it("should preserve initialSessionToken when cache changes", async () => {
sessionTokenCache.hasToken.and.returnValue(true);
sessionTokenCache.getToken.and.returnValue("original-cached-token");
nockedSend.reply(200, [eno], { "session-token": ["response-token"] });
const testOptions: IEnSrvOptions = {
enSrvUrl: "http://example.com/ensrv/",
namespace: "myNameSpace",
useCurrentSession: false,
maintainInitialSessionToken: true,
useSharedAnonymousSession: true,
};
// First request
await firstValueFrom(send([], testOptions));
expect(testOptions.initialSessionToken).toBe("original-cached-token");
// Simulate cache change
sessionTokenCache.getToken.and.returnValue("new-cached-token");
// Second request
nockedSend.reply(200, [eno], { "session-token": ["another-response-token"] });
await firstValueFrom(send([], testOptions));
expect(testOptions.initialSessionToken).toBe("original-cached-token");
});
});
});
});