gitforest 0.1.0 → 1.0.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 (183) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +24 -4
  3. package/src/github/auth.ts +3 -3
  4. package/src/utils/debug.ts +4 -4
  5. package/.bunignore +0 -7
  6. package/.github/workflows/ci.yml +0 -73
  7. package/CLAUDE.md +0 -111
  8. package/CONTRIBUTING.md +0 -145
  9. package/bun.lock +0 -267
  10. package/bunfig.toml +0 -15
  11. package/cli +0 -0
  12. package/docs/ai/IMPROVEMENT_PLAN.md +0 -341
  13. package/docs/ai/VERIFICATION_REPORT.md +0 -87
  14. package/docs/ai/architecture.md +0 -169
  15. package/docs/ai/checks/check-2025-12-02-tests.md +0 -40
  16. package/docs/ai/checks/check-2025-12-02.md +0 -55
  17. package/docs/ai/checks/test-verification-report.md +0 -85
  18. package/docs/ai/implementation-guide.md +0 -776
  19. package/docs/ai/research/gitty-codebase-analysis.md +0 -221
  20. package/docs/ai/tickets/GENERAL-sitrep.md +0 -30
  21. package/docs/ai/tickets/TASK-database-tests-sitrep.md +0 -25
  22. package/docs/ai/tickets/TASK-deprecated-functions-sitrep.md +0 -28
  23. package/docs/ai/tickets/TASK-detail-modal-sitrep.md +0 -28
  24. package/docs/ai/tickets/TASK-filter-overlay-sitrep.md +0 -24
  25. package/docs/ai/tickets/TASK-github-service-sitrep.md +0 -32
  26. package/docs/ai/tickets/TASK-github-token-sitrep.md +0 -51
  27. package/docs/ai/tickets/TASK-hascommits-sitrep.md +0 -35
  28. package/docs/ai/tickets/TASK-keybindings-sitrep.md +0 -26
  29. package/docs/ai/tickets/TASK-layout-sitrep.md +0 -25
  30. package/docs/ai/tickets/TASK-markdown-sitrep.md +0 -28
  31. package/docs/ai/tickets/TASK-project-item-sitrep.md +0 -79
  32. package/docs/ai/tickets/TASK-sitrep.md +0 -28
  33. package/docs/ai/tickets/TASK-state-sitrep.md +0 -26
  34. package/docs/ai/tickets/TASK-types-sitrep.md +0 -25
  35. package/docs/ai/tickets/TASK-unified-item-fix-sitrep.md +0 -26
  36. package/docs/ai/tickets/TKT-001-sitrep.md +0 -24
  37. package/docs/ai/tickets/TKT-002-sitrep.md +0 -25
  38. package/docs/ai/tickets/TKT-003-git-service-refactoring-complete.md +0 -46
  39. package/docs/ai/tickets/TKT-003-git-service-refactoring-plan.md +0 -135
  40. package/docs/ai/tickets/TKT-003-sitrep.md +0 -26
  41. package/docs/ai/tickets/TKT-004-sitrep.md +0 -27
  42. package/docs/ai/tickets/TKT-005-sitrep.md +0 -25
  43. package/docs/ai/tickets/TKT-006-sitrep.md +0 -26
  44. package/docs/ai/tickets/TKT-007-sitrep.md +0 -30
  45. package/docs/ai/tickets/TKT-008-sitrep.md +0 -32
  46. package/docs/ai/tickets/TKT-009-sitrep.md +0 -27
  47. package/docs/ai/tickets/TKT-010-sitrep.md +0 -27
  48. package/docs/ai/tickets/TKT-011-sitrep.md +0 -26
  49. package/docs/ai/tickets/TKT-012-sitrep.md +0 -25
  50. package/docs/ai/tickets/sitreps/TASK-actions-sitrep.md +0 -28
  51. package/docs/ai/tickets/sitreps/TASK-actions-test-sitrep.md +0 -25
  52. package/docs/ai/tickets/sitreps/TASK-app-integration-sitrep.md +0 -25
  53. package/docs/ai/tickets/sitreps/TASK-background-fetch-sitrep.md +0 -24
  54. package/docs/ai/tickets/sitreps/TASK-background-fetch-test-sitrep.md +0 -29
  55. package/docs/ai/tickets/sitreps/TASK-batch-tests-sitrep.md +0 -29
  56. package/docs/ai/tickets/sitreps/TASK-bun-test-sitrep.md +0 -26
  57. package/docs/ai/tickets/sitreps/TASK-cache-tests-sitrep.md +0 -30
  58. package/docs/ai/tickets/sitreps/TASK-cli-tests-sitrep.md +0 -28
  59. package/docs/ai/tickets/sitreps/TASK-clone-error-handling-sitrep.md +0 -26
  60. package/docs/ai/tickets/sitreps/TASK-commands-tests-sitrep.md +0 -25
  61. package/docs/ai/tickets/sitreps/TASK-component-tests-1-sitrep.md +0 -30
  62. package/docs/ai/tickets/sitreps/TASK-configloader-tests-sitrep.md +0 -25
  63. package/docs/ai/tickets/sitreps/TASK-confirm-dialog-test-sitrep.md +0 -29
  64. package/docs/ai/tickets/sitreps/TASK-coverage-sitrep.md +0 -95
  65. package/docs/ai/tickets/sitreps/TASK-database-tests-summary.md +0 -61
  66. package/docs/ai/tickets/sitreps/TASK-error-boundary-sitrep.md +0 -30
  67. package/docs/ai/tickets/sitreps/TASK-error-tests-sitrep.md +0 -27
  68. package/docs/ai/tickets/sitreps/TASK-errors-tests-sitrep.md +0 -25
  69. package/docs/ai/tickets/sitreps/TASK-extract-reducer-sitrep.md +0 -27
  70. package/docs/ai/tickets/sitreps/TASK-filter-overlay-test-sitrep.md +0 -25
  71. package/docs/ai/tickets/sitreps/TASK-final-verification-sitrep.md +0 -28
  72. package/docs/ai/tickets/sitreps/TASK-fix-all-tests-sitrep.md +0 -25
  73. package/docs/ai/tickets/sitreps/TASK-fix-hooks-sitrep.md +0 -26
  74. package/docs/ai/tickets/sitreps/TASK-fix-remaining-tests-sitrep.md +0 -25
  75. package/docs/ai/tickets/sitreps/TASK-fix-test-failures-sitrep.md +0 -26
  76. package/docs/ai/tickets/sitreps/TASK-fix-tests-sitrep.md +0 -24
  77. package/docs/ai/tickets/sitreps/TASK-formatters-tests-sitrep.md +0 -25
  78. package/docs/ai/tickets/sitreps/TASK-git-timeouts-sitrep.md +0 -29
  79. package/docs/ai/tickets/sitreps/TASK-github-cache-test-sitrep.md +0 -25
  80. package/docs/ai/tickets/sitreps/TASK-githubcli-tests-sitrep.md +0 -24
  81. package/docs/ai/tickets/sitreps/TASK-gitstatus-tests-sitrep.md +0 -24
  82. package/docs/ai/tickets/sitreps/TASK-hooks-isolation-sitrep.md +0 -27
  83. package/docs/ai/tickets/sitreps/TASK-keybindings-tests-sitrep.md +0 -25
  84. package/docs/ai/tickets/sitreps/TASK-layout-tests-sitrep.md +0 -25
  85. package/docs/ai/tickets/sitreps/TASK-mock-factories-sitrep.md +0 -27
  86. package/docs/ai/tickets/sitreps/TASK-modal-tests-sitrep.md +0 -32
  87. package/docs/ai/tickets/sitreps/TASK-processbatch-fix-sitrep.md +0 -27
  88. package/docs/ai/tickets/sitreps/TASK-projectlist-tests-sitrep.md +0 -30
  89. package/docs/ai/tickets/sitreps/TASK-projectutils-tests-sitrep.md +0 -25
  90. package/docs/ai/tickets/sitreps/TASK-scanner-tests-sitrep.md +0 -29
  91. package/docs/ai/tickets/sitreps/TASK-select-all-sitrep.md +0 -25
  92. package/docs/ai/tickets/sitreps/TASK-shell-error-handling-sitrep.md +0 -27
  93. package/docs/ai/tickets/sitreps/TASK-store-tests-sitrep.md +0 -25
  94. package/docs/ai/tickets/sitreps/TASK-test-fixes-sitrep.md +0 -26
  95. package/docs/ai/tickets/sitreps/TASK-test-summary-sitrep.md +0 -25
  96. package/docs/ai/tickets/sitreps/TASK-test-verification-sitrep.md +0 -27
  97. package/docs/ai/tickets/sitreps/TASK-testsuite-sitrep.md +0 -75
  98. package/docs/ai/tickets/sitreps/TASK-unified-reducer-tests-sitrep.md +0 -29
  99. package/docs/ai/tickets/sitreps/TASK-unified-repos-test-sitrep.md +0 -29
  100. package/docs/ai/tickets/sitreps/TASK-unified-tests-sitrep.md +0 -25
  101. package/docs/ai/tickets/sitreps/TASK-useprojects-tests-sitrep.md +0 -25
  102. package/docs/ai/tickets/sitreps/TASK-utility-tests-sitrep.md +0 -32
  103. package/docs/ai/tickets/sitreps/TKT-003-git-service-refactoring-sitrep.md +0 -64
  104. package/docs/ai/tkt-001-fix-database-error.md +0 -217
  105. package/docs/ai/ui-enhancement-plan.md +0 -562
  106. package/test/integration/app.isolated.tsx +0 -240
  107. package/test/integration/cli-commands.test.ts +0 -287
  108. package/test/integration/cli-validation.test.ts +0 -264
  109. package/test/integration/git-operations.test.ts +0 -218
  110. package/test/integration/scanner.test.ts +0 -228
  111. package/test/preload.ts +0 -18
  112. package/test/unit/cli/commands.test.ts +0 -13
  113. package/test/unit/cli/formatters.test.ts +0 -1116
  114. package/test/unit/cli/github-commands.test.ts +0 -12
  115. package/test/unit/components/CloneDialog.test.tsx +0 -240
  116. package/test/unit/components/ColumnHeader.test.tsx +0 -128
  117. package/test/unit/components/CommandPalette.test.tsx +0 -355
  118. package/test/unit/components/ConfirmDialog.test.tsx +0 -111
  119. package/test/unit/components/ErrorBoundary.test.tsx +0 -139
  120. package/test/unit/components/FilterBar.test.tsx +0 -43
  121. package/test/unit/components/FilterOptionsOverlay.test.tsx +0 -197
  122. package/test/unit/components/HelpOverlay.test.tsx +0 -90
  123. package/test/unit/components/Layout.test.tsx +0 -328
  124. package/test/unit/components/MarkdownRenderer.test.tsx +0 -45
  125. package/test/unit/components/ProgressBar.test.tsx +0 -138
  126. package/test/unit/components/ProjectItem.test.tsx +0 -182
  127. package/test/unit/components/ProjectList.test.tsx +0 -311
  128. package/test/unit/components/RepoDetailModal.test.tsx +0 -445
  129. package/test/unit/components/StatusBar.test.tsx +0 -112
  130. package/test/unit/components/UnifiedProjectItem.test.tsx +0 -618
  131. package/test/unit/components/ViewModeIndicator.test.tsx +0 -137
  132. package/test/unit/components/test-utils.tsx +0 -63
  133. package/test/unit/config/loader.test.ts +0 -692
  134. package/test/unit/db/database.test.ts +0 -978
  135. package/test/unit/db/index.test.ts +0 -314
  136. package/test/unit/fixtures/setup.ts +0 -186
  137. package/test/unit/git/commands-untested.test.ts +0 -205
  138. package/test/unit/git/commands.test.ts +0 -269
  139. package/test/unit/git/operations.test.ts +0 -322
  140. package/test/unit/git/status.test.ts +0 -219
  141. package/test/unit/github/auth.test.ts +0 -317
  142. package/test/unit/github/cache.test.ts +0 -1028
  143. package/test/unit/github/cli.test.ts +0 -135
  144. package/test/unit/github/unified.test.ts +0 -1201
  145. package/test/unit/graceful-shutdown.test.ts +0 -83
  146. package/test/unit/hooks/useBackgroundFetch.test.tsx +0 -239
  147. package/test/unit/hooks/useConfirmDialogActions.test.tsx +0 -81
  148. package/test/unit/hooks/useKeyBindings.isolated.ts +0 -715
  149. package/test/unit/hooks/useProjects.test.tsx +0 -186
  150. package/test/unit/hooks/useUnifiedRepos-simple.test.tsx +0 -115
  151. package/test/unit/hooks/useUnifiedRepos.test.tsx +0 -177
  152. package/test/unit/mocks/config.ts +0 -109
  153. package/test/unit/mocks/git-service.ts +0 -274
  154. package/test/unit/mocks/github-service.ts +0 -250
  155. package/test/unit/mocks/index.ts +0 -72
  156. package/test/unit/mocks/project.ts +0 -148
  157. package/test/unit/mocks/state-mocks.ts +0 -187
  158. package/test/unit/mocks/unified.ts +0 -169
  159. package/test/unit/operations/batch.test.ts +0 -216
  160. package/test/unit/operations/commands.test.ts +0 -550
  161. package/test/unit/scanner/errors.test.ts +0 -297
  162. package/test/unit/scanner/index.test.ts +0 -1011
  163. package/test/unit/scanner/markers.test.ts +0 -150
  164. package/test/unit/scanner/submodules.test.ts +0 -99
  165. package/test/unit/services/git-errors.test.ts +0 -190
  166. package/test/unit/services/git.test.ts +0 -442
  167. package/test/unit/services/github-errors.test.ts +0 -293
  168. package/test/unit/services/github.test.ts +0 -200
  169. package/test/unit/state/actions.test.ts +0 -217
  170. package/test/unit/state/reducer.test.ts +0 -745
  171. package/test/unit/state/store.test.tsx +0 -711
  172. package/test/unit/types/commands.test.ts +0 -220
  173. package/test/unit/types/schema.test.ts +0 -179
  174. package/test/unit/utils/array.test.ts +0 -73
  175. package/test/unit/utils/debug.test.ts +0 -23
  176. package/test/unit/utils/errors.test.ts +0 -295
  177. package/test/unit/utils/markdown.test.ts +0 -163
  178. package/test/unit/utils/project-utils.test.ts +0 -756
  179. package/test/unit/utils/rate-limiter.test.ts +0 -256
  180. package/test/unit/utils/retry.test.ts +0 -165
  181. package/test/unit/utils/strip-ansi.ts +0 -13
  182. package/test/unit/utils/timeout.test.ts +0 -93
  183. package/tsconfig.json +0 -29
