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