Skip to content

Commit b62bdd2

Browse files
aaguiarzSoulPancake
authored andcommitted
test: cover failed shared token refresh retry path
1 parent 76ba394 commit b62bdd2

1 file changed

Lines changed: 53 additions & 8 deletions

File tree

tests/credentials.test.ts

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -543,18 +543,14 @@ describe("Credentials", () => {
543543
const apiTokenIssuer = "issuer.fga.example";
544544
const expectedBaseUrl = "https://issuer.fga.example";
545545
const expectedPath = `/${DEFAULT_TOKEN_ENDPOINT_PATH}`;
546-
let tokenRequestCount = 0;
547546

548547
const scope = nock(expectedBaseUrl)
549548
.post(expectedPath)
550549
.once()
551550
.delay(20)
552-
.reply(() => {
553-
tokenRequestCount += 1;
554-
return [200, {
555-
access_token: "shared-token",
556-
expires_in: 300,
557-
}];
551+
.reply(200, {
552+
access_token: "shared-token",
553+
expires_in: 300,
558554
});
559555

560556
const credentials = new Credentials(
@@ -578,7 +574,56 @@ describe("Credentials", () => {
578574
headers.forEach(header => {
579575
expect(header?.value).toBe("Bearer shared-token");
580576
});
581-
expect(tokenRequestCount).toBe(1);
577+
expect(scope.isDone()).toBe(true);
578+
});
579+
580+
test("should clear shared refresh promise after failure and retry on the next call", async () => {
581+
const apiTokenIssuer = "issuer.fga.example";
582+
const expectedBaseUrl = "https://issuer.fga.example";
583+
const expectedPath = `/${DEFAULT_TOKEN_ENDPOINT_PATH}`;
584+
585+
const scope = nock(expectedBaseUrl)
586+
.post(expectedPath)
587+
.once()
588+
.reply(404, {
589+
code: "not_found",
590+
message: "token exchange failed",
591+
})
592+
.post(expectedPath)
593+
.once()
594+
.reply(200, {
595+
access_token: "recovered-token",
596+
expires_in: 300,
597+
});
598+
599+
const credentials = new Credentials(
600+
{
601+
method: CredentialsMethod.ClientCredentials,
602+
config: {
603+
apiTokenIssuer,
604+
apiAudience: OPENFGA_API_AUDIENCE,
605+
clientId: OPENFGA_CLIENT_ID,
606+
clientSecret: OPENFGA_CLIENT_SECRET,
607+
},
608+
} as AuthCredentialsConfig,
609+
undefined,
610+
mockTelemetryConfig,
611+
);
612+
613+
const results = await Promise.allSettled(
614+
Array.from({ length: 5 }, () => credentials.getAccessTokenHeader())
615+
);
616+
const rejected = results.filter((result): result is PromiseRejectedResult => result.status === "rejected");
617+
618+
expect(rejected).toHaveLength(5);
619+
expect(rejected[0].reason).toBe(rejected[1].reason);
620+
expect(rejected[1].reason).toBe(rejected[2].reason);
621+
expect(rejected[2].reason).toBe(rejected[3].reason);
622+
expect(rejected[3].reason).toBe(rejected[4].reason);
623+
624+
const header = await credentials.getAccessTokenHeader();
625+
626+
expect(header?.value).toBe("Bearer recovered-token");
582627
expect(scope.isDone()).toBe(true);
583628
});
584629

0 commit comments

Comments
 (0)