git.greeks.studio/lethews/hugo@v0.47.1/hugolib/alias_test.go (about)

     1  // Copyright 2018 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  	"path/filepath"
    18  	"runtime"
    19  	"testing"
    20  
    21  	"github.com/gohugoio/hugo/common/loggers"
    22  
    23  	"github.com/stretchr/testify/require"
    24  )
    25  
    26  const pageWithAlias = `---
    27  title: Has Alias
    28  aliases: ["foo/bar/"]
    29  ---
    30  For some moments the old man did not reply. He stood with bowed head, buried in deep thought. But at last he spoke.
    31  `
    32  
    33  const pageWithAliasMultipleOutputs = `---
    34  title: Has Alias for HTML and AMP
    35  aliases: ["foo/bar/"]
    36  outputs: ["HTML", "AMP", "JSON"]
    37  ---
    38  For some moments the old man did not reply. He stood with bowed head, buried in deep thought. But at last he spoke.
    39  `
    40  
    41  const basicTemplate = "<html><body>{{.Content}}</body></html>"
    42  const aliasTemplate = "<html><body>ALIASTEMPLATE</body></html>"
    43  
    44  func TestAlias(t *testing.T) {
    45  	t.Parallel()
    46  	assert := require.New(t)
    47  
    48  	b := newTestSitesBuilder(t)
    49  	b.WithSimpleConfigFile().WithContent("page.md", pageWithAlias)
    50  	b.CreateSites().Build(BuildCfg{})
    51  
    52  	assert.Equal(1, len(b.H.Sites))
    53  	require.Len(t, b.H.Sites[0].RegularPages, 1)
    54  
    55  	// the real page
    56  	b.AssertFileContent("public/page/index.html", "For some moments the old man")
    57  	// the alias redirector
    58  	b.AssertFileContent("public/foo/bar/index.html", "<meta http-equiv=\"refresh\" content=\"0; ")
    59  }
    60  
    61  func TestAliasMultipleOutputFormats(t *testing.T) {
    62  	t.Parallel()
    63  
    64  	assert := require.New(t)
    65  
    66  	b := newTestSitesBuilder(t)
    67  	b.WithSimpleConfigFile().WithContent("page.md", pageWithAliasMultipleOutputs)
    68  
    69  	b.WithTemplates(
    70  		"_default/single.html", basicTemplate,
    71  		"_default/single.amp.html", basicTemplate,
    72  		"_default/single.json", basicTemplate)
    73  
    74  	b.CreateSites().Build(BuildCfg{})
    75  
    76  	// the real pages
    77  	b.AssertFileContent("public/page/index.html", "For some moments the old man")
    78  	b.AssertFileContent("public/amp/page/index.html", "For some moments the old man")
    79  	b.AssertFileContent("public/page/index.json", "For some moments the old man")
    80  
    81  	// the alias redirectors
    82  	b.AssertFileContent("public/foo/bar/index.html", "<meta http-equiv=\"refresh\" content=\"0; ")
    83  	b.AssertFileContent("public/foo/bar/amp/index.html", "<meta http-equiv=\"refresh\" content=\"0; ")
    84  	assert.False(b.CheckExists("public/foo/bar/index.json"))
    85  }
    86  
    87  func TestAliasTemplate(t *testing.T) {
    88  	t.Parallel()
    89  
    90  	b := newTestSitesBuilder(t)
    91  	b.WithSimpleConfigFile().WithContent("page.md", pageWithAlias).WithTemplatesAdded("alias.html", aliasTemplate)
    92  
    93  	b.CreateSites().Build(BuildCfg{})
    94  
    95  	// the real page
    96  	b.AssertFileContent("public/page/index.html", "For some moments the old man")
    97  	// the alias redirector
    98  	b.AssertFileContent("public/foo/bar/index.html", "ALIASTEMPLATE")
    99  }
   100  
   101  func TestTargetPathHTMLRedirectAlias(t *testing.T) {
   102  	h := newAliasHandler(nil, loggers.NewErrorLogger(), false)
   103  
   104  	errIsNilForThisOS := runtime.GOOS != "windows"
   105  
   106  	tests := []struct {
   107  		value    string
   108  		expected string
   109  		errIsNil bool
   110  	}{
   111  		{"", "", false},
   112  		{"s", filepath.FromSlash("s/index.html"), true},
   113  		{"/", "", false},
   114  		{"alias 1", filepath.FromSlash("alias 1/index.html"), true},
   115  		{"alias 2/", filepath.FromSlash("alias 2/index.html"), true},
   116  		{"alias 3.html", "alias 3.html", true},
   117  		{"alias4.html", "alias4.html", true},
   118  		{"/alias 5.html", "alias 5.html", true},
   119  		{"/трям.html", "трям.html", true},
   120  		{"../../../../tmp/passwd", "", false},
   121  		{"/foo/../../../../tmp/passwd", filepath.FromSlash("tmp/passwd/index.html"), true},
   122  		{"foo/../../../../tmp/passwd", "", false},
   123  		{"C:\\Windows", filepath.FromSlash("C:\\Windows/index.html"), errIsNilForThisOS},
   124  		{"/trailing-space /", filepath.FromSlash("trailing-space /index.html"), errIsNilForThisOS},
   125  		{"/trailing-period./", filepath.FromSlash("trailing-period./index.html"), errIsNilForThisOS},
   126  		{"/tab\tseparated/", filepath.FromSlash("tab\tseparated/index.html"), errIsNilForThisOS},
   127  		{"/chrome/?p=help&ctx=keyboard#topic=3227046", filepath.FromSlash("chrome/?p=help&ctx=keyboard#topic=3227046/index.html"), errIsNilForThisOS},
   128  		{"/LPT1/Printer/", filepath.FromSlash("LPT1/Printer/index.html"), errIsNilForThisOS},
   129  	}
   130  
   131  	for _, test := range tests {
   132  		path, err := h.targetPathAlias(test.value)
   133  		if (err == nil) != test.errIsNil {
   134  			t.Errorf("Expected err == nil => %t, got: %t. err: %s", test.errIsNil, err == nil, err)
   135  			continue
   136  		}
   137  		if err == nil && path != test.expected {
   138  			t.Errorf("Expected: \"%s\", got: \"%s\"", test.expected, path)
   139  		}
   140  	}
   141  }