reviewflow 3.24.2 → 3.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/dashboard/index.html +212 -100
  3. package/dist/dashboard/modules/i18n.d.ts.map +1 -1
  4. package/dist/dashboard/modules/i18n.js +14 -4
  5. package/dist/dashboard/modules/i18n.js.map +1 -1
  6. package/dist/dashboard/modules/sectionVisibility.d.ts +17 -0
  7. package/dist/dashboard/modules/sectionVisibility.d.ts.map +1 -0
  8. package/dist/dashboard/modules/sectionVisibility.js +20 -0
  9. package/dist/dashboard/modules/sectionVisibility.js.map +1 -0
  10. package/dist/frameworks/settings/runtimeSettings.d.ts +36 -11
  11. package/dist/frameworks/settings/runtimeSettings.d.ts.map +1 -1
  12. package/dist/frameworks/settings/runtimeSettings.js +98 -9
  13. package/dist/frameworks/settings/runtimeSettings.js.map +1 -1
  14. package/dist/main/server.d.ts.map +1 -1
  15. package/dist/main/server.js +4 -0
  16. package/dist/main/server.js.map +1 -1
  17. package/dist/modules/cli-configuration/interface-adapters/controllers/http/settings.routes.d.ts.map +1 -1
  18. package/dist/modules/cli-configuration/interface-adapters/controllers/http/settings.routes.js +7 -11
  19. package/dist/modules/cli-configuration/interface-adapters/controllers/http/settings.routes.js.map +1 -1
  20. package/dist/modules/review-execution/entities/reviewRequest/reviewRequestState.valueObject.js +1 -1
  21. package/dist/modules/review-execution/entities/reviewRequest/reviewRequestState.valueObject.js.map +1 -1
  22. package/dist/modules/tracking/interface-adapters/controllers/http/mrTracking.routes.d.ts.map +1 -1
  23. package/dist/modules/tracking/interface-adapters/controllers/http/mrTracking.routes.js +42 -0
  24. package/dist/modules/tracking/interface-adapters/controllers/http/mrTracking.routes.js.map +1 -1
  25. package/dist/modules/tracking/usecases/tracking/transitionState.usecase.d.ts +6 -0
  26. package/dist/modules/tracking/usecases/tracking/transitionState.usecase.d.ts.map +1 -1
  27. package/dist/modules/tracking/usecases/tracking/transitionState.usecase.js +7 -0
  28. package/dist/modules/tracking/usecases/tracking/transitionState.usecase.js.map +1 -1
  29. package/dist/tests/acceptance/182-mark-pending-fix-as-merged.acceptance.test.d.ts +19 -0
  30. package/dist/tests/acceptance/182-mark-pending-fix-as-merged.acceptance.test.d.ts.map +1 -0
  31. package/dist/tests/acceptance/182-mark-pending-fix-as-merged.acceptance.test.js +157 -0
  32. package/dist/tests/acceptance/182-mark-pending-fix-as-merged.acceptance.test.js.map +1 -0
  33. package/dist/tests/units/dashboard/dashboardLayout.test.d.ts +13 -0
  34. package/dist/tests/units/dashboard/dashboardLayout.test.d.ts.map +1 -0
  35. package/dist/tests/units/dashboard/dashboardLayout.test.js +247 -0
  36. package/dist/tests/units/dashboard/dashboardLayout.test.js.map +1 -0
  37. package/dist/tests/units/dashboard/modules/sectionVisibility.test.d.ts +2 -0
  38. package/dist/tests/units/dashboard/modules/sectionVisibility.test.d.ts.map +1 -0
  39. package/dist/tests/units/dashboard/modules/sectionVisibility.test.js +58 -0
  40. package/dist/tests/units/dashboard/modules/sectionVisibility.test.js.map +1 -0
  41. package/dist/tests/units/entities/reviewRequestState.valueObject.test.js +5 -0
  42. package/dist/tests/units/entities/reviewRequestState.valueObject.test.js.map +1 -1
  43. package/dist/tests/units/frameworks/settings/runtimeSettings.test.js +123 -16
  44. package/dist/tests/units/frameworks/settings/runtimeSettings.test.js.map +1 -1
  45. package/dist/tests/units/interface-adapters/controllers/http/settings.routes.test.js +1 -1
  46. package/dist/tests/units/interface-adapters/controllers/http/settings.routes.test.js.map +1 -1
  47. package/dist/tests/units/modules/tracking/interface-adapters/controllers/http/mrTracking.routes.test.js +37 -0
  48. package/dist/tests/units/modules/tracking/interface-adapters/controllers/http/mrTracking.routes.test.js.map +1 -1
  49. package/dist/tests/units/usecases/tracking/transitionState.usecase.test.js +36 -0
  50. package/dist/tests/units/usecases/tracking/transitionState.usecase.test.js.map +1 -1
  51. package/package.json +1 -1
