// Copyright 2019 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" "testing" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/resources/page" ) func TestDisable(t *testing.T) { c := qt.New(t) newSitesBuilder := func(c *qt.C, disableKind string) *sitesBuilder { config := fmt.Sprintf(` baseURL = "http://example.com/blog" enableRobotsTXT = true ignoreErrors = ["error-disable-taxonomy"] disableKinds = [%q] `, disableKind) b := newTestSitesBuilder(c) b.WithTemplatesAdded("_default/single.html", `single`) b.WithConfigFile("toml", config).WithContent("sect/page.md", ` --- title: Page categories: ["mycat"] tags: ["mytag"] --- `, "sect/no-list.md", ` --- title: No List _build: list: false --- `, "sect/no-render.md", ` --- title: No List _build: render: false --- `, "sect/no-render-link.md", ` --- title: No Render Link aliases: ["/link-alias"] _build: render: link --- `, "sect/no-publishresources/index.md", ` --- title: No Publish Resources _build: publishResources: false --- `, "sect/headlessbundle/index.md", ` --- title: Headless headless: true --- `, "headless-local/_index.md", ` --- title: Headless Local Lists cascade: _build: render: false list: local publishResources: false --- `, "headless-local/headless-local-page.md", "---\ntitle: Headless Local Page\n---", "headless-local/sub/_index.md", ` --- title: Headless Local Lists Sub --- `, "headless-local/sub/headless-local-sub-page.md", "---\ntitle: Headless Local Sub Page\n---", ) b.WithSourceFile("content/sect/headlessbundle/data.json", "DATA") b.WithSourceFile("content/sect/no-publishresources/data.json", "DATA") return b } getPage := func(b *sitesBuilder, ref string) page.Page { b.Helper() p, err := b.H.Sites[0].getPageNew(nil, ref) b.Assert(err, qt.IsNil) return p } getPageInSitePages := func(b *sitesBuilder, ref string) page.Page { b.Helper() for _, pages := range []page.Pages{b.H.Sites[0].Pages(), b.H.Sites[0].RegularPages()} { for _, p := range pages { if ref == p.(*pageState).sourceRef() { return p } } } return nil } getPageInPagePages := func(p page.Page, ref string, pageCollections ...page.Pages) page.Page { if len(pageCollections) == 0 { pageCollections = []page.Pages{p.Pages(), p.RegularPages(), p.RegularPagesRecursive(), p.Sections()} } for _, pages := range pageCollections { for _, p := range pages { if ref == p.(*pageState).sourceRef() { return p } } } return nil } disableKind := page.KindPage c.Run("Disable "+disableKind, func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) s := b.H.Sites[0] b.Assert(getPage(b, "/sect/page.md"), qt.IsNil) b.Assert(b.CheckExists("public/sect/page/index.html"), qt.Equals, false) b.Assert(getPageInSitePages(b, "/sect/page.md"), qt.IsNil) b.Assert(getPageInPagePages(getPage(b, "/"), "/sect/page.md"), qt.IsNil) // Also check the side effects b.Assert(b.CheckExists("public/categories/mycat/index.html"), qt.Equals, false) b.Assert(len(s.Taxonomies()["categories"]), qt.Equals, 0) }) disableKind = page.KindTerm c.Run("Disable "+disableKind, func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) s := b.H.Sites[0] b.Assert(b.CheckExists("public/categories/index.html"), qt.Equals, true) b.Assert(b.CheckExists("public/categories/mycat/index.html"), qt.Equals, false) b.Assert(len(s.Taxonomies()["categories"]), qt.Equals, 0) b.Assert(getPage(b, "/categories"), qt.Not(qt.IsNil)) b.Assert(getPage(b, "/categories/mycat"), qt.IsNil) }) disableKind = page.KindTaxonomy c.Run("Disable "+disableKind, func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) s := b.H.Sites[0] b.Assert(b.CheckExists("public/categories/mycat/index.html"), qt.Equals, true) b.Assert(b.CheckExists("public/categories/index.html"), qt.Equals, false) b.Assert(len(s.Taxonomies()["categories"]), qt.Equals, 1) b.Assert(getPage(b, "/categories/mycat"), qt.Not(qt.IsNil)) categories := getPage(b, "/categories") b.Assert(categories, qt.Not(qt.IsNil)) b.Assert(categories.RelPermalink(), qt.Equals, "") b.Assert(getPageInSitePages(b, "/categories"), qt.IsNil) b.Assert(getPageInPagePages(getPage(b, "/"), "/categories"), qt.IsNil) }) disableKind = page.KindHome c.Run("Disable "+disableKind, func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) b.Assert(b.CheckExists("public/index.html"), qt.Equals, false) home := getPage(b, "/") b.Assert(home, qt.Not(qt.IsNil)) b.Assert(home.RelPermalink(), qt.Equals, "") b.Assert(getPageInSitePages(b, "/"), qt.IsNil) b.Assert(getPageInPagePages(home, "/"), qt.IsNil) b.Assert(getPage(b, "/sect/page.md"), qt.Not(qt.IsNil)) }) disableKind = page.KindSection c.Run("Disable "+disableKind, func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) b.Assert(b.CheckExists("public/sect/index.html"), qt.Equals, false) sect := getPage(b, "/sect") b.Assert(sect, qt.Not(qt.IsNil)) b.Assert(sect.RelPermalink(), qt.Equals, "") b.Assert(getPageInSitePages(b, "/sect"), qt.IsNil) home := getPage(b, "/") b.Assert(getPageInPagePages(home, "/sect"), qt.IsNil) b.Assert(home.OutputFormats(), qt.HasLen, 2) page := getPage(b, "/sect/page.md") b.Assert(page, qt.Not(qt.IsNil)) b.Assert(page.CurrentSection(), qt.Equals, sect) b.Assert(getPageInPagePages(sect, "/sect/page.md"), qt.Not(qt.IsNil)) b.AssertFileContent("public/sitemap.xml", "sitemap") b.AssertFileContent("public/index.xml", "rss") }) disableKind = kindRSS c.Run("Disable "+disableKind, func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) b.Assert(b.CheckExists("public/index.xml"), qt.Equals, false) home := getPage(b, "/") b.Assert(home.OutputFormats(), qt.HasLen, 1) }) disableKind = kindSitemap c.Run("Disable "+disableKind, func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) b.Assert(b.CheckExists("public/sitemap.xml"), qt.Equals, false) }) disableKind = kind404 c.Run("Disable "+disableKind, func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) b.Assert(b.CheckExists("public/404.html"), qt.Equals, false) }) disableKind = kindRobotsTXT c.Run("Disable "+disableKind, func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.WithTemplatesAdded("robots.txt", "myrobots") b.Build(BuildCfg{}) b.Assert(b.CheckExists("public/robots.txt"), qt.Equals, false) }) c.Run("Headless bundle", func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) b.Assert(b.CheckExists("public/sect/headlessbundle/index.html"), qt.Equals, false) b.Assert(b.CheckExists("public/sect/headlessbundle/data.json"), qt.Equals, true) bundle := getPage(b, "/sect/headlessbundle/index.md") b.Assert(bundle, qt.Not(qt.IsNil)) b.Assert(bundle.RelPermalink(), qt.Equals, "") resource := bundle.Resources()[0] b.Assert(resource.RelPermalink(), qt.Equals, "/blog/sect/headlessbundle/data.json") b.Assert(bundle.OutputFormats(), qt.HasLen, 0) b.Assert(bundle.AlternativeOutputFormats(), qt.HasLen, 0) }) c.Run("Build config, no list", func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) ref := "/sect/no-list.md" b.Assert(b.CheckExists("public/sect/no-list/index.html"), qt.Equals, true) p := getPage(b, ref) b.Assert(p, qt.Not(qt.IsNil)) b.Assert(p.RelPermalink(), qt.Equals, "/blog/sect/no-list/") b.Assert(getPageInSitePages(b, ref), qt.IsNil) sect := getPage(b, "/sect") b.Assert(getPageInPagePages(sect, ref), qt.IsNil) }) c.Run("Build config, local list", func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) ref := "/headless-local" sect := getPage(b, ref) b.Assert(sect, qt.Not(qt.IsNil)) b.Assert(getPageInSitePages(b, ref), qt.IsNil) b.Assert(getPageInSitePages(b, "/headless-local/_index.md"), qt.IsNil) b.Assert(getPageInSitePages(b, "/headless-local/headless-local-page.md"), qt.IsNil) localPageRef := ref + "/headless-local-page.md" b.Assert(getPageInPagePages(sect, localPageRef, sect.RegularPages()), qt.Not(qt.IsNil)) b.Assert(getPageInPagePages(sect, localPageRef, sect.RegularPagesRecursive()), qt.Not(qt.IsNil)) b.Assert(getPageInPagePages(sect, localPageRef, sect.Pages()), qt.Not(qt.IsNil)) ref = "/headless-local/sub" sect = getPage(b, ref) b.Assert(sect, qt.Not(qt.IsNil)) localPageRef = ref + "/headless-local-sub-page.md" b.Assert(getPageInPagePages(sect, localPageRef), qt.Not(qt.IsNil)) }) c.Run("Build config, no render", func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) ref := "/sect/no-render.md" b.Assert(b.CheckExists("public/sect/no-render/index.html"), qt.Equals, false) p := getPage(b, ref) b.Assert(p, qt.Not(qt.IsNil)) b.Assert(p.RelPermalink(), qt.Equals, "") b.Assert(p.OutputFormats(), qt.HasLen, 0) b.Assert(getPageInSitePages(b, ref), qt.Not(qt.IsNil)) sect := getPage(b, "/sect") b.Assert(getPageInPagePages(sect, ref), qt.Not(qt.IsNil)) }) c.Run("Build config, no render link", func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) ref := "/sect/no-render-link.md" b.Assert(b.CheckExists("public/sect/no-render/index.html"), qt.Equals, false) p := getPage(b, ref) b.Assert(p, qt.Not(qt.IsNil)) b.Assert(p.RelPermalink(), qt.Equals, "/blog/sect/no-render-link/") b.Assert(p.OutputFormats(), qt.HasLen, 1) b.Assert(getPageInSitePages(b, ref), qt.Not(qt.IsNil)) sect := getPage(b, "/sect") b.Assert(getPageInPagePages(sect, ref), qt.Not(qt.IsNil)) // https://github.com/gohugoio/hugo/issues/7832 // It should still render any aliases. b.AssertFileContent("public/link-alias/index.html", "refresh") }) c.Run("Build config, no publish resources", func(c *qt.C) { b := newSitesBuilder(c, disableKind) b.Build(BuildCfg{}) b.Assert(b.CheckExists("public/sect/no-publishresources/index.html"), qt.Equals, true) b.Assert(b.CheckExists("public/sect/no-publishresources/data.json"), qt.Equals, false) bundle := getPage(b, "/sect/no-publishresources/index.md") b.Assert(bundle, qt.Not(qt.IsNil)) b.Assert(bundle.RelPermalink(), qt.Equals, "/blog/sect/no-publishresources/") b.Assert(bundle.Resources(), qt.HasLen, 1) resource := bundle.Resources()[0] b.Assert(resource.RelPermalink(), qt.Equals, "/blog/sect/no-publishresources/data.json") }) } // https://github.com/gohugoio/hugo/issues/6897#issuecomment-587947078 func TestDisableRSSWithRSSInCustomOutputs(t *testing.T) { b := newTestSitesBuilder(t).WithConfigFile("toml", ` disableKinds = ["term", "taxonomy", "RSS"] [outputs] home = [ "HTML", "RSS" ] `).Build(BuildCfg{}) // The config above is a little conflicting, but it exists in the real world. // In Hugo 0.65 we consolidated the code paths and made RSS a pure output format, // but we should make sure to not break existing sites. b.Assert(b.CheckExists("public/index.xml"), qt.Equals, false) } func TestBundleNoPublishResources(t *testing.T) { b := newTestSitesBuilder(t) b.WithTemplates("index.html", ` {{ $bundle := site.GetPage "section/bundle-false" }} {{ $data1 := $bundle.Resources.GetMatch "data1*" }} Data1: {{ $data1.RelPermalink }} `) b.WithContent("section/bundle-false/index.md", `---\ntitle: BundleFalse _build: publishResources: false ---`, "section/bundle-false/data1.json", "Some data1", "section/bundle-false/data2.json", "Some data2", ) b.WithContent("section/bundle-true/index.md", `---\ntitle: BundleTrue ---`, "section/bundle-true/data3.json", "Some data 3", ) b.Build(BuildCfg{}) b.AssertFileContent("public/index.html", `Data1: /section/bundle-false/data1.json`) b.AssertFileContent("public/section/bundle-false/data1.json", `Some data1`) b.Assert(b.CheckExists("public/section/bundle-false/data2.json"), qt.Equals, false) b.AssertFileContent("public/section/bundle-true/data3.json", `Some data 3`) } func TestNoRenderAndNoPublishResources(t *testing.T) { noRenderPage := ` --- title: %s _build: render: false publishResources: false --- ` b := newTestSitesBuilder(t) b.WithTemplatesAdded("index.html", ` {{ $page := site.GetPage "sect/no-render" }} {{ $sect := site.GetPage "sect-no-render" }} Page: {{ $page.Title }}|RelPermalink: {{ $page.RelPermalink }}|Outputs: {{ len $page.OutputFormats }} Section: {{ $sect.Title }}|RelPermalink: {{ $sect.RelPermalink }}|Outputs: {{ len $sect.OutputFormats }} `) b.WithContent("sect-no-render/_index.md", fmt.Sprintf(noRenderPage, "MySection")) b.WithContent("sect/no-render.md", fmt.Sprintf(noRenderPage, "MyPage")) b.Build(BuildCfg{}) b.AssertFileContent("public/index.html", ` Page: MyPage|RelPermalink: |Outputs: 0 Section: MySection|RelPermalink: |Outputs: 0 `) b.Assert(b.CheckExists("public/sect/no-render/index.html"), qt.Equals, false) b.Assert(b.CheckExists("public/sect-no-render/index.html"), qt.Equals, false) }