hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

mediaType_test.go (10354B)

    1 // Copyright 2019 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 media
   15 
   16 import (
   17 	"encoding/json"
   18 	"io/ioutil"
   19 	"path/filepath"
   20 	"sort"
   21 	"strings"
   22 	"testing"
   23 
   24 	qt "github.com/frankban/quicktest"
   25 	"github.com/gohugoio/hugo/common/paths"
   26 )
   27 
   28 func TestDefaultTypes(t *testing.T) {
   29 	c := qt.New(t)
   30 	for _, test := range []struct {
   31 		tp               Type
   32 		expectedMainType string
   33 		expectedSubType  string
   34 		expectedSuffix   string
   35 		expectedType     string
   36 		expectedString   string
   37 	}{
   38 		{CalendarType, "text", "calendar", "ics", "text/calendar", "text/calendar"},
   39 		{CSSType, "text", "css", "css", "text/css", "text/css"},
   40 		{SCSSType, "text", "x-scss", "scss", "text/x-scss", "text/x-scss"},
   41 		{CSVType, "text", "csv", "csv", "text/csv", "text/csv"},
   42 		{HTMLType, "text", "html", "html", "text/html", "text/html"},
   43 		{JavascriptType, "application", "javascript", "js", "application/javascript", "application/javascript"},
   44 		{TypeScriptType, "application", "typescript", "ts", "application/typescript", "application/typescript"},
   45 		{TSXType, "text", "tsx", "tsx", "text/tsx", "text/tsx"},
   46 		{JSXType, "text", "jsx", "jsx", "text/jsx", "text/jsx"},
   47 		{JSONType, "application", "json", "json", "application/json", "application/json"},
   48 		{RSSType, "application", "rss", "xml", "application/rss+xml", "application/rss+xml"},
   49 		{SVGType, "image", "svg", "svg", "image/svg+xml", "image/svg+xml"},
   50 		{TextType, "text", "plain", "txt", "text/plain", "text/plain"},
   51 		{XMLType, "application", "xml", "xml", "application/xml", "application/xml"},
   52 		{TOMLType, "application", "toml", "toml", "application/toml", "application/toml"},
   53 		{YAMLType, "application", "yaml", "yaml", "application/yaml", "application/yaml"},
   54 		{PDFType, "application", "pdf", "pdf", "application/pdf", "application/pdf"},
   55 		{TrueTypeFontType, "font", "ttf", "ttf", "font/ttf", "font/ttf"},
   56 		{OpenTypeFontType, "font", "otf", "otf", "font/otf", "font/otf"},
   57 	} {
   58 		c.Assert(test.tp.MainType, qt.Equals, test.expectedMainType)
   59 		c.Assert(test.tp.SubType, qt.Equals, test.expectedSubType)
   60 
   61 		c.Assert(test.tp.Type(), qt.Equals, test.expectedType)
   62 		c.Assert(test.tp.String(), qt.Equals, test.expectedString)
   63 
   64 	}
   65 
   66 	c.Assert(len(DefaultTypes), qt.Equals, 34)
   67 }
   68 
   69 func TestGetByType(t *testing.T) {
   70 	c := qt.New(t)
   71 
   72 	types := Types{HTMLType, RSSType}
   73 
   74 	mt, found := types.GetByType("text/HTML")
   75 	c.Assert(found, qt.Equals, true)
   76 	c.Assert(HTMLType, qt.Equals, mt)
   77 
   78 	_, found = types.GetByType("text/nono")
   79 	c.Assert(found, qt.Equals, false)
   80 
   81 	mt, found = types.GetByType("application/rss+xml")
   82 	c.Assert(found, qt.Equals, true)
   83 	c.Assert(RSSType, qt.Equals, mt)
   84 
   85 	mt, found = types.GetByType("application/rss")
   86 	c.Assert(found, qt.Equals, true)
   87 	c.Assert(RSSType, qt.Equals, mt)
   88 }
   89 
   90 func TestGetByMainSubType(t *testing.T) {
   91 	c := qt.New(t)
   92 	f, found := DefaultTypes.GetByMainSubType("text", "plain")
   93 	c.Assert(found, qt.Equals, true)
   94 	c.Assert(f, qt.Equals, TextType)
   95 	_, found = DefaultTypes.GetByMainSubType("foo", "plain")
   96 	c.Assert(found, qt.Equals, false)
   97 }
   98 
   99 func TestBySuffix(t *testing.T) {
  100 	c := qt.New(t)
  101 	formats := DefaultTypes.BySuffix("xml")
  102 	c.Assert(len(formats), qt.Equals, 2)
  103 	c.Assert(formats[0].SubType, qt.Equals, "rss")
  104 	c.Assert(formats[1].SubType, qt.Equals, "xml")
  105 }
  106 
  107 func TestGetFirstBySuffix(t *testing.T) {
  108 	c := qt.New(t)
  109 
  110 	types := DefaultTypes
  111 
  112 	// Issue #8406
  113 	geoJSON := newMediaTypeWithMimeSuffix("application", "geo", "json", []string{"geojson", "gjson"})
  114 	types = append(types, geoJSON)
  115 	sort.Sort(types)
  116 
  117 	check := func(suffix string, expectedType Type) {
  118 		t, f, found := types.GetFirstBySuffix(suffix)
  119 		c.Assert(found, qt.Equals, true)
  120 		c.Assert(f, qt.Equals, SuffixInfo{
  121 			Suffix:     suffix,
  122 			FullSuffix: "." + suffix,
  123 		})
  124 		c.Assert(t, qt.Equals, expectedType)
  125 	}
  126 
  127 	check("js", JavascriptType)
  128 	check("json", JSONType)
  129 	check("geojson", geoJSON)
  130 	check("gjson", geoJSON)
  131 }
  132 
  133 func TestFromTypeString(t *testing.T) {
  134 	c := qt.New(t)
  135 	f, err := fromString("text/html")
  136 	c.Assert(err, qt.IsNil)
  137 	c.Assert(f.Type(), qt.Equals, HTMLType.Type())
  138 
  139 	f, err = fromString("application/custom")
  140 	c.Assert(err, qt.IsNil)
  141 	c.Assert(f, qt.Equals, Type{MainType: "application", SubType: "custom", mimeSuffix: ""})
  142 
  143 	f, err = fromString("application/custom+sfx")
  144 	c.Assert(err, qt.IsNil)
  145 	c.Assert(f, qt.Equals, Type{MainType: "application", SubType: "custom", mimeSuffix: "sfx"})
  146 
  147 	_, err = fromString("noslash")
  148 	c.Assert(err, qt.Not(qt.IsNil))
  149 
  150 	f, err = fromString("text/xml; charset=utf-8")
  151 	c.Assert(err, qt.IsNil)
  152 
  153 	c.Assert(f, qt.Equals, Type{MainType: "text", SubType: "xml", mimeSuffix: ""})
  154 }
  155 
  156 func TestFromStringAndExt(t *testing.T) {
  157 	c := qt.New(t)
  158 	f, err := FromStringAndExt("text/html", "html")
  159 	c.Assert(err, qt.IsNil)
  160 	c.Assert(f, qt.Equals, HTMLType)
  161 	f, err = FromStringAndExt("text/html", ".html")
  162 	c.Assert(err, qt.IsNil)
  163 	c.Assert(f, qt.Equals, HTMLType)
  164 }
  165 
  166 // Add a test for the SVG case
  167 // https://github.com/gohugoio/hugo/issues/4920
  168 func TestFromExtensionMultipleSuffixes(t *testing.T) {
  169 	c := qt.New(t)
  170 	tp, si, found := DefaultTypes.GetBySuffix("svg")
  171 	c.Assert(found, qt.Equals, true)
  172 	c.Assert(tp.String(), qt.Equals, "image/svg+xml")
  173 	c.Assert(si.Suffix, qt.Equals, "svg")
  174 	c.Assert(si.FullSuffix, qt.Equals, ".svg")
  175 	c.Assert(tp.FirstSuffix.Suffix, qt.Equals, si.Suffix)
  176 	c.Assert(tp.FirstSuffix.FullSuffix, qt.Equals, si.FullSuffix)
  177 	ftp, found := DefaultTypes.GetByType("image/svg+xml")
  178 	c.Assert(found, qt.Equals, true)
  179 	c.Assert(ftp.String(), qt.Equals, "image/svg+xml")
  180 	c.Assert(found, qt.Equals, true)
  181 }
  182 
  183 func TestFromContent(t *testing.T) {
  184 	c := qt.New(t)
  185 
  186 	files, err := filepath.Glob("./testdata/resource.*")
  187 	c.Assert(err, qt.IsNil)
  188 	mtypes := DefaultTypes
  189 
  190 	for _, filename := range files {
  191 		name := filepath.Base(filename)
  192 		c.Run(name, func(c *qt.C) {
  193 			content, err := ioutil.ReadFile(filename)
  194 			c.Assert(err, qt.IsNil)
  195 			ext := strings.TrimPrefix(paths.Ext(filename), ".")
  196 			var exts []string
  197 			if ext == "jpg" {
  198 				exts = append(exts, "foo", "bar", "jpg")
  199 			} else {
  200 				exts = []string{ext}
  201 			}
  202 			expected, _, found := mtypes.GetFirstBySuffix(ext)
  203 			c.Assert(found, qt.IsTrue)
  204 			got := FromContent(mtypes, exts, content)
  205 			c.Assert(got, qt.Equals, expected)
  206 		})
  207 	}
  208 }
  209 
  210 func TestFromContentFakes(t *testing.T) {
  211 	c := qt.New(t)
  212 
  213 	files, err := filepath.Glob("./testdata/fake.*")
  214 	c.Assert(err, qt.IsNil)
  215 	mtypes := DefaultTypes
  216 
  217 	for _, filename := range files {
  218 		name := filepath.Base(filename)
  219 		c.Run(name, func(c *qt.C) {
  220 			content, err := ioutil.ReadFile(filename)
  221 			c.Assert(err, qt.IsNil)
  222 			ext := strings.TrimPrefix(paths.Ext(filename), ".")
  223 			got := FromContent(mtypes, []string{ext}, content)
  224 			c.Assert(got, qt.Equals, zero)
  225 		})
  226 	}
  227 }
  228 
  229 func TestDecodeTypes(t *testing.T) {
  230 	c := qt.New(t)
  231 
  232 	tests := []struct {
  233 		name        string
  234 		maps        []map[string]any
  235 		shouldError bool
  236 		assert      func(t *testing.T, name string, tt Types)
  237 	}{
  238 		{
  239 			"Redefine JSON",
  240 			[]map[string]any{
  241 				{
  242 					"application/json": map[string]any{
  243 						"suffixes": []string{"jasn"},
  244 					},
  245 				},
  246 			},
  247 			false,
  248 			func(t *testing.T, name string, tt Types) {
  249 				c.Assert(len(tt), qt.Equals, len(DefaultTypes))
  250 				json, si, found := tt.GetBySuffix("jasn")
  251 				c.Assert(found, qt.Equals, true)
  252 				c.Assert(json.String(), qt.Equals, "application/json")
  253 				c.Assert(si.FullSuffix, qt.Equals, ".jasn")
  254 			},
  255 		},
  256 		{
  257 			"MIME suffix in key, multiple file suffixes, custom delimiter",
  258 			[]map[string]any{
  259 				{
  260 					"application/hugo+hg": map[string]any{
  261 						"suffixes":  []string{"hg1", "hG2"},
  262 						"Delimiter": "_",
  263 					},
  264 				},
  265 			},
  266 			false,
  267 			func(t *testing.T, name string, tt Types) {
  268 				c.Assert(len(tt), qt.Equals, len(DefaultTypes)+1)
  269 				hg, si, found := tt.GetBySuffix("hg2")
  270 				c.Assert(found, qt.Equals, true)
  271 				c.Assert(hg.mimeSuffix, qt.Equals, "hg")
  272 				c.Assert(hg.FirstSuffix.Suffix, qt.Equals, "hg1")
  273 				c.Assert(hg.FirstSuffix.FullSuffix, qt.Equals, "_hg1")
  274 				c.Assert(si.Suffix, qt.Equals, "hg2")
  275 				c.Assert(si.FullSuffix, qt.Equals, "_hg2")
  276 				c.Assert(hg.String(), qt.Equals, "application/hugo+hg")
  277 
  278 				_, found = tt.GetByType("application/hugo+hg")
  279 				c.Assert(found, qt.Equals, true)
  280 			},
  281 		},
  282 		{
  283 			"Add custom media type",
  284 			[]map[string]any{
  285 				{
  286 					"text/hugo+hgo": map[string]any{
  287 						"Suffixes": []string{"hgo2"},
  288 					},
  289 				},
  290 			},
  291 			false,
  292 			func(t *testing.T, name string, tp Types) {
  293 				c.Assert(len(tp), qt.Equals, len(DefaultTypes)+1)
  294 				// Make sure we have not broken the default config.
  295 
  296 				_, _, found := tp.GetBySuffix("json")
  297 				c.Assert(found, qt.Equals, true)
  298 
  299 				hugo, _, found := tp.GetBySuffix("hgo2")
  300 				c.Assert(found, qt.Equals, true)
  301 				c.Assert(hugo.String(), qt.Equals, "text/hugo+hgo")
  302 			},
  303 		},
  304 	}
  305 
  306 	for _, test := range tests {
  307 		result, err := DecodeTypes(test.maps...)
  308 		if test.shouldError {
  309 			c.Assert(err, qt.Not(qt.IsNil))
  310 		} else {
  311 			c.Assert(err, qt.IsNil)
  312 			test.assert(t, test.name, result)
  313 		}
  314 	}
  315 }
  316 
  317 func TestToJSON(t *testing.T) {
  318 	c := qt.New(t)
  319 	b, err := json.Marshal(MPEGType)
  320 	c.Assert(err, qt.IsNil)
  321 	c.Assert(string(b), qt.Equals, `{"mainType":"video","subType":"mpeg","delimiter":".","firstSuffix":{"suffix":"mpg","fullSuffix":".mpg"},"type":"video/mpeg","string":"video/mpeg","suffixes":["mpg","mpeg"]}`)
  322 }
  323 
  324 func BenchmarkTypeOps(b *testing.B) {
  325 	mt := MPEGType
  326 	mts := DefaultTypes
  327 	for i := 0; i < b.N; i++ {
  328 		ff := mt.FirstSuffix
  329 		_ = ff.FullSuffix
  330 		_ = mt.IsZero()
  331 		c, err := mt.MarshalJSON()
  332 		if c == nil || err != nil {
  333 			b.Fatal("failed")
  334 		}
  335 		_ = mt.String()
  336 		_ = ff.Suffix
  337 		_ = mt.Suffixes
  338 		_ = mt.Type()
  339 		_ = mts.BySuffix("xml")
  340 		_, _ = mts.GetByMainSubType("application", "xml")
  341 		_, _, _ = mts.GetBySuffix("xml")
  342 		_, _ = mts.GetByType("application")
  343 		_, _, _ = mts.GetFirstBySuffix("xml")
  344 
  345 	}
  346 }