github.com/dirkolbrich/hugo@v0.47.1/tpl/data/data_test.go (about)

     1  // Copyright 2017 The Hugo Authors. All rights reserved.
     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  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package data
    15  
    16  import (
    17  	"fmt"
    18  	"net/http"
    19  	"net/http/httptest"
    20  	"path/filepath"
    21  	"strings"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  	"github.com/stretchr/testify/require"
    26  )
    27  
    28  func TestGetCSV(t *testing.T) {
    29  	t.Parallel()
    30  
    31  	ns := newTestNs()
    32  
    33  	for i, test := range []struct {
    34  		sep     string
    35  		url     string
    36  		content string
    37  		expect  interface{}
    38  	}{
    39  		// Remotes
    40  		{
    41  			",",
    42  			`http://success/`,
    43  			"gomeetup,city\nyes,Sydney\nyes,San Francisco\nyes,Stockholm\n",
    44  			[][]string{{"gomeetup", "city"}, {"yes", "Sydney"}, {"yes", "San Francisco"}, {"yes", "Stockholm"}},
    45  		},
    46  		{
    47  			",",
    48  			`http://error.extra.field/`,
    49  			"gomeetup,city\nyes,Sydney\nyes,San Francisco\nyes,Stockholm,EXTRA\n",
    50  			false,
    51  		},
    52  		{
    53  			",",
    54  			`http://error.no.sep/`,
    55  			"gomeetup;city\nyes;Sydney\nyes;San Francisco\nyes;Stockholm\n",
    56  			false,
    57  		},
    58  		{
    59  			",",
    60  			`http://nofound/404`,
    61  			``,
    62  			false,
    63  		},
    64  
    65  		// Locals
    66  		{
    67  			";",
    68  			"pass/semi",
    69  			"gomeetup;city\nyes;Sydney\nyes;San Francisco\nyes;Stockholm\n",
    70  			[][]string{{"gomeetup", "city"}, {"yes", "Sydney"}, {"yes", "San Francisco"}, {"yes", "Stockholm"}},
    71  		},
    72  		{
    73  			";",
    74  			"fail/no-file",
    75  			"",
    76  			false,
    77  		},
    78  	} {
    79  		msg := fmt.Sprintf("Test %d", i)
    80  
    81  		// Setup HTTP test server
    82  		var srv *httptest.Server
    83  		srv, ns.client = getTestServer(func(w http.ResponseWriter, r *http.Request) {
    84  			if !haveHeader(r.Header, "Accept", "text/csv") && !haveHeader(r.Header, "Accept", "text/plain") {
    85  				http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
    86  				return
    87  			}
    88  
    89  			if r.URL.Path == "/404" {
    90  				http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
    91  				return
    92  			}
    93  
    94  			w.Header().Add("Content-type", "text/csv")
    95  
    96  			w.Write([]byte(test.content))
    97  		})
    98  		defer func() { srv.Close() }()
    99  
   100  		// Setup local test file for schema-less URLs
   101  		if !strings.Contains(test.url, ":") && !strings.HasPrefix(test.url, "fail/") {
   102  			f, err := ns.deps.Fs.Source.Create(filepath.Join(ns.deps.Cfg.GetString("workingDir"), test.url))
   103  			require.NoError(t, err, msg)
   104  			f.WriteString(test.content)
   105  			f.Close()
   106  		}
   107  
   108  		// Get on with it
   109  		got, err := ns.GetCSV(test.sep, test.url)
   110  
   111  		if _, ok := test.expect.(bool); ok {
   112  			assert.Error(t, err, msg)
   113  			continue
   114  		}
   115  		require.NoError(t, err, msg)
   116  		require.NotNil(t, got, msg)
   117  
   118  		assert.EqualValues(t, test.expect, got, msg)
   119  	}
   120  }
   121  
   122  func TestGetJSON(t *testing.T) {
   123  	t.Parallel()
   124  
   125  	ns := newTestNs()
   126  
   127  	for i, test := range []struct {
   128  		url     string
   129  		content string
   130  		expect  interface{}
   131  	}{
   132  		{
   133  			`http://success/`,
   134  			`{"gomeetup":["Sydney","San Francisco","Stockholm"]}`,
   135  			map[string]interface{}{"gomeetup": []interface{}{"Sydney", "San Francisco", "Stockholm"}},
   136  		},
   137  		{
   138  			`http://malformed/`,
   139  			`{gomeetup:["Sydney","San Francisco","Stockholm"]}`,
   140  			false,
   141  		},
   142  		{
   143  			`http://nofound/404`,
   144  			``,
   145  			false,
   146  		},
   147  		// Locals
   148  		{
   149  			"pass/semi",
   150  			`{"gomeetup":["Sydney","San Francisco","Stockholm"]}`,
   151  			map[string]interface{}{"gomeetup": []interface{}{"Sydney", "San Francisco", "Stockholm"}},
   152  		},
   153  		{
   154  			"fail/no-file",
   155  			"",
   156  			false,
   157  		},
   158  	} {
   159  		msg := fmt.Sprintf("Test %d", i)
   160  
   161  		// Setup HTTP test server
   162  		var srv *httptest.Server
   163  		srv, ns.client = getTestServer(func(w http.ResponseWriter, r *http.Request) {
   164  			if !haveHeader(r.Header, "Accept", "application/json") {
   165  				http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
   166  				return
   167  			}
   168  
   169  			if r.URL.Path == "/404" {
   170  				http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
   171  				return
   172  			}
   173  
   174  			w.Header().Add("Content-type", "application/json")
   175  
   176  			w.Write([]byte(test.content))
   177  		})
   178  		defer func() { srv.Close() }()
   179  
   180  		// Setup local test file for schema-less URLs
   181  		if !strings.Contains(test.url, ":") && !strings.HasPrefix(test.url, "fail/") {
   182  			f, err := ns.deps.Fs.Source.Create(filepath.Join(ns.deps.Cfg.GetString("workingDir"), test.url))
   183  			require.NoError(t, err, msg)
   184  			f.WriteString(test.content)
   185  			f.Close()
   186  		}
   187  
   188  		// Get on with it
   189  		got, err := ns.GetJSON(test.url)
   190  
   191  		if _, ok := test.expect.(bool); ok {
   192  			assert.Error(t, err, msg)
   193  			continue
   194  		}
   195  		require.NoError(t, err, msg)
   196  		require.NotNil(t, got, msg)
   197  
   198  		assert.EqualValues(t, test.expect, got, msg)
   199  	}
   200  }
   201  
   202  func TestParseCSV(t *testing.T) {
   203  	t.Parallel()
   204  
   205  	for i, test := range []struct {
   206  		csv []byte
   207  		sep string
   208  		exp string
   209  		err bool
   210  	}{
   211  		{[]byte("a,b,c\nd,e,f\n"), "", "", true},
   212  		{[]byte("a,b,c\nd,e,f\n"), "~/", "", true},
   213  		{[]byte("a,b,c\nd,e,f"), "|", "a,b,cd,e,f", false},
   214  		{[]byte("q,w,e\nd,e,f"), ",", "qwedef", false},
   215  		{[]byte("a|b|c\nd|e|f|g"), "|", "abcdefg", true},
   216  		{[]byte("z|y|c\nd|e|f"), "|", "zycdef", false},
   217  	} {
   218  		msg := fmt.Sprintf("Test %d: %v", i, test)
   219  
   220  		csv, err := parseCSV(test.csv, test.sep)
   221  		if test.err {
   222  			assert.Error(t, err, msg)
   223  			continue
   224  		}
   225  		require.NoError(t, err, msg)
   226  
   227  		act := ""
   228  		for _, v := range csv {
   229  			act = act + strings.Join(v, "")
   230  		}
   231  
   232  		assert.Equal(t, test.exp, act, msg)
   233  	}
   234  }
   235  
   236  func haveHeader(m http.Header, key, needle string) bool {
   237  	var s []string
   238  	var ok bool
   239  
   240  	if s, ok = m[key]; !ok {
   241  		return false
   242  	}
   243  
   244  	for _, v := range s {
   245  		if v == needle {
   246  			return true
   247  		}
   248  	}
   249  	return false
   250  }