fix: txnBot has zero test coverage after deleting recenterAccess.test.ts (#919)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-17 19:34:58 +00:00
parent 80f6d94247
commit 3d957bfb76

View file

@ -0,0 +1,134 @@
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { createTxnBot, type TxnBotDependencies } from './service.js';
import type { BotConfigService } from './services/BotConfigService.js';
import type { BlockchainService } from './services/BlockchainService.js';
import type { GraphQLService } from './services/GraphQLService.js';
const BASE_CONFIG = {
PROVIDER_URL: 'http://localhost:8545',
PRIVATE_KEY: '0xdeadbeef000000000000000000000000000000000000000000000000deadbeef',
LM_CONTRACT_ADDRESS: '0x0000000000000000000000000000000000000001',
STAKE_CONTRACT_ADDRESS: '0x0000000000000000000000000000000000000002',
GRAPHQL_ENDPOINT: 'http://localhost:42069/graphql',
ENVIRONMENT: 'test',
PORT: '3000',
};
function makeTx(hash: string) {
return { hash, wait: (): Promise<null> => Promise.resolve(null) };
}
function makeDeps(
blockchain?: Partial<{
estimateRecenterGas: () => Promise<void>;
recenter: () => Promise<ReturnType<typeof makeTx>>;
}>,
): TxnBotDependencies {
return {
configService: {
getConfig: () => ({ ...BASE_CONFIG }),
getPort: () => '3000',
} as unknown as BotConfigService,
blockchainService: {
estimateRecenterGas: blockchain?.estimateRecenterGas ?? (() => Promise.resolve()),
recenter: blockchain?.recenter ?? (() => Promise.resolve(makeTx('0xabc'))),
checkFunds: () => Promise.resolve('1.0'),
payTax: () => Promise.resolve(makeTx('0xpay')),
} as unknown as BlockchainService,
graphQLService: {
fetchActivePositions: () => Promise.resolve([]),
} as unknown as GraphQLService,
};
}
describe('evaluateRecenterOpportunity', () => {
it('returns canRecenter: true when gas estimation succeeds', async () => {
const bot = createTxnBot(makeDeps());
const result = await bot.evaluateRecenterOpportunity();
assert.equal(result.canRecenter, true);
assert.equal(result.reason, null);
assert.equal(result.error, null);
assert.ok(result.checkedAtMs > 0);
});
it('returns canRecenter: false with extracted revert reason', async () => {
const bot = createTxnBot(
makeDeps({
estimateRecenterGas: () =>
Promise.reject({
shortMessage: 'execution reverted: recenter not needed',
message: 'execution reverted: recenter not needed',
}),
}),
);
const result = await bot.evaluateRecenterOpportunity();
assert.equal(result.canRecenter, false);
assert.equal(result.reason, 'recenter not needed');
assert.equal(result.error, 'execution reverted: recenter not needed');
});
it('returns canRecenter: false with generic message when no revert prefix', async () => {
const bot = createTxnBot(
makeDeps({
estimateRecenterGas: () => Promise.reject({ message: 'connection refused' }),
}),
);
const result = await bot.evaluateRecenterOpportunity();
assert.equal(result.canRecenter, false);
assert.equal(result.reason, 'connection refused');
assert.ok(result.checkedAtMs > 0);
});
});
describe('attemptRecenter', () => {
it('calls recenter() and returns executed: true when eligible', async () => {
let recenterCalled = false;
const bot = createTxnBot(
makeDeps({
recenter: () => {
recenterCalled = true;
return Promise.resolve(makeTx('0xdeadbeef'));
},
}),
);
const result = await bot.attemptRecenter();
assert.equal(result.executed, true);
assert.equal(result.txHash, '0xdeadbeef');
assert.ok(recenterCalled, 'recenter() should have been called');
});
it('skips recenter() and returns executed: false when not eligible', async () => {
let recenterCalled = false;
const bot = createTxnBot(
makeDeps({
estimateRecenterGas: () => Promise.reject({ message: 'recenter not needed' }),
recenter: () => {
recenterCalled = true;
return Promise.resolve(makeTx('0xabc'));
},
}),
);
const result = await bot.attemptRecenter();
assert.equal(result.executed, false);
assert.equal(recenterCalled, false, 'recenter() must not be called when not eligible');
assert.ok(result.message);
});
it('propagates error thrown by recenter() — caught by liquidityLoop', async () => {
const bot = createTxnBot(
makeDeps({
recenter: () => Promise.reject(new Error('tx submission failed')),
}),
);
await assert.rejects(bot.attemptRecenter(), /tx submission failed/);
});
});