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 }