diff --git a/test/e2e/gitPush.test.ts b/test/e2e/gitPush.test.ts new file mode 100644 index 00000000..408471e8 --- /dev/null +++ b/test/e2e/gitPush.test.ts @@ -0,0 +1,194 @@ +import path from 'path'; +import 'cli-testing-library/extend-expect'; +import { exec } from 'child_process'; +import { prepareTempDir } from './utils'; +import { promisify } from 'util'; +import { render } from 'cli-testing-library'; +import { resolve } from 'path'; +import { rm } from 'fs'; +const fsExec = promisify(exec); +const fsRemove = promisify(rm); + +/** + * git remote -v + * + * [no remotes] + */ +const prepareNoRemoteGitRepository = async (): Promise<{ + gitDir: string; + cleanup: () => Promise; +}> => { + const tempDir = await prepareTempDir(); + await fsExec('git init test', { cwd: tempDir }); + const gitDir = path.resolve(tempDir, 'test'); + + const cleanup = async () => { + return fsRemove(tempDir, { recursive: true }); + }; + return { + gitDir, + cleanup + }; +}; + +/** + * git remote -v + * + * origin /tmp/remote.git (fetch) + * origin /tmp/remote.git (push) + */ +const prepareOneRemoteGitRepository = async (): Promise<{ + gitDir: string; + cleanup: () => Promise; +}> => { + const tempDir = await prepareTempDir(); + await fsExec('git init --bare remote.git', { cwd: tempDir }); + await fsExec('git clone remote.git test', { cwd: tempDir }); + const gitDir = path.resolve(tempDir, 'test'); + + const cleanup = async () => { + return fsRemove(tempDir, { recursive: true }); + }; + return { + gitDir, + cleanup + }; +}; + +/** + * git remote -v + * + * origin /tmp/remote.git (fetch) + * origin /tmp/remote.git (push) + * other ../remote2.git (fetch) + * other ../remote2.git (push) + */ +const prepareTwoRemotesGitRepository = async (): Promise<{ + gitDir: string; + cleanup: () => Promise; +}> => { + const tempDir = await prepareTempDir(); + await fsExec('git init --bare remote.git', { cwd: tempDir }); + await fsExec('git init --bare other.git', { cwd: tempDir }); + await fsExec('git clone remote.git test', { cwd: tempDir }); + const gitDir = path.resolve(tempDir, 'test'); + await fsExec('git remote add other ../other.git', { cwd: gitDir }); + + const cleanup = async () => { + return fsRemove(tempDir, { recursive: true }); + }; + return { + gitDir, + cleanup + }; +}; + +it('cli flow to do nothing when no remote', async () => { + const { gitDir, cleanup } = await prepareNoRemoteGitRepository(); + + await render('echo', [`'console.log("Hello World");' > index.ts`], { + cwd: gitDir + }); + await render('git', ['add index.ts'], { cwd: gitDir }); + + const { queryByText, findByText, userEvent } = await render( + `OCO_AI_PROVIDER='test' node`, + [resolve('./out/cli.cjs')], + { cwd: gitDir } + ); + expect(await findByText('Confirm the commit message?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + + expect( + await queryByText('Choose a remote to push to') + ).not.toBeInTheConsole(); + expect( + await queryByText('Do you want to run `git push`?') + ).not.toBeInTheConsole(); + expect( + await queryByText('Successfully pushed all commits to origin') + ).not.toBeInTheConsole(); + + await cleanup(); +}); + +it('cli flow to do nothing when GIT_PUSH set to false', async () => { + const { gitDir, cleanup } = await prepareOneRemoteGitRepository(); + + await render('echo', [`'console.log("Hello World");' > index.ts`], { + cwd: gitDir + }); + await render('git', ['add index.ts'], { cwd: gitDir }); + + const { queryByText, findByText, userEvent } = await render( + `OCO_AI_PROVIDER='test' OCO_GITPUSH='false' node`, + [resolve('./out/cli.cjs')], + { cwd: gitDir } + ); + expect(await findByText('Confirm the commit message?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + + expect( + await queryByText('Choose a remote to push to') + ).not.toBeInTheConsole(); + expect( + await queryByText('Do you want to run `git push`?') + ).not.toBeInTheConsole(); + expect( + await queryByText('Successfully pushed all commits to origin') + ).not.toBeInTheConsole(); + + await cleanup(); +}); + +it('cli flow to push git branch when one remote is set', async () => { + const { gitDir, cleanup } = await prepareOneRemoteGitRepository(); + + await render('echo', [`'console.log("Hello World");' > index.ts`], { + cwd: gitDir + }); + await render('git', ['add index.ts'], { cwd: gitDir }); + + const { findByText, userEvent } = await render( + `OCO_AI_PROVIDER='test' node`, + [resolve('./out/cli.cjs')], + { cwd: gitDir } + ); + expect(await findByText('Confirm the commit message?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + + expect(await findByText('Choose a remote to push to')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + + expect( + await findByText('Successfully pushed all commits to origin') + ).toBeInTheConsole(); + + await cleanup(); +}); + +it('cli flow to push git branch when two remotes are set', async () => { + const { gitDir, cleanup } = await prepareTwoRemotesGitRepository(); + + await render('echo', [`'console.log("Hello World");' > index.ts`], { + cwd: gitDir + }); + await render('git', ['add index.ts'], { cwd: gitDir }); + + const { findByText, userEvent } = await render( + `OCO_AI_PROVIDER='test' node`, + [resolve('./out/cli.cjs')], + { cwd: gitDir } + ); + expect(await findByText('Confirm the commit message?')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + + expect(await findByText('Choose a remote to push to')).toBeInTheConsole(); + userEvent.keyboard('[Enter]'); + + expect( + await findByText('Successfully pushed all commits to origin') + ).toBeInTheConsole(); + + await cleanup(); +}); diff --git a/test/e2e/utils.ts b/test/e2e/utils.ts index 73f909c5..6ae56633 100644 --- a/test/e2e/utils.ts +++ b/test/e2e/utils.ts @@ -15,7 +15,7 @@ export const prepareEnvironment = async (): Promise<{ gitDir: string; cleanup: () => Promise; }> => { - const tempDir = await fsMakeTempDir(path.join(tmpdir(), 'opencommit-test-')); + const tempDir = await prepareTempDir(); // Create a remote git repository int the temp directory. This is necessary to execute the `git push` command await fsExec('git init --bare remote.git', { cwd: tempDir }); await fsExec('git clone remote.git test', { cwd: tempDir }); @@ -30,4 +30,8 @@ export const prepareEnvironment = async (): Promise<{ } } +export const prepareTempDir = async(): Promise => { + return await fsMakeTempDir(path.join(tmpdir(), 'opencommit-test-')); +} + export const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));