11// src/commands/push.test.ts
22import { describe , it , expect , vi , beforeEach } from 'vitest' ;
33import { getGitHubToken } from '../auth.js' ;
4- import { pushSkills , getRepoRemoteUrl , ensureGitRepo , ensureRemote , createGitHubRepo } from '../git-ops.js' ;
4+ import { pushSkills , getRepoRemoteUrl , ensureGitRepo , ensureRemote , createGitHubRepo , isGhInstalled } from '../git-ops.js' ;
55
66const mockPrompts = vi . hoisted ( ( ) => ( {
77 intro : vi . fn ( ) ,
@@ -28,6 +28,7 @@ vi.mock('../git-ops.js', () => ({
2828 ensureGitRepo : vi . fn ( ) ,
2929 ensureRemote : vi . fn ( ) ,
3030 createGitHubRepo : vi . fn ( ) ,
31+ isGhInstalled : vi . fn ( ) ,
3132 buildRemoteUrl : vi . fn ( ( repo : string ) => `https://github.com/${ repo } .git` ) ,
3233} ) ) ;
3334
@@ -66,6 +67,7 @@ describe('push command logic', () => {
6667 remoteUrl : 'https://github.com/owner/my-skills.git' ,
6768 added : true ,
6869 } ) ;
70+ vi . mocked ( isGhInstalled ) . mockReturnValue ( true ) ;
6971 // User declines creating a remote repo
7072 mockPrompts . confirm . mockResolvedValue ( false ) ;
7173 vi . mocked ( pushSkills ) . mockResolvedValue ( { committed : true , pushed : true } ) ;
@@ -88,6 +90,7 @@ describe('push command logic', () => {
8890 remoteUrl : 'https://github.com/owner/my-skills.git' ,
8991 added : true ,
9092 } ) ;
93+ vi . mocked ( isGhInstalled ) . mockReturnValue ( true ) ;
9194 // User confirms creating repo
9295 mockPrompts . confirm . mockResolvedValue ( true ) ;
9396 vi . mocked ( createGitHubRepo ) . mockReturnValue ( undefined ) ;
@@ -150,6 +153,7 @@ describe('push command logic', () => {
150153 remoteUrl : 'https://github.com/owner/my-skills.git' ,
151154 added : true ,
152155 } ) ;
156+ vi . mocked ( isGhInstalled ) . mockReturnValue ( true ) ;
153157 // Simulate user pressing Ctrl+C on confirm prompt
154158 mockPrompts . confirm . mockResolvedValue ( Symbol ( 'cancel' ) ) ;
155159 mockPrompts . isCancel . mockImplementation ( ( val ) => typeof val === 'symbol' ) ;
@@ -173,4 +177,44 @@ describe('push command logic', () => {
173177
174178 expect ( spinnerStop ) . toHaveBeenCalledWith ( 'Unpushed commits pushed successfully!' ) ;
175179 } ) ;
180+
181+ it ( 'shows note instead of confirm when gh CLI is not installed' , async ( ) => {
182+ vi . mocked ( getGitHubToken ) . mockReturnValue ( 'ghp_test_token' ) ;
183+ vi . mocked ( ensureGitRepo ) . mockResolvedValue ( { initialized : true } ) ;
184+ vi . mocked ( getRepoRemoteUrl ) . mockResolvedValue ( null ) ;
185+ mockPrompts . text . mockResolvedValue ( 'owner/my-skills' ) ;
186+ vi . mocked ( ensureRemote ) . mockResolvedValue ( {
187+ remoteUrl : 'https://github.com/owner/my-skills.git' ,
188+ added : true ,
189+ } ) ;
190+ vi . mocked ( isGhInstalled ) . mockReturnValue ( false ) ;
191+ vi . mocked ( pushSkills ) . mockResolvedValue ( { committed : true , pushed : true } ) ;
192+
193+ const { pushCommand } = await import ( './push.js' ) ;
194+ await pushCommand ( { } ) ;
195+
196+ // Should show a note, not a confirm prompt
197+ expect ( mockPrompts . confirm ) . not . toHaveBeenCalled ( ) ;
198+ expect ( createGitHubRepo ) . not . toHaveBeenCalled ( ) ;
199+ expect ( mockPrompts . note ) . toHaveBeenCalledWith (
200+ expect . stringContaining ( 'gh CLI not found' ) ,
201+ expect . stringContaining ( 'GitHub CLI not installed' ) ,
202+ ) ;
203+ // Should still proceed with push
204+ expect ( pushSkills ) . toHaveBeenCalledOnce ( ) ;
205+ } ) ;
206+
207+ it ( 'skips gh check entirely when remote already exists' , async ( ) => {
208+ vi . mocked ( getGitHubToken ) . mockReturnValue ( 'ghp_test_token' ) ;
209+ vi . mocked ( ensureGitRepo ) . mockResolvedValue ( { initialized : false } ) ;
210+ vi . mocked ( getRepoRemoteUrl ) . mockResolvedValue ( 'https://github.com/user/repo.git' ) ;
211+ vi . mocked ( pushSkills ) . mockResolvedValue ( { committed : true , pushed : true } ) ;
212+
213+ const { pushCommand } = await import ( './push.js' ) ;
214+ await pushCommand ( { } ) ;
215+
216+ expect ( isGhInstalled ) . not . toHaveBeenCalled ( ) ;
217+ expect ( mockPrompts . confirm ) . not . toHaveBeenCalled ( ) ;
218+ expect ( createGitHubRepo ) . not . toHaveBeenCalled ( ) ;
219+ } ) ;
176220} ) ;
0 commit comments