@@ -1,83 +0,0 @@
1
- /**
2
- * Tests for graceful shutdown functionality
3
- */
4
- import { describe, test, expect } from "bun:test";
5
- import { spawn } from "bun";
6
- import { join } from "path";
7
-
8
- describe("Graceful Shutdown", () => {
9
- test("should register signal handlers when main module loads", async () => {
10
- // Test that the main module properly registers signal handlers
11
- // by spawning the process and checking it handles signals gracefully
12
-
13
- const gitforestPath = join(import.meta.dir, "../../src/index.tsx");
14
- const proc = spawn(["bun", gitforestPath, "--help"], {
15
- stdout: "pipe",
16
- stderr: "pipe",
17
- });
18
-
19
- let stdout = "";
20
- let stderr = "";
21
-
22
- for await (const chunk of proc.stdout) {
23
- stdout += new TextDecoder().decode(chunk);
24
- }
25
-
26
- for await (const chunk of proc.stderr) {
27
- stderr += new TextDecoder().decode(chunk);
28
- }
29
-
30
- const exitCode = await proc.exited;
31
-
32
- // Should exit cleanly with code 0
33
- expect(exitCode).toBe(0);
34
-
35
- // Should show help text
36
- expect(stdout).toContain("gitforest - Git Repository Manager");
37
- expect(stdout).toContain("Usage:");
38
- }, { timeout: 5000 });
39
-
40
- test("should handle multiple shutdown attempts gracefully", async () => {
41
- // Test the isShuttingDown flag behavior by simulating the pattern
42
- let isShuttingDown = false;
43
- let shutdownCount = 0;
44
-
45
- const gracefulShutdown = async (_signal: string) => {
46
- if (isShuttingDown) return;
47
- isShuttingDown = true;
48
- shutdownCount++;
49
- };
50
-
51
- // Simulate multiple rapid shutdown calls
52
- await Promise.all([
53
- gracefulShutdown("SIGINT"),
54
- gracefulShutdown("SIGINT"),
55
- gracefulShutdown("SIGTERM")
56
- ]);
57
-
58
- // With protection, only the first should execute
59
- expect(shutdownCount).toBe(1);
60
- expect(isShuttingDown).toBe(true);
61
- });
62
-
63
- test("should close database on shutdown", async () => {
64
- // Mock the database close function to verify it's called
65
- let dbClosed = false;
66
- const mockCloseDb = () => {
67
- dbClosed = true;
68
- };
69
-
70
- // Simulate shutdown sequence
71
- const gracefulShutdown = async () => {
72
- try {
73
- mockCloseDb();
74
- } catch (error) {
75
- console.error('Error during shutdown:', error);
76
- }
77
- };
78
-
79
- await gracefulShutdown();
80
-
81
- expect(dbClosed).toBe(true);
82
- });
83
- });
@@ -1,239 +0,0 @@
1
- /**
2
- * Tests for useBackgroundFetch hook
3
- *
4
- * Uses TestStoreProvider and dependency injection instead of mock.module()
5
- */
6
-
7
- import { describe, test, expect, mock } from "bun:test";
8
- import React from "react";
9
- import { render } from "ink-testing-library";
10
- import { Text } from "ink";
11
- import { useBackgroundFetch } from "../../../src/hooks/useBackgroundFetch.ts";
12
- import { TestStoreProvider } from "../../../src/state/store.tsx";
13
- import { createMockUnifiedAppState } from "../mocks/index.ts";
14
- import type { GitforestConfig, Project, UnifiedAppState } from "../../../src/types/index.ts";
15
-
16
- // Mock config factory
17
- const createDefaultConfig = (): GitforestConfig => ({
18
- directories: [{ path: "/test", maxDepth: 2 }],
19
- scan: {
20
- ignore: ["node_modules", ".git"],
21
- includeHidden: false,
22
- concurrency: 5,
23
- },
24
- github: { defaultVisibility: "private" as const },
25
- display: {
26
- showSubmodules: true,
27
- showNonGitProjects: true,
28
- sortBy: "status" as const,
29
- sortDirection: "desc" as const,
30
- },
31
- cache: {
32
- ttlSeconds: 300,
33
- githubTtlSeconds: 600,
34
- enableBackgroundRefresh: true,
35
- backgroundRefreshIntervalSeconds: 300,
36
- },
37
- commands: [],
38
- });
39
-
40
- // Create mock projects
41
- const createGitProjectWithRemote = (id: string, name: string): Project => ({
42
- id,
43
- name,
44
- path: `/test/${name}`,
45
- type: "git",
46
- projectMarker: null,
47
- submodule: null,
48
- lastScanned: new Date(),
49
- lastModified: null,
50
- status: {
51
- hasUnstagedChanges: false,
52
- hasStagedChanges: false,
53
- hasUntrackedFiles: false,
54
- modifiedCount: 0,
55
- stagedCount: 0,
56
- untrackedCount: 0,
57
- currentBranch: "main",
58
- trackingBranch: "origin/main",
59
- unpushedCommits: 0,
60
- unpulledCommits: 0,
61
- hasRemote: true,
62
- remoteUrl: "git@github.com:user/repo.git",
63
- lastLocalCommit: null,
64
- lastRemoteActivity: null,
65
- hasCommits: true,
66
- isDirty: false,
67
- isAhead: false,
68
- isBehind: false,
69
- isOutOfSync: false,
70
- },
71
- });
72
-
73
- /**
74
- * Helper to create test component with store context
75
- */
76
- function createTestComponent(
77
- config: GitforestConfig,
78
- state: UnifiedAppState,
79
- mockOnRefresh: () => Promise<void>,
80
- mockBatchFetch: () => Promise<any>,
81
- mockDispatch: (action: any) => void,
82
- ) {
83
- const TestComponent = () => {
84
- useBackgroundFetch(config, mockOnRefresh, {
85
- batchFetch: mockBatchFetch,
86
- });
87
- return <Text>Test</Text>;
88
- };
89
-
90
- return render(
91
- <TestStoreProvider initialState={state} dispatch={mockDispatch}>
92
- <TestComponent />
93
- </TestStoreProvider>
94
- );
95
- }
96
-
97
- describe("useBackgroundFetch", () => {
98
- describe("Configuration tests", () => {
99
- test("does not run when disabled in config", () => {
100
- const config = {
101
- ...createDefaultConfig(),
102
- cache: {
103
- ...createDefaultConfig().cache,
104
- enableBackgroundRefresh: false,
105
- },
106
- };
107
-
108
- const mockBatchFetch = mock(() => Promise.resolve());
109
- const mockOnRefresh = mock(() => Promise.resolve());
110
- const mockDispatch = mock(() => {});
111
-
112
- const state = createMockUnifiedAppState({
113
- isLoading: false,
114
- projects: [createGitProjectWithRemote("1", "test-repo")],
115
- });
116
-
117
- const { unmount, lastFrame } = createTestComponent(
118
- config,
119
- state,
120
- mockOnRefresh,
121
- mockBatchFetch,
122
- mockDispatch
123
- );
124
-
125
- expect(lastFrame()).toContain("Test");
126
-
127
- unmount();
128
- });
129
-
130
- test("hook renders without error when enabled", () => {
131
- const config = createDefaultConfig();
132
- const mockBatchFetch = mock(() => Promise.resolve());
133
- const mockOnRefresh = mock(() => Promise.resolve());
134
- const mockDispatch = mock(() => {});
135
-
136
- const state = createMockUnifiedAppState({
137
- isLoading: true,
138
- });
139
-
140
- const { unmount, lastFrame } = createTestComponent(
141
- config,
142
- state,
143
- mockOnRefresh,
144
- mockBatchFetch,
145
- mockDispatch
146
- );
147
-
148
- expect(lastFrame()).toContain("Test");
149
-
150
- unmount();
151
- });
152
- });
153
-
154
- describe("State-based skipping tests", () => {
155
- test("does not run during loading state", () => {
156
- const config = createDefaultConfig();
157
- const mockBatchFetch = mock(() => Promise.resolve());
158
- const mockOnRefresh = mock(() => Promise.resolve());
159
- const mockDispatch = mock(() => {});
160
-
161
- const state = createMockUnifiedAppState({
162
- isLoading: true,
163
- projects: [createGitProjectWithRemote("1", "test-repo")],
164
- });
165
-
166
- const { unmount, lastFrame } = createTestComponent(
167
- config,
168
- state,
169
- mockOnRefresh,
170
- mockBatchFetch,
171
- mockDispatch
172
- );
173
-
174
- expect(lastFrame()).toContain("Test");
175
- // Should not have dispatched any actions since loading
176
- expect(mockDispatch).not.toHaveBeenCalled();
177
-
178
- unmount();
179
- });
180
-
181
- test("does not run during action in progress", () => {
182
- const config = createDefaultConfig();
183
- const mockBatchFetch = mock(() => Promise.resolve());
184
- const mockOnRefresh = mock(() => Promise.resolve());
185
- const mockDispatch = mock(() => {});
186
-
187
- const state = createMockUnifiedAppState({
188
- isLoading: false,
189
- actionInProgress: "some-action",
190
- projects: [createGitProjectWithRemote("1", "test-repo")],
191
- });
192
-
193
- const { unmount, lastFrame } = createTestComponent(
194
- config,
195
- state,
196
- mockOnRefresh,
197
- mockBatchFetch,
198
- mockDispatch
199
- );
200
-
201
- expect(lastFrame()).toContain("Test");
202
- // Should not have dispatched since action in progress
203
- expect(mockDispatch).not.toHaveBeenCalled();
204
-
205
- unmount();
206
- });
207
- });
208
-
209
- describe("Return value tests", () => {
210
- test("returns null", () => {
211
- const config = createDefaultConfig();
212
- const mockBatchFetch = mock(() => Promise.resolve());
213
- const mockOnRefresh = mock(() => Promise.resolve());
214
- const mockDispatch = mock(() => {});
215
-
216
- const state = createMockUnifiedAppState({
217
- isLoading: true,
218
- });
219
-
220
- let returnValue: any;
221
- const TestComponent = () => {
222
- returnValue = useBackgroundFetch(config, mockOnRefresh, {
223
- batchFetch: mockBatchFetch,
224
- });
225
- return <Text>Test</Text>;
226
- };
227
-
228
- const { unmount } = render(
229
- <TestStoreProvider initialState={state} dispatch={mockDispatch}>
230
- <TestComponent />
231
- </TestStoreProvider>
232
- );
233
-
234
- expect(returnValue).toBeNull();
235
-
236
- unmount();
237
- });
238
- });
239
- });
@@ -1,81 +0,0 @@
1
- /**
2
- * Tests for useConfirmDialogActions hook
3
- *
4
- * Note: React hooks can only be tested inside React components.
5
- * These tests focus on the underlying operations and logic that don't
6
- * require the hook context. The hook's integration is tested via
7
- * component tests and integration tests.
8
- */
9
-
10
- import { describe, test, expect, mock, beforeEach } from "bun:test";
11
-
12
- // Mock git init function
13
- const mockInitGitInProject = mock(() => Promise.resolve({ success: true, operation: "init" as const }));
14
-
15
- // Mock GitHub service
16
- const mockCreateRepo = mock(() => Promise.resolve({ success: true, url: "https://github.com/test/repo" }));
17
- const mockArchiveRepo = mock(() => Promise.resolve({ success: true }));
18
-
19
- describe("useConfirmDialogActions operations", () => {
20
- beforeEach(() => {
21
- mockInitGitInProject.mockClear();
22
- mockCreateRepo.mockClear();
23
- mockArchiveRepo.mockClear();
24
- });
25
-
26
- describe("Git init operation", () => {
27
- test("init returns success for valid directory", async () => {
28
- mockInitGitInProject.mockResolvedValueOnce({ success: true, operation: "init" });
29
-
30
- const result = await mockInitGitInProject();
31
-
32
- expect(result.success).toBe(true);
33
- expect(result.operation).toBe("init");
34
- });
35
-
36
- test("init returns failure for invalid directory", async () => {
37
- mockInitGitInProject.mockResolvedValueOnce({ success: false, operation: "init" });
38
-
39
- const result = await mockInitGitInProject();
40
-
41
- expect(result.success).toBe(false);
42
- });
43
- });
44
-
45
- describe("GitHub repo creation", () => {
46
- test("creates repo successfully", async () => {
47
- mockCreateRepo.mockResolvedValueOnce({ success: true, url: "https://github.com/user/repo" });
48
-
49
- const result = await mockCreateRepo();
50
-
51
- expect(result.success).toBe(true);
52
- expect(result.url).toContain("github.com");
53
- });
54
-
55
- test("handles creation failure", async () => {
56
- mockCreateRepo.mockResolvedValueOnce({ success: false, url: "" });
57
-
58
- const result = await mockCreateRepo();
59
-
60
- expect(result.success).toBe(false);
61
- });
62
- });
63
-
64
- describe("GitHub repo archiving", () => {
65
- test("archives repo successfully", async () => {
66
- mockArchiveRepo.mockResolvedValueOnce({ success: true });
67
-
68
- const result = await mockArchiveRepo();
69
-
70
- expect(result.success).toBe(true);
71
- });
72
-
73
- test("handles archive failure", async () => {
74
- mockArchiveRepo.mockResolvedValueOnce({ success: false });
75
-
76
- const result = await mockArchiveRepo();
77
-
78
- expect(result.success).toBe(false);
79
- });
80
- });
81
- });