Replicate "too many feature flags" error in test

This commit is contained in:
Chuan-kai Lin
2025-07-16 07:06:52 -07:00
parent b37e7e2c5d
commit 3eaefb4deb
2 changed files with 62 additions and 10 deletions
+30
View File
@@ -21,6 +21,7 @@ import {
mockFeatureFlagApiEndpoint,
setupActionsVars,
setupTests,
stubFeatureFlagApiEndpoint,
} from "./testing-utils";
import { ToolsFeature } from "./tools-features";
import * as util from "./util";
@@ -132,6 +133,35 @@ test("Features use default value if they're not returned in API response", async
});
});
test("Include no more than 25 features in each API request", async (t) => {
await withTmpDir(async (tmpDir) => {
const features = setUpFeatureFlagTests(tmpDir);
stubFeatureFlagApiEndpoint((request) => {
const requestedFeatures = (request.features as string).split(",");
return {
status: requestedFeatures.length <= 25 ? 200 : 400,
messageIfError: "Can request a maximum of 25 features.",
data: {},
};
});
// We only need to call getValue once, and it does not matter which feature
// we ask for. Under the hood, the features library will request all features
// from the API.
const feature = Object.values(Feature)[0];
// TODO: change to `t.notThrowsAsync` once we implement request chunking.
await t.throwsAsync(
async () => features.getValue(feature, includeCodeQlIfRequired(feature)),
{
message:
"Encountered an error while trying to determine feature enablement: " +
"Error: Can request a maximum of 25 features.",
},
);
});
});
test("Feature flags exception is propagated if the API request errors", async (t) => {
await withTmpDir(async (tmpDir) => {
const features = setUpFeatureFlagTests(tmpDir);
+32 -10
View File
@@ -180,6 +180,21 @@ export function getRecordingLogger(messages: LoggedMessage[]): Logger {
export function mockFeatureFlagApiEndpoint(
responseStatusCode: number,
response: { [flagName: string]: boolean },
) {
stubFeatureFlagApiEndpoint(() => ({
status: responseStatusCode,
messageIfError: "some error message",
data: response,
}));
}
/** Stub the HTTP request to the feature flags enablement API endpoint. */
export function stubFeatureFlagApiEndpoint(
responseFunction: (params: any) => {
status: number;
messageIfError?: string;
data: { [flagName: string]: boolean };
},
) {
// Passing an auth token is required, so we just use a dummy value
const client = github.getOctokit("123");
@@ -189,16 +204,23 @@ export function mockFeatureFlagApiEndpoint(
const optInSpy = requestSpy.withArgs(
"GET /repos/:owner/:repo/code-scanning/codeql-action/features",
);
if (responseStatusCode < 300) {
optInSpy.resolves({
status: responseStatusCode,
data: response,
headers: {},
url: "GET /repos/:owner/:repo/code-scanning/codeql-action/features",
});
} else {
optInSpy.throws(new HTTPError("some error message", responseStatusCode));
}
optInSpy.callsFake((_route, params) => {
const response = responseFunction(params);
if (response.status < 300) {
return Promise.resolve({
status: response.status,
data: response.data,
headers: {},
url: "GET /repos/:owner/:repo/code-scanning/codeql-action/features",
});
} else {
throw new HTTPError(
response.messageIfError || "default stub error message",
response.status,
);
}
});
sinon.stub(apiClient, "getApiClient").value(() => client);
}