fix(cropper): make load failures visible; loud config errors

'Load next queued' did nothing because the running server had been started
without its env file (a restart used '-f .env' from tools/, where no .env
exists), so the cropper was unconfigured and every action answered 503 —
and none of that was visible, because notifications never rendered either:

- notifications used cds-toast/cds-toast-item, which the Carbon bundle does
  not define; a cds-toast-notification element renders nothing standalone in
  this build. The cropper now uses cds-inline-notification in the fixed
  toast viewport (renders, themed, close button) like the wizard
- an unconfigured deployment now says so on the page (503 'Cropper
  unavailable') instead of rendering actions that all fail, and logs a
  startup warning naming the missing credentials
- tests: notifications use a registered element; unconfigured page 503
This commit is contained in:
2026-10-01 04:36:31 +01:00
parent cb5b151988
commit 95200b6abf
6 changed files with 44 additions and 11 deletions
+9
View File
@@ -217,6 +217,10 @@ test('unconfigured deployment: cropper answers 503, other tools unaffected', asy
const cookies = await login(base);
const res = await fetch(`${base}/cropper/api/baseUrl`, { headers: { cookie: cookies } });
assert.equal(res.status, 503);
// the page says so too, rather than rendering actions that all fail
const page = await fetch(`${base}/cropper`, { headers: { cookie: cookies } });
assert.equal(page.status, 503);
assert.match(await page.text(), /not configured/i);
const landing = await fetch(`${base}/`);
assert.equal(landing.status, 200);
} finally {
@@ -233,6 +237,11 @@ test('crop gate: permitted operator loads the page; denied operator does not', a
const html = await page.text();
assert.match(html, /Smart Photo Editor|Image Cropper/);
assert.match(html, /window\.__SESSION__ = \{/, 'session injected server-side');
assert.match(html, /cds-header-nav-item href="\/cropper" aria-current="page"/);
// notifications must use a component the bundle actually defines
assert.match(html, /cds-inline-notification/);
assert.ok(!/cds-toast-item/.test(html), 'cds-toast-item is not a registered element');
assert.match(html, /cds-side-nav-link href="\/cropper" aria-current="page"/);
} finally {
await ok.stop();
}