Skip to content

Commit 6b03882

Browse files
authored
fix: correctly set default retry params (#394)
* fix: Correctly set default retry params * Fix outstanding test cases
1 parent 286f8fd commit 6b03882

4 files changed

Lines changed: 60 additions & 9 deletions

File tree

configuration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ export class Configuration {
158158
}
159159

160160
this.baseOptions = baseOptions;
161-
this.retryParams = params.retryParams;
161+
this.retryParams = Object.assign(GetDefaultRetryParams(), params.retryParams);
162162
this.telemetry = new TelemetryConfiguration(params?.telemetry?.metrics);
163163
}
164164

tests/client.test.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@ import {
1111
ListUsersResponse,
1212
ConsistencyPreference,
1313
ErrorCode,
14-
BatchCheckRequest,
1514
ClientWriteRequestOnDuplicateWrites,
1615
ClientWriteRequestOnMissingDeletes,
1716
} from "../index";
1817
import { baseConfig, defaultConfiguration, getNocks } from "./helpers";
1918

2019
const nocks = getNocks(nock);
21-
nock.disableNetConnect();
2220

2321
describe("OpenFGA Client", () => {
2422

@@ -1875,7 +1873,8 @@ describe("OpenFGA Client", () => {
18751873
const scope0 = nocks.check(defaultConfiguration.storeId!, tuples[0], defaultConfiguration.getBasePath(), { allowed: true }).matchHeader("X-OpenFGA-Client-Method", "ListRelations");
18761874
const scope1 = nocks.check(defaultConfiguration.storeId!, tuples[1], defaultConfiguration.getBasePath(), { allowed: false }).matchHeader("X-OpenFGA-Client-Method", "ListRelations");
18771875
const scope2 = nocks.check(defaultConfiguration.storeId!, tuples[2], defaultConfiguration.getBasePath(), { allowed: true }).matchHeader("X-OpenFGA-Client-Method", "ListRelations");
1878-
const scope3 = nocks.check(defaultConfiguration.storeId!, tuples[3], defaultConfiguration.getBasePath(), "" as any, 500).matchHeader("X-OpenFGA-Client-Method", "ListRelations");
1876+
// Mock all default retries+1 to exhaust them all and trigger actual failure.
1877+
const scope3 = Array.from({ length: 4 }, () => nocks.check(defaultConfiguration.storeId!, tuples[3], defaultConfiguration.getBasePath(), "" as any, 500).matchHeader("X-OpenFGA-Client-Method", "ListRelations"));
18791878
const scope4 = nocks.check(defaultConfiguration.storeId!, tuples[4], defaultConfiguration.getBasePath(), {
18801879
"code": "validation_error",
18811880
"message": "relation 'workspace#can_read' not found"
@@ -1890,12 +1889,12 @@ describe("OpenFGA Client", () => {
18901889
expect(scope0.isDone()).toBe(false);
18911890
expect(scope1.isDone()).toBe(false);
18921891
expect(scope2.isDone()).toBe(false);
1893-
expect(scope3.isDone()).toBe(false);
1892+
expect(scope3.every(scope => scope.isDone())).toBe(false);
18941893
expect(scope4.isDone()).toBe(false);
18951894
expect(scope5.isDone()).toBe(false);
18961895

18971896
try {
1898-
const response = await fgaClient.listRelations({
1897+
await fgaClient.listRelations({
18991898
user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
19001899
object: "workspace:1",
19011900
relations: ["admin", "guest", "reader", "viewer"],
@@ -1904,7 +1903,7 @@ describe("OpenFGA Client", () => {
19041903
expect(scope0.isDone()).toBe(true);
19051904
expect(scope1.isDone()).toBe(true);
19061905
expect(scope2.isDone()).toBe(true);
1907-
expect(scope3.isDone()).toBe(true);
1906+
expect(scope3.every(scope => scope.isDone())).toBe(true);
19081907
expect(scope4.isDone()).toBe(false);
19091908
expect(scope5.isDone()).toBe(false);
19101909
expect(err).toBeInstanceOf(FgaApiError);

tests/index.test.ts

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,12 +425,56 @@ describe("OpenFGA SDK", function () {
425425
});
426426
});
427427

428+
describe("429 with default retry config is successful", () => {
429+
const tupleKey = {
430+
user: "user:xyz",
431+
relation: "viewer",
432+
object: "foobar:x",
433+
};
434+
let failedRequestNock: nock.Scope;
435+
436+
beforeEach(async () => {
437+
fgaApi = new OpenFgaApi({ ...baseConfig });
438+
439+
nocks.tokenExchange(OPENFGA_API_TOKEN_ISSUER, "test-token");
440+
441+
failedRequestNock = nock(basePath)
442+
.post(
443+
`/stores/${storeId}/check`,
444+
{
445+
tuple_key: tupleKey,
446+
authorization_model_id: "01GXSA8YR785C4FYS3C0RTG7B1"
447+
},
448+
expect.objectContaining({ Authorization: "Bearer test-token" })
449+
)
450+
.times(1)
451+
.reply(429, {
452+
code: "rate_limit_exceeded",
453+
message: "nock error",
454+
});
455+
456+
nocks.check(baseConfig.storeId!, tupleKey);
457+
});
458+
459+
afterEach(() => {
460+
nock.cleanAll();
461+
});
462+
463+
it("should return allowed", async () => {
464+
const result = await fgaApi.check(baseConfig.storeId!, { tuple_key: tupleKey, authorization_model_id: "01GXSA8YR785C4FYS3C0RTG7B1"}, {});
465+
466+
expect(failedRequestNock.isDone()).toBe(true);
467+
expect(result.allowed).toBe(true);
468+
});
469+
});
470+
428471
describe("429 with retry in config and retry is successful", () => {
429472
const tupleKey = {
430473
user: "user:xyz",
431474
relation: "viewer",
432475
object: "foobar:x",
433476
};
477+
let failedRequestNock: nock.Scope;
434478

435479
beforeEach(async () => {
436480
const updateBaseConfig = {
@@ -441,11 +485,12 @@ describe("OpenFGA SDK", function () {
441485

442486
nocks.tokenExchange(OPENFGA_API_TOKEN_ISSUER, "test-token");
443487

444-
nock(basePath)
488+
failedRequestNock = nock(basePath)
445489
.post(
446490
`/stores/${storeId}/check`,
447491
{
448492
tuple_key: tupleKey,
493+
authorization_model_id: "01GXSA8YR785C4FYS3C0RTG7B1"
449494
},
450495
expect.objectContaining({ Authorization: "Bearer test-token" })
451496
)
@@ -465,6 +510,7 @@ describe("OpenFGA SDK", function () {
465510
it("should return allowed", async () => {
466511
const result = await fgaApi.check(baseConfig.storeId!, { tuple_key: tupleKey, authorization_model_id: "01GXSA8YR785C4FYS3C0RTG7B1"}, {});
467512

513+
expect(failedRequestNock.isDone()).toBe(true);
468514
expect(result.allowed).toBe(true);
469515
});
470516
});
@@ -475,11 +521,12 @@ describe("OpenFGA SDK", function () {
475521
relation: "viewer",
476522
object: "foobar:x",
477523
};
524+
let failedRequestNock: nock.Scope;
478525

479526
beforeEach(async () => {
480527
nocks.tokenExchange(OPENFGA_API_TOKEN_ISSUER, "test-token");
481528

482-
nock(basePath)
529+
failedRequestNock = nock(basePath)
483530
.post(
484531
`/stores/${storeId}/check`,
485532
{
@@ -507,6 +554,7 @@ describe("OpenFGA SDK", function () {
507554
{ retryParams: GetDefaultRetryParams(2, 10) }
508555
);
509556

557+
expect(failedRequestNock.isDone()).toBe(true);
510558
expect(result.allowed).toBe(true);
511559
});
512560
});

tests/setup.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import * as nock from "nock";
22

3+
beforeEach(() => {
4+
nock.disableNetConnect();
5+
});
6+
37
afterAll(() => {
48
nock.restore();
59
});

0 commit comments

Comments
 (0)