hugo/resources/page/permalinks_integration_test.go
2024-10-16 10:14:48 +02:00

270 lines
7.9 KiB
Go

// Copyright 2024 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package page_test
import (
"testing"
"github.com/bep/logg"
qt "github.com/frankban/quicktest"
"github.com/gohugoio/hugo/htesting"
"github.com/gohugoio/hugo/hugolib"
)
func TestPermalinks(t *testing.T) {
t.Parallel()
files := `
-- layouts/_default/list.html --
List|{{ .Kind }}|{{ .RelPermalink }}|
-- layouts/_default/single.html --
Single|{{ .Kind }}|{{ .RelPermalink }}|
-- hugo.toml --
[taxonomies]
tag = "tags"
[permalinks.page]
withpageslug = '/pageslug/:slug/'
withallbutlastsection = '/:sections[:last]/:slug/'
[permalinks.section]
withfilefilename = '/sectionwithfilefilename/:filename/'
withfilefiletitle = '/sectionwithfilefiletitle/:title/'
withfileslug = '/sectionwithfileslug/:slug/'
nofileslug = '/sectionnofileslug/:slug/'
nofilefilename = '/sectionnofilefilename/:filename/'
nofiletitle1 = '/sectionnofiletitle1/:title/'
nofiletitle2 = '/sectionnofiletitle2/:sections[:last]/'
[permalinks.term]
tags = '/tagsslug/tag/:slug/'
[permalinks.taxonomy]
tags = '/tagsslug/:slug/'
-- content/withpageslug/p1.md --
---
slug: "p1slugvalue"
tags: ["mytag"]
---
-- content/withfilefilename/_index.md --
-- content/withfileslug/_index.md --
---
slug: "withfileslugvalue"
---
-- content/nofileslug/p1.md --
-- content/nofilefilename/p1.md --
-- content/nofiletitle1/p1.md --
-- content/nofiletitle2/asdf/p1.md --
-- content/withallbutlastsection/subsection/p1.md --
-- content/tags/_index.md --
---
slug: "tagsslug"
---
-- content/tags/mytag/_index.md --
---
slug: "mytagslug"
---
`
b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{
T: t,
TxtarString: files,
LogLevel: logg.LevelWarn,
}).Build()
t.Log(b.LogString())
// No .File.TranslationBaseName on zero object etc. warnings.
b.Assert(b.H.Log.LoggCount(logg.LevelWarn), qt.Equals, 0)
b.AssertFileContent("public/pageslug/p1slugvalue/index.html", "Single|page|/pageslug/p1slugvalue/|")
b.AssertFileContent("public/sectionwithfilefilename/index.html", "List|section|/sectionwithfilefilename/|")
b.AssertFileContent("public/sectionwithfileslug/withfileslugvalue/index.html", "List|section|/sectionwithfileslug/withfileslugvalue/|")
b.AssertFileContent("public/sectionnofilefilename/index.html", "List|section|/sectionnofilefilename/|")
b.AssertFileContent("public/sectionnofileslug/nofileslugs/index.html", "List|section|/sectionnofileslug/nofileslugs/|")
b.AssertFileContent("public/sectionnofiletitle1/nofiletitle1s/index.html", "List|section|/sectionnofiletitle1/nofiletitle1s/|")
b.AssertFileContent("public/sectionnofiletitle2/index.html", "List|section|/sectionnofiletitle2/|")
b.AssertFileContent("public/tagsslug/tag/mytagslug/index.html", "List|term|/tagsslug/tag/mytagslug/|")
b.AssertFileContent("public/tagsslug/tagsslug/index.html", "List|taxonomy|/tagsslug/tagsslug/|")
permalinksConf := b.H.Configs.Base.Permalinks
b.Assert(permalinksConf, qt.DeepEquals, map[string]map[string]string{
"page": {"withallbutlastsection": "/:sections[:last]/:slug/", "withpageslug": "/pageslug/:slug/"},
"section": {"nofilefilename": "/sectionnofilefilename/:filename/", "nofileslug": "/sectionnofileslug/:slug/", "nofiletitle1": "/sectionnofiletitle1/:title/", "nofiletitle2": "/sectionnofiletitle2/:sections[:last]/", "withfilefilename": "/sectionwithfilefilename/:filename/", "withfilefiletitle": "/sectionwithfilefiletitle/:title/", "withfileslug": "/sectionwithfileslug/:slug/"},
"taxonomy": {"tags": "/tagsslug/:slug/"},
"term": {"tags": "/tagsslug/tag/:slug/"},
})
}
func TestPermalinksOldSetup(t *testing.T) {
t.Parallel()
files := `
-- layouts/_default/list.html --
List|{{ .Kind }}|{{ .RelPermalink }}|
-- layouts/_default/single.html --
Single|{{ .Kind }}|{{ .RelPermalink }}|
-- hugo.toml --
[permalinks]
withpageslug = '/pageslug/:slug/'
-- content/withpageslug/p1.md --
---
slug: "p1slugvalue"
---
`
b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{
T: t,
TxtarString: files,
LogLevel: logg.LevelWarn,
}).Build()
t.Log(b.LogString())
// No .File.TranslationBaseName on zero object etc. warnings.
b.Assert(b.H.Log.LoggCount(logg.LevelWarn), qt.Equals, 0)
b.AssertFileContent("public/pageslug/p1slugvalue/index.html", "Single|page|/pageslug/p1slugvalue/|")
permalinksConf := b.H.Configs.Base.Permalinks
b.Assert(permalinksConf, qt.DeepEquals, map[string]map[string]string{
"page": {"withpageslug": "/pageslug/:slug/"},
"section": {},
"taxonomy": {},
"term": {"withpageslug": "/pageslug/:slug/"},
})
}
func TestPermalinksNestedSections(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
[permalinks.page]
books = '/libros/:sections[1:]/:filename'
[permalinks.section]
books = '/libros/:sections[1:]'
-- content/books/_index.md --
---
title: Books
---
-- content/books/fiction/_index.md --
---
title: Fiction
---
-- content/books/fiction/2023/_index.md --
---
title: 2023
---
-- content/books/fiction/2023/book1/index.md --
---
title: Book 1
---
-- layouts/_default/single.html --
Single.
-- layouts/_default/list.html --
List.
`
b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{
T: t,
TxtarString: files,
LogLevel: logg.LevelWarn,
}).Build()
t.Log(b.LogString())
// No .File.TranslationBaseName on zero object etc. warnings.
b.Assert(b.H.Log.LoggCount(logg.LevelWarn), qt.Equals, 0)
b.AssertFileContent("public/libros/index.html", "List.")
b.AssertFileContent("public/libros/fiction/index.html", "List.")
b.AssertFileContent("public/libros/fiction/2023/book1/index.html", "Single.")
}
func TestPermalinksUrlCascade(t *testing.T) {
t.Parallel()
files := `
-- layouts/_default/list.html --
List|{{ .Kind }}|{{ .RelPermalink }}|
-- layouts/_default/single.html --
Single|{{ .Kind }}|{{ .RelPermalink }}|
-- hugo.toml --
-- content/cooking/delicious-recipes/_index.md --
---
url: /delicious-recipe/
cascade:
url: /delicious-recipe/:slug/
---
-- content/cooking/delicious-recipes/example1.md --
---
title: Recipe 1
---
-- content/cooking/delicious-recipes/example2.md --
---
title: Recipe 2
slug: custom-recipe-2
---
`
b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{
T: t,
TxtarString: files,
LogLevel: logg.LevelWarn,
}).Build()
t.Log(b.LogString())
b.Assert(b.H.Log.LoggCount(logg.LevelWarn), qt.Equals, 0)
b.AssertFileContent("public/delicious-recipe/index.html", "List|section|/delicious-recipe/")
b.AssertFileContent("public/delicious-recipe/recipe-1/index.html", "Single|page|/delicious-recipe/recipe-1/")
b.AssertFileContent("public/delicious-recipe/custom-recipe-2/index.html", "Single|page|/delicious-recipe/custom-recipe-2/")
}
// Issue 12948.
func TestPermalinksWithEscapedColons(t *testing.T) {
t.Parallel()
if htesting.IsWindows() {
t.Skip("Windows does not support colons in paths")
}
files := `
-- hugo.toml --
disableKinds = ['home','rss','section','sitemap','taxonomy','term']
[permalinks.page]
s2 = "/c\\:d/:slug/"
-- content/s1/p1.md --
---
title: p1
url: "/a\\:b/:slug/"
---
-- content/s2/p2.md --
---
title: p2
---
-- layouts/_default/single.html --
{{ .Title }}
`
b := hugolib.Test(t, files)
b.AssertFileExists("public/a:b/p1/index.html", true)
// The above URL comes from the URL front matter field where everything is allowed.
// We strip colons from paths constructed by Hugo (they are not supported on Windows).
b.AssertFileExists("public/cd/p2/index.html", true)
}