github-issue-tower-defence-management 1.146.0 → 1.146.2
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.
- package/CHANGELOG.md +23 -9
- package/README.md +1 -1
- package/bin/adapter/entry-points/cli/index.js +29 -7
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/cli/projectConfig.js +3 -0
- package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
- package/bin/adapter/entry-points/console/consoleGithubTokenResolver.js +41 -0
- package/bin/adapter/entry-points/console/consoleGithubTokenResolver.js.map +1 -0
- package/bin/adapter/entry-points/console/consoleOperationApi.js +34 -16
- package/bin/adapter/entry-points/console/consoleOperationApi.js.map +1 -1
- package/bin/adapter/entry-points/console/ensureConsoleRunning.js +6 -1
- package/bin/adapter/entry-points/console/ensureConsoleRunning.js.map +1 -1
- package/bin/adapter/entry-points/console/webServer.js +3 -4
- package/bin/adapter/entry-points/console/webServer.js.map +1 -1
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +3 -1
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
- package/bin/adapter/repositories/GraphqlProjectRepository.js +75 -4
- package/bin/adapter/repositories/GraphqlProjectRepository.js.map +1 -1
- package/bin/adapter/repositories/utils.js +2 -4
- package/bin/adapter/repositories/utils.js.map +1 -1
- package/bin/domain/entities/ProjectFieldName.js +6 -0
- package/bin/domain/entities/ProjectFieldName.js.map +1 -0
- package/bin/domain/entities/RequiredProjectField.js +47 -0
- package/bin/domain/entities/RequiredProjectField.js.map +1 -0
- package/bin/domain/usecases/HandleScheduledEventUseCase.js +5 -1
- package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
- package/bin/domain/usecases/ProjectRequiredFieldCreateUseCase.js +25 -0
- package/bin/domain/usecases/ProjectRequiredFieldCreateUseCase.js.map +1 -0
- package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js +6 -1
- package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js.map +1 -1
- package/bin/domain/usecases/dashboard/DashboardProjectCode.js +17 -13
- package/bin/domain/usecases/dashboard/DashboardProjectCode.js.map +1 -1
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/index.test.ts +62 -2
- package/src/adapter/entry-points/cli/index.ts +58 -11
- package/src/adapter/entry-points/cli/projectConfig.ts +8 -0
- package/src/adapter/entry-points/console/consoleDataDelivery.test.ts +37 -39
- package/src/adapter/entry-points/console/consoleDoneStore.test.ts +33 -33
- package/src/adapter/entry-points/console/consoleGithubTokenResolver.test.ts +135 -0
- package/src/adapter/entry-points/console/consoleGithubTokenResolver.ts +55 -0
- package/src/adapter/entry-points/console/consoleItemUrlLookup.test.ts +6 -6
- package/src/adapter/entry-points/console/consoleOperationApi.test.ts +92 -70
- package/src/adapter/entry-points/console/consoleOperationApi.ts +51 -44
- package/src/adapter/entry-points/console/consoleProjectResolver.test.ts +35 -35
- package/src/adapter/entry-points/console/dashboardComposeService.test.ts +28 -28
- package/src/adapter/entry-points/console/dashboardEmitterComposerKey.test.ts +26 -20
- package/src/adapter/entry-points/console/ensureConsoleRunning.test.ts +19 -2
- package/src/adapter/entry-points/console/ensureConsoleRunning.ts +8 -0
- package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +1 -1
- package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +1 -1
- package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.stories.tsx +2 -2
- package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.test.tsx +3 -3
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleNavigation.test.ts +19 -31
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.test.ts +24 -32
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOverlay.test.ts +6 -6
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsolePjcode.test.ts +4 -4
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.test.ts +8 -8
- package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.test.ts +5 -5
- package/src/adapter/entry-points/console/ui/src/features/console/logic/overlay.test.ts +1 -1
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +13 -13
- package/src/adapter/entry-points/console/webServer.test.ts +55 -52
- package/src/adapter/entry-points/console/webServer.ts +5 -4
- package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.test.ts +2 -2
- package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +4 -0
- package/src/adapter/entry-points/handlers/dashboardRowWriter.test.ts +5 -5
- package/src/adapter/entry-points/handlers/inTmuxByHumanDataWriter.test.ts +5 -5
- package/src/adapter/repositories/GraphqlProjectRepository.ts +110 -4
- package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +1 -1
- package/src/adapter/repositories/utils.ts +3 -3
- package/src/domain/entities/ProjectFieldName.ts +2 -0
- package/src/domain/entities/RequiredProjectField.ts +64 -0
- package/src/domain/usecases/HandleScheduledEventUseCase.test.ts +4 -0
- package/src/domain/usecases/HandleScheduledEventUseCase.ts +5 -0
- package/src/domain/usecases/NotifySilentLiveSessionsUseCase.test.ts +3 -3
- package/src/domain/usecases/ProjectRequiredFieldCreateUseCase.test.ts +159 -0
- package/src/domain/usecases/ProjectRequiredFieldCreateUseCase.ts +32 -0
- package/src/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.test.ts +19 -19
- package/src/domain/usecases/SetupTowerDefenceProjectUseCase.test.ts +24 -14
- package/src/domain/usecases/SetupTowerDefenceProjectUseCase.ts +10 -1
- package/src/domain/usecases/adapter-interfaces/ProjectRepository.ts +6 -0
- package/src/domain/usecases/dashboard/ComposeDashboardUseCase.test.ts +28 -28
- package/src/domain/usecases/dashboard/DashboardProjectCode.test.ts +21 -21
- package/src/domain/usecases/dashboard/DashboardProjectCode.ts +21 -15
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/entry-points/cli/projectConfig.d.ts +1 -0
- package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
- package/types/adapter/entry-points/console/consoleGithubTokenResolver.d.ts +6 -0
- package/types/adapter/entry-points/console/consoleGithubTokenResolver.d.ts.map +1 -0
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts +2 -1
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts.map +1 -1
- package/types/adapter/entry-points/console/ensureConsoleRunning.d.ts +1 -1
- package/types/adapter/entry-points/console/ensureConsoleRunning.d.ts.map +1 -1
- package/types/adapter/entry-points/console/webServer.d.ts +2 -2
- package/types/adapter/entry-points/console/webServer.d.ts.map +1 -1
- package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
- package/types/adapter/repositories/GraphqlProjectRepository.d.ts +4 -1
- package/types/adapter/repositories/GraphqlProjectRepository.d.ts.map +1 -1
- package/types/adapter/repositories/utils.d.ts.map +1 -1
- package/types/domain/entities/ProjectFieldName.d.ts +2 -0
- package/types/domain/entities/ProjectFieldName.d.ts.map +1 -0
- package/types/domain/entities/RequiredProjectField.d.ts +13 -0
- package/types/domain/entities/RequiredProjectField.d.ts.map +1 -0
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +3 -1
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
- package/types/domain/usecases/ProjectRequiredFieldCreateUseCase.d.ts +10 -0
- package/types/domain/usecases/ProjectRequiredFieldCreateUseCase.d.ts.map +1 -0
- package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts.map +1 -1
- package/types/domain/usecases/adapter-interfaces/ProjectRepository.d.ts +3 -0
- package/types/domain/usecases/adapter-interfaces/ProjectRepository.d.ts.map +1 -1
- package/types/domain/usecases/dashboard/DashboardProjectCode.d.ts +2 -2
- package/types/domain/usecases/dashboard/DashboardProjectCode.d.ts.map +1 -1
|
@@ -244,7 +244,7 @@ test('lists a still-open item and keeps its tab visible when the browser overlay
|
|
|
244
244
|
|
|
245
245
|
await page.evaluate(() => {
|
|
246
246
|
localStorage.setItem(
|
|
247
|
-
'
|
|
247
|
+
'pv_overlay_acme',
|
|
248
248
|
JSON.stringify({
|
|
249
249
|
PVTI_lADOABCD1234zgTODO00869: {
|
|
250
250
|
done: true,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from '../../consoleReadApi';
|
|
20
20
|
import { startWebServer } from '../../webServer';
|
|
21
21
|
|
|
22
|
-
export const CONSOLE_E2E_PJCODE = '
|
|
22
|
+
export const CONSOLE_E2E_PJCODE = 'acme';
|
|
23
23
|
export const CONSOLE_E2E_TOKEN = 'console-e2e-fixture-token-3f9c1a';
|
|
24
24
|
|
|
25
25
|
export type ConsoleE2eReviewCommentCall = {
|
|
@@ -7,9 +7,9 @@ const meta: Meta<typeof ConsoleTabList> = {
|
|
|
7
7
|
title: 'Console/ConsoleTabList',
|
|
8
8
|
component: ConsoleTabList,
|
|
9
9
|
args: {
|
|
10
|
-
pjcode: '
|
|
10
|
+
pjcode: 'acme',
|
|
11
11
|
generatedAt: '2026-06-19T08:42:11.000Z',
|
|
12
|
-
tabHref: (tab: ConsoleTabName) => `/projects/
|
|
12
|
+
tabHref: (tab: ConsoleTabName) => `/projects/acme/${tab}`,
|
|
13
13
|
onSelectTab: () => {},
|
|
14
14
|
},
|
|
15
15
|
};
|
|
@@ -13,9 +13,9 @@ const counts: Record<ConsoleTabName, number> = {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
const baseProps = {
|
|
16
|
-
pjcode: '
|
|
16
|
+
pjcode: 'acme',
|
|
17
17
|
generatedAt: '2026-06-19T08:42:11.000Z',
|
|
18
|
-
tabHref: (tab: ConsoleTabName) => `/projects/
|
|
18
|
+
tabHref: (tab: ConsoleTabName) => `/projects/acme/${tab}`,
|
|
19
19
|
onSelectTab: () => {},
|
|
20
20
|
};
|
|
21
21
|
|
|
@@ -87,7 +87,7 @@ describe('ConsoleTabList', () => {
|
|
|
87
87
|
const { getByText } = render(
|
|
88
88
|
<ConsoleTabList {...baseProps} activeTab="prs" counts={counts} />,
|
|
89
89
|
);
|
|
90
|
-
expect(getByText('
|
|
90
|
+
expect(getByText('acme')).toBeInTheDocument();
|
|
91
91
|
expect(getByText('snapshot: 2026-06-19T08:42:11.000Z')).toBeInTheDocument();
|
|
92
92
|
});
|
|
93
93
|
|
package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleNavigation.test.ts
CHANGED
|
@@ -21,15 +21,15 @@ const counts = (
|
|
|
21
21
|
|
|
22
22
|
describe('parseTabFromPath', () => {
|
|
23
23
|
it('reads a known tab from the project path', () => {
|
|
24
|
-
expect(parseTabFromPath('/projects/
|
|
24
|
+
expect(parseTabFromPath('/projects/acme/triage')).toBe('triage');
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
it('returns null for an unknown tab segment', () => {
|
|
28
|
-
expect(parseTabFromPath('/projects/
|
|
28
|
+
expect(parseTabFromPath('/projects/acme/unknown')).toBeNull();
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
it('returns null when there is no tab segment', () => {
|
|
32
|
-
expect(parseTabFromPath('/projects/
|
|
32
|
+
expect(parseTabFromPath('/projects/acme')).toBeNull();
|
|
33
33
|
});
|
|
34
34
|
});
|
|
35
35
|
|
|
@@ -45,39 +45,31 @@ describe('parseItemKeyFromHash', () => {
|
|
|
45
45
|
|
|
46
46
|
describe('useConsoleNavigation', () => {
|
|
47
47
|
beforeEach(() => {
|
|
48
|
-
window.history.replaceState({}, '', '/projects/
|
|
48
|
+
window.history.replaceState({}, '', '/projects/acme/prs?k=token');
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
it('reads the active tab from the path and no selected item', () => {
|
|
52
|
-
const { result } = renderHook(() =>
|
|
53
|
-
useConsoleNavigation('umino', counts()),
|
|
54
|
-
);
|
|
52
|
+
const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
|
|
55
53
|
expect(result.current.activeTab).toBe('prs');
|
|
56
54
|
expect(result.current.selectedItemKey).toBeNull();
|
|
57
55
|
});
|
|
58
56
|
|
|
59
57
|
it('builds a project tab href', () => {
|
|
60
|
-
const { result } = renderHook(() =>
|
|
61
|
-
|
|
62
|
-
);
|
|
63
|
-
expect(result.current.tabHref('triage')).toBe('/projects/umino/triage');
|
|
58
|
+
const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
|
|
59
|
+
expect(result.current.tabHref('triage')).toBe('/projects/acme/triage');
|
|
64
60
|
});
|
|
65
61
|
|
|
66
62
|
it('selects a tab and updates the path', () => {
|
|
67
|
-
const { result } = renderHook(() =>
|
|
68
|
-
useConsoleNavigation('umino', counts()),
|
|
69
|
-
);
|
|
63
|
+
const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
|
|
70
64
|
act(() => {
|
|
71
65
|
result.current.selectTab('unread');
|
|
72
66
|
});
|
|
73
67
|
expect(result.current.activeTab).toBe('unread');
|
|
74
|
-
expect(window.location.pathname).toBe('/projects/
|
|
68
|
+
expect(window.location.pathname).toBe('/projects/acme/unread');
|
|
75
69
|
});
|
|
76
70
|
|
|
77
71
|
it('opens an item and reflects it in the hash', () => {
|
|
78
|
-
const { result } = renderHook(() =>
|
|
79
|
-
useConsoleNavigation('umino', counts()),
|
|
80
|
-
);
|
|
72
|
+
const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
|
|
81
73
|
act(() => {
|
|
82
74
|
result.current.openItem('PVTI_open');
|
|
83
75
|
});
|
|
@@ -86,10 +78,8 @@ describe('useConsoleNavigation', () => {
|
|
|
86
78
|
});
|
|
87
79
|
|
|
88
80
|
it('closes an item and clears the hash', () => {
|
|
89
|
-
window.history.replaceState({}, '', '/projects/
|
|
90
|
-
const { result } = renderHook(() =>
|
|
91
|
-
useConsoleNavigation('umino', counts()),
|
|
92
|
-
);
|
|
81
|
+
window.history.replaceState({}, '', '/projects/acme/prs#item/PVTI_open');
|
|
82
|
+
const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
|
|
93
83
|
expect(result.current.selectedItemKey).toBe('PVTI_open');
|
|
94
84
|
act(() => {
|
|
95
85
|
result.current.closeItem();
|
|
@@ -101,13 +91,13 @@ describe('useConsoleNavigation', () => {
|
|
|
101
91
|
|
|
102
92
|
describe('useConsoleNavigation default tab without a tab segment', () => {
|
|
103
93
|
beforeEach(() => {
|
|
104
|
-
window.history.replaceState({}, '', '/projects/
|
|
94
|
+
window.history.replaceState({}, '', '/projects/acme?k=token');
|
|
105
95
|
});
|
|
106
96
|
|
|
107
97
|
it('lands on the left-most tab when all tabs are non-empty', () => {
|
|
108
98
|
const { result } = renderHook(() =>
|
|
109
99
|
useConsoleNavigation(
|
|
110
|
-
'
|
|
100
|
+
'acme',
|
|
111
101
|
counts({
|
|
112
102
|
'workflow-blocker': 3,
|
|
113
103
|
prs: 5,
|
|
@@ -124,7 +114,7 @@ describe('useConsoleNavigation default tab without a tab segment', () => {
|
|
|
124
114
|
it('skips the empty left-most tab and lands on the next non-empty tab', () => {
|
|
125
115
|
const { result } = renderHook(() =>
|
|
126
116
|
useConsoleNavigation(
|
|
127
|
-
'
|
|
117
|
+
'acme',
|
|
128
118
|
counts({ 'workflow-blocker': 0, prs: 0, triage: 8 }),
|
|
129
119
|
),
|
|
130
120
|
);
|
|
@@ -132,16 +122,14 @@ describe('useConsoleNavigation default tab without a tab segment', () => {
|
|
|
132
122
|
});
|
|
133
123
|
|
|
134
124
|
it('falls back to the first tab when every tab is empty', () => {
|
|
135
|
-
const { result } = renderHook(() =>
|
|
136
|
-
useConsoleNavigation('umino', counts()),
|
|
137
|
-
);
|
|
125
|
+
const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
|
|
138
126
|
expect(result.current.activeTab).toBe('workflow-blocker');
|
|
139
127
|
});
|
|
140
128
|
|
|
141
129
|
it('updates the default tab when counts arrive after the initial render', () => {
|
|
142
130
|
const { result, rerender } = renderHook(
|
|
143
131
|
({ tabCounts }: { tabCounts: Record<ConsoleTabName, number> }) =>
|
|
144
|
-
useConsoleNavigation('
|
|
132
|
+
useConsoleNavigation('acme', tabCounts),
|
|
145
133
|
{ initialProps: { tabCounts: counts() } },
|
|
146
134
|
);
|
|
147
135
|
expect(result.current.activeTab).toBe('workflow-blocker');
|
|
@@ -150,9 +138,9 @@ describe('useConsoleNavigation default tab without a tab segment', () => {
|
|
|
150
138
|
});
|
|
151
139
|
|
|
152
140
|
it('keeps the tab from the path even when counts are present', () => {
|
|
153
|
-
window.history.replaceState({}, '', '/projects/
|
|
141
|
+
window.history.replaceState({}, '', '/projects/acme/triage?k=token');
|
|
154
142
|
const { result } = renderHook(() =>
|
|
155
|
-
useConsoleNavigation('
|
|
143
|
+
useConsoleNavigation('acme', counts({ unread: 6 })),
|
|
156
144
|
);
|
|
157
145
|
expect(result.current.activeTab).toBe('triage');
|
|
158
146
|
});
|
package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.test.ts
CHANGED
|
@@ -44,10 +44,10 @@ const lastBody = (fetchMock: jest.Mock): Record<string, unknown> => {
|
|
|
44
44
|
|
|
45
45
|
const setup = () => {
|
|
46
46
|
localStorage.clear();
|
|
47
|
-
window.history.replaceState({}, '', '/projects/
|
|
47
|
+
window.history.replaceState({}, '', '/projects/acme/prs?k=token');
|
|
48
48
|
return renderHook(() => {
|
|
49
|
-
const overlay = useConsoleOverlay('
|
|
50
|
-
const operations = useConsoleOperations('
|
|
49
|
+
const overlay = useConsoleOverlay('acme');
|
|
50
|
+
const operations = useConsoleOperations('acme', 'prs', overlay);
|
|
51
51
|
return { overlay, operations };
|
|
52
52
|
});
|
|
53
53
|
};
|
|
@@ -65,7 +65,7 @@ describe('useConsoleOperations', () => {
|
|
|
65
65
|
});
|
|
66
66
|
expect(fetchMock.mock.calls[0][0]).toBe('/api/review');
|
|
67
67
|
expect(lastBody(fetchMock)).toMatchObject({
|
|
68
|
-
pjcode: '
|
|
68
|
+
pjcode: 'acme',
|
|
69
69
|
action: 'close',
|
|
70
70
|
prUrl: prItem.url,
|
|
71
71
|
commentBody: 'totally wrong',
|
|
@@ -99,7 +99,7 @@ describe('useConsoleOperations', () => {
|
|
|
99
99
|
);
|
|
100
100
|
});
|
|
101
101
|
const stored = JSON.parse(
|
|
102
|
-
localStorage.getItem(overlayStorageKey('
|
|
102
|
+
localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
|
|
103
103
|
);
|
|
104
104
|
expect(stored[prItem.projectItemId].done).toBe(true);
|
|
105
105
|
});
|
|
@@ -115,7 +115,7 @@ describe('useConsoleOperations', () => {
|
|
|
115
115
|
});
|
|
116
116
|
expect(fetchMock.mock.calls[0][0]).toBe('/api/triage');
|
|
117
117
|
expect(lastBody(fetchMock)).toMatchObject({
|
|
118
|
-
pjcode: '
|
|
118
|
+
pjcode: 'acme',
|
|
119
119
|
action: 'close_not_planned',
|
|
120
120
|
issueUrl: issueItem.url,
|
|
121
121
|
});
|
|
@@ -129,13 +129,13 @@ describe('useConsoleOperations', () => {
|
|
|
129
129
|
});
|
|
130
130
|
expect(fetchMock.mock.calls[0][0]).toBe('/api/triage');
|
|
131
131
|
expect(lastBody(fetchMock)).toMatchObject({
|
|
132
|
-
pjcode: '
|
|
132
|
+
pjcode: 'acme',
|
|
133
133
|
action: 'close',
|
|
134
134
|
issueUrl: prItem.url,
|
|
135
135
|
});
|
|
136
136
|
expect(prItem.url).toContain('/pull/');
|
|
137
137
|
const stored = JSON.parse(
|
|
138
|
-
localStorage.getItem(overlayStorageKey('
|
|
138
|
+
localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
|
|
139
139
|
);
|
|
140
140
|
expect(stored[prItem.projectItemId].done).toBe(true);
|
|
141
141
|
});
|
|
@@ -152,7 +152,7 @@ describe('useConsoleOperations', () => {
|
|
|
152
152
|
statusName: option.name,
|
|
153
153
|
});
|
|
154
154
|
const stored = JSON.parse(
|
|
155
|
-
localStorage.getItem(overlayStorageKey('
|
|
155
|
+
localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
|
|
156
156
|
);
|
|
157
157
|
expect(stored[issueItem.projectItemId].status.name).toBe(option.name);
|
|
158
158
|
});
|
|
@@ -166,7 +166,7 @@ describe('useConsoleOperations', () => {
|
|
|
166
166
|
});
|
|
167
167
|
expect(fetchMock.mock.calls[0][0]).toBe('/api/intmux');
|
|
168
168
|
expect(lastBody(fetchMock)).toMatchObject({
|
|
169
|
-
pjcode: '
|
|
169
|
+
pjcode: 'acme',
|
|
170
170
|
action: 'set_intmux',
|
|
171
171
|
});
|
|
172
172
|
});
|
|
@@ -181,7 +181,7 @@ describe('useConsoleOperations', () => {
|
|
|
181
181
|
);
|
|
182
182
|
});
|
|
183
183
|
const stored = JSON.parse(
|
|
184
|
-
localStorage.getItem(overlayStorageKey('
|
|
184
|
+
localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
|
|
185
185
|
);
|
|
186
186
|
expect(stored[issueItem.projectItemId].done).toBe(true);
|
|
187
187
|
});
|
|
@@ -189,18 +189,10 @@ describe('useConsoleOperations', () => {
|
|
|
189
189
|
it('marks done on snooze in the todo-by-human tab so the item is skipped', async () => {
|
|
190
190
|
captureFetch();
|
|
191
191
|
localStorage.clear();
|
|
192
|
-
window.history.replaceState(
|
|
193
|
-
{},
|
|
194
|
-
'',
|
|
195
|
-
'/projects/umino/todo-by-human?k=token',
|
|
196
|
-
);
|
|
192
|
+
window.history.replaceState({}, '', '/projects/acme/todo-by-human?k=token');
|
|
197
193
|
const { result } = renderHook(() => {
|
|
198
|
-
const overlay = useConsoleOverlay('
|
|
199
|
-
const operations = useConsoleOperations(
|
|
200
|
-
'umino',
|
|
201
|
-
'todo-by-human',
|
|
202
|
-
overlay,
|
|
203
|
-
);
|
|
194
|
+
const overlay = useConsoleOverlay('acme');
|
|
195
|
+
const operations = useConsoleOperations('acme', 'todo-by-human', overlay);
|
|
204
196
|
return { overlay, operations };
|
|
205
197
|
});
|
|
206
198
|
await act(async () => {
|
|
@@ -210,7 +202,7 @@ describe('useConsoleOperations', () => {
|
|
|
210
202
|
);
|
|
211
203
|
});
|
|
212
204
|
const stored = JSON.parse(
|
|
213
|
-
localStorage.getItem(overlayStorageKey('
|
|
205
|
+
localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
|
|
214
206
|
);
|
|
215
207
|
expect(stored[issueItem.projectItemId].done).toBe(true);
|
|
216
208
|
});
|
|
@@ -241,7 +233,7 @@ describe('useConsoleOperations', () => {
|
|
|
241
233
|
});
|
|
242
234
|
expect(fetchMock.mock.calls[0][0]).toBe('/api/comment');
|
|
243
235
|
expect(lastBody(fetchMock)).toMatchObject({
|
|
244
|
-
pjcode: '
|
|
236
|
+
pjcode: 'acme',
|
|
245
237
|
url: issueItem.url,
|
|
246
238
|
body: 'Thanks for the parity fix.',
|
|
247
239
|
});
|
|
@@ -266,7 +258,7 @@ describe('useConsoleOperations', () => {
|
|
|
266
258
|
});
|
|
267
259
|
expect(fetchMock.mock.calls[0][0]).toBe('/api/reviewcomment');
|
|
268
260
|
expect(lastBody(fetchMock)).toEqual({
|
|
269
|
-
pjcode: '
|
|
261
|
+
pjcode: 'acme',
|
|
270
262
|
url: prItem.url,
|
|
271
263
|
path: 'src/index.ts',
|
|
272
264
|
line: 42,
|
|
@@ -295,7 +287,7 @@ describe('useConsoleOperations', () => {
|
|
|
295
287
|
});
|
|
296
288
|
expect(fetchMock.mock.calls[0][0]).toBe('/api/review');
|
|
297
289
|
expect(lastBody(fetchMock)).toMatchObject({
|
|
298
|
-
pjcode: '
|
|
290
|
+
pjcode: 'acme',
|
|
299
291
|
action: 'request_changes',
|
|
300
292
|
prUrl: prItem.url,
|
|
301
293
|
commentBody: 'src/index.ts:17 Please rename this variable.',
|
|
@@ -341,13 +333,13 @@ describe('useConsoleOperations', () => {
|
|
|
341
333
|
it('invalidates the operated item body and comments cache on a review', async () => {
|
|
342
334
|
captureFetch();
|
|
343
335
|
localStorage.clear();
|
|
344
|
-
window.history.replaceState({}, '', '/projects/
|
|
336
|
+
window.history.replaceState({}, '', '/projects/acme/prs?k=token');
|
|
345
337
|
const caches = buildOperationCaches();
|
|
346
338
|
const bodyInvalidate = jest.spyOn(caches.body, 'invalidate');
|
|
347
339
|
const commentsInvalidate = jest.spyOn(caches.comments, 'invalidate');
|
|
348
340
|
const { result } = renderHook(() => {
|
|
349
|
-
const overlay = useConsoleOverlay('
|
|
350
|
-
const operations = useConsoleOperations('
|
|
341
|
+
const overlay = useConsoleOverlay('acme');
|
|
342
|
+
const operations = useConsoleOperations('acme', 'prs', overlay, caches);
|
|
351
343
|
return { overlay, operations };
|
|
352
344
|
});
|
|
353
345
|
await act(async () => {
|
|
@@ -373,12 +365,12 @@ describe('useConsoleOperations', () => {
|
|
|
373
365
|
}));
|
|
374
366
|
global.fetch = fetchMock as unknown as typeof fetch;
|
|
375
367
|
localStorage.clear();
|
|
376
|
-
window.history.replaceState({}, '', '/projects/
|
|
368
|
+
window.history.replaceState({}, '', '/projects/acme/prs?k=token');
|
|
377
369
|
const caches = buildOperationCaches();
|
|
378
370
|
const commentsInvalidate = jest.spyOn(caches.comments, 'invalidate');
|
|
379
371
|
const { result } = renderHook(() => {
|
|
380
|
-
const overlay = useConsoleOverlay('
|
|
381
|
-
const operations = useConsoleOperations('
|
|
372
|
+
const overlay = useConsoleOverlay('acme');
|
|
373
|
+
const operations = useConsoleOperations('acme', 'prs', overlay, caches);
|
|
382
374
|
return { overlay, operations };
|
|
383
375
|
});
|
|
384
376
|
await act(async () => {
|
package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOverlay.test.ts
CHANGED
|
@@ -9,32 +9,32 @@ describe('useConsoleOverlay', () => {
|
|
|
9
9
|
|
|
10
10
|
it('starts from the persisted overlay', () => {
|
|
11
11
|
localStorage.setItem(
|
|
12
|
-
overlayStorageKey('
|
|
12
|
+
overlayStorageKey('acme'),
|
|
13
13
|
JSON.stringify({ PVTI_1: { ts: 5, mode: 'prs', done: true } }),
|
|
14
14
|
);
|
|
15
|
-
const { result } = renderHook(() => useConsoleOverlay('
|
|
15
|
+
const { result } = renderHook(() => useConsoleOverlay('acme'));
|
|
16
16
|
expect(result.current.overlay.PVTI_1?.done).toBe(true);
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
it('patches and persists overlay entries with timestamp and mode', () => {
|
|
20
|
-
const { result } = renderHook(() => useConsoleOverlay('
|
|
20
|
+
const { result } = renderHook(() => useConsoleOverlay('acme'));
|
|
21
21
|
act(() => {
|
|
22
22
|
result.current.patchOverlay('PVTI_2', { done: true }, 'triage');
|
|
23
23
|
});
|
|
24
24
|
expect(result.current.overlay.PVTI_2?.done).toBe(true);
|
|
25
25
|
expect(result.current.overlay.PVTI_2?.mode).toBe('triage');
|
|
26
26
|
const stored = JSON.parse(
|
|
27
|
-
localStorage.getItem(overlayStorageKey('
|
|
27
|
+
localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
|
|
28
28
|
);
|
|
29
29
|
expect(stored.PVTI_2.done).toBe(true);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
it('ignores malformed persisted entries', () => {
|
|
33
33
|
localStorage.setItem(
|
|
34
|
-
overlayStorageKey('
|
|
34
|
+
overlayStorageKey('acme'),
|
|
35
35
|
JSON.stringify({ bad: { no: 'ts' } }),
|
|
36
36
|
);
|
|
37
|
-
const { result } = renderHook(() => useConsoleOverlay('
|
|
37
|
+
const { result } = renderHook(() => useConsoleOverlay('acme'));
|
|
38
38
|
expect(result.current.overlay.bad).toBeUndefined();
|
|
39
39
|
});
|
|
40
40
|
});
|
package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsolePjcode.test.ts
CHANGED
|
@@ -2,13 +2,13 @@ import { parsePjcodeFromPath } from './useConsolePjcode';
|
|
|
2
2
|
|
|
3
3
|
describe('parsePjcodeFromPath', () => {
|
|
4
4
|
it('extracts the pjcode from a projects path', () => {
|
|
5
|
-
expect(parsePjcodeFromPath('/projects/
|
|
6
|
-
expect(parsePjcodeFromPath('/projects/
|
|
7
|
-
expect(parsePjcodeFromPath('/projects/
|
|
5
|
+
expect(parsePjcodeFromPath('/projects/acme')).toBe('acme');
|
|
6
|
+
expect(parsePjcodeFromPath('/projects/acme/prs')).toBe('acme');
|
|
7
|
+
expect(parsePjcodeFromPath('/projects/globex/triage')).toBe('globex');
|
|
8
8
|
});
|
|
9
9
|
|
|
10
10
|
it('tolerates a trailing slash', () => {
|
|
11
|
-
expect(parsePjcodeFromPath('/projects/
|
|
11
|
+
expect(parsePjcodeFromPath('/projects/umbrella/')).toBe('umbrella');
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
it('returns null when the path is not under projects', () => {
|
package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.test.ts
CHANGED
|
@@ -16,7 +16,7 @@ describe('useConsoleTabData', () => {
|
|
|
16
16
|
ok: true,
|
|
17
17
|
status: 200,
|
|
18
18
|
json: async () => ({
|
|
19
|
-
pjcode: '
|
|
19
|
+
pjcode: 'acme',
|
|
20
20
|
generatedAt: '2026-06-19T00:00:00.000Z',
|
|
21
21
|
statusOptions: [{ id: 's1', name: 'Unread', color: 'ORANGE' }],
|
|
22
22
|
storyColors: {},
|
|
@@ -27,13 +27,13 @@ describe('useConsoleTabData', () => {
|
|
|
27
27
|
}));
|
|
28
28
|
global.fetch = fetchMock as unknown as typeof fetch;
|
|
29
29
|
|
|
30
|
-
const { result } = renderHook(() => useConsoleTabData('
|
|
30
|
+
const { result } = renderHook(() => useConsoleTabData('acme'));
|
|
31
31
|
await waitFor(() => {
|
|
32
32
|
expect(result.current.isLoading).toBe(false);
|
|
33
33
|
});
|
|
34
34
|
expect(fetchMock).toHaveBeenCalledTimes(CONSOLE_TABS.length);
|
|
35
35
|
expect(fetchMock).toHaveBeenCalledWith(
|
|
36
|
-
expect.stringContaining('/projects/
|
|
36
|
+
expect.stringContaining('/projects/acme/prs/list.json'),
|
|
37
37
|
);
|
|
38
38
|
expect(result.current.snapshots.prs?.items.length).toBe(1);
|
|
39
39
|
expect(result.current.snapshots.prs?.generatedAt).toBe(
|
|
@@ -46,7 +46,7 @@ describe('useConsoleTabData', () => {
|
|
|
46
46
|
ok: true,
|
|
47
47
|
status: 200,
|
|
48
48
|
json: async () => ({
|
|
49
|
-
pjcode: '
|
|
49
|
+
pjcode: 'acme',
|
|
50
50
|
generatedAt: '2026-06-19T00:00:00.000Z',
|
|
51
51
|
statusOptions: [],
|
|
52
52
|
storyColors: {},
|
|
@@ -68,7 +68,7 @@ describe('useConsoleTabData', () => {
|
|
|
68
68
|
}));
|
|
69
69
|
global.fetch = fetchMock as unknown as typeof fetch;
|
|
70
70
|
|
|
71
|
-
const { result } = renderHook(() => useConsoleTabData('
|
|
71
|
+
const { result } = renderHook(() => useConsoleTabData('acme'));
|
|
72
72
|
await waitFor(() => {
|
|
73
73
|
expect(result.current.isLoading).toBe(false);
|
|
74
74
|
});
|
|
@@ -87,7 +87,7 @@ describe('useConsoleTabData', () => {
|
|
|
87
87
|
ok: true,
|
|
88
88
|
status: 200,
|
|
89
89
|
json: async () => ({
|
|
90
|
-
pjcode: '
|
|
90
|
+
pjcode: 'acme',
|
|
91
91
|
generatedAt: '2026-06-19T00:00:00.000Z',
|
|
92
92
|
statusOptions: [],
|
|
93
93
|
storyColors: {},
|
|
@@ -99,7 +99,7 @@ describe('useConsoleTabData', () => {
|
|
|
99
99
|
}));
|
|
100
100
|
global.fetch = fetchMock as unknown as typeof fetch;
|
|
101
101
|
|
|
102
|
-
const { result } = renderHook(() => useConsoleTabData('
|
|
102
|
+
const { result } = renderHook(() => useConsoleTabData('acme'));
|
|
103
103
|
await waitFor(() => {
|
|
104
104
|
expect(result.current.snapshots.prs?.items.length).toBe(1);
|
|
105
105
|
});
|
|
@@ -123,7 +123,7 @@ describe('useConsoleTabData', () => {
|
|
|
123
123
|
json: async () => ({}),
|
|
124
124
|
}));
|
|
125
125
|
global.fetch = fetchMock as unknown as typeof fetch;
|
|
126
|
-
const { result } = renderHook(() => useConsoleTabData('
|
|
126
|
+
const { result } = renderHook(() => useConsoleTabData('acme'));
|
|
127
127
|
await waitFor(() => {
|
|
128
128
|
expect(result.current.error).toBe('HTTP 500');
|
|
129
129
|
});
|
|
@@ -256,7 +256,7 @@ describe('postConsoleOperation', () => {
|
|
|
256
256
|
it('posts a JSON body to the operation endpoint', async () => {
|
|
257
257
|
const fetchMock = mockFetchOnce({ ok: true });
|
|
258
258
|
await postConsoleOperation('/api/review', {
|
|
259
|
-
pjcode: '
|
|
259
|
+
pjcode: 'acme',
|
|
260
260
|
action: 'approve',
|
|
261
261
|
prUrl: 'https://github.com/o/r/pull/1',
|
|
262
262
|
projectItemId: 'PVTI_1',
|
|
@@ -268,7 +268,7 @@ describe('postConsoleOperation', () => {
|
|
|
268
268
|
|
|
269
269
|
const failingReview = (): Promise<void> =>
|
|
270
270
|
postConsoleOperation('/api/review', {
|
|
271
|
-
pjcode: '
|
|
271
|
+
pjcode: 'acme',
|
|
272
272
|
action: 'approve',
|
|
273
273
|
prUrl: 'https://github.com/o/r/pull/1',
|
|
274
274
|
projectItemId: 'PVTI_1',
|
|
@@ -299,7 +299,7 @@ describe('postConsoleReviewComment', () => {
|
|
|
299
299
|
it('posts the inline review comment body to the reviewcomment endpoint', async () => {
|
|
300
300
|
const fetchMock = mockFetchOnce({ ok: true });
|
|
301
301
|
await postConsoleReviewComment({
|
|
302
|
-
pjcode: '
|
|
302
|
+
pjcode: 'acme',
|
|
303
303
|
url: 'https://github.com/o/r/pull/1',
|
|
304
304
|
path: 'src/index.ts',
|
|
305
305
|
line: 42,
|
|
@@ -310,7 +310,7 @@ describe('postConsoleReviewComment', () => {
|
|
|
310
310
|
expect(url).toBe('/api/reviewcomment');
|
|
311
311
|
expect(init).toMatchObject({ method: 'POST' });
|
|
312
312
|
expect(JSON.parse((init as { body: string }).body)).toEqual({
|
|
313
|
-
pjcode: '
|
|
313
|
+
pjcode: 'acme',
|
|
314
314
|
url: 'https://github.com/o/r/pull/1',
|
|
315
315
|
path: 'src/index.ts',
|
|
316
316
|
line: 42,
|
|
@@ -329,7 +329,7 @@ describe('postConsoleReviewComment', () => {
|
|
|
329
329
|
);
|
|
330
330
|
await expect(
|
|
331
331
|
postConsoleReviewComment({
|
|
332
|
-
pjcode: '
|
|
332
|
+
pjcode: 'acme',
|
|
333
333
|
url: 'https://github.com/o/r/pull/1',
|
|
334
334
|
path: 'src/index.ts',
|
|
335
335
|
line: 42,
|
|
@@ -30,7 +30,7 @@ const item = (number: number): ConsoleListItem => ({
|
|
|
30
30
|
|
|
31
31
|
describe('overlay helpers', () => {
|
|
32
32
|
it('builds the per-project storage key', () => {
|
|
33
|
-
expect(overlayStorageKey('
|
|
33
|
+
expect(overlayStorageKey('acme')).toBe('pv_overlay_acme');
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it('uses the projectItemId as the overlay key when present', () => {
|
|
@@ -20,7 +20,7 @@ jest.mock('../lib/mermaidLoader', () => ({
|
|
|
20
20
|
}));
|
|
21
21
|
|
|
22
22
|
const listPayload = (tab: string) => ({
|
|
23
|
-
pjcode: '
|
|
23
|
+
pjcode: 'acme',
|
|
24
24
|
generatedAt: '2026-06-19T00:00:00.000Z',
|
|
25
25
|
statusOptions: [{ id: 's1', name: 'Awaiting Workspace', color: 'BLUE' }],
|
|
26
26
|
storyOptions: [{ id: 'st1', name: 'TDPM Console port', color: 'BLUE' }],
|
|
@@ -89,7 +89,7 @@ const installFetch = (): void => {
|
|
|
89
89
|
describe('ConsolePage', () => {
|
|
90
90
|
beforeEach(() => {
|
|
91
91
|
localStorage.clear();
|
|
92
|
-
window.history.replaceState({}, '', '/projects/
|
|
92
|
+
window.history.replaceState({}, '', '/projects/acme/prs?k=token');
|
|
93
93
|
installFetch();
|
|
94
94
|
});
|
|
95
95
|
|
|
@@ -254,7 +254,7 @@ describe('ConsolePage', () => {
|
|
|
254
254
|
expect(getByText('Add serveConsole subcommand')).toBeInTheDocument();
|
|
255
255
|
});
|
|
256
256
|
expect(queryByText('TDPM Console')).toBeNull();
|
|
257
|
-
expect(queryByText('project:
|
|
257
|
+
expect(queryByText('project: acme')).toBeNull();
|
|
258
258
|
});
|
|
259
259
|
|
|
260
260
|
it('removes a processed workflow-blocker item from the list and decrements its tab badge, like every other tab', async () => {
|
|
@@ -312,7 +312,7 @@ describe('ConsolePage', () => {
|
|
|
312
312
|
});
|
|
313
313
|
global.fetch = fetchMock as unknown as typeof fetch;
|
|
314
314
|
localStorage.setItem(
|
|
315
|
-
'
|
|
315
|
+
'pv_overlay_acme',
|
|
316
316
|
JSON.stringify({
|
|
317
317
|
PVTI_B1: {
|
|
318
318
|
ts: Date.parse('2026-06-19T00:05:00.000Z'),
|
|
@@ -324,7 +324,7 @@ describe('ConsolePage', () => {
|
|
|
324
324
|
window.history.replaceState(
|
|
325
325
|
{},
|
|
326
326
|
'',
|
|
327
|
-
'/projects/
|
|
327
|
+
'/projects/acme/workflow-blocker?k=token',
|
|
328
328
|
);
|
|
329
329
|
|
|
330
330
|
const { getByText, queryByText } = render(<ConsolePage />);
|
|
@@ -378,7 +378,7 @@ describe('ConsolePage', () => {
|
|
|
378
378
|
});
|
|
379
379
|
global.fetch = fetchMock as unknown as typeof fetch;
|
|
380
380
|
localStorage.setItem(
|
|
381
|
-
'
|
|
381
|
+
'pv_overlay_acme',
|
|
382
382
|
JSON.stringify({
|
|
383
383
|
PVTI_B1: {
|
|
384
384
|
ts: Date.parse('2026-06-18T23:00:00.000Z'),
|
|
@@ -390,7 +390,7 @@ describe('ConsolePage', () => {
|
|
|
390
390
|
window.history.replaceState(
|
|
391
391
|
{},
|
|
392
392
|
'',
|
|
393
|
-
'/projects/
|
|
393
|
+
'/projects/acme/workflow-blocker?k=token',
|
|
394
394
|
);
|
|
395
395
|
|
|
396
396
|
const { getByText } = render(<ConsolePage />);
|
|
@@ -462,7 +462,7 @@ describe('ConsolePage', () => {
|
|
|
462
462
|
});
|
|
463
463
|
|
|
464
464
|
const twoItemPrPayload = () => ({
|
|
465
|
-
pjcode: '
|
|
465
|
+
pjcode: 'acme',
|
|
466
466
|
generatedAt: '2026-06-19T00:00:00.000Z',
|
|
467
467
|
statusOptions: [{ id: 's1', name: 'Awaiting Workspace', color: 'BLUE' }],
|
|
468
468
|
storyOptions: [{ id: 'st1', name: 'TDPM Console port', color: 'BLUE' }],
|
|
@@ -533,7 +533,7 @@ const swipeDetailScreen = (
|
|
|
533
533
|
describe('ConsolePage swipe navigation', () => {
|
|
534
534
|
beforeEach(() => {
|
|
535
535
|
localStorage.clear();
|
|
536
|
-
window.history.replaceState({}, '', '/projects/
|
|
536
|
+
window.history.replaceState({}, '', '/projects/acme/prs?k=token');
|
|
537
537
|
const fetchMock = jest.fn(async (url: string) => {
|
|
538
538
|
const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
|
|
539
539
|
if (listMatch !== null) {
|
|
@@ -601,7 +601,7 @@ describe('ConsolePage swipe navigation', () => {
|
|
|
601
601
|
describe('ConsolePage auto-advance', () => {
|
|
602
602
|
beforeEach(() => {
|
|
603
603
|
localStorage.clear();
|
|
604
|
-
window.history.replaceState({}, '', '/projects/
|
|
604
|
+
window.history.replaceState({}, '', '/projects/acme/prs?k=token');
|
|
605
605
|
const fetchMock = jest.fn(async (url: string) => {
|
|
606
606
|
const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
|
|
607
607
|
if (listMatch !== null) {
|
|
@@ -644,7 +644,7 @@ describe('ConsolePage auto-advance', () => {
|
|
|
644
644
|
describe('ConsolePage scroll reset', () => {
|
|
645
645
|
beforeEach(() => {
|
|
646
646
|
localStorage.clear();
|
|
647
|
-
window.history.replaceState({}, '', '/projects/
|
|
647
|
+
window.history.replaceState({}, '', '/projects/acme/prs?k=token');
|
|
648
648
|
const fetchMock = jest.fn(async (url: string) => {
|
|
649
649
|
const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
|
|
650
650
|
if (listMatch !== null) {
|
|
@@ -706,7 +706,7 @@ describe('ConsolePage scroll reset', () => {
|
|
|
706
706
|
describe('ConsolePage comment composer isolation', () => {
|
|
707
707
|
beforeEach(() => {
|
|
708
708
|
localStorage.clear();
|
|
709
|
-
window.history.replaceState({}, '', '/projects/
|
|
709
|
+
window.history.replaceState({}, '', '/projects/acme/prs?k=token');
|
|
710
710
|
const fetchMock = jest.fn(async (url: string, init?: RequestInit) => {
|
|
711
711
|
const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
|
|
712
712
|
if (listMatch !== null) {
|
|
@@ -784,7 +784,7 @@ describe('ConsolePage comment composer isolation', () => {
|
|
|
784
784
|
describe('ConsolePage auto-advance tab', () => {
|
|
785
785
|
beforeEach(() => {
|
|
786
786
|
localStorage.clear();
|
|
787
|
-
window.history.replaceState({}, '', '/projects/
|
|
787
|
+
window.history.replaceState({}, '', '/projects/acme/prs?k=token');
|
|
788
788
|
installFetch();
|
|
789
789
|
});
|
|
790
790
|
|