fix: updateCampaignStatus überschreibt keine bestehenden Scheduling-Daten, fehlende Tests ergänzt

This commit is contained in:
2026-04-17 09:55:45 +00:00
parent 4245a1fbde
commit 4a54d31bd0
2 changed files with 39 additions and 3 deletions

View File

@@ -102,6 +102,13 @@ describe('updateCampaign', () => {
const result = await updateCampaign('tenant1', 'uuid-1', {}) const result = await updateCampaign('tenant1', 'uuid-1', {})
expect(result.ok).toBe(false) expect(result.ok).toBe(false)
}) })
it('gibt err zurück wenn Kampagne nicht im Draft-Status', async () => {
mockClient.query.mockResolvedValueOnce([])
const result = await updateCampaign('tenant1', 'uuid-1', { name: 'Neu' })
expect(result.ok).toBe(false)
if (!result.ok) expect(result.error.message).toContain('Draft-Status')
})
}) })
describe('updateCampaignStatus', () => { describe('updateCampaignStatus', () => {
@@ -119,4 +126,20 @@ describe('updateCampaignStatus', () => {
const result = await updateCampaignStatus('tenant1', 'uuid-1', 'sent') const result = await updateCampaignStatus('tenant1', 'uuid-1', 'sent')
expect(result.ok).toBe(false) expect(result.ok).toBe(false)
}) })
it('setzt scheduledAt ohne cron_expression zu überschreiben', async () => {
const scheduled = new Date('2026-05-01T09:00:00Z')
mockClient.query.mockResolvedValueOnce([{ ...mockRow, status: 'scheduled', scheduled_at: scheduled }])
const result = await updateCampaignStatus('tenant1', 'uuid-1', 'scheduled', { scheduledAt: scheduled })
expect(result.ok).toBe(true)
expect(mockClient.query).toHaveBeenCalledWith(
expect.stringContaining('scheduled_at'),
expect.arrayContaining([scheduled])
)
// cron_expression darf NICHT im Query sein
expect(mockClient.query).not.toHaveBeenCalledWith(
expect.stringContaining('cron_expression'),
expect.anything()
)
})
}) })

View File

@@ -99,12 +99,25 @@ export async function updateCampaignStatus(
status: CampaignStatus, status: CampaignStatus,
extra?: { scheduledAt?: Date; cronExpression?: string } extra?: { scheduledAt?: Date; cronExpression?: string }
): Promise<Result<Campaign>> { ): Promise<Result<Campaign>> {
const fields: string[] = ['status = $1']
const values: unknown[] = [status]
let idx = 2
if (extra?.scheduledAt !== undefined) {
fields.push(`scheduled_at = $${idx++}`)
values.push(extra.scheduledAt)
}
if (extra?.cronExpression !== undefined) {
fields.push(`cron_expression = $${idx++}`)
values.push(extra.cronExpression)
}
values.push(id)
try { try {
const rows = await withTenant(tenantId, (client) => const rows = await withTenant(tenantId, (client) =>
client.query( client.query(
`UPDATE campaigns SET status = $1, scheduled_at = $2, cron_expression = $3 `UPDATE campaigns SET ${fields.join(', ')} WHERE id = $${idx} RETURNING *`,
WHERE id = $4 RETURNING *`, values
[status, extra?.scheduledAt ?? null, extra?.cronExpression ?? null, id]
) )
) )
if (rows.length === 0) return err(new Error('Kampagne nicht gefunden')) if (rows.length === 0) return err(new Error('Kampagne nicht gefunden'))