fix: address cashbox-export whole-branch review findings

- Reject dates that are not strict YYYY-MM-DD (was accepting full ISO
  datetimes, which silently produced empty exports instead of a 400)
  and reject from > to with a 400 before touching the team/DB.
- Emit the cashbox_export_download and cashbox_export_subscription_update
  audit log events that were declared but never fired, matching the
  audit trail every sibling feature already has.
- Restore full type checking on the pdfkit import via `import = require()`
  instead of an untyped require() with an eslint-disable.
- Tighten a cashbox.spec.ts assertion to check the exact dialog class
  instead of expect.anything(), so it can't pass with the wrong dialog
  wired to the Export button.
- Style and announce the export dialogs' error messages using this
  codebase's established error-message/role=alert pattern.
This commit is contained in:
Bastian Wagner
2026-08-04 09:20:44 +02:00
parent ce0b500d7a
commit da5998487a
12 changed files with 100 additions and 15 deletions

View File

@@ -30,7 +30,7 @@ const rangeValid: ValidatorFn = (group): ValidationErrors | null => {
<form [formGroup]="form" (ngSubmit)="download()">
<mat-dialog-content>
@if (downloadError()) {
<p class="error">{{ downloadError() }}</p>
<p class="error-message" role="alert">{{ downloadError() }}</p>
}
<mat-form-field appearance="outline">
<mat-label>Von</mat-label>
@@ -54,6 +54,14 @@ const rangeValid: ValidatorFn = (group): ValidationErrors | null => {
</mat-dialog-actions>
</form>
`,
styles: `
.error-message {
padding: 12px 16px;
border-radius: 12px;
color: var(--mat-sys-error);
background: var(--mat-sys-error-container);
}
`,
})
export class CashboxExportDialog {
protected readonly dialogRef = inject(MatDialogRef<CashboxExportDialog>);

View File

@@ -1,10 +1,10 @@
<h2 mat-dialog-title>Automatischen Versand einrichten</h2>
<mat-dialog-content>
@if (loadError()) {
<p class="error">{{ loadError() }}</p>
<p class="error-message" role="alert">{{ loadError() }}</p>
}
@if (saveError()) {
<p class="error">{{ saveError() }}</p>
<p class="error-message" role="alert">{{ saveError() }}</p>
}
<mat-form-field appearance="outline">
<mat-label>E-Mail-Adresse hinzufügen</mat-label>

View File

@@ -0,0 +1,6 @@
.error-message {
padding: 12px 16px;
border-radius: 12px;
color: var(--mat-sys-error);
background: var(--mat-sys-error-container);
}

View File

@@ -27,6 +27,7 @@ const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
MatSlideToggleModule,
],
templateUrl: './cashbox-export-subscription-dialog.html',
styleUrl: './cashbox-export-subscription-dialog.scss',
})
export class CashboxExportSubscriptionDialog {
protected readonly dialogRef = inject(MatDialogRef<CashboxExportSubscriptionDialog>);

View File

@@ -8,6 +8,7 @@ import { PenaltyApi } from '../../../core/team/penalty-api';
import { TeamStore } from '../../../core/team/team-store';
import { TransactionsApi } from '../../../core/team/transactions-api';
import { Cashbox } from './cashbox';
import { CashboxExportDialog } from './cashbox-export-dialog/cashbox-export-dialog';
describe('Cashbox', () => {
const team = {
@@ -292,7 +293,7 @@ describe('Cashbox', () => {
exportButton?.click();
expect(dialog.open).toHaveBeenCalledWith(
expect.anything(),
CashboxExportDialog,
expect.objectContaining({ data: { teamId: expect.any(Number) } }),
);
});