Offer rebuild retry for failed creation commands

This commit is contained in:
2026-10-08 14:05:38 -04:00
parent 511f090552
commit e01b143a09
12 changed files with 298 additions and 20 deletions
@@ -19,6 +19,20 @@ function fixture(): ProvisioningDetail {
}
describe('provisioning outcome and evidence presentation', () => {
it('distinguishes a failed creation retry from readiness verification and its linked recovery', () => {
const detail = fixture();
detail.deployment.state = 'failed';
detail.canRetryWithRebuild = true;
expect(provisioningOutcome(detail)).toMatchObject({ active: false, headline: 'Create failed' });
expect(provisioningOutcome(detail).description).toContain('new attempt for the same lobby and port');
detail.canRetryWithRebuild = false;
detail.progress = progress({ recovery: { state: 'transferred', operationId: 'recovery-a', at, message: 'Rebuild requested' } });
expect(provisioningOutcome(detail).headline).toBe('Create failed');
expect(provisioningOutcome(detail).description).toContain('linked operation');
detail.progress = progress();
detail.canResumeVerification = true;
expect(provisioningOutcome(detail).description).toContain('remaining restart and rebuild recovery steps');
});
it('distinguishes cancellation from confirmed cleanup and validates its link data', () => {
const detail = fixture();
detail.deployment.state = 'cancelled';
@@ -142,6 +156,15 @@ describe('provisioning outcome and evidence presentation', () => {
});
describe('provisioning response and return-context boundaries', () => {
it('accepts optional retry eligibility only as an authoritative boolean', () => {
const detail = fixture();
for (const canRetryWithRebuild of [undefined, false, true]) {
expect(isProvisioningDetail({ ...detail, canRetryWithRebuild }, detail.deployment.id)).toBe(true);
}
for (const canRetryWithRebuild of ['true', 1, null]) {
expect(isProvisioningDetail({ ...detail, canRetryWithRebuild }, detail.deployment.id)).toBe(false);
}
});
it('accepts persisted usernames and legacy details but rejects malformed requesters', () => {
const detail = fixture();
for (const requested_by of [undefined, null, 'alice']) {