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