github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/internal/util/parse/parse_test.go (about)

     1  // Copyright 2021 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package parse
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"testing"
    21  
    22  	"github.com/GoogleContainerTools/kpt/internal/printer"
    23  	v1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1"
    24  	"github.com/stretchr/testify/assert"
    25  	"github.com/stretchr/testify/require"
    26  )
    27  
    28  func Test_pkgURLFromGHURL(t *testing.T) {
    29  	tests := []struct {
    30  		name     string
    31  		ghURL    string
    32  		want     string
    33  		errS     string
    34  		branches []string
    35  	}{
    36  		{
    37  			name:     "simple",
    38  			ghURL:    "https://github.com/owner/repo",
    39  			want:     "https://github.com/owner/repo.git",
    40  			errS:     "",
    41  			branches: nil,
    42  		},
    43  		{
    44  			name:     "with trailing slash",
    45  			ghURL:    "https://github.com/owner/repo/",
    46  			want:     "https://github.com/owner/repo.git",
    47  			errS:     "",
    48  			branches: nil,
    49  		},
    50  		{
    51  			name:     "with ref",
    52  			ghURL:    "https://github.com/owner/repo/tree/main",
    53  			want:     "https://github.com/owner/repo.git@main",
    54  			errS:     "",
    55  			branches: nil,
    56  		},
    57  		{
    58  			name:     "with commit SHA",
    59  			ghURL:    "https://github.com/owner/repo/tree/fc0193e5cf7ff836f8208644ff2dc14901ed06c9",
    60  			want:     "https://github.com/owner/repo.git@fc0193e5cf7ff836f8208644ff2dc14901ed06c9",
    61  			errS:     "",
    62  			branches: nil,
    63  		},
    64  		{
    65  			name:     "with ref with branches",
    66  			ghURL:    "https://github.com/owner/repo/tree/main",
    67  			want:     "https://github.com/owner/repo.git@main",
    68  			errS:     "",
    69  			branches: []string{"test", "main"},
    70  		},
    71  		{
    72  			name:  "with commit SHA with branches",
    73  			ghURL: "https://github.com/owner/repo/tree/fc0193e5cf7ff836f8208644ff2dc14901ed06c9",
    74  			want:  "https://github.com/owner/repo.git@fc0193e5cf7ff836f8208644ff2dc14901ed06c9", errS: "", branches: []string{"test", "main"},
    75  		},
    76  		{
    77  			name:     "with ref with branches ambiguous",
    78  			ghURL:    "https://github.com/owner/repo/tree/main/foo/bar",
    79  			want:     "",
    80  			errS:     "ambiguous repo/dir@version specify '.git' in argument",
    81  			branches: []string{"test", "main", "main/foo"},
    82  		},
    83  		{
    84  			name:  "with ref with nested dir",
    85  			ghURL: "https://github.com/owner/repo/tree/foobranch/my/nested/pkg",
    86  			want:  "https://github.com/owner/repo.git/my/nested/pkg@foobranch",
    87  			errS:  "", branches: []string{"test", "main", "foobranch"},
    88  		},
    89  		{
    90  			name:     "with ref with nested dir ambiguous",
    91  			ghURL:    "https://github.com/owner/repo/tree/foobranch/my/nested/pkg",
    92  			want:     "",
    93  			errS:     "ambiguous repo/dir@version specify '.git' in argument",
    94  			branches: []string{"test", "main", "foobranch/bar"},
    95  		},
    96  		{
    97  			name:     "with ref trailing slash",
    98  			ghURL:    "https://github.com/owner/repo/tree/main/",
    99  			want:     "https://github.com/owner/repo.git@main",
   100  			errS:     "",
   101  			branches: nil,
   102  		},
   103  		{
   104  			name:     "with tree no ref",
   105  			ghURL:    "https://github.com/owner/repo/tree",
   106  			want:     "https://github.com/owner/repo.git/tree",
   107  			errS:     "",
   108  			branches: []string{"test", "tree/"},
   109  		},
   110  		{
   111  			name:     "with tree no ref trailing slash",
   112  			ghURL:    "https://github.com/owner/repo/tree/",
   113  			want:     "https://github.com/owner/repo.git/tree",
   114  			errS:     "",
   115  			branches: []string{"test", "tree/"},
   116  		},
   117  		{
   118  			name:     "with dir no ref",
   119  			ghURL:    "https://github.com/owner/repo/my/nested/pkg",
   120  			want:     "https://github.com/owner/repo.git/my/nested/pkg",
   121  			errS:     "",
   122  			branches: nil,
   123  		},
   124  		{
   125  			name:     "malformed github url domain",
   126  			ghURL:    "https://foo.com/github.com",
   127  			want:     "",
   128  			errS:     "invalid GitHub url",
   129  			branches: nil,
   130  		},
   131  		{
   132  			name:     "malformed github url no repo",
   133  			ghURL:    "https://github.com/owner",
   134  			want:     "",
   135  			errS:     "invalid GitHub pkg url",
   136  			branches: nil,
   137  		},
   138  		{
   139  			name:     "malformed github url no owner no repo",
   140  			ghURL:    "https://github.com/owner",
   141  			want:     "",
   142  			errS:     "invalid GitHub pkg url",
   143  			branches: nil,
   144  		},
   145  		{
   146  			name:     "malformed github url no scheme",
   147  			ghURL:    "github.com/owner",
   148  			want:     "",
   149  			errS:     "invalid GitHub url",
   150  			branches: nil,
   151  		},
   152  		{
   153  			name:     "not github url",
   154  			ghURL:    "https://foo.com/bar",
   155  			want:     "",
   156  			errS:     "invalid GitHub url",
   157  			branches: nil,
   158  		},
   159  		{
   160  			name:     "empty",
   161  			ghURL:    "",
   162  			want:     "",
   163  			errS:     "invalid GitHub url",
   164  			branches: nil,
   165  		},
   166  	}
   167  	for _, tt := range tests {
   168  		tt := tt
   169  		t.Run(tt.name, func(t *testing.T) {
   170  			r := require.New(t)
   171  			ctx := printer.WithContext(context.Background(), printer.New(nil, nil))
   172  			// getBranches returns test branches slice
   173  			getBranches := func(ctx context.Context, repo string) ([]string, error) {
   174  				return tt.branches, nil
   175  			}
   176  			got, err := pkgURLFromGHURL(ctx, tt.ghURL, getBranches)
   177  			if tt.errS != "" {
   178  				r.Equal("", got, "url should be empty")
   179  				r.EqualError(err, fmt.Sprintf("%s: %s", tt.errS, tt.ghURL), "should equal")
   180  			} else {
   181  				r.NoError(err, "should not return error")
   182  				r.Equal(tt.want, got, "url should be equal")
   183  			}
   184  		})
   185  	}
   186  }
   187  
   188  func Test_parseURL(t *testing.T) {
   189  	type expected struct {
   190  		repo    string
   191  		dir     string
   192  		version string
   193  	}
   194  	tests := map[string]struct {
   195  		ghURL string
   196  		expected
   197  	}{
   198  		"simple": {
   199  			ghURL:    "https://my.git-server.com/repository.git/directory@main",
   200  			expected: expected{repo: "https://my.git-server.com/repository", dir: "/directory", version: "main"},
   201  		},
   202  		"no ref": {
   203  			ghURL:    "https://github.com/GoogleContainerTools/kpt-functions-catalog.git/examples/apply-replacements-simple",
   204  			expected: expected{repo: "https://github.com/GoogleContainerTools/kpt-functions-catalog", dir: "/examples/apply-replacements-simple", version: ""},
   205  		},
   206  		".git appears in the middle": {
   207  			ghURL:    "https://my-site.com/root.gitops.git/foo@main",
   208  			expected: expected{repo: "https://my-site.com/root.gitops", dir: "/foo", version: "main"},
   209  		},
   210  	}
   211  	for name, test := range tests {
   212  		test := test // capture range variable
   213  		t.Run(name, func(t *testing.T) {
   214  			repo, dir, version, err := URL(test.ghURL)
   215  			assert.NoError(t, err)
   216  			assert.Equal(t, expected{repo: repo, dir: dir, version: version}, test.expected)
   217  		})
   218  	}
   219  }
   220  
   221  func Test_GitParseArgs(t *testing.T) {
   222  	tests := map[string]struct {
   223  		ghURL    string
   224  		skip     bool
   225  		expected Target
   226  	}{
   227  		"git@ url with .git suffix": {
   228  			ghURL: "git@github.com:GoogleContainerTools/kpt.git",
   229  			expected: Target{Git: v1.Git{
   230  				Repo:      "git@github.com:GoogleContainerTools/kpt",
   231  				Directory: "/",
   232  				Ref:       "main",
   233  			},
   234  				Destination: "kpt"},
   235  			// in CI we get the error "git@github.com: Permission denied (publickey)" because the ssh key is not set up.
   236  			skip: true,
   237  		},
   238  		"http url with .git suffix": {
   239  			ghURL: "https://github.com/GoogleContainerTools/kpt.git",
   240  			expected: Target{Git: v1.Git{
   241  				Repo:      "https://github.com/GoogleContainerTools/kpt",
   242  				Directory: "/",
   243  				Ref:       "main",
   244  			},
   245  				Destination: "kpt"},
   246  		},
   247  		"starts with github.com": {
   248  			ghURL: "https://github.com/GoogleContainerTools/kpt",
   249  			expected: Target{Git: v1.Git{
   250  				Repo:      "https://github.com/GoogleContainerTools/kpt",
   251  				Directory: "/",
   252  				Ref:       "main",
   253  			},
   254  				Destination: "kpt"},
   255  		},
   256  	}
   257  	for name, test := range tests {
   258  		test := test // capture range variable
   259  		t.Run(name, func(t *testing.T) {
   260  			if test.skip {
   261  				t.SkipNow()
   262  			}
   263  			ctx := printer.WithContext(context.Background(), printer.New(nil, nil))
   264  			actual, err := GitParseArgs(ctx, []string{test.ghURL, ""})
   265  			assert.NoError(t, err)
   266  			assert.Equal(t, test.expected, actual)
   267  		})
   268  	}
   269  }