mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:41:09 +02:00
test(mana/web): consistency guard for workbench-registry ↔ MANA_APPS
Adds the test that would have caught the inventar↔inventory drift
months earlier (commit 45790ffbb fixed the actual mismatch). Walks
both directions:
1. Every workbench-registered app must have a MANA_APPS entry, OR
be in the WORKBENCH_ONLY allowlist (currently `automations`,
`playground` — internal devtools we don't want in marketing).
2. Every MANA_APPS entry must be registered in the workbench, OR
be in the BRANDING_ONLY allowlist (`mana` itself, standalone
subdomains like `arcade`, "Coming Soon" placeholders like
`wisekeep`/`mail`/`events`, and modules whose workbench
integration is still pending like `guides`/`who`).
Plus a regression guard that fails loudly if anyone reintroduces
`inventar` as an id in either registry.
The point: every future drift between the two registries forces the
contributor to either fix it on the spot or explicitly classify the
new entry in one of the allowlists with a comment. No more silent
fail-open tier-gating.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c184991b3a
commit
df72a92b4c
1 changed files with 78 additions and 0 deletions
78
apps/mana/apps/web/src/lib/app-registry/registry.spec.ts
Normal file
78
apps/mana/apps/web/src/lib/app-registry/registry.spec.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import { describe, it, expect } from 'vitest';
|
||||
import { MANA_APPS } from '@mana/shared-branding';
|
||||
// Side-effect import: registers every workbench app via ./apps.
|
||||
// Without this, getAllApps() would return an empty list.
|
||||
import './apps';
|
||||
import { getAllApps } from './registry';
|
||||
|
||||
/**
|
||||
* Apps that intentionally exist in the workbench but are NOT in MANA_APPS
|
||||
* (e.g. internal devtools we don't want in marketing/branding lists).
|
||||
*
|
||||
* Adding to this list = "yes, this is supposed to drift, here's why".
|
||||
* Anything else triggers the test below and surfaces the drift early —
|
||||
* the kind of mismatch that produced the silent inventar↔inventory bug
|
||||
* before commit 45790ffbb.
|
||||
*/
|
||||
const WORKBENCH_ONLY = new Set(['automations', 'playground']);
|
||||
|
||||
/**
|
||||
* Apps that intentionally exist in MANA_APPS but are NOT in the workbench
|
||||
* registry (standalone subdomains, marketing-only "Coming Soon" entries,
|
||||
* modules that exist as routes/i18n but aren't workbench-integrated yet,
|
||||
* or the unified-app meta entry itself).
|
||||
*
|
||||
* When you add a new app to MANA_APPS, you must EITHER register it in the
|
||||
* workbench (apps/web/src/lib/app-registry/apps.ts) or add it here with a
|
||||
* comment explaining why it doesn't belong in the workbench. This forces
|
||||
* the drift conversation to happen at the time of the change instead of
|
||||
* months later.
|
||||
*/
|
||||
const BRANDING_ONLY = new Set([
|
||||
// Meta entry for the unified Mana app itself — it can't be a "module"
|
||||
// of its own workbench.
|
||||
'mana',
|
||||
// Standalone web app on its own subdomain (arcade.mana.how).
|
||||
'arcade',
|
||||
// Marketing placeholders, status: 'planning' / 'development'. No
|
||||
// workbench module exists yet — they only show up in the AppsPage
|
||||
// gallery as "Coming Soon" hints.
|
||||
'wisekeep',
|
||||
'mail',
|
||||
'events',
|
||||
// Status 'beta' but the workbench integration is still pending. Move
|
||||
// out of this list once the apps.ts entry exists.
|
||||
'guides',
|
||||
'who',
|
||||
]);
|
||||
|
||||
describe('app registry ↔ MANA_APPS consistency', () => {
|
||||
it('every workbench-registry app has a MANA_APPS entry or is in WORKBENCH_ONLY', () => {
|
||||
const brandingIds = new Set(MANA_APPS.map((a) => a.id));
|
||||
const unaccounted = getAllApps()
|
||||
.map((a) => a.id)
|
||||
.filter((id) => !brandingIds.has(id) && !WORKBENCH_ONLY.has(id));
|
||||
expect(unaccounted, `Workbench apps missing from MANA_APPS: ${unaccounted.join(', ')}`).toEqual(
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it('every MANA_APPS entry is registered in the workbench or is in BRANDING_ONLY', () => {
|
||||
const workbenchIds = new Set(getAllApps().map((a) => a.id));
|
||||
const unaccounted = MANA_APPS.map((a) => a.id).filter(
|
||||
(id) => !workbenchIds.has(id) && !BRANDING_ONLY.has(id)
|
||||
);
|
||||
expect(
|
||||
unaccounted,
|
||||
`MANA_APPS entries missing from workbench registry: ${unaccounted.join(', ')}`
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it('inventar→inventory rename is fully applied (regression guard)', () => {
|
||||
// The whole point of commit 45790ffbb. If anyone re-introduces an
|
||||
// `inventar` id in either registry, the join in registry.ts
|
||||
// silently goes back to fail-open for that module.
|
||||
const allIds = [...getAllApps().map((a) => a.id), ...MANA_APPS.map((a) => a.id)];
|
||||
expect(allIds).not.toContain('inventar');
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue