import {
  cloneRepo,
  commitRepo,
  createAndPublishNewBranch,
  pushRepo,
  removeRepo,
} from "../gitClient";
import { existsSync, readdirSync } from "fs";
import { exec, execSync } from "child_process";

test("successfully clones repo", async () => {
  const folderPath = await cloneRepo("https://github.com/octocat/Spoon-Knife");

  expect(existsSync(folderPath)).toBe(true);
  const directoryContents = readdirSync(folderPath);
  expect(directoryContents).toContain("index.html");
  expect(directoryContents).toContain("README.md");
});

test("successfully commits to repo", async () => {
  const folderPath = await cloneRepo("https://github.com/octocat/Spoon-Knife");
  let thrownError = undefined;
  try {
    execSync(`cd ${folderPath} && touch newFile.ts`);
    await commitRepo(folderPath);
    execSync("git reset --hard"); // hard reset to delete any uncommitted files
    const directoryContents = readdirSync(folderPath);
    expect(directoryContents).toContain("newFile.ts");
  } catch (error) {
    thrownError = error;
  }
  expect(thrownError).toBeUndefined();
});

test("successfully tries to pushes to repo", async () => {
  const folderPath = await cloneRepo("https://github.com/octocat/Spoon-Knife"); // NOTE: user needs permission to push to repo in order for this to work
  let thrownError = undefined;
  try {
    execSync(`cd ${folderPath} && touch newerFile.ts`);
    await createAndPublishNewBranch(folderPath, "prefix");
    await commitRepo(folderPath);
    await pushRepo(folderPath);
    const directoryContents = readdirSync(folderPath);
    expect(directoryContents).toContain("newerFile.ts");
  } catch (error) {
    thrownError = error;
  }

  // Should try to push to a repo (will get permission denied though)
  expect(thrownError).toContain(
    " Permission to octocat/Spoon-Knife.git denied to"
  );
});

test("throws error if can't clone repo", async () => {
  let thrownError = undefined;
  try {
    await cloneRepo("kdskdfj");
  } catch (error) {
    thrownError = error;
  }

  expect(thrownError).not.toBeUndefined();
});
