github.com/zaquestion/lab@v0.25.1/cmd/fork_test.go (about)

     1  package cmd
     2  
     3  import (
     4  	"os"
     5  	"os/exec"
     6  	"path"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/pkg/errors"
    11  	"github.com/stretchr/testify/require"
    12  	lab "github.com/zaquestion/lab/internal/gitlab"
    13  )
    14  
    15  func cleanupFork(t *testing.T, project string) {
    16  	// Failing to find the project will fail the test and is a legit
    17  	// failure case since its the only thing asserting the project exists
    18  	// (was forked)
    19  	p, err := lab.FindProject(project)
    20  	if err != nil {
    21  		t.Fatal(errors.Wrap(err, "failed to find project "+project+" for cleanup"))
    22  	}
    23  	err = lab.ProjectDelete(p.ID)
    24  	if err != nil {
    25  		t.Fatal(errors.Wrap(err, "failed to delete project "+project+" during cleanup"))
    26  	}
    27  }
    28  
    29  func Test_fork(t *testing.T) {
    30  	tests := []struct {
    31  		desc      string
    32  		args      []string
    33  		name      string
    34  		path      string
    35  		namespace string
    36  	}{
    37  		{
    38  			desc:      "do_fork",
    39  			args:      []string{},
    40  			name:      "fork_test",
    41  			path:      "",
    42  			namespace: "",
    43  		},
    44  		{
    45  			desc:      "do_fork_name",
    46  			args:      []string{"-n", "fork_test_name"},
    47  			name:      "fork_test_name",
    48  			path:      "",
    49  			namespace: "",
    50  		},
    51  		{
    52  			desc:      "do_fork_path",
    53  			args:      []string{"-p", "fork_test_path"},
    54  			name:      "fork_test",
    55  			path:      "fork_test_path",
    56  			namespace: "",
    57  		},
    58  		{
    59  			desc:      "do_fork_name_path",
    60  			args:      []string{"-n", "fork_test_name_1", "-p", "fork_test_path_1"},
    61  			name:      "fork_test_name_1",
    62  			path:      "fork_test_path_1",
    63  			namespace: "",
    64  		},
    65  		{
    66  			desc:      "do_fork_namespace",
    67  			args:      []string{"-g", "lab-testing-test-group"},
    68  			name:      "fork_test",
    69  			path:      "",
    70  			namespace: "lab-testing-test-group",
    71  		},
    72  		{
    73  			desc:      "do_fork_namespace_name",
    74  			args:      []string{"-g", "lab-testing-test-group", "-n", "fork_test_name"},
    75  			name:      "fork_test_name",
    76  			path:      "",
    77  			namespace: "lab-testing-test-group",
    78  		},
    79  		{
    80  			desc:      "do_fork_namespace_path",
    81  			args:      []string{"-g", "lab-testing-test-group", "-p", "fork_test_path"},
    82  			name:      "fork_test",
    83  			path:      "fork_test_path",
    84  			namespace: "lab-testing-test-group",
    85  		},
    86  		{
    87  			desc:      "do_fork_namespace_name_path",
    88  			args:      []string{"-g", "lab-testing-test-group", "-n", "fork_test_name_1", "-p", "fork_test_path_1"},
    89  			name:      "fork_test_name_1",
    90  			path:      "fork_test_path_1",
    91  			namespace: "lab-testing-test-group",
    92  		},
    93  	}
    94  
    95  	t.Parallel()
    96  
    97  	for _, test := range tests {
    98  		test := test
    99  		t.Run(test.desc, func(t *testing.T) {
   100  			// remove the .git/config so no remotes exist
   101  			repo := copyTestRepo(t)
   102  			os.Remove(path.Join(repo, ".git/config"))
   103  
   104  			cmd := exec.Command("git", "remote", "add", "origin", "git@gitlab.com:zaquestion/fork_test")
   105  			cmd.Dir = repo
   106  			err := cmd.Run()
   107  			if err != nil {
   108  				t.Fatal(err)
   109  			}
   110  
   111  			namespace := "lab-testing"
   112  			if test.namespace != "" {
   113  				namespace = test.namespace
   114  			}
   115  			name := test.name
   116  			if test.path != "" {
   117  				name = test.path
   118  			}
   119  			project := namespace + "/" + name
   120  
   121  			args := []string{"fork"}
   122  			if len(test.args) > 0 {
   123  				args = append(args, test.args...)
   124  			}
   125  			cmd = exec.Command(labBinaryPath, args...)
   126  			cmd.Dir = repo
   127  			b, err := cmd.CombinedOutput()
   128  			out := string(b)
   129  			if err != nil {
   130  				t.Log(out)
   131  				cleanupFork(t, project)
   132  				t.Fatal(err)
   133  			}
   134  
   135  			require.Contains(t, out, "From gitlab.com:"+project)
   136  			require.Contains(t, out, "new remote: "+namespace)
   137  
   138  			cmd = exec.Command("git", "remote", "-v")
   139  			cmd.Dir = repo
   140  
   141  			b, err = cmd.CombinedOutput()
   142  			if err != nil {
   143  				t.Fatal(err)
   144  			}
   145  			require.Contains(t, string(b), namespace)
   146  			time.Sleep(2 * time.Second)
   147  			cleanupFork(t, project)
   148  		})
   149  	}
   150  }
   151  
   152  func Test_forkWait(t *testing.T) {
   153  	repo := copyTestRepo(t)
   154  	os.Remove(path.Join(repo, ".git/config"))
   155  
   156  	cmd := exec.Command("git", "remote", "add", "origin", "git@gitlab.com:zaquestion/fork_test")
   157  	cmd.Dir = repo
   158  	err := cmd.Run()
   159  	if err != nil {
   160  		t.Fatal(err)
   161  	}
   162  
   163  	// The default behavior is to "wait" for the fork and it's already being
   164  	// tested in the Test_fork() test. Here we only test the --no-wait
   165  	// option, which we can't effectively test because we don't have a big
   166  	// enough repo.
   167  	t.Run("fork_nowait", func(t *testing.T) {
   168  		cmd = exec.Command(labBinaryPath, []string{"fork", "--no-wait"}...)
   169  		cmd.Dir = repo
   170  		b, err := cmd.CombinedOutput()
   171  		out := string(b)
   172  		if err != nil {
   173  			t.Log(out)
   174  			t.Fatal(err)
   175  		}
   176  		require.Contains(t, out, "From gitlab.com:lab-testing/fork_test")
   177  		require.Contains(t, out, "new remote: lab-testing")
   178  		cleanupFork(t, "fork_test")
   179  	})
   180  }
   181  
   182  func Test_determineForkRemote(t *testing.T) {
   183  	tests := []struct {
   184  		desc     string
   185  		custom   string
   186  		project  string
   187  		expected string
   188  	}{
   189  		{"project is forked from repo", "", "zaquestion", "lab-testing"},
   190  		{"project is user", "", "lab-testing", "upstream"},
   191  		{"project is user", "custom-test", "lab-testing", "custom-test"},
   192  	}
   193  
   194  	for _, test := range tests {
   195  		test := test
   196  		remoteName = test.custom
   197  		t.Run(test.desc, func(t *testing.T) {
   198  			require.Equal(t, test.expected, determineForkRemote(test.project))
   199  		})
   200  	}
   201  }