@@ -0,0 +1,19 @@
1
+ /**
2
+ * SPEC-182 — Manually mark a pending-fix MR as merged
3
+ *
4
+ * Outer-loop acceptance test (SDD): exercises POST /api/mr-tracking/mark-as-merged
5
+ * through the Fastify plugin wired with the in-memory tracking gateway. Covers
6
+ * the 8 scenarios from the spec.
7
+ *
8
+ * Scenarios from docs/specs/182-mark-pending-fix-as-merged.md:
9
+ * - valid pending-fix → merged: 200 + state="merged" + mergedAt set
10
+ * - pending-approval rejected: 409 + invalid-current-state message
11
+ * - approved rejected: 409 + invalid-current-state message
12
+ * - merged rejected: 409 + invalid-current-state message
13
+ * - unknown MR: 404 + "MR non trouvée"
14
+ * - missing mrId: 400 + "mrId requis"
15
+ * - missing project path: 400 + "Chemin du projet requis"
16
+ * - invalid project path: 400 + "Chemin invalide"
17
+ */
18
+ export {};
19
+ //# sourceMappingURL=182-mark-pending-fix-as-merged.acceptance.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"182-mark-pending-fix-as-merged.acceptance.test.d.ts","sourceRoot":"","sources":["../../../src/tests/acceptance/182-mark-pending-fix-as-merged.acceptance.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * SPEC-182 — Manually mark a pending-fix MR as merged
3
+ *
4
+ * Outer-loop acceptance test (SDD): exercises POST /api/mr-tracking/mark-as-merged
5
+ * through the Fastify plugin wired with the in-memory tracking gateway. Covers
6
+ * the 8 scenarios from the spec.
7
+ *
8
+ * Scenarios from docs/specs/182-mark-pending-fix-as-merged.md:
9
+ * - valid pending-fix → merged: 200 + state="merged" + mergedAt set
10
+ * - pending-approval rejected: 409 + invalid-current-state message
11
+ * - approved rejected: 409 + invalid-current-state message
12
+ * - merged rejected: 409 + invalid-current-state message
13
+ * - unknown MR: 404 + "MR non trouvée"
14
+ * - missing mrId: 400 + "mrId requis"
15
+ * - missing project path: 400 + "Chemin du projet requis"
16
+ * - invalid project path: 400 + "Chemin invalide"
17
+ */
18
+ import Fastify from 'fastify';
19
+ import { beforeEach, describe, expect, it } from 'vitest';
20
+ import { mrTrackingRoutes } from '../../modules/tracking/interface-adapters/controllers/http/mrTracking.routes.js';
21
+ import { InMemoryReviewRequestTrackingGateway } from '../../tests/stubs/reviewRequestTracking.stub.js';
22
+ import { TrackedMrFactory } from '../../tests/factories/trackedMr.factory.js';
23
+ const INVALID_CURRENT_STATE_MESSAGE = 'Seules les MR en correction peuvent être marquées comme mergées';
24
+ async function buildApp(gateway) {
25
+ const app = Fastify();
26
+ await app.register(mrTrackingRoutes, {
27
+ reviewRequestTrackingGateway: gateway,
28
+ getQualityThreshold: () => null,
29
+ });
30
+ return app;
31
+ }
32
+ function seedMr(gateway, projectPath, overrides) {
33
+ gateway.create(projectPath, TrackedMrFactory.create({ id: 'mr-42', ...overrides }));
34
+ }
35
+ describe('Acceptance — SPEC-182: Manually mark a pending-fix MR as merged', () => {
36
+ let gateway;
37
+ const projectPath = '/home/user/proj';
38
+ beforeEach(() => {
39
+ gateway = new InMemoryReviewRequestTrackingGateway();
40
+ });
41
+ describe('Rule: pending-fix MR can be transitioned to merged', () => {
42
+ it('valid pending-fix transition → status "merged" + mergedAt set', async () => {
43
+ seedMr(gateway, projectPath, { state: 'pending-fix' });
44
+ const app = await buildApp(gateway);
45
+ const response = await app.inject({
46
+ method: 'POST',
47
+ url: '/api/mr-tracking/mark-as-merged',
48
+ payload: { mrId: 'mr-42', projectPath },
49
+ });
50
+ expect(response.statusCode).toBe(200);
51
+ const body = response.json();
52
+ expect(body.success).toBe(true);
53
+ expect(body.mrId).toBe('mr-42');
54
+ const updated = gateway.getById(projectPath, 'mr-42');
55
+ expect(updated?.state).toBe('merged');
56
+ expect(updated?.mergedAt).not.toBeNull();
57
+ });
58
+ });
59
+ describe('Rule: transition restricted to pending-fix state', () => {
60
+ it('pending-approval rejected → 409 with invalid-current-state message', async () => {
61
+ seedMr(gateway, projectPath, { state: 'pending-approval' });
62
+ const app = await buildApp(gateway);
63
+ const response = await app.inject({
64
+ method: 'POST',
65
+ url: '/api/mr-tracking/mark-as-merged',
66
+ payload: { mrId: 'mr-42', projectPath },
67
+ });
68
+ expect(response.statusCode).toBe(409);
69
+ const body = response.json();
70
+ expect(body.success).toBe(false);
71
+ expect(body.error).toBe(INVALID_CURRENT_STATE_MESSAGE);
72
+ const untouched = gateway.getById(projectPath, 'mr-42');
73
+ expect(untouched?.state).toBe('pending-approval');
74
+ expect(untouched?.mergedAt).toBeNull();
75
+ });
76
+ it('approved rejected → 409 with invalid-current-state message', async () => {
77
+ seedMr(gateway, projectPath, { state: 'approved' });
78
+ const app = await buildApp(gateway);
79
+ const response = await app.inject({
80
+ method: 'POST',
81
+ url: '/api/mr-tracking/mark-as-merged',
82
+ payload: { mrId: 'mr-42', projectPath },
83
+ });
84
+ expect(response.statusCode).toBe(409);
85
+ const body = response.json();
86
+ expect(body.success).toBe(false);
87
+ expect(body.error).toBe(INVALID_CURRENT_STATE_MESSAGE);
88
+ const untouched = gateway.getById(projectPath, 'mr-42');
89
+ expect(untouched?.state).toBe('approved');
90
+ expect(untouched?.mergedAt).toBeNull();
91
+ });
92
+ it('merged rejected → 409 with invalid-current-state message', async () => {
93
+ seedMr(gateway, projectPath, { state: 'merged', mergedAt: '2026-01-01T00:00:00.000Z' });
94
+ const app = await buildApp(gateway);
95
+ const response = await app.inject({
96
+ method: 'POST',
97
+ url: '/api/mr-tracking/mark-as-merged',
98
+ payload: { mrId: 'mr-42', projectPath },
99
+ });
100
+ expect(response.statusCode).toBe(409);
101
+ const body = response.json();
102
+ expect(body.success).toBe(false);
103
+ expect(body.error).toBe(INVALID_CURRENT_STATE_MESSAGE);
104
+ });
105
+ });
106
+ describe('Rule: action requires a known MR and valid inputs', () => {
107
+ it('unknown MR → 404 with "MR non trouvée"', async () => {
108
+ const app = await buildApp(gateway);
109
+ const response = await app.inject({
110
+ method: 'POST',
111
+ url: '/api/mr-tracking/mark-as-merged',
112
+ payload: { mrId: 'ghost', projectPath },
113
+ });
114
+ expect(response.statusCode).toBe(404);
115
+ const body = response.json();
116
+ expect(body.success).toBe(false);
117
+ expect(body.error).toBe('MR non trouvée');
118
+ });
119
+ it('missing mrId → 400 with "mrId requis"', async () => {
120
+ const app = await buildApp(gateway);
121
+ const response = await app.inject({
122
+ method: 'POST',
123
+ url: '/api/mr-tracking/mark-as-merged',
124
+ payload: { mrId: '', projectPath },
125
+ });
126
+ expect(response.statusCode).toBe(400);
127
+ const body = response.json();
128
+ expect(body.success).toBe(false);
129
+ expect(body.error).toBe('mrId requis');
130
+ });
131
+ it('missing project path → 400 with "Chemin du projet requis"', async () => {
132
+ const app = await buildApp(gateway);
133
+ const response = await app.inject({
134
+ method: 'POST',
135
+ url: '/api/mr-tracking/mark-as-merged',
136
+ payload: { mrId: 'mr-42', projectPath: '' },
137
+ });
138
+ expect(response.statusCode).toBe(400);
139
+ const body = response.json();
140
+ expect(body.success).toBe(false);
141
+ expect(body.error).toBe('Chemin du projet requis');
142
+ });
143
+ it('invalid project path → 400 with "Chemin invalide"', async () => {
144
+ const app = await buildApp(gateway);
145
+ const response = await app.inject({
146
+ method: 'POST',
147
+ url: '/api/mr-tracking/mark-as-merged',
148
+ payload: { mrId: 'mr-42', projectPath: '../etc' },
149
+ });
150
+ expect(response.statusCode).toBe(400);
151
+ const body = response.json();
152
+ expect(body.success).toBe(false);
153
+ expect(body.error).toBe('Chemin invalide');
154
+ });
155
+ });
156
+ });
157
+ //# sourceMappingURL=182-mark-pending-fix-as-merged.acceptance.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"182-mark-pending-fix-as-merged.acceptance.test.js","sourceRoot":"","sources":["../../../src/tests/acceptance/182-mark-pending-fix-as-merged.acceptance.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * SPEC-181 — Dashboard Empty-State Restructure & Team-First Layout
3
+ *
4
+ * SDD outer-loop test (per orchestrator instruction — UI-only spec, the
5
+ * dashboard test convention keeps acceptance inside src/tests/units/dashboard/).
6
+ * Structural assertions on src/dashboard/index.html via raw-string + regex,
7
+ * matching the precedent of SPEC-178 acceptance test. No jsdom dependency
8
+ * required (anti-overengineering — same fidelity as SPEC-178).
9
+ *
10
+ * Source of truth: docs/specs/181-dashboard-empty-state-restructure.md.
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=dashboardLayout.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboardLayout.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/units/dashboard/dashboardLayout.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * SPEC-181 — Dashboard Empty-State Restructure & Team-First Layout
3
+ *
4
+ * SDD outer-loop test (per orchestrator instruction — UI-only spec, the
5
+ * dashboard test convention keeps acceptance inside src/tests/units/dashboard/).
6
+ * Structural assertions on src/dashboard/index.html via raw-string + regex,
7
+ * matching the precedent of SPEC-178 acceptance test. No jsdom dependency
8
+ * required (anti-overengineering — same fidelity as SPEC-178).
9
+ *
10
+ * Source of truth: docs/specs/181-dashboard-empty-state-restructure.md.
11
+ */
12
+ import { readFileSync } from 'node:fs';
13
+ import { dirname, join } from 'node:path';
14
+ import { fileURLToPath } from 'node:url';
15
+ import { beforeEach, describe, expect, it } from 'vitest';
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+ const PROJECT_ROOT = join(__dirname, '..', '..', '..', '..');
19
+ const INDEX_HTML_PATH = join(PROJECT_ROOT, 'src', 'dashboard', 'index.html');
20
+ function extractMainBlock(html) {
21
+ const match = html.match(/<main class="dashboard-main">[\s\S]*?<\/main>/);
22
+ return match?.[0] ?? '';
23
+ }
24
+ function extractSidebarBlock(html) {
25
+ const match = html.match(/<aside class="dashboard-sidebar"[\s\S]*?<\/aside>/);
26
+ return match?.[0] ?? '';
27
+ }
28
+ function extractInlineScript(html) {
29
+ const match = html.match(/<script type="module">[\s\S]*?<\/script>/);
30
+ return match?.[0] ?? '';
31
+ }
32
+ function extractElementSubtree(html, openingTag) {
33
+ const startIndex = html.indexOf(openingTag);
34
+ if (startIndex === -1)
35
+ return '';
36
+ const tagOpenRegex = /<div\b[^>]*>/g;
37
+ const tagCloseRegex = /<\/div>/g;
38
+ tagOpenRegex.lastIndex = startIndex;
39
+ const firstOpen = tagOpenRegex.exec(html);
40
+ if (firstOpen === null || firstOpen.index !== startIndex)
41
+ return '';
42
+ let depth = 1;
43
+ let cursor = startIndex + firstOpen[0].length;
44
+ while (depth > 0) {
45
+ tagOpenRegex.lastIndex = cursor;
46
+ tagCloseRegex.lastIndex = cursor;
47
+ const nextOpen = tagOpenRegex.exec(html);
48
+ const nextClose = tagCloseRegex.exec(html);
49
+ if (nextClose === null)
50
+ return '';
51
+ if (nextOpen !== null && nextOpen.index < nextClose.index) {
52
+ depth += 1;
53
+ cursor = nextOpen.index + nextOpen[0].length;
54
+ }
55
+ else {
56
+ depth -= 1;
57
+ cursor = nextClose.index + nextClose[0].length;
58
+ }
59
+ }
60
+ return html.substring(startIndex, cursor);
61
+ }
62
+ function extractTopLevelChildIds(mainBlock) {
63
+ const childRegex = /^\s{8}<(div|section|main|aside|nav|button|footer|header|article)\b([^>]*)>/gm;
64
+ const ids = [];
65
+ let result = childRegex.exec(mainBlock);
66
+ while (result !== null) {
67
+ const attributes = result[2] ?? '';
68
+ const idMatch = attributes.match(/id="([^"]+)"/);
69
+ const classMatch = attributes.match(/class="([^"]+)"/);
70
+ if (idMatch) {
71
+ ids.push(`#${idMatch[1]}`);
72
+ }
73
+ else if (classMatch) {
74
+ ids.push(`.${classMatch[1].split(/\s+/)[0]}`);
75
+ }
76
+ else {
77
+ ids.push('?');
78
+ }
79
+ result = childRegex.exec(mainBlock);
80
+ }
81
+ return ids;
82
+ }
83
+ describe('SPEC-181 — Dashboard Empty-State Restructure & Team-First Layout', () => {
84
+ let indexHtml;
85
+ let mainBlock;
86
+ let sidebarBlock;
87
+ let inlineScript;
88
+ beforeEach(() => {
89
+ indexHtml = readFileSync(INDEX_HTML_PATH, 'utf-8');
90
+ mainBlock = extractMainBlock(indexHtml);
91
+ sidebarBlock = extractSidebarBlock(indexHtml);
92
+ inlineScript = extractInlineScript(indexHtml);
93
+ });
94
+ describe('main DOM order', () => {
95
+ it('team-section is the first top-level child of <main class="dashboard-main">', () => {
96
+ const childIds = extractTopLevelChildIds(mainBlock);
97
+ expect(childIds[0]).toBe('#team-section');
98
+ });
99
+ it('focus-strip is the second top-level child of <main class="dashboard-main">', () => {
100
+ const childIds = extractTopLevelChildIds(mainBlock);
101
+ expect(childIds[1]).toBe('.focus-strip');
102
+ });
103
+ it('matches the expected top-level child order inside <main>', () => {
104
+ const childIds = extractTopLevelChildIds(mainBlock);
105
+ expect(childIds).toEqual([
106
+ '#team-section',
107
+ '.focus-strip',
108
+ '#overview-section',
109
+ '#data-loading-state',
110
+ '#config-info',
111
+ '#claude-login-section',
112
+ '#git-login-section',
113
+ '#pending-reviews-section',
114
+ '#logs-section',
115
+ '#active-reviews-section',
116
+ '#active-followups-section',
117
+ '#pending-fix-section',
118
+ '#pending-approval-section',
119
+ '#completed-reviews-section',
120
+ '#cleanup-section',
121
+ '.refresh-info',
122
+ ]);
123
+ });
124
+ it('does NOT contain #claude-economics-section inside <main>', () => {
125
+ expect(mainBlock).not.toMatch(/id="claude-economics-section"/);
126
+ });
127
+ it('does NOT contain #stats-section inside <main>', () => {
128
+ expect(mainBlock).not.toMatch(/id="stats-section"/);
129
+ });
130
+ });
131
+ describe('sidebar buttons', () => {
132
+ it('#open-economics-sheet-btn exists inside <aside class="dashboard-sidebar">', () => {
133
+ expect(sidebarBlock).toMatch(/id="open-economics-sheet-btn"/);
134
+ });
135
+ it('#open-economics-sheet-btn has no `hidden` attribute (always visible)', () => {
136
+ const buttonMatch = sidebarBlock.match(/<button[^>]*id="open-economics-sheet-btn"[^>]*>/);
137
+ expect(buttonMatch).not.toBeNull();
138
+ expect(buttonMatch?.[0]).not.toMatch(/\bhidden\b/);
139
+ });
140
+ it('#open-stats-sheet-btn exists inside <aside class="dashboard-sidebar">', () => {
141
+ expect(sidebarBlock).toMatch(/id="open-stats-sheet-btn"/);
142
+ });
143
+ it('#open-stats-sheet-btn is initially disabled and aria-disabled', () => {
144
+ const buttonMatch = sidebarBlock.match(/<button[^>]*id="open-stats-sheet-btn"[^>]*>/);
145
+ expect(buttonMatch).not.toBeNull();
146
+ expect(buttonMatch?.[0]).toMatch(/\bdisabled\b/);
147
+ expect(buttonMatch?.[0]).toMatch(/aria-disabled="true"/);
148
+ });
149
+ });
150
+ describe('economics sheet markup', () => {
151
+ it('declares #economics-sheet-overlay, #economics-sheet, #economics-sheet-content', () => {
152
+ expect(indexHtml).toMatch(/id="economics-sheet-overlay"/);
153
+ expect(indexHtml).toMatch(/id="economics-sheet"/);
154
+ expect(indexHtml).toMatch(/id="economics-sheet-content"/);
155
+ });
156
+ it('preserves inner DOM ids needed by existing fetchers/renderers', () => {
157
+ const sheetBlock = extractElementSubtree(indexHtml, '<div id="economics-sheet"');
158
+ expect(sheetBlock).not.toBe('');
159
+ expect(sheetBlock).toMatch(/id="token-usage-content"/);
160
+ expect(sheetBlock).toMatch(/id="budget-tile"/);
161
+ expect(sheetBlock).toMatch(/id="budget-slider"/);
162
+ expect(sheetBlock).toMatch(/id="budget-slider-value"/);
163
+ expect(sheetBlock).toMatch(/id="budget-slider-submit"/);
164
+ expect(sheetBlock).toMatch(/id="budget-slider-status"/);
165
+ });
166
+ it('wires open and close handlers via onclick attributes', () => {
167
+ expect(indexHtml).toMatch(/id="open-economics-sheet-btn"[^>]*onclick="openEconomicsSheet\(\)"/);
168
+ expect(indexHtml).toMatch(/id="economics-sheet-overlay"[^>]*onclick="closeEconomicsSheet\(\)"/);
169
+ });
170
+ it('contains a sheet-close button inside the economics sheet', () => {
171
+ const sheetBlock = extractElementSubtree(indexHtml, '<div id="economics-sheet"');
172
+ expect(sheetBlock).toMatch(/class="sheet-close"/);
173
+ });
174
+ });
175
+ describe('stats sheet markup', () => {
176
+ it('declares #stats-sheet-overlay, #stats-sheet, #stats-sheet-content', () => {
177
+ expect(indexHtml).toMatch(/id="stats-sheet-overlay"/);
178
+ expect(indexHtml).toMatch(/id="stats-sheet"/);
179
+ expect(indexHtml).toMatch(/id="stats-sheet-content"/);
180
+ });
181
+ it('preserves inner DOM ids needed by existing fetchers/renderers', () => {
182
+ const sheetBlock = extractElementSubtree(indexHtml, '<div id="stats-sheet"');
183
+ expect(sheetBlock).not.toBe('');
184
+ expect(sheetBlock).toMatch(/id="project-stats"/);
185
+ expect(sheetBlock).toMatch(/id="recalculate-btn"/);
186
+ expect(sheetBlock).toMatch(/id="recalculate-label"/);
187
+ expect(sheetBlock).toMatch(/id="backfill-progress"/);
188
+ });
189
+ it('wires open and close handlers via onclick attributes', () => {
190
+ expect(indexHtml).toMatch(/id="open-stats-sheet-btn"[^>]*onclick="openStatsSheet\(\)"/);
191
+ expect(indexHtml).toMatch(/id="stats-sheet-overlay"[^>]*onclick="closeStatsSheet\(\)"/);
192
+ });
193
+ it('contains a sheet-close button inside the stats sheet', () => {
194
+ const sheetBlock = extractElementSubtree(indexHtml, '<div id="stats-sheet"');
195
+ expect(sheetBlock).toMatch(/class="sheet-close"/);
196
+ });
197
+ });
198
+ describe('removed empty-state markup', () => {
199
+ it('#pending-reviews-section is still present but #pending-reviews-empty-state is gone', () => {
200
+ expect(mainBlock).toMatch(/id="pending-reviews-section"/);
201
+ expect(mainBlock).not.toMatch(/id="pending-reviews-empty-state"/);
202
+ });
203
+ it('#active-reviews-section is still present but #i18n-empty-active-reviews placeholder div is gone', () => {
204
+ expect(mainBlock).toMatch(/id="active-reviews-section"/);
205
+ const activeReviewsMatch = mainBlock.match(/<div[^>]*id="active-reviews-section"[\s\S]*?<\/div>\s*<\/div>/);
206
+ expect(activeReviewsMatch).not.toBeNull();
207
+ const activeReviewsBlock = activeReviewsMatch?.[0] ?? '';
208
+ expect(activeReviewsBlock).not.toMatch(/<div[^>]*id="i18n-empty-active-reviews"[^>]*>\s*<\/div>/);
209
+ });
210
+ });
211
+ describe('script wiring', () => {
212
+ it('imports the sectionVisibility helper module', () => {
213
+ expect(inlineScript).toMatch(/from\s+['"]\.\/modules\/sectionVisibility\.js['"]/);
214
+ });
215
+ it('invokes shouldHidePendingReviewsSection and shouldHideActiveReviewsSection in the script body', () => {
216
+ expect(inlineScript).toMatch(/shouldHidePendingReviewsSection\(/);
217
+ expect(inlineScript).toMatch(/shouldHideActiveReviewsSection\(/);
218
+ });
219
+ it('drops the dead-code reference to claude-economics-section from secondarySections', () => {
220
+ const secondaryMatch = inlineScript.match(/const secondarySections\s*=\s*\[[^\]]*\];/);
221
+ expect(secondaryMatch).not.toBeNull();
222
+ expect(secondaryMatch?.[0]).not.toMatch(/'claude-economics-section'/);
223
+ });
224
+ it('no longer declares or exposes toggleStats', () => {
225
+ expect(inlineScript).not.toMatch(/function toggleStats\b/);
226
+ expect(inlineScript).not.toMatch(/window\.toggleStats\s*=/);
227
+ });
228
+ it('no longer references removed empty-state translation lookup ids', () => {
229
+ expect(inlineScript).not.toMatch(/getElementById\(['"]i18n-empty-active-reviews['"]\)/);
230
+ expect(inlineScript).not.toMatch(/getElementById\(['"]i18n-empty-pending-reviews['"]\)/);
231
+ });
232
+ });
233
+ describe('i18n orphan keys', () => {
234
+ let i18nSource;
235
+ beforeEach(() => {
236
+ const I18N_PATH = join(PROJECT_ROOT, 'src', 'dashboard', 'modules', 'i18n.js');
237
+ i18nSource = readFileSync(I18N_PATH, 'utf-8');
238
+ });
239
+ it('drops empty.activeReviews translation key in both locales', () => {
240
+ expect(i18nSource).not.toMatch(/['"]empty\.activeReviews['"]\s*:/);
241
+ });
242
+ it('drops empty.pendingReviews translation key in both locales', () => {
243
+ expect(i18nSource).not.toMatch(/['"]empty\.pendingReviews['"]\s*:/);
244
+ });
245
+ });
246
+ });
247
+ //# sourceMappingURL=dashboardLayout.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboardLayout.test.js","sourceRoot":"","sources":["../../../../src/tests/units/dashboard/dashboardLayout.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sectionVisibility.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sectionVisibility.test.d.ts","sourceRoot":"","sources":["../../../../../src/tests/units/dashboard/modules/sectionVisibility.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,58 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { shouldHideActiveReviewsSection, shouldHidePendingReviewsSection, } from '../../../../dashboard/modules/sectionVisibility.js';
3
+ describe('shouldHidePendingReviewsSection', () => {
4
+ it('returns true when pendingReviews is an empty array', () => {
5
+ expect(shouldHidePendingReviewsSection({ pendingReviews: [] })).toBe(true);
6
+ });
7
+ it('returns true when pendingReviews is null', () => {
8
+ expect(shouldHidePendingReviewsSection({ pendingReviews: null })).toBe(true);
9
+ });
10
+ it('returns true when the pendingReviews key is missing', () => {
11
+ expect(shouldHidePendingReviewsSection({})).toBe(true);
12
+ });
13
+ it('returns false when pendingReviews has at least one entry', () => {
14
+ expect(shouldHidePendingReviewsSection({ pendingReviews: [{ id: 'p1' }] })).toBe(false);
15
+ });
16
+ });
17
+ describe('shouldHideActiveReviewsSection', () => {
18
+ it('returns true when activeReviews is an empty array', () => {
19
+ expect(shouldHideActiveReviewsSection({ activeReviews: [] })).toBe(true);
20
+ });
21
+ it('returns true when activeReviews contains only a single followup', () => {
22
+ expect(shouldHideActiveReviewsSection({
23
+ activeReviews: [{ id: 'r1', jobType: 'followup' }],
24
+ })).toBe(true);
25
+ });
26
+ it('returns true when activeReviews contains multiple followups only', () => {
27
+ expect(shouldHideActiveReviewsSection({
28
+ activeReviews: [
29
+ { id: 'r1', jobType: 'followup' },
30
+ { id: 'r2', jobType: 'followup' },
31
+ { id: 'r3', jobType: 'followup' },
32
+ ],
33
+ })).toBe(true);
34
+ });
35
+ it('returns false when activeReviews contains one non-followup review', () => {
36
+ expect(shouldHideActiveReviewsSection({
37
+ activeReviews: [{ id: 'r1', jobType: 'review' }],
38
+ })).toBe(false);
39
+ });
40
+ it('returns false when activeReviews mixes followups and a non-followup', () => {
41
+ expect(shouldHideActiveReviewsSection({
42
+ activeReviews: [
43
+ { id: 'r1', jobType: 'followup' },
44
+ { id: 'r2', jobType: 'review' },
45
+ ],
46
+ })).toBe(false);
47
+ });
48
+ it('returns false when an entry has no jobType (treated as non-followup)', () => {
49
+ expect(shouldHideActiveReviewsSection({
50
+ activeReviews: [{ id: 'r1' }],
51
+ })).toBe(false);
52
+ });
53
+ it('returns true when activeReviews is null or missing', () => {
54
+ expect(shouldHideActiveReviewsSection({ activeReviews: null })).toBe(true);
55
+ expect(shouldHideActiveReviewsSection({})).toBe(true);
56
+ });
57
+ });
58
+ //# sourceMappingURL=sectionVisibility.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sectionVisibility.test.js","sourceRoot":"","sources":["../../../../../src/tests/units/dashboard/modules/sectionVisibility.test.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,11 @@ describe('ReviewRequestState', () => {
39
39
  const merged = ReviewRequestState.create('merged');
40
40
  expect(() => merged.transitionTo('closed')).toThrow();
41
41
  });
42
+ it('should allow transition from pending-fix to merged', () => {
43
+ const state = ReviewRequestState.pendingFix();
44
+ const newState = state.transitionTo('merged');
45
+ expect(newState.current).toBe('merged');
46
+ });
42
47
  });
43
48
  describe('canTransitionTo', () => {
44
49
  it('should return true for valid transition', () => {
@@ -1 +1 @@
1
- {"version":3,"file":"reviewRequestState.valueObject.test.js","sourceRoot":"","sources":["../../../../src/tests/units/entities/reviewRequestState.valueObject.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reviewRequestState.valueObject.test.js","sourceRoot":"","sources":["../../../../src/tests/units/entities/reviewRequestState.valueObject.test.ts"],"names":[],"mappings":"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"}