🧾 test: Pin the Transactions Config Wiring on the Fallback Path (#14779)

Follow-up to #14774. Its tests cover `AgentClient.recordTokenUsage` in
isolation, so the `BaseClient` half of the fix was unpinned: deleting the
`transactions` property from the call site restored the bug with the suite
still green.

These cases drive `sendMessage` with a real app config on `req` and assert the
resolved value reaches `recordTokenUsage` — disabled, the default when no
config is present, and the balance-enabled override that force-enables it.
Each fails if either half of #14774 is reverted.

They also isolate `options.endpoint` for the block. `options` is shared across
this file, and an endpoint left behind by an earlier case routes the
balance-enabled arrangement into `checkBalance`.
This commit is contained in:
Danny Avila 2026-08-12 23:42:23 -04:00 committed by GitHub
parent 298a3d9ee9
commit c44d11ebf4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1240,6 +1240,80 @@ describe('BaseClient', () => {
});
});
/**
* The `transactions.enabled` guard lives in `createTransaction`, which reads it off
* the object it is handed. Dropping the config anywhere between here and there
* silently re-enables the writes rather than failing, so pin the wiring itself.
*/
describe('recordTokenUsage transactions config', () => {
let priorEndpoint;
let priorEndpointType;
const arrangeFallbackPath = () => {
TestClient.getTokenCountForResponse = jest.fn().mockReturnValue(50);
TestClient.recordTokenUsage = jest.fn().mockResolvedValue(undefined);
TestClient.buildMessages.mockReturnValue({
prompt: [],
tokenCountMap: { res: 50 },
});
};
/** `options` is shared across this file's tests, so an endpoint left behind by an earlier
* case would route the balance-enabled arrangement into `checkBalance`. */
beforeEach(() => {
priorEndpoint = TestClient.options.endpoint;
priorEndpointType = TestClient.options.endpointType;
delete TestClient.options.endpoint;
delete TestClient.options.endpointType;
});
afterEach(() => {
delete TestClient.options.req;
TestClient.options.endpoint = priorEndpoint;
TestClient.options.endpointType = priorEndpointType;
});
test('should forward the resolved transactions config to recordTokenUsage', async () => {
TestClient.options.req = { config: { transactions: { enabled: false } } };
arrangeFallbackPath();
await TestClient.sendMessage('Hello', {});
expect(TestClient.recordTokenUsage).toHaveBeenCalledWith(
expect.objectContaining({
transactions: { enabled: false },
}),
);
});
test('should default to enabled transactions when no app config is present', async () => {
arrangeFallbackPath();
await TestClient.sendMessage('Hello', {});
expect(TestClient.recordTokenUsage).toHaveBeenCalledWith(
expect.objectContaining({
transactions: { enabled: true },
}),
);
});
test('should forward transactions as enabled when balance tracking overrides the setting', async () => {
TestClient.options.req = {
config: { transactions: { enabled: false }, balance: { enabled: true } },
};
arrangeFallbackPath();
await TestClient.sendMessage('Hello', {});
expect(TestClient.recordTokenUsage).toHaveBeenCalledWith(
expect.objectContaining({
transactions: { enabled: true },
}),
);
});
});
describe('getMessagesWithinTokenLimit with instructions', () => {
test('should always include instructions when present', async () => {
TestClient.maxContextTokens = 50;