99import { afterEach , beforeEach , describe , expect , spyOn , test } from "bun:test" ;
1010import path from "node:path" ;
1111import { initCommand } from "../../src/commands/init.js" ;
12- // biome-ignore lint/performance/noNamespaceImport: spyOn requires object reference
13- import * as apiClient from "../../src/lib/api-client.js" ;
1412import { ContextError } from "../../src/lib/errors.js" ;
1513// biome-ignore lint/performance/noNamespaceImport: spyOn requires object reference
14+ import * as prefetchNs from "../../src/lib/init/prefetch.js" ;
15+ import { resetPrefetch } from "../../src/lib/init/prefetch.js" ;
16+ // biome-ignore lint/performance/noNamespaceImport: spyOn requires object reference
1617import * as wizardRunner from "../../src/lib/init/wizard-runner.js" ;
1718// biome-ignore lint/performance/noNamespaceImport: spyOn requires object reference
1819import * as resolveTarget from "../../src/lib/resolve-target.js" ;
@@ -21,8 +22,7 @@ import * as resolveTarget from "../../src/lib/resolve-target.js";
2122let capturedArgs : Record < string , unknown > | undefined ;
2223let runWizardSpy : ReturnType < typeof spyOn > ;
2324let resolveProjectSpy : ReturnType < typeof spyOn > ;
24- let resolveOrgSpy : ReturnType < typeof spyOn > ;
25- let listOrgsSpy : ReturnType < typeof spyOn > ;
25+ let warmSpy : ReturnType < typeof spyOn > ;
2626
2727const func = ( await initCommand . loader ( ) ) as unknown as (
2828 this : {
@@ -49,6 +49,7 @@ const DEFAULT_FLAGS = { yes: true, "dry-run": false } as const;
4949
5050beforeEach ( ( ) => {
5151 capturedArgs = undefined ;
52+ resetPrefetch ( ) ;
5253 runWizardSpy = spyOn ( wizardRunner , "runWizard" ) . mockImplementation (
5354 ( args : Record < string , unknown > ) => {
5455 capturedArgs = args ;
@@ -63,21 +64,19 @@ beforeEach(() => {
6364 org : "resolved-org" ,
6465 project : slug ,
6566 } ) ) ;
66- // Mock resolveOrg and listOrganizations to prevent real DSN scans / API calls
67- // from the background detection promises fired in init's func()
68- resolveOrgSpy = spyOn ( resolveTarget , "resolveOrg" ) . mockImplementation (
69- async ( ) => null
70- ) ;
71- listOrgsSpy = spyOn ( apiClient , "listOrganizations" ) . mockImplementation (
72- async ( ) => [ ]
67+ // Spy on warmOrgDetection to verify it's called/skipped appropriately.
68+ // The mock prevents real DSN scans and API calls from the background.
69+ warmSpy = spyOn ( prefetchNs , "warmOrgDetection" ) . mockImplementation (
70+ // biome-ignore lint/suspicious/noEmptyBlockStatements: intentional no-op mock
71+ ( ) => { }
7372 ) ;
7473} ) ;
7574
7675afterEach ( ( ) => {
7776 runWizardSpy . mockRestore ( ) ;
7877 resolveProjectSpy . mockRestore ( ) ;
79- resolveOrgSpy . mockRestore ( ) ;
80- listOrgsSpy . mockRestore ( ) ;
78+ warmSpy . mockRestore ( ) ;
79+ resetPrefetch ( ) ;
8180} ) ;
8281
8382describe ( "init command func" , ( ) => {
@@ -342,55 +341,44 @@ describe("init command func", () => {
342341 // ── Background org detection ──────────────────────────────────────────
343342
344343 describe ( "background org detection" , ( ) => {
345- test ( "passes bgOrgDetection when org is not explicit" , async ( ) => {
344+ test ( "warms prefetch when org is not explicit" , async ( ) => {
346345 const ctx = makeContext ( ) ;
347346 await func . call ( ctx , DEFAULT_FLAGS ) ;
348- const bg = capturedArgs ?. bgOrgDetection as
349- | { orgPromise : Promise < unknown > ; orgListPromise : Promise < unknown > }
350- | undefined ;
351- expect ( bg ) . toBeDefined ( ) ;
352- expect ( bg ?. orgPromise ) . toBeInstanceOf ( Promise ) ;
353- expect ( bg ?. orgListPromise ) . toBeInstanceOf ( Promise ) ;
347+ expect ( warmSpy ) . toHaveBeenCalledTimes ( 1 ) ;
348+ expect ( warmSpy ) . toHaveBeenCalledWith ( "/projects/app" ) ;
354349 } ) ;
355350
356- test ( "fires resolveOrg for background detection" , async ( ) => {
357- const ctx = makeContext ( ) ;
358- await func . call ( ctx , DEFAULT_FLAGS ) ;
359- expect ( resolveOrgSpy ) . toHaveBeenCalled ( ) ;
360- } ) ;
361-
362- test ( "fires listOrganizations for background detection" , async ( ) => {
363- const ctx = makeContext ( ) ;
364- await func . call ( ctx , DEFAULT_FLAGS ) ;
365- expect ( listOrgsSpy ) . toHaveBeenCalled ( ) ;
366- } ) ;
367-
368- test ( "omits bgOrgDetection when org is explicit" , async ( ) => {
351+ test ( "skips prefetch when org is explicit" , async ( ) => {
369352 const ctx = makeContext ( ) ;
370353 await func . call ( ctx , DEFAULT_FLAGS , "acme/my-app" ) ;
371- expect ( capturedArgs ?. bgOrgDetection ) . toBeUndefined ( ) ;
354+ expect ( warmSpy ) . not . toHaveBeenCalled ( ) ;
372355 } ) ;
373356
374- test ( "omits bgOrgDetection when org-only is explicit" , async ( ) => {
357+ test ( "skips prefetch when org-only is explicit" , async ( ) => {
375358 const ctx = makeContext ( ) ;
376359 await func . call ( ctx , DEFAULT_FLAGS , "acme/" ) ;
377- expect ( capturedArgs ?. bgOrgDetection ) . toBeUndefined ( ) ;
360+ expect ( warmSpy ) . not . toHaveBeenCalled ( ) ;
378361 } ) ;
379362
380- test ( "passes bgOrgDetection for bare slug (project-search resolves org)" , async ( ) => {
381- // Even though resolveProjectBySlug finds an org, the bgDetection
382- // is skipped because explicitOrg is set from the resolved result
363+ test ( "skips prefetch for bare slug (project-search resolves org)" , async ( ) => {
383364 const ctx = makeContext ( ) ;
384365 await func . call ( ctx , DEFAULT_FLAGS , "my-app" ) ;
385- // resolveProjectBySlug returns { org: "resolved-org", project: "my-app" }
386- // so explicitOrg is set → bgOrgDetection should be undefined
387- expect ( capturedArgs ?. bgOrgDetection ) . toBeUndefined ( ) ;
366+ // resolveProjectBySlug returns { org: "resolved-org" } → org is known
367+ expect ( warmSpy ) . not . toHaveBeenCalled ( ) ;
388368 } ) ;
389369
390- test ( "passes bgOrgDetection for path-only arg" , async ( ) => {
370+ test ( "warms prefetch for path-only arg" , async ( ) => {
391371 const ctx = makeContext ( ) ;
392372 await func . call ( ctx , DEFAULT_FLAGS , "./subdir" ) ;
393- expect ( capturedArgs ?. bgOrgDetection ) . toBeDefined ( ) ;
373+ expect ( warmSpy ) . toHaveBeenCalledTimes ( 1 ) ;
374+ } ) ;
375+
376+ test ( "warms prefetch with resolved directory path" , async ( ) => {
377+ const ctx = makeContext ( "/projects/app" ) ;
378+ await func . call ( ctx , DEFAULT_FLAGS , "./subdir" ) ;
379+ expect ( warmSpy ) . toHaveBeenCalledWith (
380+ path . resolve ( "/projects/app" , "./subdir" )
381+ ) ;
394382 } ) ;
395383 } ) ;
396384} ) ;
0 commit comments