github.com/hairyhenderson/templater@v3.5.0+incompatible/data/datasource_test.go (about)

     1  package data
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"runtime"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/spf13/afero"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  const osWindows = "windows"
    16  
    17  func TestNewData(t *testing.T) {
    18  	d, err := NewData(nil, nil)
    19  	assert.NoError(t, err)
    20  	assert.Len(t, d.Sources, 0)
    21  
    22  	d, err = NewData([]string{"foo=http:///foo.json"}, nil)
    23  	assert.NoError(t, err)
    24  	assert.Equal(t, "/foo.json", d.Sources["foo"].URL.Path)
    25  
    26  	d, err = NewData([]string{"foo=http:///foo.json"}, []string{})
    27  	assert.NoError(t, err)
    28  	assert.Equal(t, "/foo.json", d.Sources["foo"].URL.Path)
    29  	assert.Empty(t, d.Sources["foo"].header)
    30  
    31  	d, err = NewData([]string{"foo=http:///foo.json"}, []string{"bar=Accept: blah"})
    32  	assert.NoError(t, err)
    33  	assert.Equal(t, "/foo.json", d.Sources["foo"].URL.Path)
    34  	assert.Empty(t, d.Sources["foo"].header)
    35  
    36  	d, err = NewData([]string{"foo=http:///foo.json"}, []string{"foo=Accept: blah"})
    37  	assert.NoError(t, err)
    38  	assert.Equal(t, "/foo.json", d.Sources["foo"].URL.Path)
    39  	assert.Equal(t, "blah", d.Sources["foo"].header["Accept"][0])
    40  }
    41  
    42  func TestParseSourceNoAlias(t *testing.T) {
    43  	s, err := parseSource("foo.json")
    44  	assert.NoError(t, err)
    45  	assert.Equal(t, "foo", s.Alias)
    46  
    47  	_, err = parseSource("../foo.json")
    48  	assert.Error(t, err)
    49  
    50  	_, err = parseSource("ftp://example.com/foo.yml")
    51  	assert.Error(t, err)
    52  }
    53  
    54  func TestParseSourceWithAlias(t *testing.T) {
    55  	s, err := parseSource("data=foo.json")
    56  	assert.NoError(t, err)
    57  	assert.Equal(t, "data", s.Alias)
    58  	assert.Equal(t, "file", s.URL.Scheme)
    59  	assert.True(t, s.URL.IsAbs())
    60  
    61  	s, err = parseSource("data=/otherdir/foo.json")
    62  	assert.NoError(t, err)
    63  	assert.Equal(t, "data", s.Alias)
    64  	assert.Equal(t, "file", s.URL.Scheme)
    65  	assert.True(t, s.URL.IsAbs())
    66  	assert.Equal(t, "/otherdir/foo.json", s.URL.Path)
    67  
    68  	if runtime.GOOS == osWindows {
    69  		s, err = parseSource("data=foo.json")
    70  		assert.NoError(t, err)
    71  		assert.Equalf(t, byte(':'), s.URL.Path[1], "Path was %s", s.URL.Path)
    72  
    73  		s, err = parseSource(`data=\otherdir\foo.json`)
    74  		assert.NoError(t, err)
    75  		assert.Equal(t, "data", s.Alias)
    76  		assert.Equal(t, "file", s.URL.Scheme)
    77  		assert.True(t, s.URL.IsAbs())
    78  		assert.Equal(t, `/otherdir/foo.json`, s.URL.Path)
    79  
    80  		s, err = parseSource("data=C:\\windowsdir\\foo.json")
    81  		assert.NoError(t, err)
    82  		assert.Equal(t, "data", s.Alias)
    83  		assert.Equal(t, "file", s.URL.Scheme)
    84  		assert.True(t, s.URL.IsAbs())
    85  		assert.Equal(t, "C:/windowsdir/foo.json", s.URL.Path)
    86  
    87  		s, err = parseSource("data=\\\\somehost\\share\\foo.json")
    88  		assert.NoError(t, err)
    89  		assert.Equal(t, "data", s.Alias)
    90  		assert.Equal(t, "file", s.URL.Scheme)
    91  		assert.Equal(t, "somehost", s.URL.Host)
    92  		assert.True(t, s.URL.IsAbs())
    93  		assert.Equal(t, "/share/foo.json", s.URL.Path)
    94  	}
    95  
    96  	s, err = parseSource("data=sftp://example.com/blahblah/foo.json")
    97  	assert.NoError(t, err)
    98  	assert.Equal(t, "data", s.Alias)
    99  	assert.Equal(t, "sftp", s.URL.Scheme)
   100  	assert.True(t, s.URL.IsAbs())
   101  	assert.Equal(t, "/blahblah/foo.json", s.URL.Path)
   102  
   103  	s, err = parseSource("merged=merge:./foo.yaml|http://example.com/bar.json%3Ffoo=bar")
   104  	assert.NoError(t, err)
   105  	assert.Equal(t, "merged", s.Alias)
   106  	assert.Equal(t, "merge", s.URL.Scheme)
   107  	assert.Equal(t, "./foo.yaml|http://example.com/bar.json%3Ffoo=bar", s.URL.Opaque)
   108  }
   109  
   110  func TestDatasource(t *testing.T) {
   111  	setup := func(ext, mime string, contents []byte) *Data {
   112  		fname := "foo." + ext
   113  		fs := afero.NewMemMapFs()
   114  		var uPath string
   115  		var f afero.File
   116  		if runtime.GOOS == osWindows {
   117  			_ = fs.Mkdir("C:\\tmp", 0777)
   118  			f, _ = fs.Create("C:\\tmp\\" + fname)
   119  			_, _ = f.Write(contents)
   120  			uPath = "C:/tmp/" + fname
   121  		} else {
   122  			_ = fs.Mkdir("/tmp", 0777)
   123  			f, _ = fs.Create("/tmp/" + fname)
   124  			uPath = "/tmp/" + fname
   125  		}
   126  		_, _ = f.Write(contents)
   127  
   128  		sources := map[string]*Source{
   129  			"foo": {
   130  				Alias:     "foo",
   131  				URL:       &url.URL{Scheme: "file", Path: uPath},
   132  				mediaType: mime,
   133  				fs:        fs,
   134  			},
   135  		}
   136  		return &Data{Sources: sources}
   137  	}
   138  	test := func(ext, mime string, contents []byte) {
   139  		data := setup(ext, mime, contents)
   140  		expected := map[string]interface{}{"hello": map[string]interface{}{"cruel": "world"}}
   141  		actual, err := data.Datasource("foo")
   142  		assert.NoError(t, err)
   143  		assert.Equal(t, expected, actual)
   144  	}
   145  
   146  	test("json", jsonMimetype, []byte(`{"hello":{"cruel":"world"}}`))
   147  	test("yml", yamlMimetype, []byte("hello:\n  cruel: world\n"))
   148  
   149  	d := setup("", textMimetype, nil)
   150  	actual, err := d.Datasource("foo")
   151  	assert.NoError(t, err)
   152  	assert.Equal(t, "", actual)
   153  
   154  	_, err = d.Datasource("bar")
   155  	assert.Error(t, err)
   156  }
   157  
   158  func TestDatasourceReachable(t *testing.T) {
   159  	fname := "foo.json"
   160  	fs := afero.NewMemMapFs()
   161  	var uPath string
   162  	var f afero.File
   163  	if runtime.GOOS == osWindows {
   164  		_ = fs.Mkdir("C:\\tmp", 0777)
   165  		f, _ = fs.Create("C:\\tmp\\" + fname)
   166  		uPath = "C:/tmp/" + fname
   167  	} else {
   168  		_ = fs.Mkdir("/tmp", 0777)
   169  		f, _ = fs.Create("/tmp/" + fname)
   170  		uPath = "/tmp/" + fname
   171  	}
   172  	_, _ = f.Write([]byte("{}"))
   173  
   174  	sources := map[string]*Source{
   175  		"foo": {
   176  			Alias:     "foo",
   177  			URL:       &url.URL{Scheme: "file", Path: uPath},
   178  			mediaType: jsonMimetype,
   179  			fs:        fs,
   180  		},
   181  		"bar": {
   182  			Alias: "bar",
   183  			URL:   &url.URL{Scheme: "file", Path: "/bogus"},
   184  			fs:    fs,
   185  		},
   186  	}
   187  	data := &Data{Sources: sources}
   188  
   189  	assert.True(t, data.DatasourceReachable("foo"))
   190  	assert.False(t, data.DatasourceReachable("bar"))
   191  }
   192  
   193  func TestDatasourceExists(t *testing.T) {
   194  	sources := map[string]*Source{
   195  		"foo": {Alias: "foo"},
   196  	}
   197  	data := &Data{Sources: sources}
   198  	assert.True(t, data.DatasourceExists("foo"))
   199  	assert.False(t, data.DatasourceExists("bar"))
   200  }
   201  
   202  func TestInclude(t *testing.T) {
   203  	ext := "txt"
   204  	contents := "hello world"
   205  	fname := "foo." + ext
   206  	fs := afero.NewMemMapFs()
   207  
   208  	var uPath string
   209  	var f afero.File
   210  	if runtime.GOOS == osWindows {
   211  		_ = fs.Mkdir("C:\\tmp", 0777)
   212  		f, _ = fs.Create("C:\\tmp\\" + fname)
   213  		uPath = "C:/tmp/" + fname
   214  	} else {
   215  		_ = fs.Mkdir("/tmp", 0777)
   216  		f, _ = fs.Create("/tmp/" + fname)
   217  		uPath = "/tmp/" + fname
   218  	}
   219  	_, _ = f.Write([]byte(contents))
   220  
   221  	sources := map[string]*Source{
   222  		"foo": {
   223  			Alias:     "foo",
   224  			URL:       &url.URL{Scheme: "file", Path: uPath},
   225  			mediaType: textMimetype,
   226  			fs:        fs,
   227  		},
   228  	}
   229  	data := &Data{
   230  		Sources: sources,
   231  	}
   232  	actual, err := data.Include("foo")
   233  	assert.NoError(t, err)
   234  	assert.Equal(t, contents, actual)
   235  }
   236  
   237  type errorReader struct{}
   238  
   239  func (e errorReader) Read(p []byte) (n int, err error) {
   240  	return 0, fmt.Errorf("error")
   241  }
   242  
   243  func TestReadStdin(t *testing.T) {
   244  	defer func() {
   245  		stdin = nil
   246  	}()
   247  	stdin = strings.NewReader("foo")
   248  	out, err := readStdin(nil)
   249  	assert.NoError(t, err)
   250  	assert.Equal(t, []byte("foo"), out)
   251  
   252  	stdin = errorReader{}
   253  	_, err = readStdin(nil)
   254  	assert.Error(t, err)
   255  }
   256  
   257  // nolint: megacheck
   258  func TestDefineDatasource(t *testing.T) {
   259  	d := &Data{}
   260  	_, err := d.DefineDatasource("", "foo.json")
   261  	assert.Error(t, err)
   262  
   263  	d = &Data{}
   264  	_, err = d.DefineDatasource("", "../foo.json")
   265  	assert.Error(t, err)
   266  
   267  	d = &Data{}
   268  	_, err = d.DefineDatasource("", "ftp://example.com/foo.yml")
   269  	assert.Error(t, err)
   270  
   271  	d = &Data{}
   272  	_, err = d.DefineDatasource("data", "foo.json")
   273  	s := d.Sources["data"]
   274  	assert.NoError(t, err)
   275  	assert.Equal(t, "data", s.Alias)
   276  	assert.Equal(t, "file", s.URL.Scheme)
   277  	assert.True(t, s.URL.IsAbs())
   278  
   279  	d = &Data{}
   280  	_, err = d.DefineDatasource("data", "/otherdir/foo.json")
   281  	s = d.Sources["data"]
   282  	assert.NoError(t, err)
   283  	assert.Equal(t, "data", s.Alias)
   284  	assert.Equal(t, "file", s.URL.Scheme)
   285  	assert.True(t, s.URL.IsAbs())
   286  	assert.Equal(t, "/otherdir/foo.json", s.URL.Path)
   287  
   288  	d = &Data{}
   289  	_, err = d.DefineDatasource("data", "sftp://example.com/blahblah/foo.json")
   290  	s = d.Sources["data"]
   291  	assert.NoError(t, err)
   292  	assert.Equal(t, "data", s.Alias)
   293  	assert.Equal(t, "sftp", s.URL.Scheme)
   294  	assert.True(t, s.URL.IsAbs())
   295  	assert.Equal(t, "/blahblah/foo.json", s.URL.Path)
   296  
   297  	d = &Data{
   298  		Sources: map[string]*Source{
   299  			"data": {Alias: "data"},
   300  		},
   301  	}
   302  	_, err = d.DefineDatasource("data", "/otherdir/foo.json")
   303  	s = d.Sources["data"]
   304  	assert.NoError(t, err)
   305  	assert.Equal(t, "data", s.Alias)
   306  	assert.Nil(t, s.URL)
   307  }
   308  
   309  func TestMimeType(t *testing.T) {
   310  	s := &Source{URL: mustParseURL("http://example.com/foo.json")}
   311  	mt, err := s.mimeType()
   312  	assert.NoError(t, err)
   313  	assert.Equal(t, jsonMimetype, mt)
   314  
   315  	s = &Source{URL: mustParseURL("http://example.com/foo.json"), mediaType: "text/foo"}
   316  	mt, err = s.mimeType()
   317  	assert.NoError(t, err)
   318  	assert.Equal(t, "text/foo", mt)
   319  
   320  	s = &Source{URL: mustParseURL("http://example.com/foo.json"), mediaType: "text/foo"}
   321  	mt, err = s.mimeType()
   322  	assert.NoError(t, err)
   323  	assert.Equal(t, "text/foo", mt)
   324  
   325  	s = &Source{URL: mustParseURL("http://example.com/foo.json?type=application/yaml"), mediaType: "text/foo"}
   326  	mt, err = s.mimeType()
   327  	assert.NoError(t, err)
   328  	assert.Equal(t, "application/yaml", mt)
   329  }
   330  
   331  func TestQueryParse(t *testing.T) {
   332  	expected := &url.URL{
   333  		Scheme:   "http",
   334  		Host:     "example.com",
   335  		Path:     "/foo.json",
   336  		RawQuery: "bar",
   337  	}
   338  	u, err := parseSourceURL("http://example.com/foo.json?bar")
   339  	assert.NoError(t, err)
   340  	assert.EqualValues(t, expected, u)
   341  }