|
1 | 1 | import { HttpResponse, http } from 'msw' |
2 | | -import { fetchPoolGlobalStates, processPoolData } from '@/api/contracts' |
| 2 | +import { fetchPoolGlobalStates, isPoolGlobalStateComplete, processPoolData } from '@/api/contracts' |
3 | 3 | import { LocalPoolInfo } from '@/interfaces/validator' |
4 | 4 | import { |
5 | 5 | LAST_ROUND, |
@@ -48,8 +48,8 @@ describe('fetchPoolGlobalStates', () => { |
48 | 48 | lastPayout: 1000n, |
49 | 49 | algodVer: '3.23.1 rel/stable [34171a94] : v0.8.2 [c58270f]', |
50 | 50 | }) |
51 | | - // A pool that has never paid out simply has no lastPayout key |
52 | | - expect(states.get(1020n)?.lastPayout).toBeUndefined() |
| 51 | + // A pool whose node daemon has never reported has no algodVer, but still has lastPayout |
| 52 | + expect(states.get(1020n)).toEqual({ lastPayout: 1080n }) |
53 | 53 | }) |
54 | 54 |
|
55 | 55 | it('warns and returns what it got when algod truncates the created app list', async () => { |
@@ -109,10 +109,38 @@ describe('processPoolData', () => { |
109 | 109 | expect(paths).toContain('/v2/applications/1011') |
110 | 110 | }) |
111 | 111 |
|
112 | | - it('leaves lastPayout undefined for a pool that has never paid out', async () => { |
| 112 | + it('recovers a pool whose bulk entry came back without lastPayout', async () => { |
| 113 | + const paths = trackRequests() |
| 114 | + |
| 115 | + // Truthy, so a presence check would accept it and leave lastPayout undefined - which the |
| 116 | + // Status column renders as "payouts stopped" |
113 | 117 | const poolData = await processPoolData(poolFixture(1020n), { algodVer: '3.23.1' }) |
114 | 118 |
|
115 | | - expect(poolData.lastPayout).toBeUndefined() |
| 119 | + expect(poolData.lastPayout).toBe(1080n) |
| 120 | + expect(paths).toContain('/v2/applications/1020') |
| 121 | + }) |
| 122 | + |
| 123 | + it('does not re-read a complete entry that has no algodVer', async () => { |
| 124 | + const paths = trackRequests() |
| 125 | + |
| 126 | + const poolData = await processPoolData(poolFixture(1020n), { lastPayout: 1080n }) |
| 127 | + |
| 128 | + expect(poolData.lastPayout).toBe(1080n) |
116 | 129 | expect(poolData.balance).toBe(AVAILABLE_BALANCE) |
| 130 | + expect(paths.some((path) => path.startsWith('/v2/applications/'))).toBe(false) |
| 131 | + }) |
| 132 | +}) |
| 133 | + |
| 134 | +describe('isPoolGlobalStateComplete', () => { |
| 135 | + it('accepts an entry carrying lastPayout, with or without algodVer', () => { |
| 136 | + expect(isPoolGlobalStateComplete({ lastPayout: 1000n })).toBe(true) |
| 137 | + expect(isPoolGlobalStateComplete({ lastPayout: 0n, algodVer: '3.23.1' })).toBe(true) |
| 138 | + }) |
| 139 | + |
| 140 | + it('rejects a missing or partially decoded entry', () => { |
| 141 | + expect(isPoolGlobalStateComplete(undefined)).toBe(false) |
| 142 | + expect(isPoolGlobalStateComplete({})).toBe(false) |
| 143 | + // algodVer alone is not enough - lastPayout is what every pool is guaranteed to have |
| 144 | + expect(isPoolGlobalStateComplete({ algodVer: '3.23.1' })).toBe(false) |
117 | 145 | }) |
118 | 146 | }) |
0 commit comments