Projektarten: Zuordnen gibt Warnungen von assignProject weiter
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
36c7822783
commit
3e6f35f836
2 files changed
+51
-2
No files matched your search
@@ -50,6 +50,7 @@ export async function completeAssignment(
|
||||
const customer = !!forCustomer
|
||||
let createdTicketId = null
|
||||
let finalTicketId = null
|
||||
const warnings = []
|
||||
|
||||
if (customer) {
|
||||
if (!(await loadOrNull(config.collections.customers, customerId))) throw fail(400, 'Kunde nicht gefunden.')
|
||||
@@ -80,7 +81,9 @@ export async function completeAssignment(
|
||||
}
|
||||
|
||||
try {
|
||||
await assign(projectId, { customerId, ticketId: finalTicketId }, { now })
|
||||
const assigned = await assign(projectId, { customerId, ticketId: finalTicketId }, { now })
|
||||
// assignProject schluckt Umzug-/Nachtrage-Fehler und meldet sie als Warnungen.
|
||||
if (assigned?.warnings?.length) warnings.push(...assigned.warnings)
|
||||
} catch (err) {
|
||||
if (createdTicketId) await deleteTicket(createdTicketId).catch(() => {})
|
||||
throw err
|
||||
@@ -100,9 +103,10 @@ export async function completeAssignment(
|
||||
await updateProject(projectId, { subdomain: preview.subdomain, projectType: 'preview' })
|
||||
} catch (err) {
|
||||
// Art und Zuordnung sind gespeichert - die Preview laesst sich nachtraeglich einschalten.
|
||||
result.warnings = [`Die Preview konnte nicht eingeschaltet werden (${err.message}).`]
|
||||
warnings.push(`Die Preview konnte nicht eingeschaltet werden (${err.message}).`)
|
||||
}
|
||||
}
|
||||
if (warnings.length) result.warnings = warnings
|
||||
return result
|
||||
})
|
||||
}
|
||||
@@ -44,6 +44,10 @@ before(async () => {
|
||||
newProj('p9', 'doppelt'),
|
||||
newProj('p10', 'prev'),
|
||||
newProj('p11', 'route'),
|
||||
newProj('p13', 'warn'),
|
||||
newProj('p14', 'race'),
|
||||
newProj('p15', 'kunde'),
|
||||
newProj('p16', 'eins'),
|
||||
newProj('p12', 'schon', { kind: 'app', kindSetBy: 'Max', kindSetAt: '2026-09-29T08:00:00.000Z' }),
|
||||
],
|
||||
workorders: [
|
||||
@@ -176,6 +180,47 @@ test('Website mit Subdomain ⇒ updateWebsiteProject(preview)', async () => {
|
||||
assert.deepEqual(s.calls.update, [['p10', { subdomain: 'prev', projectType: 'preview' }]])
|
||||
})
|
||||
|
||||
test('Warnungen von assignProject und Preview-Fehler werden zusammengefuehrt', async () => {
|
||||
const s = stubs()
|
||||
s.deps.assignProject = async () => ({ ok: true, warnings: ['Umzug fehlgeschlagen'] })
|
||||
s.deps.updateWebsiteProject = async () => { throw new Error('Gitea aus') }
|
||||
const r = await completeAssignment('p13', { kind: 'website', forCustomer: true, customerId: 'c1', ticketId: 't1', preview: { subdomain: 'w' } }, opts(s.deps))
|
||||
assert.equal(r.ticketId, 't1')
|
||||
assert.equal(r.warnings.length, 2)
|
||||
assert.equal(r.warnings[0], 'Umzug fehlgeschlagen')
|
||||
assert.match(r.warnings[1], /Preview/)
|
||||
assert.equal(aw.get('websiteProjects', 'p13').kind, 'website')
|
||||
})
|
||||
|
||||
test('gleichzeitiger Doppelaufruf ⇒ genau ein Ticket und ein 409', async () => {
|
||||
const s = stubs()
|
||||
const before = aw.all('workorders').length
|
||||
const body = { kind: 'app', forCustomer: true, customerId: 'c1', newTicket: { topic: 'race' } }
|
||||
const res = await Promise.allSettled([completeAssignment('p14', body, opts(s.deps)), completeAssignment('p14', body, opts(s.deps))])
|
||||
assert.equal(res.filter((x) => x.status === 'fulfilled').length, 1)
|
||||
const rej = res.find((x) => x.status === 'rejected')
|
||||
assert.equal(rej.reason.status, 409)
|
||||
assert.equal(aw.all('workorders').length, before + 1)
|
||||
})
|
||||
|
||||
test('forCustomer mit unbekanntem Kunden ⇒ 400', async () => {
|
||||
const s = stubs()
|
||||
await assert.rejects(
|
||||
() => completeAssignment('p15', { kind: 'website', forCustomer: true, customerId: 'nix', newTicket: { topic: 'x' } }, opts(s.deps)),
|
||||
(e) => e.status === 400
|
||||
)
|
||||
assert.equal(aw.get('websiteProjects', 'p15').kind, undefined)
|
||||
})
|
||||
|
||||
test('ticketId und newTicket beide oder keins ⇒ 400', async () => {
|
||||
const s = stubs()
|
||||
const base = { kind: 'website', forCustomer: true, customerId: 'c1' }
|
||||
for (const extra of [{ ticketId: 't1', newTicket: { topic: 'x' } }, {}]) {
|
||||
await assert.rejects(() => completeAssignment('p16', { ...base, ...extra }, opts(s.deps)), (e) => e.status === 400)
|
||||
}
|
||||
assert.equal(aw.get('websiteProjects', 'p16').kind, undefined)
|
||||
})
|
||||
|
||||
test('Route: ohne Staff-JWT ⇒ 401, mit JWT intern 200, bereits zugeordnet 409, unbekannt 404', async () => {
|
||||
const post = (id, body, jwt) =>
|
||||
fetch(`${baseUrl}/api/admin/website-projects/${id}/zuordnen`, {
|
||||
|
||||
Reference in new issue
Block a user