// Copyright 2016 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 hugolib
import (
"fmt"
"path/filepath"
"strings"
"testing"
"time"
"github.com/spf13/afero"
"github.com/spf13/hugo/deps"
"github.com/spf13/hugo/hugofs"
"github.com/stretchr/testify/require"
)
/*
This file will test the "making everything a page" transition.
See https://github.com/spf13/hugo/issues/2297
*/
func TestNodesAsPage(t *testing.T) {
t.Parallel()
for _, preserveTaxonomyNames := range []bool{false, true} {
for _, ugly := range []bool{true, false} {
doTestNodeAsPage(t, ugly, preserveTaxonomyNames)
}
}
}
func doTestNodeAsPage(t *testing.T, ugly, preserveTaxonomyNames bool) {
/* Will have to decide what to name the node content files, but:
Home page should have:
Content, shortcode support
Metadata (title, dates etc.)
Params
Taxonomies (categories, tags)
*/
var (
cfg, fs = newTestCfg()
th = testHelper{cfg, fs, t}
)
cfg.Set("uglyURLs", ugly)
cfg.Set("preserveTaxonomyNames", preserveTaxonomyNames)
cfg.Set("paginate", 1)
cfg.Set("title", "Hugo Rocks")
cfg.Set("rssURI", "customrss.xml")
writeLayoutsForNodeAsPageTests(t, fs)
writeNodePagesForNodeAsPageTests(t, fs, "")
writeRegularPagesForNodeAsPageTests(t, fs)
sites, err := NewHugoSites(deps.DepsCfg{Fs: fs, Cfg: cfg})
require.NoError(t, err)
require.NoError(t, sites.Build(BuildCfg{}))
// date order: home, sect1, sect2, cat/hugo, cat/web, categories
th.assertFileContent(filepath.Join("public", "index.html"),
"Index Title: Home Sweet Home!",
"Home Content!",
"# Pages: 4",
"Date: 2009-01-02",
"Lastmod: 2009-01-03",
"GetPage: Section1 ",
)
th.assertFileContent(expectedFilePath(ugly, "public", "sect1", "regular1"), "Single Title: Page 01", "Content Page 01")
nodes := sites.findAllPagesByKindNotIn(KindPage)
require.Len(t, nodes, 8)
home := nodes[7] // oldest
require.True(t, home.IsHome())
require.True(t, home.IsNode())
require.False(t, home.IsPage())
require.True(t, home.Path() != "")
section2 := nodes[5]
require.Equal(t, "Section2", section2.Title)
pages := sites.findAllPagesByKind(KindPage)
require.Len(t, pages, 4)
first := pages[0]
require.False(t, first.IsHome())
require.False(t, first.IsNode())
require.True(t, first.IsPage())
// Check Home paginator
th.assertFileContent(expectedFilePath(ugly, "public", "page", "2"),
"Pag: Page 02")
// Check Sections
th.assertFileContent(expectedFilePath(ugly, "public", "sect1"),
"Section Title: Section", "Section1 Content!",
"Date: 2009-01-04",
"Lastmod: 2009-01-05",
)
th.assertFileContent(expectedFilePath(ugly, "public", "sect2"),
"Section Title: Section", "Section2 Content!",
"Date: 2009-01-06",
"Lastmod: 2009-01-07",
)
// Check Sections paginator
th.assertFileContent(expectedFilePath(ugly, "public", "sect1", "page", "2"),
"Pag: Page 02")
sections := sites.findAllPagesByKind(KindSection)
require.Len(t, sections, 2)
// Check taxonomy lists
th.assertFileContent(expectedFilePath(ugly, "public", "categories", "hugo"),
"Taxonomy Title: Taxonomy Hugo", "Taxonomy Hugo Content!",
"Date: 2009-01-08",
"Lastmod: 2009-01-09",
)
th.assertFileContent(expectedFilePath(ugly, "public", "categories", "hugo-rocks"),
"Taxonomy Title: Taxonomy Hugo Rocks",
)
s := sites.Sites[0]
web := s.getPage(KindTaxonomy, "categories", "web")
require.NotNil(t, web)
require.Len(t, web.Data["Pages"].(Pages), 4)
th.assertFileContent(expectedFilePath(ugly, "public", "categories", "web"),
"Taxonomy Title: Taxonomy Web",
"Taxonomy Web Content!",
"Date: 2009-01-10",
"Lastmod: 2009-01-11",
)
// Check taxonomy list paginator
th.assertFileContent(expectedFilePath(ugly, "public", "categories", "hugo", "page", "2"),
"Taxonomy Title: Taxonomy Hugo",
"Pag: Page 02")
// Check taxonomy terms
th.assertFileContent(expectedFilePath(ugly, "public", "categories"),
"Taxonomy Terms Title: Taxonomy Term Categories", "Taxonomy Term Categories Content!", "k/v: hugo",
"Date: 2009-01-14",
"Lastmod: 2009-01-15",
)
// There are no pages to paginate over in the taxonomy terms.
// RSS
th.assertFileContent(filepath.Join("public", "customrss.xml"), "Recent content in Home Sweet Home! on Hugo Rocks", "Content!")
th.assertFileContent(filepath.Join("public", "de", "index.html"),
"Index Title: Home Sweet Home!", "Content!")
// Taxonomy list
th.assertFileContent(expectedFilePath(ugly, "public", "nn", "categories", "hugo"),
"Taxonomy Title: Hugo")
th.assertFileContent(expectedFilePath(ugly, "public", "en", "categories", "hugo"),
"Taxonomy Title: Taxonomy Hugo")
// Taxonomy terms
th.assertFileContent(expectedFilePath(ugly, "public", "nn", "categories"),
"Taxonomy Terms Title: Categories")
th.assertFileContent(expectedFilePath(ugly, "public", "en", "categories"),
"Taxonomy Terms Title: Taxonomy Term Categories")
// Sections
th.assertFileContent(expectedFilePath(ugly, "public", "nn", "sect1"),
"Section Title: Sect1s")
th.assertFileContent(expectedFilePath(ugly, "public", "nn", "sect2"),
"Section Title: Sect2s")
th.assertFileContent(expectedFilePath(ugly, "public", "en", "sect1"),
"Section Title: Section1")
th.assertFileContent(expectedFilePath(ugly, "public", "en", "sect2"),
"Section Title: Section2")
// Regular pages
th.assertFileContent(expectedFilePath(ugly, "public", "en", "sect1", "regular1"),
"Single Title: Page 01")
th.assertFileContent(expectedFilePath(ugly, "public", "nn", "sect1", "regular2"),
"Single Title: Page 02")
// RSS
th.assertFileContent(filepath.Join("public", "nn", "customrss.xml"), "Hugo på norsk", " 2 {
sect = "sect2"
date, _ = time.Parse(format, "2008-07-15") // Nodes are placed in 2009
}
date = date.Add(-24 * time.Duration(i) * time.Hour)
writeSource(t, fs, filepath.Join("content", sect, fmt.Sprintf("regular%d.%smd", i, langStr)), fmt.Sprintf(`---
title: Page %02d
lastMod : %q
date : %q
categories: [
"Hugo",
"Web",
"Hugo Rocks!"
]
---
Content Page %02d
`, i, date.Add(time.Duration(i)*-24*time.Hour).Format(time.RFC822), date.Add(time.Duration(i)*-2*24*time.Hour).Format(time.RFC822), i))
}
}
func writeNodePagesForNodeAsPageTests(t *testing.T, fs *hugofs.Fs, lang string) {
filename := "_index.md"
if lang != "" {
filename = fmt.Sprintf("_index.%s.md", lang)
}
format := "2006-01-02"
date, _ := time.Parse(format, "2009-01-01")
writeSource(t, fs, filepath.Join("content", filename), fmt.Sprintf(`---
title: Home Sweet Home!
date : %q
lastMod : %q
---
l-%s Home **Content!**
`, date.Add(1*24*time.Hour).Format(time.RFC822), date.Add(2*24*time.Hour).Format(time.RFC822), lang))
writeSource(t, fs, filepath.Join("content", "sect1", filename), fmt.Sprintf(`---
title: Section1
date : %q
lastMod : %q
---
Section1 **Content!**
`, date.Add(3*24*time.Hour).Format(time.RFC822), date.Add(4*24*time.Hour).Format(time.RFC822)))
writeSource(t, fs, filepath.Join("content", "sect2", filename), fmt.Sprintf(`---
title: Section2
date : %q
lastMod : %q
---
Section2 **Content!**
`, date.Add(5*24*time.Hour).Format(time.RFC822), date.Add(6*24*time.Hour).Format(time.RFC822)))
writeSource(t, fs, filepath.Join("content", "categories", "hugo", filename), fmt.Sprintf(`---
title: Taxonomy Hugo
date : %q
lastMod : %q
---
Taxonomy Hugo **Content!**
`, date.Add(7*24*time.Hour).Format(time.RFC822), date.Add(8*24*time.Hour).Format(time.RFC822)))
writeSource(t, fs, filepath.Join("content", "categories", "web", filename), fmt.Sprintf(`---
title: Taxonomy Web
date : %q
lastMod : %q
---
Taxonomy Web **Content!**
`, date.Add(9*24*time.Hour).Format(time.RFC822), date.Add(10*24*time.Hour).Format(time.RFC822)))
writeSource(t, fs, filepath.Join("content", "categories", "hugo-rocks", filename), fmt.Sprintf(`---
title: Taxonomy Hugo Rocks
date : %q
lastMod : %q
---
Taxonomy Hugo Rocks **Content!**
`, date.Add(11*24*time.Hour).Format(time.RFC822), date.Add(12*24*time.Hour).Format(time.RFC822)))
writeSource(t, fs, filepath.Join("content", "categories", filename), fmt.Sprintf(`---
title: Taxonomy Term Categories
date : %q
lastMod : %q
---
Taxonomy Term Categories **Content!**
`, date.Add(13*24*time.Hour).Format(time.RFC822), date.Add(14*24*time.Hour).Format(time.RFC822)))
writeSource(t, fs, filepath.Join("content", "tags", filename), fmt.Sprintf(`---
title: Taxonomy Term Tags
date : %q
lastMod : %q
---
Taxonomy Term Tags **Content!**
`, date.Add(15*24*time.Hour).Format(time.RFC822), date.Add(16*24*time.Hour).Format(time.RFC822)))
}
func writeLayoutsForNodeAsPageTests(t *testing.T, fs *hugofs.Fs) {
writeSource(t, fs, filepath.Join("layouts", "index.html"), `
Index Title: {{ .Title }}
Index Content: {{ .Content }}
# Pages: {{ len .Data.Pages }}
{{ range .Paginator.Pages }}
Pag: {{ .Title }}
{{ end }}
{{ with .Site.Menus.mymenu }}
{{ range . }}
Home Menu Item: {{ .Name }}: {{ .URL }}
{{ end }}
{{ end }}
Date: {{ .Date.Format "2006-01-02" }}
Lastmod: {{ .Lastmod.Format "2006-01-02" }}
GetPage: {{ with .Site.GetPage "section" "sect1" }}{{ .Title }}{{ end }}
`)
writeSource(t, fs, filepath.Join("layouts", "_default", "single.html"), `
Single Title: {{ .Title }}
Single Content: {{ .Content }}
Date: {{ .Date.Format "2006-01-02" }}
Lastmod: {{ .Lastmod.Format "2006-01-02" }}
`)
writeSource(t, fs, filepath.Join("layouts", "_default", "section.html"), `
Section Title: {{ .Title }}
Section Content: {{ .Content }}
# Pages: {{ len .Data.Pages }}
{{ range .Paginator.Pages }}
Pag: {{ .Title }}
{{ end }}
{{ with .Site.Menus.mymenu }}
{{ range . }}
Section Menu Item: {{ .Name }}: {{ .URL }}
{{ end }}
{{ end }}
Date: {{ .Date.Format "2006-01-02" }}
Lastmod: {{ .Lastmod.Format "2006-01-02" }}
`)
// Taxonomy lists
writeSource(t, fs, filepath.Join("layouts", "_default", "taxonomy.html"), `
Taxonomy Title: {{ .Title }}
Taxonomy Content: {{ .Content }}
# Pages: {{ len .Data.Pages }}
{{ range .Paginator.Pages }}
Pag: {{ .Title }}
{{ end }}
{{ with .Site.Menus.mymenu }}
{{ range . }}
Taxonomy Menu Item: {{ .Name }}: {{ .URL }}
{{ end }}
{{ end }}
Date: {{ .Date.Format "2006-01-02" }}
Lastmod: {{ .Lastmod.Format "2006-01-02" }}
`)
// Taxonomy terms
writeSource(t, fs, filepath.Join("layouts", "_default", "terms.html"), `
Taxonomy Terms Title: {{ .Title }}
Taxonomy Terms Content: {{ .Content }}
{{ range $key, $value := .Data.Terms }}
k/v: {{ $key | lower }} / {{ printf "%s" $value }}
{{ end }}
{{ with .Site.Menus.mymenu }}
{{ range . }}
Taxonomy Terms Menu Item: {{ .Name }}: {{ .URL }}
{{ end }}
{{ end }}
Date: {{ .Date.Format "2006-01-02" }}
Lastmod: {{ .Lastmod.Format "2006-01-02" }}
`)
}
func expectedFilePath(ugly bool, path ...string) string {
if ugly {
return filepath.Join(append(path[0:len(path)-1], path[len(path)-1]+".html")...)
}
return filepath.Join(append(path, "index.html")...)
}
func expetedPermalink(ugly bool, path string) string {
if ugly {
return strings.TrimSuffix(path, "/") + ".html"
}
return path
}