fix(260923-le6): Proxmox-Karte verweist Nicht-Admins nicht auf den Aktualisieren-Knopf
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,8 @@ vi.mock('next-intl', () => ({
|
|||||||
'card.unknownValue': 'unbekannt',
|
'card.unknownValue': 'unbekannt',
|
||||||
'card.lastPolledLabel': 'Letzte Abfrage',
|
'card.lastPolledLabel': 'Letzte Abfrage',
|
||||||
'card.notPolledYet': 'Noch keine Abfrage gelaufen. Klicken Sie oben auf „{refreshLabel}“.',
|
'card.notPolledYet': 'Noch keine Abfrage gelaufen. Klicken Sie oben auf „{refreshLabel}“.',
|
||||||
|
'card.notPolledYetAutomatic':
|
||||||
|
'Noch keine Abfrage gelaufen. Die Werte erscheinen nach der nächsten automatischen Abfrage.',
|
||||||
'card.refresh': 'Jetzt aktualisieren',
|
'card.refresh': 'Jetzt aktualisieren',
|
||||||
'card.lastOkLabel': 'Letzte erfolgreiche Messung',
|
'card.lastOkLabel': 'Letzte erfolgreiche Messung',
|
||||||
'card.pve.nodeCount': 'Knoten',
|
'card.pve.nodeCount': 'Knoten',
|
||||||
@@ -255,7 +257,7 @@ describe('ServerCard', () => {
|
|||||||
expect(screen.getByText(/Letzte Abfrage/)).toBeInTheDocument();
|
expect(screen.getByText(/Letzte Abfrage/)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Nachbesserung Befund 2: ein frisch angelegter, noch nie abgefragter Server zeigt den ruhigen Hinweis statt "Ein unerwarteter Fehler ist aufgetreten"', async () => {
|
it('Nachbesserung Befund 2: ein frisch angelegter, noch nie abgefragter Server zeigt Admins den ruhigen Hinweis mit Knopfverweis statt "Ein unerwarteter Fehler ist aufgetreten"', async () => {
|
||||||
const { ServerCard } = await import('./ServerCard');
|
const { ServerCard } = await import('./ServerCard');
|
||||||
// Zustand direkt nach `createServer`: leere Zwischenlagerzeile, noch nie abgefragt.
|
// Zustand direkt nach `createServer`: leere Zwischenlagerzeile, noch nie abgefragt.
|
||||||
const server = makeServer({
|
const server = makeServer({
|
||||||
@@ -273,12 +275,68 @@ describe('ServerCard', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
render(<ServerCard server={server} isAdmin />);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
screen.getByText('Noch keine Abfrage gelaufen. Klicken Sie oben auf „Jetzt aktualisieren“.'),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
// Ohne die Korrektur erschiene hier faelschlich die Sammelmeldung — roter Test.
|
||||||
|
expect(screen.queryByText('Unerwarteter Fehler.')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('260923-le6: isAdmin={false}, noch nie abgefragt -> automatischer Hinweis ohne Knopfverweis', async () => {
|
||||||
|
const { ServerCard } = await import('./ServerCard');
|
||||||
|
const server = makeServer({
|
||||||
|
status: {
|
||||||
|
id: 's1',
|
||||||
|
serverId: 'srv-1',
|
||||||
|
lastPolledAt: null,
|
||||||
|
lastOkAt: null,
|
||||||
|
reachable: false,
|
||||||
|
errorKind: null,
|
||||||
|
errorDetail: null,
|
||||||
|
rawSample: null,
|
||||||
|
updatedAt: '2026-09-23T10:00:00.000Z',
|
||||||
|
metrics: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<ServerCard server={server} isAdmin={false} />);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
screen.getByText(
|
||||||
|
'Noch keine Abfrage gelaufen. Die Werte erscheinen nach der nächsten automatischen Abfrage.',
|
||||||
|
),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText(/Jetzt aktualisieren/)).not.toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Unerwarteter Fehler.')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('260923-le6: isAdmin weggelassen, noch nie abgefragt -> verhaelt sich wie isAdmin={false} (sichere Vorgabe)', async () => {
|
||||||
|
const { ServerCard } = await import('./ServerCard');
|
||||||
|
const server = makeServer({
|
||||||
|
status: {
|
||||||
|
id: 's1',
|
||||||
|
serverId: 'srv-1',
|
||||||
|
lastPolledAt: null,
|
||||||
|
lastOkAt: null,
|
||||||
|
reachable: false,
|
||||||
|
errorKind: null,
|
||||||
|
errorDetail: null,
|
||||||
|
rawSample: null,
|
||||||
|
updatedAt: '2026-09-23T10:00:00.000Z',
|
||||||
|
metrics: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
render(<ServerCard server={server} />);
|
render(<ServerCard server={server} />);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen.getByText('Noch keine Abfrage gelaufen. Klicken Sie oben auf „Jetzt aktualisieren“.'),
|
screen.getByText(
|
||||||
|
'Noch keine Abfrage gelaufen. Die Werte erscheinen nach der nächsten automatischen Abfrage.',
|
||||||
|
),
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
// Ohne die Korrektur erschiene hier faelschlich die Sammelmeldung — roter Test.
|
expect(screen.queryByText(/Jetzt aktualisieren/)).not.toBeInTheDocument();
|
||||||
expect(screen.queryByText('Unerwarteter Fehler.')).not.toBeInTheDocument();
|
expect(screen.queryByText('Unerwarteter Fehler.')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -146,13 +146,14 @@ function errorMessage(t: ReturnType<typeof useTranslations>, kind: ProxmoxErrorK
|
|||||||
|
|
||||||
interface ServerCardProps {
|
interface ServerCardProps {
|
||||||
server: ProxmoxServer;
|
server: ProxmoxServer;
|
||||||
|
isAdmin?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Anzeige EINES Servers (Aufgabe 6) — verzweigt ueber `productType` auf der
|
* Anzeige EINES Servers (Aufgabe 6) — verzweigt ueber `productType` auf der
|
||||||
* unterscheidbaren Union aus Aufgabe 3.
|
* unterscheidbaren Union aus Aufgabe 3.
|
||||||
*/
|
*/
|
||||||
export function ServerCard({ server }: ServerCardProps) {
|
export function ServerCard({ server, isAdmin = false }: ServerCardProps) {
|
||||||
const t = useTranslations('proxmox');
|
const t = useTranslations('proxmox');
|
||||||
const unknown = t('card.unknownValue');
|
const unknown = t('card.unknownValue');
|
||||||
const status = server.status;
|
const status = server.status;
|
||||||
@@ -178,11 +179,13 @@ export function ServerCard({ server }: ServerCardProps) {
|
|||||||
(`lastPolledAt === null`), zeigt einen ruhigen Hinweis statt der
|
(`lastPolledAt === null`), zeigt einen ruhigen Hinweis statt der
|
||||||
Fehlermeldung — die leere Zwischenlagerzeile aus `createServer` hat
|
Fehlermeldung — die leere Zwischenlagerzeile aus `createServer` hat
|
||||||
`reachable: false` und `errorKind: null`, was sonst faelschlich als
|
`reachable: false` und `errorKind: null`, was sonst faelschlich als
|
||||||
"unbekannter Fehler" erschien.
|
"unbekannter Fehler" erschien. Nicht-Admins sehen den Knopf nicht
|
||||||
|
(der Poll-Endpunkt verlangt ADMIN/SUPER_ADMIN) und bekommen deshalb
|
||||||
|
den Text ohne Knopfverweis (260923-le6).
|
||||||
*/}
|
*/}
|
||||||
{status && !status.lastPolledAt && (
|
{status && !status.lastPolledAt && (
|
||||||
<p className="mt-2 text-xs text-muted-foreground">
|
<p className="mt-2 text-xs text-muted-foreground">
|
||||||
{t('card.notPolledYet', { refreshLabel: t('card.refresh') })}
|
{isAdmin ? t('card.notPolledYet', { refreshLabel: t('card.refresh') }) : t('card.notPolledYetAutomatic')}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -713,6 +713,7 @@
|
|||||||
"unknownValue": "unbekannt",
|
"unknownValue": "unbekannt",
|
||||||
"lastPolledLabel": "Letzte Abfrage",
|
"lastPolledLabel": "Letzte Abfrage",
|
||||||
"notPolledYet": "Noch keine Abfrage gelaufen. Klicken Sie oben auf „{refreshLabel}“.",
|
"notPolledYet": "Noch keine Abfrage gelaufen. Klicken Sie oben auf „{refreshLabel}“.",
|
||||||
|
"notPolledYetAutomatic": "Noch keine Abfrage gelaufen. Die Werte erscheinen nach der nächsten automatischen Abfrage.",
|
||||||
"lastOkLabel": "Letzte erfolgreiche Messung",
|
"lastOkLabel": "Letzte erfolgreiche Messung",
|
||||||
"refresh": "Jetzt aktualisieren",
|
"refresh": "Jetzt aktualisieren",
|
||||||
"refreshing": "Wird aktualisiert...",
|
"refreshing": "Wird aktualisiert...",
|
||||||
|
|||||||
@@ -713,6 +713,7 @@
|
|||||||
"unknownValue": "unknown",
|
"unknownValue": "unknown",
|
||||||
"lastPolledLabel": "Last poll",
|
"lastPolledLabel": "Last poll",
|
||||||
"notPolledYet": "No poll has run yet. Click \"{refreshLabel}\" above.",
|
"notPolledYet": "No poll has run yet. Click \"{refreshLabel}\" above.",
|
||||||
|
"notPolledYetAutomatic": "No poll has run yet. The values will appear after the next automatic poll.",
|
||||||
"lastOkLabel": "Last successful measurement",
|
"lastOkLabel": "Last successful measurement",
|
||||||
"refresh": "Refresh now",
|
"refresh": "Refresh now",
|
||||||
"refreshing": "Refreshing...",
|
"refreshing": "Refreshing...",
|
||||||
|
|||||||
Reference in New Issue
Block a user