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

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os/exec"
     7  	"path/filepath"
     8  	"strconv"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/acarl005/stripansi"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func closeMR(t *testing.T, targetRepo string, cmdDir string, mrID string) {
    17  	if mrID == "" {
    18  		t.Skip("mrID is empty, create likely failed")
    19  	}
    20  	cmd := exec.Command(labBinaryPath, "mr", "close", targetRepo, mrID)
    21  	cmd.Dir = cmdDir
    22  
    23  	b, err := cmd.CombinedOutput()
    24  	if err != nil {
    25  		t.Log(string(b))
    26  		t.Fatal(err)
    27  	}
    28  	require.Contains(t, string(b), fmt.Sprintf("Merge Request !%s closed", mrID))
    29  }
    30  
    31  func cleanupMR(t *testing.T, targetRepo string, cmdDir string, MRtitle string) {
    32  	var openMRcmd *exec.Cmd
    33  
    34  	if MRtitle == "" {
    35  		openMRcmd = exec.Command(labBinaryPath, "mr", "list", targetRepo)
    36  	} else {
    37  		openMRcmd = exec.Command(labBinaryPath, "mr", "list", targetRepo, MRtitle)
    38  	}
    39  	openMRcmd.Dir = cmdDir
    40  	openMRout, err := openMRcmd.CombinedOutput()
    41  	if err != nil {
    42  		t.Log(string(openMRout))
    43  	}
    44  
    45  	// find MR number
    46  	s := strings.Split(string(openMRout), " ")
    47  	openMRstr := s[0]
    48  	// strip off "!"
    49  	openMRstr = openMRstr[1:]
    50  
    51  	openMR, err := strconv.Atoi(openMRstr)
    52  	if err != nil {
    53  		t.Log(string(openMRstr))
    54  		return
    55  	}
    56  
    57  	if openMR <= 0 {
    58  		// no open MRs
    59  		return
    60  	}
    61  
    62  	// close the existing MR
    63  	closeMR(t, targetRepo, cmdDir, string(openMRstr))
    64  }
    65  
    66  func Test_mrCmd(t *testing.T) {
    67  	repo := copyTestRepo(t)
    68  	var mrID string
    69  	t.Run("prepare", func(t *testing.T) {
    70  		cleanupMR(t, "lab-testing", repo, "")
    71  	})
    72  	t.Run("create", func(t *testing.T) {
    73  		git := exec.Command("git", "checkout", "mrtest")
    74  		git.Dir = repo
    75  		b, err := git.CombinedOutput()
    76  		if err != nil {
    77  			t.Log(string(b))
    78  			t.Fatal(err)
    79  		}
    80  
    81  		cmd := exec.Command(labBinaryPath, "mr", "create", "lab-testing", "master",
    82  			"-m", "mr title",
    83  			"-m", "mr description",
    84  			"-a", "lab-testing",
    85  		)
    86  		cmd.Dir = repo
    87  
    88  		b, _ = cmd.CombinedOutput()
    89  		out := string(b)
    90  		t.Log(out)
    91  		require.Contains(t, out, "https://gitlab.com/lab-testing/test/-/merge_requests")
    92  
    93  		i := strings.Index(out, "/diffs\n")
    94  		mrID = strings.TrimPrefix(out[:i], "https://gitlab.com/lab-testing/test/-/merge_requests/")
    95  		t.Log(mrID)
    96  	})
    97  	t.Run("show", func(t *testing.T) {
    98  		if mrID == "" {
    99  			t.Skip("mrID is empty, create likely failed")
   100  		}
   101  		cmd := exec.Command(labBinaryPath, "mr", "show", "lab-testing", mrID)
   102  		cmd.Dir = repo
   103  
   104  		b, err := cmd.CombinedOutput()
   105  		if err != nil {
   106  			t.Log(string(b))
   107  			t.Fatal(err)
   108  		}
   109  
   110  		out := string(b)
   111  		outStripped := stripansi.Strip(out) // This is required because glamour adds a lot of ansi chars
   112  		require.Contains(t, out, "Project: lab-testing/test\n")
   113  		require.Contains(t, out, "Branches: mrtest->master\n")
   114  		require.Contains(t, out, "Status: Open\n")
   115  		require.Contains(t, out, "Assignee: lab-testing\n")
   116  		require.Contains(t, out, fmt.Sprintf("!%s mr title", mrID))
   117  		require.Contains(t, out, "===================================")
   118  		require.Contains(t, outStripped, "mr description")
   119  		require.Contains(t, out, fmt.Sprintf("WebURL: https://gitlab.com/lab-testing/test/-/merge_requests/%s", mrID))
   120  	})
   121  	t.Run("close", func(t *testing.T) {
   122  		closeMR(t, "lab-testing", repo, mrID)
   123  	})
   124  }
   125  
   126  func Test_mrCmd_MR_description_and_options(t *testing.T) {
   127  	repo := copyTestRepo(t)
   128  	var (
   129  		mrID      string
   130  		commentID string
   131  	)
   132  	t.Run("prepare", func(t *testing.T) {
   133  		cleanupMR(t, "lab-testing", repo, "")
   134  	})
   135  	t.Run("create MR from file", func(t *testing.T) {
   136  		git := exec.Command("git", "checkout", "mrtest")
   137  		git.Dir = repo
   138  		b, err := git.CombinedOutput()
   139  		if err != nil {
   140  			t.Log(string(b))
   141  			t.Fatal(err)
   142  		}
   143  
   144  		err = ioutil.WriteFile(filepath.Join(repo, "hellolab.txt"), []byte("Fancy Description\n\nFancy body of text describing this merge request.\n"), 0644)
   145  		if err != nil {
   146  			t.Fatal(err)
   147  		}
   148  
   149  		cmd := exec.Command(labBinaryPath, "mr", "create", "lab-testing", "master",
   150  			"-F", "hellolab.txt",
   151  			"-a", "lab-testing",
   152  		)
   153  		cmd.Dir = repo
   154  
   155  		b, _ = cmd.CombinedOutput()
   156  		out := string(b)
   157  		t.Log(out)
   158  		require.Contains(t, out, "https://gitlab.com/lab-testing/test/-/merge_requests")
   159  
   160  		i := strings.Index(out, "/diffs\n")
   161  		mrID = strings.TrimPrefix(out[:i], "https://gitlab.com/lab-testing/test/-/merge_requests/")
   162  		t.Log(mrID)
   163  
   164  	})
   165  	t.Run("update MR description", func(t *testing.T) {
   166  		update := exec.Command(labBinaryPath, "mr", "edit", "lab-testing", mrID, "-m", "Updated Description", "-m", "Updated body of text describing this merge request.")
   167  		update.Dir = repo
   168  		b, err := update.CombinedOutput()
   169  		if err != nil {
   170  			t.Log(string(b))
   171  			t.Fatal(err)
   172  		}
   173  		cmd := exec.Command(labBinaryPath, "mr", "show", "lab-testing", mrID)
   174  		cmd.Dir = repo
   175  		b, err = cmd.CombinedOutput()
   176  		if err != nil {
   177  			t.Log(string(b))
   178  			t.Fatal(err)
   179  		}
   180  		out := string(b)
   181  		out = stripansi.Strip(out)
   182  
   183  		require.Contains(t, out, "Updated Description")
   184  		require.Contains(t, out, "Updated body of text describing this merge request.")
   185  		require.NotContains(t, out, "Fancy")
   186  	})
   187  	t.Run("add MR comment", func(t *testing.T) {
   188  		addComment := exec.Command(labBinaryPath, "mr", "note", "lab-testing", mrID, "-m", "Fancy comment on this merge request.")
   189  		addComment.Dir = repo
   190  		b, err := addComment.CombinedOutput()
   191  		if err != nil {
   192  			t.Log(string(b))
   193  			t.Fatal(err)
   194  		}
   195  		out := string(b)
   196  		s := strings.Split(out, "_")
   197  		commentID = s[2]
   198  		s = strings.Split(commentID, "\n")
   199  		commentID = s[0]
   200  
   201  		t.Log("commentID =", commentID)
   202  
   203  		url := "https://gitlab.com/lab-testing/test/merge_requests/" + mrID + "#note_" + commentID
   204  		require.Contains(t, out, url)
   205  	})
   206  	t.Run("show MR with comment", func(t *testing.T) {
   207  		showComment := exec.Command(labBinaryPath, "mr", "show", "lab-testing", mrID, "--comments")
   208  		showComment.Dir = repo
   209  		b, err := showComment.CombinedOutput()
   210  		if err != nil {
   211  			t.Log(string(b))
   212  			t.Fatal(err)
   213  		}
   214  		out := string(b)
   215  		t.Log("commentID =", commentID)
   216  		_commentID := "#" + commentID + ": lab-testing"
   217  		require.Contains(t, out, _commentID)
   218  	})
   219  	t.Run("close", func(t *testing.T) {
   220  		closeMR(t, "lab-testing", repo, mrID)
   221  	})
   222  }
   223  
   224  func Test_mrCmd_DifferingUpstreamBranchName(t *testing.T) {
   225  	repo := copyTestRepo(t)
   226  	var mrID string
   227  	t.Run("prepare", func(t *testing.T) {
   228  		cleanupMR(t, "lab-testing", repo, "")
   229  	})
   230  	t.Run("create", func(t *testing.T) {
   231  		git := exec.Command("git", "checkout", "-b", "local/mrtest", "origin/mrtest")
   232  		git.Dir = repo
   233  		b, err := git.CombinedOutput()
   234  		if err != nil {
   235  			t.Log(string(b))
   236  			t.Fatal(err)
   237  		}
   238  
   239  		cmd := exec.Command(labBinaryPath, "mr", "create", "lab-testing", "master",
   240  			"-m", "mr title",
   241  			"-m", "mr description",
   242  			"-a", "lab-testing",
   243  		)
   244  		cmd.Dir = repo
   245  
   246  		b, _ = cmd.CombinedOutput()
   247  		out := string(b)
   248  		t.Log(out)
   249  		require.Contains(t, out, "https://gitlab.com/lab-testing/test/-/merge_requests")
   250  
   251  		i := strings.Index(out, "/diffs\n")
   252  		mrID = strings.TrimPrefix(out[:i], "https://gitlab.com/lab-testing/test/-/merge_requests/")
   253  		t.Log(mrID)
   254  	})
   255  	t.Run("close", func(t *testing.T) {
   256  		closeMR(t, "lab-testing", repo, mrID)
   257  	})
   258  }
   259  
   260  func Test_mrCmd_Draft(t *testing.T) {
   261  	repo := copyTestRepo(t)
   262  	var mrID string
   263  	t.Run("prepare", func(t *testing.T) {
   264  		cleanupMR(t, "lab-testing", repo, "")
   265  	})
   266  	t.Run("create", func(t *testing.T) {
   267  		git := exec.Command("git", "checkout", "mrtest")
   268  		git.Dir = repo
   269  		b, err := git.CombinedOutput()
   270  		if err != nil {
   271  			t.Log(string(b))
   272  			t.Fatal(err)
   273  		}
   274  
   275  		cmd := exec.Command(labBinaryPath, "mr", "create", "--draft", "lab-testing", "master",
   276  			"-m", "Test draft merge request",
   277  		)
   278  		cmd.Dir = repo
   279  
   280  		b, _ = cmd.CombinedOutput()
   281  		out := string(b)
   282  		t.Log(out)
   283  		require.Contains(t, out, "https://gitlab.com/lab-testing/test/-/merge_requests")
   284  
   285  		i := strings.Index(out, "/diffs\n")
   286  		mrID = strings.TrimPrefix(out[:i], "https://gitlab.com/lab-testing/test/-/merge_requests/")
   287  		t.Log(mrID)
   288  	})
   289  	t.Run("list", func(t *testing.T) {
   290  		if mrID == "" {
   291  			t.Skip("mrID is empty, create likely failed")
   292  		}
   293  		cmd := exec.Command(labBinaryPath, "mr", "list", "--draft", "lab-testing")
   294  		cmd.Dir = repo
   295  
   296  		b, _ := cmd.CombinedOutput()
   297  		out := string(b)
   298  		t.Log(out)
   299  		require.Contains(t, out, "Test draft merge request")
   300  	})
   301  	t.Run("modify", func(t *testing.T) {
   302  		if mrID == "" {
   303  			t.Skip("mrID is empty, create likely failed")
   304  		}
   305  		cmd := exec.Command(labBinaryPath, "mr", "edit", "--ready", "lab-testing")
   306  		cmd.Dir = repo
   307  
   308  		b, _ := cmd.CombinedOutput()
   309  		t.Log(string(b))
   310  
   311  		cmd = exec.Command(labBinaryPath, "mr", "list", "--draft", "lab-testing")
   312  		cmd.Dir = repo
   313  
   314  		b, _ = cmd.CombinedOutput()
   315  		out := string(b)
   316  		t.Log(out)
   317  		require.NotContains(t, out, "Test draft merge request")
   318  	})
   319  	t.Run("close", func(t *testing.T) {
   320  		closeMR(t, "lab-testing", repo, mrID)
   321  	})
   322  }
   323  
   324  func Test_mrCmd_Milestone(t *testing.T) {
   325  	repo := copyTestRepo(t)
   326  	var mrID string
   327  	t.Run("prepare", func(t *testing.T) {
   328  		cleanupMR(t, "origin", repo, "MR for 1.0")
   329  	})
   330  	t.Run("create", func(t *testing.T) {
   331  		git := exec.Command("git", "checkout", "mrtest")
   332  		git.Dir = repo
   333  		b, err := git.CombinedOutput()
   334  		if err != nil {
   335  			t.Log(string(b))
   336  			t.Fatal(err)
   337  		}
   338  
   339  		cmd := exec.Command(labBinaryPath, "mr", "create", "--milestone", "1.0", "origin", "master",
   340  			"-m", "MR for 1.0",
   341  		)
   342  		cmd.Dir = repo
   343  
   344  		b, _ = cmd.CombinedOutput()
   345  		out := string(b)
   346  		t.Log(out)
   347  		require.Contains(t, out, "https://gitlab.com/zaquestion/test/-/merge_requests")
   348  
   349  		i := strings.Index(out, "/diffs")
   350  		if i < 0 {
   351  			t.Error("wrong MR URL format")
   352  		}
   353  
   354  		mrID = strings.TrimPrefix(out[:i], "https://gitlab.com/zaquestion/test/-/merge_requests/")
   355  		t.Log("mrID:", mrID)
   356  	})
   357  	t.Run("list", func(t *testing.T) {
   358  		if mrID == "" {
   359  			t.Skip("mrID is empty, create likely failed")
   360  		}
   361  		cmd := exec.Command(labBinaryPath, "mr", "list", "--milestone", "1.0", "origin")
   362  		cmd.Dir = repo
   363  
   364  		b, _ := cmd.CombinedOutput()
   365  		out := string(b)
   366  		t.Log(out)
   367  		require.Contains(t, out, "MR for 1.0")
   368  	})
   369  	t.Run("modify", func(t *testing.T) {
   370  		if mrID == "" {
   371  			t.Skip("mrID is empty, create likely failed")
   372  		}
   373  		t.Log("mrID: ", mrID)
   374  		cmd := exec.Command(labBinaryPath, "mr", "edit", mrID, "--milestone", "")
   375  		cmd.Dir = repo
   376  
   377  		b, _ := cmd.CombinedOutput()
   378  		t.Log(string(b))
   379  
   380  		cmd = exec.Command(labBinaryPath, "mr", "list", "--milestone", "1.0", "origin")
   381  		cmd.Dir = repo
   382  
   383  		b, _ = cmd.CombinedOutput()
   384  		out := string(b)
   385  		t.Log(out)
   386  		require.NotContains(t, out, "MR for 1.0")
   387  	})
   388  	t.Run("close", func(t *testing.T) {
   389  		closeMR(t, "origin", repo, mrID)
   390  	})
   391  }
   392  
   393  func Test_mrCmd_ByBranch(t *testing.T) {
   394  	repo := copyTestRepo(t)
   395  	var mrID string
   396  	t.Run("prepare", func(t *testing.T) {
   397  		cleanupMR(t, "lab-testing", repo, "")
   398  	})
   399  	t.Run("create", func(t *testing.T) {
   400  		git := exec.Command("git", "checkout", "mrtest")
   401  		git.Dir = repo
   402  		b, err := git.CombinedOutput()
   403  		if err != nil {
   404  			t.Log(string(b))
   405  			t.Fatal(err)
   406  		}
   407  
   408  		cmd := exec.Command(labBinaryPath, "mr", "create", "--draft", "lab-testing", "master",
   409  			"-m", "mr by branch",
   410  		)
   411  		cmd.Dir = repo
   412  
   413  		b, _ = cmd.CombinedOutput()
   414  		out := string(b)
   415  		t.Log(out)
   416  		require.Contains(t, out, "https://gitlab.com/lab-testing/test/-/merge_requests")
   417  
   418  		i := strings.Index(out, "/diffs\n")
   419  		mrID = strings.TrimPrefix(out[:i], "https://gitlab.com/lab-testing/test/-/merge_requests/")
   420  		t.Log(mrID)
   421  	})
   422  	t.Run("show", func(t *testing.T) {
   423  		if mrID == "" {
   424  			t.Skip("mrID is empty, create likely failed")
   425  		}
   426  		cmd := exec.Command(labBinaryPath, "mr", "show", "lab-testing", "mrtest")
   427  		cmd.Dir = repo
   428  
   429  		b, err := cmd.CombinedOutput()
   430  		if err != nil {
   431  			t.Log(string(b))
   432  			t.Fatal(err)
   433  		}
   434  
   435  		out := string(b)
   436  		require.Contains(t, out, fmt.Sprintf("WebURL: https://gitlab.com/lab-testing/test/-/merge_requests/%s", mrID))
   437  	})
   438  	t.Run("close", func(t *testing.T) {
   439  		closeMR(t, "lab-testing", repo, mrID)
   440  	})
   441  }
   442  
   443  func Test_mrCmd_source(t *testing.T) {
   444  	repo := copyTestRepo(t)
   445  	var mrID string
   446  	t.Run("prepare", func(t *testing.T) {
   447  		cleanupMR(t, "lab-testing", repo, "")
   448  	})
   449  	t.Run("create_invalid", func(t *testing.T) {
   450  		git := exec.Command("git", "checkout", "mrtest")
   451  		git.Dir = repo
   452  		b, err := git.CombinedOutput()
   453  		if err != nil {
   454  			t.Log(string(b))
   455  			t.Fatal(err)
   456  		}
   457  
   458  		cmd := exec.Command(labBinaryPath, "mr", "create", "lab-testing", "master",
   459  			"--source", "origin:mrtestDoesNotExist",
   460  			"-m", "mr title",
   461  			"-m", "mr description",
   462  			"-a", "lab-testing",
   463  		)
   464  		cmd.Dir = repo
   465  
   466  		b, _ = cmd.CombinedOutput()
   467  		out := string(b)
   468  		t.Log(out)
   469  		require.Contains(t, out, "origin:mrtestDoesNotExist is not a valid reference")
   470  	})
   471  	t.Run("create_valid", func(t *testing.T) {
   472  		git := exec.Command("git", "checkout", "mrtest")
   473  		git.Dir = repo
   474  		b, err := git.CombinedOutput()
   475  		if err != nil {
   476  			t.Log(string(b))
   477  			t.Fatal(err)
   478  		}
   479  
   480  		cmd := exec.Command(labBinaryPath, "mr", "create", "lab-testing", "master",
   481  			"--source", "origin:mrtest",
   482  			"-m", "mr title",
   483  			"-m", "mr description",
   484  			"-a", "lab-testing",
   485  		)
   486  		cmd.Dir = repo
   487  
   488  		b, _ = cmd.CombinedOutput()
   489  		out := string(b)
   490  		t.Log(out)
   491  		require.Contains(t, out, "https://gitlab.com/lab-testing/test/-/merge_requests")
   492  
   493  		i := strings.Index(out, "/diffs\n")
   494  		mrID = strings.TrimPrefix(out[:i], "https://gitlab.com/lab-testing/test/-/merge_requests/")
   495  		t.Log(mrID)
   496  	})
   497  	t.Run("close", func(t *testing.T) {
   498  		closeMR(t, "lab-testing", repo, mrID)
   499  	})
   500  }
   501  
   502  func Test_mrCmd_assign_and_review(t *testing.T) {
   503  	var mrID string
   504  	mrIDString := "MR for assign and review commands"
   505  
   506  	repo := copyTestRepo(t)
   507  
   508  	// find the test MR
   509  	mrIDlist := exec.Command(labBinaryPath, "mr", "list", mrIDString)
   510  	mrIDlist.Dir = repo
   511  	mrIDOut, err := mrIDlist.CombinedOutput()
   512  	if err != nil {
   513  		t.Log(string(mrIDOut))
   514  		t.Fatal(err)
   515  	}
   516  
   517  	// find MR number
   518  	s := strings.Split(string(mrIDOut), " ")
   519  	mrID = s[0]
   520  	// strip off "!"
   521  	mrID = mrID[1:]
   522  
   523  	mrURL := "https://gitlab.com/zaquestion/test/-/merge_requests/" + mrID
   524  
   525  	t.Run("assign_and_unassign", func(t *testing.T) {
   526  		mrEdit := exec.Command(labBinaryPath, "mr", "edit", mrID, "--assign", "lab-testing")
   527  		mrEdit.Dir = repo
   528  		mrEditOut, err := mrEdit.CombinedOutput()
   529  		if err != nil {
   530  			t.Log(string(mrEditOut))
   531  			t.Fatal(err)
   532  		}
   533  
   534  		mrList := exec.Command(labBinaryPath, "mr", "list", "--assignee", "lab-testing")
   535  		mrList.Dir = repo
   536  		mrListOut, err := mrList.CombinedOutput()
   537  		if err != nil {
   538  			t.Log(string(mrListOut))
   539  			t.Fatal(err)
   540  		}
   541  
   542  		mrUnEdit := exec.Command(labBinaryPath, "mr", "edit", mrID, "--unassign", "lab-testing")
   543  		mrUnEdit.Dir = repo
   544  		mrUnEditOut, err := mrUnEdit.CombinedOutput()
   545  		if err != nil {
   546  			t.Log(string(mrUnEditOut))
   547  			t.Fatal(err)
   548  		}
   549  
   550  		require.Contains(t, string(mrEditOut), mrURL)
   551  		require.Contains(t, string(mrListOut), mrIDString)
   552  		require.Contains(t, string(mrUnEditOut), mrURL)
   553  	})
   554  
   555  	// This tests 'lab mr edit --review' and 'lab mr list --unreview'
   556  	t.Run("review_and_unreview", func(t *testing.T) {
   557  		mrEdit := exec.Command(labBinaryPath, "mr", "edit", mrID, "--review", "lab-testing")
   558  		mrEdit.Dir = repo
   559  		mrEditOut, err := mrEdit.CombinedOutput()
   560  		if err != nil {
   561  			t.Log(string(mrEditOut))
   562  			t.Fatal(err)
   563  		}
   564  
   565  		mrList := exec.Command(labBinaryPath, "mr", "list", "--reviewer", "lab-testing")
   566  		mrList.Dir = repo
   567  		mrListOut, err := mrList.CombinedOutput()
   568  		if err != nil {
   569  			t.Log(string(mrListOut))
   570  			t.Fatal(err)
   571  		}
   572  
   573  		mrUnEdit := exec.Command(labBinaryPath, "mr", "edit", mrID, "--unreview", "lab-testing")
   574  		mrUnEdit.Dir = repo
   575  		mrUnEditOut, err := mrUnEdit.CombinedOutput()
   576  		if err != nil {
   577  			t.Log(string(mrUnEditOut))
   578  			t.Fatal(err)
   579  		}
   580  
   581  		require.Contains(t, string(mrEditOut), mrURL)
   582  		require.Contains(t, string(mrListOut), mrIDString)
   583  		require.Contains(t, string(mrUnEditOut), mrURL)
   584  
   585  	})
   586  }
   587  
   588  func Test_mrCmd_noArgs(t *testing.T) {
   589  	repo := copyTestRepo(t)
   590  	cmd := exec.Command(labBinaryPath, "mr")
   591  	cmd.Dir = repo
   592  
   593  	b, err := cmd.CombinedOutput()
   594  	if err != nil {
   595  		t.Log(string(b))
   596  		t.Fatal(err)
   597  	}
   598  	require.Contains(t, string(b), `Usage:
   599    lab mr [flags]
   600    lab mr [command]`)
   601  }