hugo

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

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

page_paths_test.go (11738B)

    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 page
   15 
   16 import (
   17 	"fmt"
   18 	"path/filepath"
   19 	"strings"
   20 	"testing"
   21 
   22 	"github.com/gohugoio/hugo/media"
   23 
   24 	"github.com/gohugoio/hugo/output"
   25 )
   26 
   27 func TestPageTargetPath(t *testing.T) {
   28 	pathSpec := newTestPathSpec()
   29 
   30 	noExtNoDelimMediaType := media.WithDelimiterAndSuffixes(media.TextType, "", "")
   31 	noExtNoDelimMediaType.Delimiter = ""
   32 
   33 	// Netlify style _redirects
   34 	noExtDelimFormat := output.Format{
   35 		Name:      "NER",
   36 		MediaType: noExtNoDelimMediaType,
   37 		BaseName:  "_redirects",
   38 	}
   39 
   40 	for _, langPrefixPath := range []string{"", "no"} {
   41 		for _, langPrefixLink := range []string{"", "no"} {
   42 			for _, uglyURLs := range []bool{false, true} {
   43 
   44 				tests := []struct {
   45 					name     string
   46 					d        TargetPathDescriptor
   47 					expected TargetPaths
   48 				}{
   49 					{"JSON home", TargetPathDescriptor{Kind: KindHome, Type: output.JSONFormat}, TargetPaths{TargetFilename: "/index.json", SubResourceBaseTarget: "", Link: "/index.json"}},
   50 					{"AMP home", TargetPathDescriptor{Kind: KindHome, Type: output.AMPFormat}, TargetPaths{TargetFilename: "/amp/index.html", SubResourceBaseTarget: "/amp", Link: "/amp/"}},
   51 					{"HTML home", TargetPathDescriptor{Kind: KindHome, BaseName: "_index", Type: output.HTMLFormat}, TargetPaths{TargetFilename: "/index.html", SubResourceBaseTarget: "", Link: "/"}},
   52 					{"Netlify redirects", TargetPathDescriptor{Kind: KindHome, BaseName: "_index", Type: noExtDelimFormat}, TargetPaths{TargetFilename: "/_redirects", SubResourceBaseTarget: "", Link: "/_redirects"}},
   53 					{"HTML section list", TargetPathDescriptor{
   54 						Kind:     KindSection,
   55 						Sections: []string{"sect1"},
   56 						BaseName: "_index",
   57 						Type:     output.HTMLFormat,
   58 					}, TargetPaths{TargetFilename: "/sect1/index.html", SubResourceBaseTarget: "/sect1", Link: "/sect1/"}},
   59 					{"HTML taxonomy term", TargetPathDescriptor{
   60 						Kind:     KindTerm,
   61 						Sections: []string{"tags", "hugo"},
   62 						BaseName: "_index",
   63 						Type:     output.HTMLFormat,
   64 					}, TargetPaths{TargetFilename: "/tags/hugo/index.html", SubResourceBaseTarget: "/tags/hugo", Link: "/tags/hugo/"}},
   65 					{"HTML taxonomy", TargetPathDescriptor{
   66 						Kind:     KindTaxonomy,
   67 						Sections: []string{"tags"},
   68 						BaseName: "_index",
   69 						Type:     output.HTMLFormat,
   70 					}, TargetPaths{TargetFilename: "/tags/index.html", SubResourceBaseTarget: "/tags", Link: "/tags/"}},
   71 					{
   72 						"HTML page", TargetPathDescriptor{
   73 							Kind:     KindPage,
   74 							Dir:      "/a/b",
   75 							BaseName: "mypage",
   76 							Sections: []string{"a"},
   77 							Type:     output.HTMLFormat,
   78 						}, TargetPaths{TargetFilename: "/a/b/mypage/index.html", SubResourceBaseTarget: "/a/b/mypage", Link: "/a/b/mypage/"},
   79 					},
   80 
   81 					{
   82 						"HTML page with index as base", TargetPathDescriptor{
   83 							Kind:     KindPage,
   84 							Dir:      "/a/b",
   85 							BaseName: "index",
   86 							Sections: []string{"a"},
   87 							Type:     output.HTMLFormat,
   88 						}, TargetPaths{TargetFilename: "/a/b/index.html", SubResourceBaseTarget: "/a/b", Link: "/a/b/"},
   89 					},
   90 
   91 					{
   92 						"HTML page with special chars", TargetPathDescriptor{
   93 							Kind:     KindPage,
   94 							Dir:      "/a/b",
   95 							BaseName: "My Page!",
   96 							Type:     output.HTMLFormat,
   97 						}, TargetPaths{TargetFilename: "/a/b/my-page/index.html", SubResourceBaseTarget: "/a/b/my-page", Link: "/a/b/my-page/"},
   98 					},
   99 					{"RSS home", TargetPathDescriptor{Kind: "rss", Type: output.RSSFormat}, TargetPaths{TargetFilename: "/index.xml", SubResourceBaseTarget: "", Link: "/index.xml"}},
  100 					{"RSS section list", TargetPathDescriptor{
  101 						Kind:     "rss",
  102 						Sections: []string{"sect1"},
  103 						Type:     output.RSSFormat,
  104 					}, TargetPaths{TargetFilename: "/sect1/index.xml", SubResourceBaseTarget: "/sect1", Link: "/sect1/index.xml"}},
  105 					{
  106 						"AMP page", TargetPathDescriptor{
  107 							Kind:     KindPage,
  108 							Dir:      "/a/b/c",
  109 							BaseName: "myamp",
  110 							Type:     output.AMPFormat,
  111 						}, TargetPaths{TargetFilename: "/amp/a/b/c/myamp/index.html", SubResourceBaseTarget: "/amp/a/b/c/myamp", Link: "/amp/a/b/c/myamp/"},
  112 					},
  113 					{
  114 						"AMP page with URL with suffix", TargetPathDescriptor{
  115 							Kind:     KindPage,
  116 							Dir:      "/sect/",
  117 							BaseName: "mypage",
  118 							URL:      "/some/other/url.xhtml",
  119 							Type:     output.HTMLFormat,
  120 						}, TargetPaths{TargetFilename: "/some/other/url.xhtml", SubResourceBaseTarget: "/some/other", Link: "/some/other/url.xhtml"},
  121 					},
  122 					{
  123 						"JSON page with URL without suffix", TargetPathDescriptor{
  124 							Kind:     KindPage,
  125 							Dir:      "/sect/",
  126 							BaseName: "mypage",
  127 							URL:      "/some/other/path/",
  128 							Type:     output.JSONFormat,
  129 						}, TargetPaths{TargetFilename: "/some/other/path/index.json", SubResourceBaseTarget: "/some/other/path", Link: "/some/other/path/index.json"},
  130 					},
  131 					{
  132 						"JSON page with URL without suffix and no trailing slash", TargetPathDescriptor{
  133 							Kind:     KindPage,
  134 							Dir:      "/sect/",
  135 							BaseName: "mypage",
  136 							URL:      "/some/other/path",
  137 							Type:     output.JSONFormat,
  138 						}, TargetPaths{TargetFilename: "/some/other/path/index.json", SubResourceBaseTarget: "/some/other/path", Link: "/some/other/path/index.json"},
  139 					},
  140 					{
  141 						"HTML page with URL without suffix and no trailing slash", TargetPathDescriptor{
  142 							Kind:     KindPage,
  143 							Dir:      "/sect/",
  144 							BaseName: "mypage",
  145 							URL:      "/some/other/path",
  146 							Type:     output.HTMLFormat,
  147 						}, TargetPaths{TargetFilename: "/some/other/path/index.html", SubResourceBaseTarget: "/some/other/path", Link: "/some/other/path/"},
  148 					},
  149 					{
  150 						"HTML page with URL containing double hyphen", TargetPathDescriptor{
  151 							Kind:     KindPage,
  152 							Dir:      "/sect/",
  153 							BaseName: "mypage",
  154 							URL:      "/some/other--url/",
  155 							Type:     output.HTMLFormat,
  156 						}, TargetPaths{TargetFilename: "/some/other--url/index.html", SubResourceBaseTarget: "/some/other--url", Link: "/some/other--url/"},
  157 					},
  158 					{
  159 						"HTML page with expanded permalink", TargetPathDescriptor{
  160 							Kind:              KindPage,
  161 							Dir:               "/a/b",
  162 							BaseName:          "mypage",
  163 							ExpandedPermalink: "/2017/10/my-title/",
  164 							Type:              output.HTMLFormat,
  165 						}, TargetPaths{TargetFilename: "/2017/10/my-title/index.html", SubResourceBaseTarget: "/2017/10/my-title", Link: "/2017/10/my-title/"},
  166 					},
  167 					{
  168 						"Paginated HTML home", TargetPathDescriptor{
  169 							Kind:     KindHome,
  170 							BaseName: "_index",
  171 							Type:     output.HTMLFormat,
  172 							Addends:  "page/3",
  173 						}, TargetPaths{TargetFilename: "/page/3/index.html", SubResourceBaseTarget: "/page/3", Link: "/page/3/"},
  174 					},
  175 					{
  176 						"Paginated Taxonomy terms list", TargetPathDescriptor{
  177 							Kind:     KindTerm,
  178 							BaseName: "_index",
  179 							Sections: []string{"tags", "hugo"},
  180 							Type:     output.HTMLFormat,
  181 							Addends:  "page/3",
  182 						}, TargetPaths{TargetFilename: "/tags/hugo/page/3/index.html", SubResourceBaseTarget: "/tags/hugo/page/3", Link: "/tags/hugo/page/3/"},
  183 					},
  184 					{
  185 						"Regular page with addend", TargetPathDescriptor{
  186 							Kind:     KindPage,
  187 							Dir:      "/a/b",
  188 							BaseName: "mypage",
  189 							Addends:  "c/d/e",
  190 							Type:     output.HTMLFormat,
  191 						}, TargetPaths{TargetFilename: "/a/b/mypage/c/d/e/index.html", SubResourceBaseTarget: "/a/b/mypage/c/d/e", Link: "/a/b/mypage/c/d/e/"},
  192 					},
  193 				}
  194 
  195 				for i, test := range tests {
  196 					t.Run(fmt.Sprintf("langPrefixPath=%s,langPrefixLink=%s,uglyURLs=%t,name=%s", langPrefixPath, langPrefixLink, uglyURLs, test.name),
  197 						func(t *testing.T) {
  198 							test.d.ForcePrefix = true
  199 							test.d.PathSpec = pathSpec
  200 							test.d.UglyURLs = uglyURLs
  201 							test.d.PrefixFilePath = langPrefixPath
  202 							test.d.PrefixLink = langPrefixLink
  203 							test.d.Dir = filepath.FromSlash(test.d.Dir)
  204 							isUgly := uglyURLs && !test.d.Type.NoUgly
  205 
  206 							expected := test.expected
  207 
  208 							// TODO(bep) simplify
  209 							if test.d.Kind == KindPage && test.d.BaseName == test.d.Type.BaseName {
  210 							} else if test.d.Kind == KindHome && test.d.Type.Path != "" {
  211 							} else if test.d.Type.MediaType.FirstSuffix.Suffix != "" && (!strings.HasPrefix(expected.TargetFilename, "/index") || test.d.Addends != "") && test.d.URL == "" && isUgly {
  212 								expected.TargetFilename = strings.Replace(expected.TargetFilename,
  213 									"/"+test.d.Type.BaseName+"."+test.d.Type.MediaType.FirstSuffix.Suffix,
  214 									"."+test.d.Type.MediaType.FirstSuffix.Suffix, 1)
  215 								expected.Link = strings.TrimSuffix(expected.Link, "/") + "." + test.d.Type.MediaType.FirstSuffix.Suffix
  216 
  217 							}
  218 
  219 							if test.d.PrefixFilePath != "" && !strings.HasPrefix(test.d.URL, "/"+test.d.PrefixFilePath) {
  220 								expected.TargetFilename = "/" + test.d.PrefixFilePath + expected.TargetFilename
  221 								expected.SubResourceBaseTarget = "/" + test.d.PrefixFilePath + expected.SubResourceBaseTarget
  222 							}
  223 
  224 							if test.d.PrefixLink != "" && !strings.HasPrefix(test.d.URL, "/"+test.d.PrefixLink) {
  225 								expected.Link = "/" + test.d.PrefixLink + expected.Link
  226 							}
  227 
  228 							expected.TargetFilename = filepath.FromSlash(expected.TargetFilename)
  229 							expected.SubResourceBaseTarget = filepath.FromSlash(expected.SubResourceBaseTarget)
  230 
  231 							pagePath := CreateTargetPaths(test.d)
  232 
  233 							if !eqTargetPaths(pagePath, expected) {
  234 								t.Fatalf("[%d] [%s] targetPath expected\n%#v, got:\n%#v", i, test.name, expected, pagePath)
  235 							}
  236 						})
  237 				}
  238 			}
  239 		}
  240 	}
  241 }
  242 
  243 func TestPageTargetPathPrefix(t *testing.T) {
  244 	pathSpec := newTestPathSpec()
  245 	tests := []struct {
  246 		name     string
  247 		d        TargetPathDescriptor
  248 		expected TargetPaths
  249 	}{
  250 		{
  251 			"URL set, prefix both, no force",
  252 			TargetPathDescriptor{Kind: KindPage, Type: output.JSONFormat, URL: "/mydir/my.json", ForcePrefix: false, PrefixFilePath: "pf", PrefixLink: "pl"},
  253 			TargetPaths{TargetFilename: "/mydir/my.json", SubResourceBaseTarget: "/mydir", SubResourceBaseLink: "/mydir", Link: "/mydir/my.json"},
  254 		},
  255 		{
  256 			"URL set, prefix both, force",
  257 			TargetPathDescriptor{Kind: KindPage, Type: output.JSONFormat, URL: "/mydir/my.json", ForcePrefix: true, PrefixFilePath: "pf", PrefixLink: "pl"},
  258 			TargetPaths{TargetFilename: "/pf/mydir/my.json", SubResourceBaseTarget: "/pf/mydir", SubResourceBaseLink: "/pl/mydir", Link: "/pl/mydir/my.json"},
  259 		},
  260 	}
  261 
  262 	for i, test := range tests {
  263 		t.Run(fmt.Sprintf(test.name),
  264 			func(t *testing.T) {
  265 				test.d.PathSpec = pathSpec
  266 				expected := test.expected
  267 				expected.TargetFilename = filepath.FromSlash(expected.TargetFilename)
  268 				expected.SubResourceBaseTarget = filepath.FromSlash(expected.SubResourceBaseTarget)
  269 
  270 				pagePath := CreateTargetPaths(test.d)
  271 
  272 				if pagePath != expected {
  273 					t.Fatalf("[%d] [%s] targetPath expected\n%#v, got:\n%#v", i, test.name, expected, pagePath)
  274 				}
  275 			})
  276 	}
  277 }
  278 
  279 func eqTargetPaths(p1, p2 TargetPaths) bool {
  280 	if p1.Link != p2.Link {
  281 		return false
  282 	}
  283 
  284 	if p1.SubResourceBaseTarget != p2.SubResourceBaseTarget {
  285 		return false
  286 	}
  287 
  288 	if p1.TargetFilename != p2.TargetFilename {
  289 		return false
  290 	}
  291 
  292 	return true
  293 }