import axios from 'axios';
import { execSync } from 'child_process';

// Mock axios and child_process
jest.mock('axios');
jest.mock('child_process');

const mockedAxios = axios as jest.Mocked<typeof axios>;
const mockedExecSync = execSync as jest.Mock;

describe('GitHub Integration', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe('Pull Request Creation', () => {
    it('should create a pull request successfully', async () => {
      // Mock GitHub API response
      mockedAxios.post.mockResolvedValueOnce({
        data: {
          html_url: 'https://github.com/test/repo/pull/123',
          number: 123
        }
      });

      // Mock git commands
      mockedExecSync.mockReturnValue('');

      const result = await createPullRequest({
        title: 'Test PR',
        body: 'Test Description',
        branch: 'feature/test'
      });

      expect(result).toBe('https://github.com/test/repo/pull/123');
      expect(mockedAxios.post).toHaveBeenCalledWith(
        expect.stringContaining('/repos/test/repo/pulls'),
        expect.objectContaining({
          title: 'Test PR',
          body: 'Test Description',
          head: 'feature/test',
          base: 'main'
        })
      );
    });

    it('should handle PR creation errors', async () => {
      mockedAxios.post.mockRejectedValueOnce(new Error('GitHub API Error'));

      await expect(
        createPullRequest({
          title: 'Test PR',
          body: 'Test Description',
          branch: 'feature/test'
        })
      ).rejects.toThrow('GitHub API Error');
    });

    it('should handle git command failures', async () => {
      mockedExecSync.mockImplementation(() => {
        throw new Error('Git command failed');
      });

      await expect(
        createPullRequest({
          title: 'Test PR',
          body: 'Test Description',
          branch: 'feature/test'
        })
      ).rejects.toThrow('Git command failed');
    });
  });

  describe('Branch Management', () => {
    it('should create and switch to new branch', async () => {
      mockedExecSync.mockReturnValue('');

      await createBranch('feature/test');

      expect(mockedExecSync).toHaveBeenCalledWith('git checkout -b feature/test');
    });

    it('should handle branch creation errors', async () => {
      mockedExecSync.mockImplementation(() => {
        throw new Error('Branch creation failed');
      });

      await expect(createBranch('feature/test')).rejects.toThrow('Branch creation failed');
    });
  });

  describe('Documentation Updates', () => {
    it('should commit documentation changes', async () => {
      mockedExecSync.mockReturnValue('');

      await commitDocumentation('docs/auto-generated.md');

      expect(mockedExecSync).toHaveBeenCalledWith('git add docs/auto-generated.md');
      expect(mockedExecSync).toHaveBeenCalledWith(
        expect.stringContaining('git commit -m "docs: Update documentation"')
      );
    });

    it('should handle documentation commit errors', async () => {
      mockedExecSync.mockImplementation(() => {
        throw new Error('Commit failed');
      });

      await expect(commitDocumentation('docs/auto-generated.md')).rejects.toThrow('Commit failed');
    });
  });
}); 