diff --git a/backend/src/controllers/stream.controller.ts b/backend/src/controllers/stream.controller.ts index 7823c9e9..8a908b9c 100644 --- a/backend/src/controllers/stream.controller.ts +++ b/backend/src/controllers/stream.controller.ts @@ -598,6 +598,13 @@ export const topUpStreamHandler = async (req: Request, res: Response) => { return res.status(403).json({ error: 'Only the stream sender may top up this stream' }); } + if (!stream.isActive) { + return res.status(409).json({ error: 'Conflict', message: 'Cannot top up an inactive stream' }); + } + if (stream.isPaused) { + return res.status(409).json({ error: 'Conflict', message: 'Cannot top up a paused stream' }); + } + const txHash = await topUpStream(streamId, amount, callerAddress); const newDeposited = (BigInt(stream.depositedAmount) + amount).toString(); diff --git a/backend/tests/integration/top-up.test.ts b/backend/tests/integration/top-up.test.ts index e6549e8f..9c42e2af 100644 --- a/backend/tests/integration/top-up.test.ts +++ b/backend/tests/integration/top-up.test.ts @@ -161,4 +161,28 @@ describe('POST /v1/streams/:streamId/top-up', () => { }), ); }); + + it('returns 409 when stream is inactive', async () => { + vi.mocked(mockPrisma.stream.findUnique).mockResolvedValue({ ...mockStream, isActive: false } as any); + + const res = await request(app) + .post('/v1/streams/42/top-up') + .set('Authorization', 'Bearer dummy') + .send({ amount: '1000' }); + + expect(res.status).toBe(409); + expect(res.body.message).toMatch(/inactive stream/); + }); + + it('returns 409 when stream is paused', async () => { + vi.mocked(mockPrisma.stream.findUnique).mockResolvedValue({ ...mockStream, isPaused: true } as any); + + const res = await request(app) + .post('/v1/streams/42/top-up') + .set('Authorization', 'Bearer dummy') + .send({ amount: '1000' }); + + expect(res.status).toBe(409); + expect(res.body.message).toMatch(/paused stream/); + }); });