2026-02-23 20:34:12 +01:00
|
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
|
|
|
import { renderHook, act } from '@testing-library/react'
|
|
|
|
|
import { useCommitFlow } from './useCommitFlow'
|
|
|
|
|
|
|
|
|
|
describe('useCommitFlow', () => {
|
|
|
|
|
let savePending: vi.Mock
|
|
|
|
|
let loadModifiedFiles: vi.Mock
|
|
|
|
|
let commitAndPush: vi.Mock
|
|
|
|
|
let setToastMessage: vi.Mock
|
2026-03-19 09:51:06 +01:00
|
|
|
let onPushRejected: vi.Mock
|
2026-02-23 20:34:12 +01:00
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
|
savePending = vi.fn().mockResolvedValue(undefined)
|
|
|
|
|
loadModifiedFiles = vi.fn().mockResolvedValue(undefined)
|
2026-03-19 09:51:06 +01:00
|
|
|
commitAndPush = vi.fn().mockResolvedValue({ status: 'ok', message: 'Pushed to remote' })
|
2026-02-23 20:34:12 +01:00
|
|
|
setToastMessage = vi.fn()
|
2026-03-19 09:51:06 +01:00
|
|
|
onPushRejected = vi.fn()
|
2026-02-23 20:34:12 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function renderCommitFlow() {
|
2026-03-19 09:51:06 +01:00
|
|
|
return renderHook(() => useCommitFlow({ savePending, loadModifiedFiles, commitAndPush, setToastMessage, onPushRejected }))
|
2026-02-23 20:34:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it('openCommitDialog saves pending, refreshes files, then opens dialog', async () => {
|
|
|
|
|
const { result } = renderCommitFlow()
|
|
|
|
|
expect(result.current.showCommitDialog).toBe(false)
|
|
|
|
|
|
|
|
|
|
await act(async () => {
|
|
|
|
|
await result.current.openCommitDialog()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
expect(savePending).toHaveBeenCalledTimes(1)
|
|
|
|
|
expect(loadModifiedFiles).toHaveBeenCalledTimes(1)
|
|
|
|
|
expect(result.current.showCommitDialog).toBe(true)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('handleCommitPush saves pending, commits, shows toast, and refreshes files', async () => {
|
|
|
|
|
const { result } = renderCommitFlow()
|
|
|
|
|
|
|
|
|
|
await act(async () => {
|
|
|
|
|
await result.current.handleCommitPush('test message')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
expect(savePending).toHaveBeenCalled()
|
|
|
|
|
expect(commitAndPush).toHaveBeenCalledWith('test message')
|
|
|
|
|
expect(setToastMessage).toHaveBeenCalledWith('Committed and pushed')
|
|
|
|
|
expect(loadModifiedFiles).toHaveBeenCalled()
|
|
|
|
|
expect(result.current.showCommitDialog).toBe(false)
|
|
|
|
|
})
|
|
|
|
|
|
2026-03-19 09:51:06 +01:00
|
|
|
it('handleCommitPush calls onPushRejected when push is rejected', async () => {
|
|
|
|
|
commitAndPush.mockResolvedValueOnce({ status: 'rejected', message: 'Push rejected' })
|
|
|
|
|
const { result } = renderCommitFlow()
|
|
|
|
|
|
|
|
|
|
await act(async () => {
|
|
|
|
|
await result.current.handleCommitPush('test message')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
expect(onPushRejected).toHaveBeenCalledTimes(1)
|
|
|
|
|
expect(setToastMessage).toHaveBeenCalledWith(expect.stringContaining('push rejected'))
|
|
|
|
|
})
|
|
|
|
|
|
2026-02-23 20:34:12 +01:00
|
|
|
it('handleCommitPush shows error toast on failure', async () => {
|
|
|
|
|
commitAndPush.mockRejectedValueOnce(new Error('push failed'))
|
|
|
|
|
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
|
|
|
const { result } = renderCommitFlow()
|
|
|
|
|
|
|
|
|
|
await act(async () => {
|
|
|
|
|
await result.current.handleCommitPush('test')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
expect(setToastMessage).toHaveBeenCalledWith(expect.stringContaining('Commit failed'))
|
|
|
|
|
consoleSpy.mockRestore()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('closeCommitDialog closes the dialog', async () => {
|
|
|
|
|
const { result } = renderCommitFlow()
|
|
|
|
|
|
|
|
|
|
await act(async () => {
|
|
|
|
|
await result.current.openCommitDialog()
|
|
|
|
|
})
|
|
|
|
|
expect(result.current.showCommitDialog).toBe(true)
|
|
|
|
|
|
|
|
|
|
act(() => {
|
|
|
|
|
result.current.closeCommitDialog()
|
|
|
|
|
})
|
|
|
|
|
expect(result.current.showCommitDialog).toBe(false)
|
|
|
|
|
})
|
|
|
|
|
})
|