github.com/neohugo/neohugo@v0.123.8/hugolib/config_test.go (about)

     1  // Copyright 2016-present 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 hugolib
    15  
    16  import (
    17  	"bytes"
    18  	"fmt"
    19  	"path/filepath"
    20  	"strings"
    21  	"testing"
    22  
    23  	"github.com/bep/logg"
    24  	"github.com/neohugo/neohugo/config"
    25  	"github.com/neohugo/neohugo/config/allconfig"
    26  
    27  	qt "github.com/frankban/quicktest"
    28  	"github.com/neohugo/neohugo/common/maps"
    29  	"github.com/spf13/afero"
    30  )
    31  
    32  func TestLoadConfigLanguageParamsOverrideIssue10620(t *testing.T) {
    33  	t.Parallel()
    34  
    35  	files := `
    36  -- hugo.toml --
    37  baseURL = "https://example.com"
    38  disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "page", "section"]
    39  title = "Base Title"
    40  staticDir = "mystatic"
    41  [params]
    42  [params.comments]
    43  color = "blue"
    44  title = "Default Comments Title"
    45  [languages]
    46  [languages.en]
    47  title = "English Title"
    48  [languages.en.params.comments]
    49  title = "English Comments Title"
    50  
    51  `
    52  	b := Test(t, files)
    53  
    54  	enSite := b.H.Sites[0]
    55  	b.Assert(enSite.Title(), qt.Equals, "English Title")
    56  	b.Assert(enSite.Home().Title(), qt.Equals, "English Title")
    57  	b.Assert(enSite.Params(), qt.DeepEquals, maps.Params{
    58  		"comments": maps.Params{
    59  			"color": "blue",
    60  			"title": "English Comments Title",
    61  		},
    62  	},
    63  	)
    64  }
    65  
    66  func TestLoadConfig(t *testing.T) {
    67  	t.Run("2 languages", func(t *testing.T) {
    68  		t.Parallel()
    69  
    70  		files := `
    71  -- hugo.toml --
    72  baseURL = "https://example.com"
    73  disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "page", "section"]
    74  title = "Base Title"
    75  staticDir = "mystatic"
    76  [params]
    77  p1 = "p1base"
    78  p2 = "p2base"
    79  [languages]
    80  [languages.en]
    81  title = "English Title"
    82  [languages.en.params]
    83  myparam = "enParamValue"
    84  p1 = "p1en"
    85  weight = 1
    86  [languages.sv]
    87  title = "Svensk Title"
    88  staticDir = "mysvstatic"
    89  weight = 2
    90  [languages.sv.params]
    91  myparam = "svParamValue"
    92  
    93  `
    94  		b := Test(t, files)
    95  
    96  		enSite := b.H.Sites[0]
    97  		svSite := b.H.Sites[1]
    98  		b.Assert(enSite.Title(), qt.Equals, "English Title")
    99  		b.Assert(enSite.Home().Title(), qt.Equals, "English Title")
   100  		b.Assert(enSite.Params()["myparam"], qt.Equals, "enParamValue")
   101  		b.Assert(enSite.Params()["p1"], qt.Equals, "p1en")
   102  		b.Assert(enSite.Params()["p2"], qt.Equals, "p2base")
   103  		b.Assert(svSite.Params()["p1"], qt.Equals, "p1base")
   104  		b.Assert(enSite.conf.StaticDir[0], qt.Equals, "mystatic")
   105  
   106  		b.Assert(svSite.Title(), qt.Equals, "Svensk Title")
   107  		b.Assert(svSite.Home().Title(), qt.Equals, "Svensk Title")
   108  		b.Assert(svSite.Params()["myparam"], qt.Equals, "svParamValue")
   109  		b.Assert(svSite.conf.StaticDir[0], qt.Equals, "mysvstatic")
   110  	})
   111  
   112  	t.Run("disable default language", func(t *testing.T) {
   113  		t.Parallel()
   114  
   115  		files := `
   116  -- hugo.toml --
   117  baseURL = "https://example.com"
   118  disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "page", "section"]
   119  title = "Base Title"
   120  defaultContentLanguage = "sv"
   121  disableLanguages = ["sv"]
   122  [languages.en]
   123  weight = 1
   124  [languages.sv]
   125  weight = 2
   126  `
   127  		b, err := NewIntegrationTestBuilder(
   128  			IntegrationTestConfig{
   129  				T:           t,
   130  				TxtarString: files,
   131  			},
   132  		).BuildE()
   133  
   134  		b.Assert(err, qt.IsNotNil)
   135  		b.Assert(err.Error(), qt.Contains, "cannot disable default content language")
   136  	})
   137  
   138  	t.Run("no internal config from outside", func(t *testing.T) {
   139  		t.Parallel()
   140  
   141  		files := `
   142  -- hugo.toml --
   143  baseURL = "https://example.com"
   144  [internal]
   145  running = true
   146  `
   147  		b := Test(t, files)
   148  
   149  		b.Assert(b.H.Conf.Running(), qt.Equals, false)
   150  	})
   151  
   152  	t.Run("env overrides", func(t *testing.T) {
   153  		t.Parallel()
   154  
   155  		files := `
   156  -- hugo.toml --
   157  baseURL = "https://example.com"
   158  disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "page", "section"]
   159  title = "Base Title"
   160  [params]
   161  p1 = "p1base"
   162  p2 = "p2base"
   163  [params.pm2]
   164  pm21 = "pm21base"
   165  pm22 = "pm22base"
   166  -- layouts/index.html --
   167  p1: {{ .Site.Params.p1 }}
   168  p2: {{ .Site.Params.p2 }}
   169  pm21: {{ .Site.Params.pm2.pm21 }}
   170  pm22: {{ .Site.Params.pm2.pm22 }}
   171  pm31: {{ .Site.Params.pm3.pm31 }}
   172  
   173  
   174  
   175  `
   176  		b := NewIntegrationTestBuilder(
   177  			IntegrationTestConfig{
   178  				T:           t,
   179  				TxtarString: files,
   180  				Environ:     []string{"HUGO_PARAMS_P2=p2env", "HUGO_PARAMS_PM2_PM21=pm21env", "HUGO_PARAMS_PM3_PM31=pm31env"},
   181  			},
   182  		).Build()
   183  
   184  		b.AssertFileContent("public/index.html", "p1: p1base\np2: p2env\npm21: pm21env\npm22: pm22base\npm31: pm31env")
   185  	})
   186  }
   187  
   188  func TestLoadConfigThemeLanguage(t *testing.T) {
   189  	t.Parallel()
   190  
   191  	files := `
   192  -- /hugo.toml --
   193  baseURL = "https://example.com"
   194  defaultContentLanguage = "en"
   195  defaultContentLanguageInSubdir = true
   196  theme = "mytheme"
   197  [languages]
   198  [languages.en]
   199  title = "English Title"
   200  weight = 1
   201  [languages.sv]
   202  weight = 2
   203  -- themes/mytheme/hugo.toml --
   204  [params]
   205  p1 = "p1base"
   206  [languages]
   207  [languages.en]
   208  title = "English Title Theme"
   209  [languages.en.params]
   210  p2 = "p2en"
   211  [languages.en.params.sub]
   212  sub1 = "sub1en"
   213  [languages.sv]
   214  title = "Svensk Title Theme"
   215  -- layouts/index.html --
   216  title: {{ .Title }}|
   217  p1: {{ .Site.Params.p1 }}|
   218  p2: {{ .Site.Params.p2 }}|
   219  sub: {{ .Site.Params.sub }}|
   220  `
   221  	b := Test(t, files)
   222  
   223  	b.AssertFileContent("public/en/index.html", `
   224  title: English Title|
   225  p1: p1base
   226  p2: p2en
   227  sub: map[sub1:sub1en]
   228  `)
   229  }
   230  
   231  func TestDisableRootSlicesFromEnv(t *testing.T) {
   232  	t.Parallel()
   233  
   234  	files := `
   235  -- hugo.toml --
   236  baseURL = "https://example.com"
   237  defaultContentLanguage = "en"
   238  defaultContentLanguageInSubdir = true
   239  [languages]
   240  [languages.en]
   241  weight = 1
   242  [languages.sv]
   243  weight = 2
   244  [languages.no]
   245  weight = 3
   246  
   247  -- layouts/index.html --
   248  Home.
   249  `
   250  
   251  	for _, delim := range []string{" ", ","} {
   252  		environ := []string{"HUGO_DISABLELANGUAGES=sv no", "HUGO_DISABLEKINDS=taxonomy term"}
   253  		for i, v := range environ {
   254  			environ[i] = strings.ReplaceAll(v, " ", delim)
   255  		}
   256  		b := NewIntegrationTestBuilder(
   257  			IntegrationTestConfig{
   258  				T:           t,
   259  				TxtarString: files,
   260  				Environ:     environ,
   261  				BuildCfg:    BuildCfg{SkipRender: true},
   262  			},
   263  		).Build()
   264  
   265  		conf := b.H.Configs.Base
   266  		b.Assert(conf.DisableLanguages, qt.DeepEquals, []string{"sv", "no"})
   267  		b.Assert(conf.DisableKinds, qt.DeepEquals, []string{"taxonomy", "term"})
   268  	}
   269  }
   270  
   271  func TestLoadMultiConfig(t *testing.T) {
   272  	t.Parallel()
   273  
   274  	c := qt.New(t)
   275  
   276  	// Add a random config variable for testing.
   277  	// side = page in Norwegian.
   278  	configContentBase := `
   279  	Paginate = 32
   280  	PaginatePath = "side"
   281  	`
   282  	configContentSub := `
   283  	PaginatePath = "top"
   284  	`
   285  	mm := afero.NewMemMapFs()
   286  
   287  	writeToFs(t, mm, "base.toml", configContentBase)
   288  
   289  	writeToFs(t, mm, "override.toml", configContentSub)
   290  
   291  	all, err := allconfig.LoadConfig(allconfig.ConfigSourceDescriptor{Fs: mm, Filename: "base.toml,override.toml"})
   292  	c.Assert(err, qt.IsNil)
   293  	cfg := all.Base
   294  
   295  	c.Assert(cfg.PaginatePath, qt.Equals, "top")
   296  	c.Assert(cfg.Paginate, qt.Equals, 32)
   297  }
   298  
   299  func TestLoadConfigFromThemes(t *testing.T) {
   300  	t.Parallel()
   301  
   302  	c := qt.New(t)
   303  
   304  	mainConfigTemplate := `
   305  theme = "test-theme"
   306  baseURL = "https://example.com/"
   307  
   308  [frontmatter]
   309  date = ["date","publishDate"]
   310  
   311  [params]
   312  MERGE_PARAMS
   313  p1 = "p1 main"
   314  [params.b]
   315  b1 = "b1 main"
   316  [params.b.c]
   317  bc1 = "bc1 main"
   318  
   319  [mediaTypes]
   320  [mediaTypes."text/m1"]
   321  suffixes = ["m1main"]
   322  
   323  [outputFormats.o1]
   324  mediaType = "text/m1"
   325  baseName = "o1main"
   326  
   327  [languages]
   328  [languages.en]
   329  languageName = "English"
   330  [languages.en.params]
   331  pl1 = "p1-en-main"
   332  [languages.nb]
   333  languageName = "Norsk"
   334  [languages.nb.params]
   335  pl1 = "p1-nb-main"
   336  
   337  [[menu.main]]
   338  name = "menu-main-main"
   339  
   340  [[menu.top]]
   341  name = "menu-top-main"
   342  
   343  `
   344  
   345  	themeConfig := `
   346  baseURL = "http://bep.is/"
   347  
   348  # Can not be set in theme.
   349  disableKinds = ["taxonomy", "term"]
   350  
   351  # Can not be set in theme.
   352  [frontmatter]
   353  expiryDate = ["date"]
   354  
   355  [params]
   356  p1 = "p1 theme"
   357  p2 = "p2 theme"
   358  [params.b]
   359  b1 = "b1 theme"
   360  b2 = "b2 theme"
   361  [params.b.c]
   362  bc1 = "bc1 theme"
   363  bc2 = "bc2 theme"
   364  [params.b.c.d]
   365  bcd1 = "bcd1 theme"
   366  
   367  [mediaTypes]
   368  [mediaTypes."text/m1"]
   369  suffixes = ["m1theme"]
   370  [mediaTypes."text/m2"]
   371  suffixes = ["m2theme"]
   372  
   373  [outputFormats.o1]
   374  mediaType = "text/m1"
   375  baseName = "o1theme"
   376  [outputFormats.o2]
   377  mediaType = "text/m2"
   378  baseName = "o2theme"
   379  
   380  [languages]
   381  [languages.en]
   382  languageName = "English2"
   383  [languages.en.params]
   384  pl1 = "p1-en-theme"
   385  pl2 = "p2-en-theme"
   386  [[languages.en.menu.main]]
   387  name   = "menu-lang-en-main"
   388  [[languages.en.menu.theme]]
   389  name   = "menu-lang-en-theme"
   390  [languages.nb]
   391  languageName = "Norsk2"
   392  [languages.nb.params]
   393  pl1 = "p1-nb-theme"
   394  pl2 = "p2-nb-theme"
   395  top = "top-nb-theme"
   396  [[languages.nb.menu.main]]
   397  name   = "menu-lang-nb-main"
   398  [[languages.nb.menu.theme]]
   399  name   = "menu-lang-nb-theme"
   400  [[languages.nb.menu.top]]
   401  name   = "menu-lang-nb-top"
   402  
   403  [[menu.main]]
   404  name = "menu-main-theme"
   405  
   406  [[menu.thememenu]]
   407  name = "menu-theme"
   408  
   409  `
   410  
   411  	buildForConfig := func(t testing.TB, mainConfig, themeConfig string) *sitesBuilder {
   412  		b := newTestSitesBuilder(t)
   413  		b.WithConfigFile("toml", mainConfig).WithThemeConfigFile("toml", themeConfig)
   414  		return b.Build(BuildCfg{})
   415  	}
   416  
   417  	buildForStrategy := func(t testing.TB, s string) *sitesBuilder {
   418  		mainConfig := strings.ReplaceAll(mainConfigTemplate, "MERGE_PARAMS", s)
   419  		return buildForConfig(t, mainConfig, themeConfig)
   420  	}
   421  
   422  	c.Run("Merge default", func(c *qt.C) {
   423  		b := buildForStrategy(c, "")
   424  
   425  		got := b.Configs.Base
   426  
   427  		b.Assert(got.Params, qt.DeepEquals, maps.Params{
   428  			"b": maps.Params{
   429  				"b1": "b1 main",
   430  				"c": maps.Params{
   431  					"bc1": "bc1 main",
   432  					"bc2": "bc2 theme",
   433  					"d":   maps.Params{"bcd1": string("bcd1 theme")},
   434  				},
   435  				"b2": "b2 theme",
   436  			},
   437  			"p2": "p2 theme",
   438  			"p1": "p1 main",
   439  		})
   440  
   441  		c.Assert(got.BaseURL, qt.Equals, "https://example.com/")
   442  	})
   443  
   444  	c.Run("Merge shallow", func(c *qt.C) {
   445  		b := buildForStrategy(c, fmt.Sprintf("_merge=%q", "shallow"))
   446  
   447  		got := b.Configs.Base.Params
   448  
   449  		// Shallow merge, only add new keys to params.
   450  		b.Assert(got, qt.DeepEquals, maps.Params{
   451  			"p1": "p1 main",
   452  			"b": maps.Params{
   453  				"b1": "b1 main",
   454  				"c": maps.Params{
   455  					"bc1": "bc1 main",
   456  				},
   457  			},
   458  			"p2": "p2 theme",
   459  		})
   460  	})
   461  
   462  	c.Run("Merge no params in project", func(c *qt.C) {
   463  		b := buildForConfig(
   464  			c,
   465  			"baseURL=\"https://example.org\"\ntheme = \"test-theme\"\n",
   466  			"[params]\np1 = \"p1 theme\"\n",
   467  		)
   468  
   469  		got := b.Configs.Base.Params
   470  
   471  		b.Assert(got, qt.DeepEquals, maps.Params{
   472  			"p1": "p1 theme",
   473  		})
   474  	})
   475  
   476  	// Issue #8724
   477  	for _, mergeStrategy := range []string{"none", "shallow"} {
   478  		c.Run(fmt.Sprintf("Merge with sitemap config in theme, mergestrategy %s", mergeStrategy), func(c *qt.C) {
   479  			smapConfigTempl := `[sitemap]
   480    changefreq = %q
   481    filename = "sitemap.xml"
   482    priority = 0.5`
   483  
   484  			b := buildForConfig(
   485  				c,
   486  				fmt.Sprintf("_merge=%q\nbaseURL=\"https://example.org\"\ntheme = \"test-theme\"\n", mergeStrategy),
   487  				"baseURL=\"http://example.com\"\n"+fmt.Sprintf(smapConfigTempl, "monthly"),
   488  			)
   489  
   490  			got := b.Configs.Base
   491  
   492  			if mergeStrategy == "none" {
   493  				b.Assert(got.Sitemap, qt.DeepEquals, config.SitemapConfig{ChangeFreq: "", Priority: -1, Filename: "sitemap.xml"})
   494  
   495  				b.AssertFileContent("public/sitemap.xml", "schemas/sitemap")
   496  			} else {
   497  				b.Assert(got.Sitemap, qt.DeepEquals, config.SitemapConfig{ChangeFreq: "monthly", Priority: -1, Filename: "sitemap.xml"})
   498  				b.AssertFileContent("public/sitemap.xml", "<changefreq>monthly</changefreq>")
   499  			}
   500  		})
   501  	}
   502  }
   503  
   504  func TestLoadConfigFromThemeDir(t *testing.T) {
   505  	t.Parallel()
   506  
   507  	mainConfig := `
   508  theme = "test-theme"
   509  
   510  [params]
   511  m1 = "mv1"	
   512  `
   513  
   514  	themeConfig := `
   515  [params]
   516  t1 = "tv1"	
   517  t2 = "tv2"
   518  `
   519  
   520  	themeConfigDir := filepath.Join("themes", "test-theme", "config")
   521  	themeConfigDirDefault := filepath.Join(themeConfigDir, "_default")
   522  	themeConfigDirProduction := filepath.Join(themeConfigDir, "production")
   523  
   524  	projectConfigDir := "config"
   525  
   526  	b := newTestSitesBuilder(t)
   527  	b.WithConfigFile("toml", mainConfig).WithThemeConfigFile("toml", themeConfig)
   528  	b.Assert(b.Fs.Source.MkdirAll(themeConfigDirDefault, 0o777), qt.IsNil)
   529  	b.Assert(b.Fs.Source.MkdirAll(themeConfigDirProduction, 0o777), qt.IsNil)
   530  	b.Assert(b.Fs.Source.MkdirAll(projectConfigDir, 0o777), qt.IsNil)
   531  
   532  	b.WithSourceFile(filepath.Join(projectConfigDir, "config.toml"), `[params]
   533  m2 = "mv2"
   534  `)
   535  	b.WithSourceFile(filepath.Join(themeConfigDirDefault, "config.toml"), `[params]
   536  t2 = "tv2d"
   537  t3 = "tv3d"
   538  `)
   539  
   540  	b.WithSourceFile(filepath.Join(themeConfigDirProduction, "config.toml"), `[params]
   541  t3 = "tv3p"
   542  `)
   543  
   544  	b.Build(BuildCfg{})
   545  
   546  	got := b.Configs.Base.Params
   547  
   548  	b.Assert(got, qt.DeepEquals, maps.Params{
   549  		"t3": "tv3p",
   550  		"m1": "mv1",
   551  		"t1": "tv1",
   552  		"t2": "tv2d",
   553  	})
   554  }
   555  
   556  func TestPrivacyConfig(t *testing.T) {
   557  	t.Parallel()
   558  
   559  	c := qt.New(t)
   560  
   561  	tomlConfig := `
   562  
   563  someOtherValue = "foo"
   564  
   565  [privacy]
   566  [privacy.youtube]
   567  privacyEnhanced = true
   568  `
   569  
   570  	b := newTestSitesBuilder(t)
   571  	b.WithConfigFile("toml", tomlConfig)
   572  	b.Build(BuildCfg{SkipRender: true})
   573  
   574  	c.Assert(b.H.Sites[0].Config().Privacy.YouTube.PrivacyEnhanced, qt.Equals, true)
   575  }
   576  
   577  func TestLoadConfigModules(t *testing.T) {
   578  	t.Parallel()
   579  
   580  	c := qt.New(t)
   581  
   582  	// https://github.com/neohugo/neohugoThemes#themetoml
   583  
   584  	const (
   585  		// Before Hugo 0.56 each theme/component could have its own theme.toml
   586  		// with some settings, mostly used on the Hugo themes site.
   587  		// To preserve combability we read these files into the new "modules"
   588  		// section in config.toml.
   589  		o1t = `
   590  name = "Component o1"
   591  license = "MIT"
   592  min_version = 0.38
   593  `
   594  		// This is the component's config.toml, using the old theme syntax.
   595  		o1c = `
   596  theme = ["n2"]
   597  `
   598  
   599  		n1 = `
   600  title = "Component n1"
   601  
   602  [module]
   603  description = "Component n1 description"
   604  [module.hugoVersion]
   605  min = "0.40.0"
   606  max = "0.50.0"
   607  extended = true
   608  [[module.imports]]
   609  path="o1"
   610  [[module.imports]]
   611  path="n3"
   612  
   613  
   614  `
   615  
   616  		n2 = `
   617  title = "Component n2"
   618  `
   619  
   620  		n3 = `
   621  title = "Component n3"
   622  `
   623  
   624  		n4 = `
   625  title = "Component n4"
   626  `
   627  	)
   628  
   629  	b := newTestSitesBuilder(t)
   630  
   631  	writeThemeFiles := func(name, configTOML, themeTOML string) {
   632  		b.WithSourceFile(filepath.Join("themes", name, "data", "module.toml"), fmt.Sprintf("name=%q", name))
   633  		if configTOML != "" {
   634  			b.WithSourceFile(filepath.Join("themes", name, "config.toml"), configTOML)
   635  		}
   636  		if themeTOML != "" {
   637  			b.WithSourceFile(filepath.Join("themes", name, "theme.toml"), themeTOML)
   638  		}
   639  	}
   640  
   641  	writeThemeFiles("n1", n1, "")
   642  	writeThemeFiles("n2", n2, "")
   643  	writeThemeFiles("n3", n3, "")
   644  	writeThemeFiles("n4", n4, "")
   645  	writeThemeFiles("o1", o1c, o1t)
   646  
   647  	b.WithConfigFile("toml", `
   648  [module]
   649  [[module.imports]]
   650  path="n1"
   651  [[module.imports]]
   652  path="n4"
   653  
   654  `)
   655  
   656  	b.Build(BuildCfg{})
   657  
   658  	modulesClient := b.H.Configs.ModulesClient
   659  	var graphb bytes.Buffer
   660  	c.Assert(modulesClient.Graph(&graphb), qt.IsNil)
   661  
   662  	expected := `project n1
   663  n1 o1
   664  o1 n2
   665  n1 n3
   666  project n4
   667  `
   668  
   669  	c.Assert(graphb.String(), qt.Equals, expected)
   670  }
   671  
   672  func TestInvalidDefaultMarkdownHandler(t *testing.T) {
   673  	t.Parallel()
   674  
   675  	files := `
   676  -- config.toml --
   677  [markup]
   678  defaultMarkdownHandler = 'blackfriday'
   679  -- content/_index.md --
   680  ## Foo
   681  -- layouts/index.html --
   682  {{ .Content }}
   683  
   684  `
   685  
   686  	b, err := NewIntegrationTestBuilder(
   687  		IntegrationTestConfig{
   688  			T:           t,
   689  			TxtarString: files,
   690  		},
   691  	).BuildE()
   692  
   693  	b.Assert(err, qt.IsNotNil)
   694  	b.Assert(err.Error(), qt.Contains, "Configured defaultMarkdownHandler \"blackfriday\" not found. Did you mean to use goldmark? Blackfriday was removed in Hugo v0.100.0.")
   695  }
   696  
   697  // Issue 8979
   698  func TestHugoConfig(t *testing.T) {
   699  	filesTemplate := `
   700  -- hugo.toml --
   701  theme = "mytheme"
   702  [social]
   703  twitter = "bepsays"
   704  [author]
   705  name = "bep"
   706  [params]
   707  rootparam = "rootvalue"
   708  -- config/_default/hugo.toml --
   709  [params]
   710  rootconfigparam = "rootconfigvalue"
   711  -- themes/mytheme/config/_default/hugo.toml --
   712  [params]
   713  themeconfigdirparam = "themeconfigdirvalue"
   714  -- themes/mytheme/hugo.toml --
   715  [params]
   716  themeparam = "themevalue"
   717  -- layouts/index.html --
   718  rootparam: {{ site.Params.rootparam }}
   719  rootconfigparam: {{ site.Params.rootconfigparam }}
   720  themeparam: {{ site.Params.themeparam }}
   721  themeconfigdirparam: {{ site.Params.themeconfigdirparam }}
   722  social: {{ site.Social }}
   723  author: {{ site.Author }}
   724  
   725  
   726  `
   727  
   728  	for _, configName := range []string{"hugo.toml", "config.toml"} {
   729  		configName := configName
   730  		t.Run(configName, func(t *testing.T) {
   731  			t.Parallel()
   732  
   733  			files := strings.ReplaceAll(filesTemplate, "hugo.toml", configName)
   734  
   735  			b, err := NewIntegrationTestBuilder(
   736  				IntegrationTestConfig{
   737  					T:           t,
   738  					TxtarString: files,
   739  				},
   740  			).BuildE()
   741  
   742  			b.Assert(err, qt.IsNil)
   743  			b.AssertFileContent("public/index.html",
   744  				"rootparam: rootvalue",
   745  				"rootconfigparam: rootconfigvalue",
   746  				"themeparam: themevalue",
   747  				"themeconfigdirparam: themeconfigdirvalue",
   748  				"social: map[twitter:bepsays]",
   749  				"author: map[name:bep]",
   750  			)
   751  		})
   752  	}
   753  }
   754  
   755  // Issue #11089
   756  func TestHugoConfigSliceOverrides(t *testing.T) {
   757  	t.Parallel()
   758  
   759  	filesTemplate := `
   760  -- hugo.toml --
   761  disableKinds = ["section"]
   762  [languages]
   763  [languages.en]
   764  disableKinds = []
   765  title = "English"
   766  weigHt = WEIGHT_EN
   767  [languages.sv]
   768  title = "Swedish"
   769  wEight =  WEIGHT_SV
   770  disableKinds = ["page"]
   771  -- layouts/index.html --
   772  Home: {{ .Lang}}|{{ len site.RegularPages }}|
   773  -- layouts/_default/single.html --
   774  Single.
   775  -- content/p1.en.md --
   776  -- content/p2.en.md --
   777  -- content/p1.sv.md --
   778  -- content/p2.sv.md --
   779  
   780  `
   781  
   782  	t.Run("En first", func(t *testing.T) {
   783  		files := strings.ReplaceAll(filesTemplate, "WEIGHT_EN", "1")
   784  		files = strings.ReplaceAll(files, "WEIGHT_SV", "2")
   785  
   786  		cfg := config.New()
   787  		b, err := NewIntegrationTestBuilder(
   788  			IntegrationTestConfig{
   789  				T:           t,
   790  				TxtarString: files,
   791  				BaseCfg:     cfg,
   792  			},
   793  		).BuildE()
   794  
   795  		b.Assert(err, qt.IsNil)
   796  		b.AssertFileContent("public/index.html", "Home: en|2|")
   797  		b.AssertFileContent("public/sv/index.html", "Home: sv|0|")
   798  	})
   799  
   800  	t.Run("Sv first", func(t *testing.T) {
   801  		files := strings.ReplaceAll(filesTemplate, "WEIGHT_EN", "2")
   802  		files = strings.ReplaceAll(files, "WEIGHT_SV", "1")
   803  
   804  		for i := 0; i < 20; i++ {
   805  			cfg := config.New()
   806  			b, err := NewIntegrationTestBuilder(
   807  				IntegrationTestConfig{
   808  					T:           t,
   809  					TxtarString: files,
   810  					BaseCfg:     cfg,
   811  				},
   812  			).BuildE()
   813  
   814  			b.Assert(err, qt.IsNil)
   815  			b.AssertFileContent("public/index.html", "Home: en|2|")
   816  			b.AssertFileContent("public/sv/index.html", "Home: sv|0|")
   817  		}
   818  	})
   819  }
   820  
   821  func TestConfigOutputFormatDefinedInTheme(t *testing.T) {
   822  	t.Parallel()
   823  
   824  	files := `
   825  -- hugo.toml --
   826  theme = "mytheme"
   827  [outputFormats]
   828  [outputFormats.myotherformat]
   829  baseName = 'myotherindex'
   830  mediaType = 'text/html'
   831  [outputs]
   832    home = ['myformat']
   833  -- themes/mytheme/hugo.toml --
   834  [outputFormats]
   835  [outputFormats.myformat]
   836  baseName = 'myindex'
   837  mediaType = 'text/html'
   838  -- layouts/index.html --
   839  Home.
   840  
   841  
   842  
   843  `
   844  
   845  	b, err := NewIntegrationTestBuilder(
   846  		IntegrationTestConfig{
   847  			T:           t,
   848  			TxtarString: files,
   849  		},
   850  	).BuildE()
   851  
   852  	b.Assert(err, qt.IsNil)
   853  	b.AssertFileContent("public/myindex.html", "Home.")
   854  }
   855  
   856  func TestConfigParamSetOnLanguageLevel(t *testing.T) {
   857  	t.Skip("this has correctly started to fail now.")
   858  	t.Parallel()
   859  
   860  	files := `
   861  -- hugo.toml --
   862  disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT"]
   863  [languages]
   864  [languages.en]
   865  title = "English Title"
   866  thisIsAParam = "thisIsAParamValue"
   867  [languages.en.params]
   868  myparam = "enParamValue"
   869  [languages.sv]
   870  title = "Svensk Title"
   871  [languages.sv.params]
   872  myparam = "svParamValue"
   873  -- layouts/index.html --
   874  MyParam: {{ site.Params.myparam }}
   875  ThisIsAParam: {{ site.Params.thisIsAParam }}
   876  
   877  
   878  `
   879  
   880  	b, err := NewIntegrationTestBuilder(
   881  		IntegrationTestConfig{
   882  			T:           t,
   883  			TxtarString: files,
   884  		},
   885  	).BuildE()
   886  
   887  	b.Assert(err, qt.IsNil)
   888  	b.AssertFileContent("public/index.html", `		
   889  MyParam: enParamValue
   890  ThisIsAParam: thisIsAParamValue	
   891  `)
   892  }
   893  
   894  func TestReproCommentsIn10947(t *testing.T) {
   895  	t.Parallel()
   896  
   897  	files := `
   898  -- hugo.toml --
   899  baseURL = "https://example.com"
   900  disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT"]
   901  [languages]
   902  [languages.en]
   903  languageCode = "en-US"
   904  title = "English Title"
   905  [languages.en.params]
   906  myparam = "enParamValue"
   907  [languages.sv]
   908  title = "Svensk Title"
   909  [languages.sv.params]
   910  myparam = "svParamValue"
   911  -- content/mysection/_index.en.md --
   912  ---
   913  title: "My English Section"
   914  ---
   915  -- content/mysection/_index.sv.md --
   916  ---
   917  title: "My Swedish Section"
   918  ---
   919  -- layouts/index.html --
   920  LanguageCode: {{ eq site.LanguageCode site.Language.LanguageCode }}|{{ site.Language.LanguageCode }}|
   921  {{ range $i, $e := (slice site .Site) }}
   922  {{ $i }}|AllPages: {{ len .AllPages }}|Sections: {{ if .Sections }}true{{ end }}| Author: {{ .Authors }}|BuildDrafts: {{ .BuildDrafts }}|IsMultiLingual: {{ .IsMultiLingual }}|Param: {{ .Language.Params.myparam }}|Language string: {{ .Language }}|Languages: {{ .Languages }}
   923  {{ end }}
   924  
   925  
   926  
   927  `
   928  	b := NewIntegrationTestBuilder(
   929  		IntegrationTestConfig{
   930  			T:           t,
   931  			TxtarString: files,
   932  			LogLevel:    logg.LevelWarn,
   933  		},
   934  	).Build()
   935  
   936  	{
   937  		b.Assert(b.H.Log.LoggCount(logg.LevelWarn), qt.Equals, 1)
   938  	}
   939  	b.AssertFileContent("public/index.html", `
   940  AllPages: 4|
   941  Sections: true|
   942  Param: enParamValue	
   943  Param: enParamValue	
   944  IsMultiLingual: true
   945  LanguageCode: true|en-US|
   946  `)
   947  
   948  	b.AssertFileContent("public/sv/index.html", `
   949  Param: svParamValue
   950  LanguageCode: true|sv|
   951  
   952  `)
   953  }
   954  
   955  func TestConfigEmptyMainSections(t *testing.T) {
   956  	t.Parallel()
   957  
   958  	files := `
   959  -- hugo.yml --
   960  params:
   961    mainSections:
   962  -- content/mysection/_index.md --
   963  -- content/mysection/mycontent.md --
   964  -- layouts/index.html --
   965  mainSections: {{ site.Params.mainSections }}
   966  
   967  `
   968  	b := Test(t, files)
   969  
   970  	b.AssertFileContent("public/index.html", `
   971  mainSections: []
   972  `)
   973  }
   974  
   975  func TestConfigHugoWorkingDir(t *testing.T) {
   976  	t.Parallel()
   977  
   978  	files := `
   979  -- hugo.toml --
   980  -- layouts/index.html --
   981  WorkingDir: {{ hugo.WorkingDir }}|
   982  
   983  `
   984  	b := NewIntegrationTestBuilder(
   985  		IntegrationTestConfig{
   986  			T:           t,
   987  			TxtarString: files,
   988  			WorkingDir:  "myworkingdir",
   989  		},
   990  	).Build()
   991  
   992  	b.AssertFileContent("public/index.html", `
   993  WorkingDir: myworkingdir|
   994  `)
   995  }
   996  
   997  func TestConfigMergeLanguageDeepEmptyLefSide(t *testing.T) {
   998  	t.Parallel()
   999  
  1000  	files := `
  1001  -- hugo.toml --
  1002  [params]
  1003  p1 = "p1base"
  1004  [languages.en]
  1005  languageCode = 'en-US'
  1006  languageName = 'English'
  1007  weight = 1
  1008  [languages.en.markup.goldmark.extensions.typographer]
  1009  leftDoubleQuote = '&ldquo;'   # default &ldquo;
  1010  rightDoubleQuote = '&rdquo;'  # default &rdquo;
  1011  
  1012  [languages.de]
  1013  languageCode = 'de-DE'
  1014  languageName = 'Deutsch'
  1015  weight = 2
  1016  [languages.de.params]
  1017  p1 = "p1de"
  1018  [languages.de.markup.goldmark.extensions.typographer]
  1019  leftDoubleQuote = '&laquo;'   # default &ldquo;
  1020  rightDoubleQuote = '&raquo;'  # default &rdquo;
  1021  -- layouts/index.html --
  1022  {{ .Content }}
  1023  p1: {{ site.Params.p1 }}|
  1024  -- content/_index.en.md --
  1025  ---
  1026  title: "English Title"
  1027  ---
  1028  A "quote" in English.
  1029  -- content/_index.de.md --
  1030  ---
  1031  title: "Deutsch Title"
  1032  ---
  1033  Ein "Zitat" auf Deutsch.
  1034  
  1035  
  1036  
  1037  `
  1038  	b := Test(t, files)
  1039  
  1040  	b.AssertFileContent("public/index.html", "p1: p1base", "<p>A &ldquo;quote&rdquo; in English.</p>")
  1041  	b.AssertFileContent("public/de/index.html", "p1: p1de", "<p>Ein &laquo;Zitat&raquo; auf Deutsch.</p>")
  1042  }
  1043  
  1044  func TestConfigLegacyValues(t *testing.T) {
  1045  	t.Parallel()
  1046  
  1047  	files := `
  1048  -- hugo.toml --
  1049  # taxonomyTerm was renamed to taxonomy in Hugo 0.60.0.
  1050  disableKinds = ["taxonomyTerm"]
  1051  
  1052  -- layouts/index.html --
  1053  Home
  1054  
  1055  `
  1056  
  1057  	b, err := NewIntegrationTestBuilder(
  1058  		IntegrationTestConfig{
  1059  			T:           t,
  1060  			TxtarString: files,
  1061  		},
  1062  	).BuildE()
  1063  
  1064  	b.Assert(err, qt.IsNil)
  1065  	b.AssertFileContent("public/index.html", `		
  1066  Home
  1067  `)
  1068  
  1069  	conf := b.H.Configs.Base
  1070  	b.Assert(conf.IsKindEnabled("taxonomy"), qt.Equals, false)
  1071  }
  1072  
  1073  // Issue #11000
  1074  func TestConfigEmptyTOMLString(t *testing.T) {
  1075  	t.Parallel()
  1076  
  1077  	files := `
  1078  -- hugo.toml --
  1079  [mediaTypes]
  1080  [mediaTypes."text/htaccess"]
  1081  suffixes = ["htaccess"]
  1082  [outputFormats]
  1083  [outputFormats.htaccess]
  1084  mediaType = "text/htaccess"
  1085  baseName = ""
  1086  isPlainText = false
  1087  notAlternative = true
  1088  -- content/_index.md --
  1089  ---
  1090  outputs: ["html", "htaccess"]
  1091  ---
  1092  -- layouts/index.html --
  1093  HTML.
  1094  -- layouts/_default/list.htaccess --
  1095  HTACCESS.
  1096  
  1097  
  1098  	
  1099  `
  1100  	b := Test(t, files)
  1101  
  1102  	b.AssertFileContent("public/.htaccess", "HTACCESS")
  1103  }
  1104  
  1105  func TestConfigLanguageCodeTopLevel(t *testing.T) {
  1106  	t.Parallel()
  1107  
  1108  	files := `
  1109  -- hugo.toml --
  1110  languageCode = "en-US"
  1111  -- layouts/index.html --
  1112  LanguageCode: {{ .Site.LanguageCode }}|{{ site.Language.LanguageCode }}|
  1113  
  1114  	
  1115  `
  1116  	b := Test(t, files)
  1117  
  1118  	b.AssertFileContent("public/index.html", "LanguageCode: en-US|en-US|")
  1119  }
  1120  
  1121  // See #11159
  1122  func TestConfigOutputFormatsPerLanguage(t *testing.T) {
  1123  	t.Parallel()
  1124  
  1125  	files := `
  1126  -- hugo.toml --
  1127  [languages]
  1128  [languages.en]
  1129  title = "English Title"
  1130  [languages.sv]
  1131  title = "Swedish Title"
  1132  [languages.sv.outputFormats.html]
  1133  path = "foo"
  1134  [languages.sv.mediatypes."text/html"]
  1135  suffixes = ["bar"]
  1136  
  1137  -- layouts/index.html --
  1138  Home.
  1139  
  1140  	
  1141  `
  1142  	b := Test(t, files)
  1143  
  1144  	b.AssertFileContent("public/index.html", "Home.")
  1145  
  1146  	enConfig := b.H.Sites[0].conf
  1147  	m, _ := enConfig.MediaTypes.Config.GetByType("text/html")
  1148  	b.Assert(m.Suffixes(), qt.DeepEquals, []string{"html"})
  1149  
  1150  	svConfig := b.H.Sites[1].conf
  1151  	f, _ := svConfig.OutputFormats.Config.GetByName("html")
  1152  	b.Assert(f.Path, qt.Equals, "foo")
  1153  	m, _ = svConfig.MediaTypes.Config.GetByType("text/html")
  1154  	b.Assert(m.Suffixes(), qt.DeepEquals, []string{"bar"})
  1155  }
  1156  
  1157  func TestConfigMiscPanics(t *testing.T) {
  1158  	t.Parallel()
  1159  
  1160  	// Issue 11047,
  1161  	t.Run("empty params", func(t *testing.T) {
  1162  		files := `
  1163  -- hugo.yaml --
  1164  params:
  1165  -- layouts/index.html --
  1166  Foo: {{ site.Params.foo }}|
  1167  	
  1168  		
  1169  	`
  1170  		b := Test(t, files)
  1171  
  1172  		b.AssertFileContent("public/index.html", "Foo: |")
  1173  	})
  1174  
  1175  	// Issue 11046
  1176  	t.Run("invalid language setup", func(t *testing.T) {
  1177  		files := `
  1178  -- hugo.toml --
  1179  baseURL = "https://example.org"
  1180  languageCode = "en-us"
  1181  title = "Blog of me"
  1182  defaultContentLanguage = "en"
  1183  
  1184  [languages]
  1185  	[en]
  1186  	lang = "en"
  1187  	languageName = "English"
  1188  	weight = 1
  1189  -- layouts/index.html --
  1190  Foo: {{ site.Params.foo }}|
  1191  	
  1192  		
  1193  	`
  1194  		b, err := NewIntegrationTestBuilder(
  1195  			IntegrationTestConfig{
  1196  				T:           t,
  1197  				TxtarString: files,
  1198  			},
  1199  		).BuildE()
  1200  
  1201  		b.Assert(err, qt.IsNotNil)
  1202  		b.Assert(err.Error(), qt.Contains, "no languages")
  1203  	})
  1204  
  1205  	// Issue 11044
  1206  	t.Run("invalid defaultContentLanguage", func(t *testing.T) {
  1207  		files := `
  1208  -- hugo.toml --
  1209  baseURL = "https://example.org"
  1210  defaultContentLanguage = "sv"
  1211  
  1212  [languages]
  1213  [languages.en]
  1214  languageCode = "en"
  1215  languageName = "English"
  1216  weight = 1
  1217  
  1218  	
  1219  		
  1220  	`
  1221  		b, err := NewIntegrationTestBuilder(
  1222  			IntegrationTestConfig{
  1223  				T:           t,
  1224  				TxtarString: files,
  1225  			},
  1226  		).BuildE()
  1227  
  1228  		b.Assert(err, qt.IsNotNil)
  1229  		b.Assert(err.Error(), qt.Contains, "defaultContentLanguage does not match any language definition")
  1230  	})
  1231  }
  1232  
  1233  // Issue #11040
  1234  func TestConfigModuleDefaultMountsInConfig(t *testing.T) {
  1235  	t.Parallel()
  1236  
  1237  	files := `
  1238  -- hugo.toml --
  1239  baseURL = "https://example.org"
  1240  contentDir = "mycontent"
  1241  -- layouts/index.html --
  1242  Home.
  1243  
  1244  	
  1245  `
  1246  	b := Test(t, files)
  1247  
  1248  	b.Assert(b.H.Configs.Base.Module.Mounts, qt.HasLen, 7)
  1249  	b.Assert(b.H.Configs.LanguageConfigSlice[0].Module.Mounts, qt.HasLen, 7)
  1250  }
  1251  
  1252  func TestDefaultContentLanguageInSubdirOnlyOneLanguage(t *testing.T) {
  1253  	t.Run("One language, default in sub dir", func(t *testing.T) {
  1254  		t.Parallel()
  1255  
  1256  		files := `
  1257  -- hugo.toml --
  1258  baseURL = "https://example.com"
  1259  defaultContentLanguage = "en"
  1260  defaultContentLanguageInSubdir = true
  1261  disableKinds = ["taxonomy", "term", "page", "section"]
  1262  -- content/foo/bar.txt --
  1263  Foo.
  1264  -- layouts/index.html --
  1265  Home.
  1266  `
  1267  		b := Test(t, files)
  1268  
  1269  		b.AssertFileContent("public/en/index.html", "Home.")
  1270  		b.AssertFileContent("public/en/foo/bar.txt", "Foo.")
  1271  		b.AssertFileContent("public/index.html", "refresh")
  1272  		b.AssertFileContent("public/sitemap.xml", "sitemapindex")
  1273  		b.AssertFileContent("public/en/sitemap.xml", "urlset")
  1274  	})
  1275  
  1276  	t.Run("Two languages, default in sub dir", func(t *testing.T) {
  1277  		t.Parallel()
  1278  
  1279  		files := `
  1280  -- hugo.toml --
  1281  baseURL = "https://example.com"
  1282  defaultContentLanguage = "en"
  1283  defaultContentLanguageInSubdir = true
  1284  disableKinds = ["taxonomy", "term", "page", "section"]
  1285  [languages]
  1286  [languages.en]
  1287  title = "English Title"
  1288  [languages.sv]
  1289  title = "Swedish Title"
  1290  -- content/foo/bar.txt --
  1291  Foo.
  1292  -- layouts/index.html --
  1293  Home.
  1294  `
  1295  		b := Test(t, files)
  1296  
  1297  		b.AssertFileContent("public/en/index.html", "Home.")
  1298  		b.AssertFileContent("public/en/foo/bar.txt", "Foo.")
  1299  		b.AssertFileContent("public/index.html", "refresh")
  1300  		b.AssertFileContent("public/sitemap.xml", "sitemapindex")
  1301  		b.AssertFileContent("public/en/sitemap.xml", "urlset")
  1302  	})
  1303  
  1304  	t.Run("Two languages, default in root", func(t *testing.T) {
  1305  		t.Parallel()
  1306  
  1307  		files := `
  1308  -- hugo.toml --
  1309  baseURL = "https://example.com"
  1310  defaultContentLanguage = "en"
  1311  defaultContentLanguageInSubdir = false
  1312  disableKinds = ["taxonomy", "term", "page", "section"]
  1313  [languages]
  1314  [languages.en]
  1315  title = "English Title"
  1316  [languages.sv]
  1317  title = "Swedish Title"
  1318  -- content/foo/bar.txt --
  1319  Foo.
  1320  -- layouts/index.html --
  1321  Home.
  1322  `
  1323  		b := Test(t, files)
  1324  
  1325  		b.AssertFileContent("public/index.html", "Home.")
  1326  		b.AssertFileContent("public/foo/bar.txt", "Foo.")
  1327  		b.AssertFileContent("public/sitemap.xml", "sitemapindex")
  1328  		b.AssertFileContent("public/en/sitemap.xml", "urlset")
  1329  	})
  1330  }
  1331  
  1332  func TestLanguagesDisabled(t *testing.T) {
  1333  	t.Parallel()
  1334  
  1335  	files := `
  1336  -- hugo.toml --
  1337  [languages]
  1338  [languages.en]
  1339  title = "English Title"
  1340  [languages.sv]
  1341  title = "Swedish Title"
  1342  disabled = true
  1343  -- layouts/index.html --
  1344  Home.
  1345  
  1346  	
  1347  `
  1348  	b := Test(t, files)
  1349  
  1350  	b.Assert(len(b.H.Sites), qt.Equals, 1)
  1351  }
  1352  
  1353  func TestLoadConfigYamlEnvVar(t *testing.T) {
  1354  	defaultEnv := []string{`HUGO_OUTPUTS=home: ['json']`}
  1355  
  1356  	runVariant := func(t testing.TB, files string, env []string) *IntegrationTestBuilder {
  1357  		if env == nil {
  1358  			env = defaultEnv
  1359  		}
  1360  
  1361  		b := NewIntegrationTestBuilder(
  1362  			IntegrationTestConfig{
  1363  				T:           t,
  1364  				TxtarString: files,
  1365  				Environ:     env,
  1366  				BuildCfg:    BuildCfg{SkipRender: true},
  1367  			},
  1368  		).Build()
  1369  
  1370  		outputs := b.H.Configs.Base.Outputs
  1371  		if env == nil {
  1372  			home := outputs["home"]
  1373  			b.Assert(home, qt.Not(qt.IsNil))
  1374  			b.Assert(home, qt.DeepEquals, []string{"json"})
  1375  		}
  1376  
  1377  		return b
  1378  	}
  1379  
  1380  	t.Run("with empty slice", func(t *testing.T) {
  1381  		t.Parallel()
  1382  
  1383  		files := `
  1384  -- hugo.toml --
  1385  baseURL = "https://example.com"
  1386  disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "page", "section"]
  1387  [outputs]
  1388  home = ["html"]
  1389  
  1390  		`
  1391  		b := runVariant(t, files, []string{`HUGO_OUTPUTS=section: []`})
  1392  		outputs := b.H.Configs.Base.Outputs
  1393  		b.Assert(outputs, qt.DeepEquals, map[string][]string{
  1394  			"home":     {"html"},
  1395  			"page":     {"html"},
  1396  			"rss":      {"rss"},
  1397  			"section":  nil,
  1398  			"taxonomy": {"html", "rss"},
  1399  			"term":     {"html", "rss"},
  1400  		})
  1401  	})
  1402  
  1403  	t.Run("with existing outputs", func(t *testing.T) {
  1404  		t.Parallel()
  1405  
  1406  		files := `
  1407  -- hugo.toml --
  1408  baseURL = "https://example.com"
  1409  disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "page", "section"]
  1410  [outputs]
  1411  home = ["html"]
  1412  
  1413  		`
  1414  
  1415  		runVariant(t, files, nil)
  1416  	})
  1417  
  1418  	{
  1419  		t.Run("with existing outputs direct", func(t *testing.T) {
  1420  			t.Parallel()
  1421  
  1422  			files := `
  1423  -- hugo.toml --
  1424  baseURL = "https://example.com"
  1425  disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "page", "section"]
  1426  [outputs]
  1427  home = ["html"]
  1428  
  1429  		`
  1430  			runVariant(t, files, []string{"HUGO_OUTPUTS_HOME=json"})
  1431  		})
  1432  	}
  1433  
  1434  	t.Run("without existing outputs", func(t *testing.T) {
  1435  		t.Parallel()
  1436  
  1437  		files := `
  1438  -- hugo.toml --
  1439  baseURL = "https://example.com"
  1440  disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "page", "section"]
  1441  		
  1442  		`
  1443  
  1444  		runVariant(t, files, nil)
  1445  	})
  1446  
  1447  	t.Run("without existing outputs direct", func(t *testing.T) {
  1448  		t.Parallel()
  1449  
  1450  		files := `
  1451  -- hugo.toml --
  1452  baseURL = "https://example.com"
  1453  disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "page", "section"]
  1454  		`
  1455  
  1456  		runVariant(t, files, []string{"HUGO_OUTPUTS_HOME=json"})
  1457  	})
  1458  }
  1459  
  1460  // Issue #11257
  1461  func TestDisableKindsTaxonomyTerm(t *testing.T) {
  1462  	t.Parallel()
  1463  
  1464  	files := `
  1465  -- hugo.toml --
  1466  baseURL = "https://example.com"
  1467  disableKinds = ['taxonomyTerm']
  1468  [taxonomies]
  1469  category = 'categories'
  1470  -- content/p1.md --
  1471  ---
  1472  title: "P1"
  1473  categories: ["c1"]
  1474  ---
  1475  -- layouts/index.html --
  1476  Home.
  1477  -- layouts/_default/list.html --
  1478  List.
  1479  
  1480  
  1481  
  1482  `
  1483  	b := Test(t, files)
  1484  
  1485  	b.AssertFileExists("public/index.html", true)
  1486  	b.AssertFileExists("public/categories/c1/index.html", true)
  1487  	b.AssertFileExists("public/categories/index.html", false)
  1488  }
  1489  
  1490  func TestKindsUnknown(t *testing.T) {
  1491  	t.Parallel()
  1492  
  1493  	files := `
  1494  -- hugo.toml --
  1495  disableKinds = ['foo', 'home']
  1496  [outputs]
  1497  foo = ['HTML', 'AMP', 'RSS']
  1498  -- layouts/_default/list.html --
  1499  List.
  1500  
  1501  
  1502  
  1503  `
  1504  	b := NewIntegrationTestBuilder(
  1505  		IntegrationTestConfig{
  1506  			T:           t,
  1507  			TxtarString: files,
  1508  			LogLevel:    logg.LevelWarn,
  1509  		},
  1510  	).Init()
  1511  
  1512  	b.AssertLogContains("WARN  Unknown kind \"foo\" in disableKinds configuration.\n")
  1513  	b.AssertLogContains("WARN  Unknown kind \"foo\" in outputs configuration.\n")
  1514  }
  1515  
  1516  func TestDeprecateTaxonomyTerm(t *testing.T) {
  1517  	t.Parallel()
  1518  
  1519  	files := `
  1520  -- hugo.toml --
  1521  disableKinds = ['taxonomyTerm']
  1522  [outputs]
  1523  taxonomyterm = ['HTML', 'AMP', 'RSS']
  1524  -- layouts/_default/list.html --
  1525  List.
  1526  
  1527  
  1528  
  1529  `
  1530  	b := NewIntegrationTestBuilder(
  1531  		IntegrationTestConfig{
  1532  			T:           t,
  1533  			TxtarString: files,
  1534  			LogLevel:    logg.LevelWarn,
  1535  			BuildCfg:    BuildCfg{SkipRender: true},
  1536  		},
  1537  	).Init()
  1538  
  1539  	b.AssertLogContains("WARN  DEPRECATED: Kind \"taxonomyterm\" used in disableKinds is deprecated, use \"taxonomy\" instead.\n")
  1540  	b.AssertLogContains("WARN  DEPRECATED: Kind \"taxonomyterm\" used in outputs configuration is deprecated, use \"taxonomy\" instead.\n")
  1541  }
  1542  
  1543  func TestDisableKindsIssue12144(t *testing.T) {
  1544  	files := `
  1545  -- hugo.toml --
  1546  disableKinds = ["page"]
  1547  defaultContentLanguage = "pt-br"
  1548  -- layouts/index.html --
  1549  Home.
  1550  -- content/custom/index.pt-br.md --
  1551  ---
  1552  title: "P1 pt"
  1553  ---
  1554  -- content/custom/index.en-us.md --
  1555  ---
  1556  title: "P1 us"
  1557  ---
  1558  `
  1559  	Test(t, files)
  1560  }