@@ -106,6 +106,83 @@ describe('GitHub Adapter', () => {
106106 expect ( connectToAdapterOnUiMock ) . toHaveBeenCalled ( ) ;
107107 expect ( githubAdapterInstance . config . userConnection ) . toEqual ( undefined ) ;
108108 } ) ;
109+
110+ it ( 'should prompt the user to select a connection when multiple GitHub connections exist' , async ( ) => {
111+ const multipleUserConnections = [
112+ { __typename : 'UserConnection' , userUid : 'testuser1' , provider : 'GitHub' , namespace : 'personal-account' } ,
113+ { __typename : 'UserConnection' , userUid : 'testuser1' , provider : 'GitHub' , namespace : 'org-account' } ,
114+ ] ;
115+ const userConnectionResponse = { data : { userConnections : multipleUserConnections } } ;
116+ const apolloClient = {
117+ query : jest . fn ( ) . mockResolvedValueOnce ( userConnectionResponse ) ,
118+ } as any ;
119+ const githubAdapterInstance = new GitHub ( {
120+ config : { projectBasePath : '/home/project1' , provider : 'GitHub' } ,
121+ apolloClient : apolloClient ,
122+ log : logMock ,
123+ } as any ) ;
124+ ( ux . inquire as jest . Mock ) . mockResolvedValueOnce ( 'org-account' ) ;
125+
126+ await githubAdapterInstance . checkGitHubConnected ( ) ;
127+
128+ expect ( ux . inquire ) . toHaveBeenCalledWith ( {
129+ type : 'search-list' ,
130+ name : 'userConnection' ,
131+ message : 'Choose a GitHub Namespace' ,
132+ choices : [ 'personal-account' , 'org-account' ] ,
133+ } ) ;
134+ expect ( githubAdapterInstance . config . userConnection ) . toEqual ( multipleUserConnections [ 1 ] ) ;
135+ } ) ;
136+
137+ it ( 'should use the --namespace flag to select a connection without prompting' , async ( ) => {
138+ const multipleUserConnections = [
139+ { __typename : 'UserConnection' , userUid : 'testuser1' , provider : 'GitHub' , namespace : 'personal-account' } ,
140+ { __typename : 'UserConnection' , userUid : 'testuser1' , provider : 'GitHub' , namespace : 'org-account' } ,
141+ ] ;
142+ const userConnectionResponse = { data : { userConnections : multipleUserConnections } } ;
143+ const apolloClient = {
144+ query : jest . fn ( ) . mockResolvedValueOnce ( userConnectionResponse ) ,
145+ } as any ;
146+ const githubAdapterInstance = new GitHub ( {
147+ config : { projectBasePath : '/home/project1' , provider : 'GitHub' , flags : { namespace : 'org-account' } } ,
148+ apolloClient : apolloClient ,
149+ log : logMock ,
150+ } as any ) ;
151+
152+ await githubAdapterInstance . checkGitHubConnected ( ) ;
153+
154+ expect ( ux . inquire ) . not . toHaveBeenCalled ( ) ;
155+ expect ( githubAdapterInstance . config . userConnection ) . toEqual ( multipleUserConnections [ 1 ] ) ;
156+ } ) ;
157+
158+ it ( 'should log an error and exit if the --namespace flag does not match any connection' , async ( ) => {
159+ const multipleUserConnections = [
160+ { __typename : 'UserConnection' , userUid : 'testuser1' , provider : 'GitHub' , namespace : 'personal-account' } ,
161+ { __typename : 'UserConnection' , userUid : 'testuser1' , provider : 'GitHub' , namespace : 'org-account' } ,
162+ ] ;
163+ const userConnectionResponse = { data : { userConnections : multipleUserConnections } } ;
164+ const apolloClient = {
165+ query : jest . fn ( ) . mockResolvedValueOnce ( userConnectionResponse ) ,
166+ } as any ;
167+ const githubAdapterInstance = new GitHub ( {
168+ config : { projectBasePath : '/home/project1' , provider : 'GitHub' , flags : { namespace : 'unknown-account' } } ,
169+ apolloClient : apolloClient ,
170+ log : logMock ,
171+ exit : exitMock ,
172+ } as any ) ;
173+
174+ let err ;
175+ try {
176+ await githubAdapterInstance . checkGitHubConnected ( ) ;
177+ } catch ( error : any ) {
178+ err = error ;
179+ }
180+
181+ expect ( ux . inquire ) . not . toHaveBeenCalled ( ) ;
182+ expect ( logMock ) . toHaveBeenCalledWith ( 'GitHub connection namespace not found!' , 'error' ) ;
183+ expect ( exitMock ) . toHaveBeenCalledWith ( 1 ) ;
184+ expect ( err ) . toEqual ( new Error ( '1' ) ) ;
185+ } ) ;
109186 } ) ;
110187
111188 describe ( 'checkGitRemoteAvailableAndValid' , ( ) => {
@@ -212,6 +289,31 @@ describe('GitHub Adapter', () => {
212289 expect ( result ) . toBe ( true ) ;
213290 } ) ;
214291
292+ it ( 'should scope the repositories query to the selected GitHub connection namespace' , async ( ) => {
293+ ( existsSync as jest . Mock ) . mockReturnValueOnce ( true ) ;
294+ ( getRemoteUrls as jest . Mock ) . mockResolvedValueOnce ( {
295+ origin : 'https://github.com/test-user/eleventy-sample.git' ,
296+ } ) ;
297+ const apolloClient = {
298+ query : jest . fn ( ) . mockResolvedValueOnce ( repositoriesResponse ) ,
299+ } as any ;
300+ const githubAdapterInstance = new GitHub ( {
301+ config : {
302+ projectBasePath : '/home/project1' ,
303+ provider : 'GitHub' ,
304+ userConnection : { provider : 'GitHub' , namespace : 'org-account' } ,
305+ } ,
306+ apolloClient : apolloClient ,
307+ } as any ) ;
308+
309+ await githubAdapterInstance . checkGitRemoteAvailableAndValid ( ) ;
310+
311+ expect ( apolloClient . query ) . toHaveBeenCalledWith ( {
312+ query : repositoriesQuery ,
313+ variables : { page : 1 , first : 100 , query : { provider : 'GitHub' , namespace : 'org-account' } } ,
314+ } ) ;
315+ } ) ;
316+
215317 it ( 'should log an error and exit if git config file does not exists' , async ( ) => {
216318 ( existsSync as jest . Mock ) . mockReturnValueOnce ( false ) ;
217319 const githubAdapterInstance = new GitHub ( {
@@ -298,6 +400,37 @@ describe('GitHub Adapter', () => {
298400 expect ( err ) . toEqual ( new Error ( '1' ) ) ;
299401 } ) ;
300402
403+ it ( 'should reference the selected connection namespace when the GitHub app is uninstalled' , async ( ) => {
404+ ( existsSync as jest . Mock ) . mockReturnValueOnce ( true ) ;
405+ ( getRemoteUrls as jest . Mock ) . mockResolvedValueOnce ( {
406+ origin : 'https://github.com/test-user/eleventy-sample.git' ,
407+ } ) ;
408+ const apolloClient = {
409+ query : jest . fn ( ) . mockRejectedValue ( new Error ( 'GitHub app error' ) ) ,
410+ } as any ;
411+ jest . spyOn ( BaseClass . prototype , 'connectToAdapterOnUi' ) . mockResolvedValueOnce ( ) ;
412+ const githubAdapterInstance = new GitHub ( {
413+ config : {
414+ projectBasePath : '/home/project1' ,
415+ userConnection : { provider : 'GitHub' , namespace : 'org-account' } ,
416+ } ,
417+ apolloClient : apolloClient ,
418+ log : logMock ,
419+ exit : exitMock ,
420+ } as any ) ;
421+
422+ try {
423+ await githubAdapterInstance . checkGitRemoteAvailableAndValid ( ) ;
424+ } catch {
425+ // exitMock throws to halt the flow under test, same as sibling tests in this file
426+ }
427+
428+ expect ( logMock ) . toHaveBeenCalledWith (
429+ 'GitHub app uninstalled for the "org-account" connection. Please reconnect the app and try again' ,
430+ 'error' ,
431+ ) ;
432+ } ) ;
433+
301434 it ( 'should log an error and exit if repository is not found in the list of available repositories' , async ( ) => {
302435 ( existsSync as jest . Mock ) . mockReturnValueOnce ( true ) ;
303436 ( getRemoteUrls as jest . Mock ) . mockResolvedValueOnce ( {
@@ -464,6 +597,46 @@ describe('GitHub Adapter', () => {
464597 expect ( exitMock ) . toHaveBeenCalledWith ( 1 ) ;
465598 expect ( err ) . toEqual ( new Error ( '1' ) ) ;
466599 } ) ;
600+
601+ it ( 'should reference the selected connection namespace when the repository is beyond the checked pages' , async ( ) => {
602+ ( existsSync as jest . Mock ) . mockReturnValueOnce ( true ) ;
603+ ( getRemoteUrls as jest . Mock ) . mockResolvedValueOnce ( {
604+ origin : 'https://github.com/test-user/missing-repo.git' ,
605+ } ) ;
606+ const apolloClient = {
607+ query : jest . fn ( ) . mockImplementation ( ( { variables } ) => {
608+ const { page, first } = variables ;
609+ const edges = Array . from ( { length : first } , ( _ , i ) => ( {
610+ node : {
611+ __typename : 'GitRepository' ,
612+ id : `${ ( page - 1 ) * first + i } ` ,
613+ url : `https://github.com/test-user/repo-${ ( page - 1 ) * first + i } ` ,
614+ name : `repo-${ ( page - 1 ) * first + i } ` ,
615+ fullName : `test-user/repo-${ ( page - 1 ) * first + i } ` ,
616+ defaultBranch : 'main' ,
617+ } ,
618+ } ) ) ;
619+ return Promise . resolve ( { data : { repositories : { edges, pageData : { page } , pageInfo : { hasNextPage : true } } } } ) ;
620+ } ) ,
621+ } as any ;
622+ const githubAdapterInstance = new GitHub ( {
623+ config : {
624+ projectBasePath : '/home/project1' ,
625+ userConnection : { provider : 'GitHub' , namespace : 'org-account' } ,
626+ } ,
627+ log : logMock ,
628+ exit : exitMock ,
629+ apolloClient : apolloClient ,
630+ } as any ) ;
631+
632+ try {
633+ await githubAdapterInstance . checkGitRemoteAvailableAndValid ( ) ;
634+ } catch {
635+ // exitMock throws to halt the flow under test, same as sibling tests in this file
636+ }
637+
638+ expect ( logMock ) . toHaveBeenCalledWith ( expect . stringContaining ( 'the "org-account" connection' ) , 'error' ) ;
639+ } ) ;
467640 } ) ;
468641
469642 describe ( 'runGitHubFlow' , ( ) => {
0 commit comments