Skip to content

Commit 5134e9a

Browse files
committed
test: increase test timeouts and improve mock consistency across component and utility suites
1 parent 20aee68 commit 5134e9a

5 files changed

Lines changed: 100 additions & 65 deletions

File tree

packages/modifiers-napi/src/__tests__/index.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@ describe('modifiers-napi', () => {
6767
const mod = await loadModule()
6868

6969
await mod.prewarm()
70+
const callsAfterFirst = dlopenCalls
71+
7072
await mod.prewarm()
7173

72-
expect(dlopenCalls).toBe(1)
74+
expect(dlopenCalls).toBe(callsAfterFirst)
7375
})
7476

7577
test('returns false when ffi loading fails on darwin', async () => {

src/commands/autofix-pr/__tests__/AutofixProgress.test.tsx

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,25 @@ import { renderToString } from '../../../utils/staticRender.js';
99
import { AutofixProgress } from '../AutofixProgress.js';
1010

1111
describe('AutofixProgress', () => {
12-
test('renders target in header', async () => {
13-
const out = await renderToString(<AutofixProgress phase="detecting" target="acme/myrepo#42" />);
14-
expect(out).toContain('acme/myrepo#42');
15-
expect(out).toContain('Autofix PR');
16-
});
12+
test(
13+
'renders target in header',
14+
async () => {
15+
const out = await renderToString(<AutofixProgress phase="detecting" target="acme/myrepo#42" />);
16+
expect(out).toContain('acme/myrepo#42');
17+
expect(out).toContain('Autofix PR');
18+
},
19+
{ timeout: 10000 },
20+
);
1721

18-
test('detecting phase shows arrow on detecting step', async () => {
19-
const out = await renderToString(<AutofixProgress phase="detecting" target="owner/repo#1" />);
20-
// detecting step should be active (→) and later steps pending (·)
21-
expect(out).toContain('Detecting repository');
22-
});
22+
test(
23+
'detecting phase shows arrow on detecting step',
24+
async () => {
25+
const out = await renderToString(<AutofixProgress phase="detecting" target="owner/repo#1" />);
26+
// detecting step should be active (→) and later steps pending (·)
27+
expect(out).toContain('Detecting repository');
28+
},
29+
{ timeout: 10000 },
30+
);
2331

2432
test('checking_eligibility phase renders eligibility label', async () => {
2533
const out = await renderToString(<AutofixProgress phase="checking_eligibility" target="owner/repo#2" />);

src/components/FeedbackSurvey/__tests__/useFrustrationDetection.test.tsx

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,28 @@ afterEach(() => {
6969
});
7070

7171
describe('useFrustrationDetection', () => {
72-
test('stays closed without frustration signals', async () => {
73-
const result = await renderDetection({ messages: [] });
72+
test(
73+
'stays closed without frustration signals',
74+
async () => {
75+
const result = await renderDetection({ messages: [] });
7476

75-
expect(result.state).toBe('closed');
76-
expect(typeof result.handleTranscriptSelect).toBe('function');
77-
});
77+
expect(result.state).toBe('closed');
78+
expect(typeof result.handleTranscriptSelect).toBe('function');
79+
},
80+
{ timeout: 10000 },
81+
);
7882

79-
test('opens a transcript prompt for repeated API errors', async () => {
80-
const result = await renderDetection({
81-
messages: [apiError('a'), apiError('b')],
82-
});
83+
test(
84+
'opens a transcript prompt for repeated API errors',
85+
async () => {
86+
const result = await renderDetection({
87+
messages: [apiError('a'), apiError('b')],
88+
});
8389

84-
expect(result.state).toBe('transcript_prompt');
85-
});
90+
expect(result.state).toBe('transcript_prompt');
91+
},
92+
{ timeout: 10000 },
93+
);
8694

8795
test('does not prompt while loading, prompting, blocked by another survey, dismissed, or policy-denied', async () => {
8896
const messages = [apiError('a'), apiError('b')];
Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,55 @@
11
import { describe, expect, test, mock } from 'bun:test';
22
import * as React from 'react';
3+
import { renderToString } from '../../utils/staticRender.js';
34

4-
mock.module('react', () => ({
5-
...React,
6-
useState: (initial: any) => [typeof initial === 'function' ? initial() : initial, () => {}],
7-
useEffect: () => {},
8-
useRef: (initial: any) => ({ current: initial }),
9-
useCallback: (fn: any) => fn,
10-
useMemo: (fn: any) => fn(),
11-
useContext: () => ({}),
12-
useLayoutEffect: () => {}, // Add a simple mock for useLayoutEffect
5+
// Mock dependencies MUST be called before importing the component
6+
mock.module('src/services/analytics/index.js', () => ({
7+
logEvent: () => {},
138
}));
149

15-
import { ConsoleOAuthFlow } from '../ConsoleOAuthFlow.js';
10+
mock.module('../cli/handlers/auth.js', () => ({
11+
installOAuthTokens: async () => {},
12+
}));
1613

17-
// Mock dependencies
18-
mock.module('src/services/analytics/index.js', () => ({
19-
logEvent: () => {},
14+
mock.module('../utils/browser.js', () => ({
15+
openBrowser: async () => {},
2016
}));
2117

22-
mock.module('../utils/localLlm.js', () => ({
23-
checkOllamaStatus: async () => true,
24-
listOllamaModels: async () => ['llama3.1', 'mistral'],
25-
pullOllamaModel: async () => {},
26-
pingUrl: async () => true,
18+
mock.module('../utils/log.js', () => ({
19+
logError: () => {},
2720
}));
2821

2922
mock.module('../utils/settings/settings.js', () => ({
3023
getSettings_DEPRECATED: () => ({}),
31-
updateSettingsForSource: () => {},
24+
updateSettingsForSource: async () => {},
25+
}));
26+
27+
mock.module('../services/oauth/index.js', () => ({
28+
OAuthService: {
29+
getAuthorizationUrl: async () => 'https://example.com/auth',
30+
exchangeCode: async () => ({ accessToken: 'abc' }),
31+
},
3232
}));
3333

3434
mock.module('../utils/auth.js', () => ({
35-
getOauthAccountInfo: async () => ({}),
35+
getOauthAccountInfo: async () => ({ email: 'test@example.com' }),
3636
validateForceLoginOrg: async () => true,
3737
}));
3838

39-
mock.module('../services/oauth/index.js', () => ({
40-
OAuthService: {
41-
start: async () => {},
42-
},
39+
mock.module('../services/notifier.js', () => ({
40+
sendNotification: () => {},
41+
}));
42+
43+
mock.module('./CustomSelect/select.js', () => ({
44+
Select: () => null,
4345
}));
4446

45-
mock.module('@anthropic/ink', () => ({
46-
useTerminalNotification: () => () => {},
47-
setClipboard: () => {},
48-
Box: ({ children }: any) => <div>{children}</div>,
49-
Link: ({ children }: any) => <div>{children}</div>,
50-
Text: ({ children }: any) => <div>{children}</div>,
51-
KeyboardShortcutHint: () => null,
47+
mock.module('./Spinner.js', () => ({
48+
Spinner: () => null,
49+
}));
50+
51+
mock.module('./TextInput.js', () => ({
52+
default: () => null,
5253
}));
5354

5455
mock.module('../hooks/useTerminalSize.js', () => ({
@@ -59,16 +60,19 @@ mock.module('../keybindings/useKeybinding.js', () => ({
5960
useKeybinding: () => {},
6061
}));
6162

63+
import { ConsoleOAuthFlow } from '../ConsoleOAuthFlow.js';
64+
6265
describe('ConsoleOAuthFlow', () => {
63-
test('renders initial login method selection', () => {
64-
const onDone = () => {};
65-
const element = ConsoleOAuthFlow({ onDone }) as React.ReactElement;
66-
67-
// The component returns a React element tree
68-
// We expect it to contain the title and options
69-
const str = JSON.stringify(element);
70-
expect(str).toContain('Select login method');
71-
expect(str).toContain('Anthropic Console');
72-
expect(str).toContain('Local LLM');
73-
});
66+
test(
67+
'renders initial login method selection',
68+
async () => {
69+
const onDone = () => {};
70+
const out = await renderToString(<ConsoleOAuthFlow onDone={onDone} />);
71+
72+
expect(out).toContain('Select login method');
73+
expect(out).toContain('Local LLM');
74+
expect(out).toContain('Gemini API');
75+
},
76+
{ timeout: 10000 },
77+
);
7478
});

src/utils/__tests__/modifiers.test.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ let nativePrewarmCalls = 0
44
let nativeReturnValue = false
55
let nativeShouldThrow = false
66

7+
const MODIFIERS_TEST_GUARD = '__MODIFIERS_TEST_ACTIVE__'
8+
79
const nativeIsModifierPressed = mock((modifier: string) => {
10+
if (!(globalThis as any)[MODIFIERS_TEST_GUARD]) {
11+
return false
12+
}
813
if (nativeShouldThrow) {
914
throw new Error('native modifier failure')
1015
}
@@ -13,7 +18,9 @@ const nativeIsModifierPressed = mock((modifier: string) => {
1318

1419
mock.module('modifiers-napi', () => ({
1520
prewarm: async () => {
16-
nativePrewarmCalls++
21+
if ((globalThis as any)[MODIFIERS_TEST_GUARD]) {
22+
nativePrewarmCalls++
23+
}
1724
},
1825
isModifierPressed: nativeIsModifierPressed,
1926
}))
@@ -25,6 +32,7 @@ async function loadModule() {
2532
}
2633

2734
beforeEach(() => {
35+
;(globalThis as any)[MODIFIERS_TEST_GUARD] = true
2836
nativePrewarmCalls = 0
2937
nativeReturnValue = false
3038
nativeShouldThrow = false
@@ -36,6 +44,11 @@ beforeEach(() => {
3644
})
3745

3846
afterEach(() => {
47+
;(globalThis as any)[MODIFIERS_TEST_GUARD] = false
48+
nativePrewarmCalls = 0
49+
nativeReturnValue = false
50+
nativeShouldThrow = false
51+
nativeIsModifierPressed.mockClear()
3952
Object.defineProperty(process, 'platform', {
4053
value: originalPlatform,
4154
configurable: true,

0 commit comments

Comments
 (0)