github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/lib/http/serve/dir_test.go (about)

     1  package serve
     2  
     3  import (
     4  	"errors"
     5  	"html/template"
     6  	"io"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"net/url"
    10  	"testing"
    11  	"time"
    12  
    13  	libhttp "github.com/rclone/rclone/lib/http"
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func GetTemplate(t *testing.T) *template.Template {
    19  	htmlTemplate, err := libhttp.GetTemplate("../../../cmd/serve/http/testdata/golden/testindex.html")
    20  	require.NoError(t, err)
    21  	return htmlTemplate
    22  }
    23  
    24  func TestNewDirectory(t *testing.T) {
    25  	d := NewDirectory("z", GetTemplate(t))
    26  	assert.Equal(t, "z", d.DirRemote)
    27  	assert.Equal(t, "Directory listing of /z", d.Title)
    28  }
    29  
    30  func TestSetQuery(t *testing.T) {
    31  	d := NewDirectory("z", GetTemplate(t))
    32  	assert.Equal(t, "", d.Query)
    33  	d.SetQuery(url.Values{"potato": []string{"42"}})
    34  	assert.Equal(t, "?potato=42", d.Query)
    35  	d.SetQuery(url.Values{})
    36  	assert.Equal(t, "", d.Query)
    37  }
    38  
    39  func TestAddHTMLEntry(t *testing.T) {
    40  	var modtime = time.Now()
    41  	var d = NewDirectory("z", GetTemplate(t))
    42  	d.AddHTMLEntry("", true, 0, modtime)
    43  	d.AddHTMLEntry("dir", true, 0, modtime)
    44  	d.AddHTMLEntry("a/b/c/d.txt", false, 64, modtime)
    45  	d.AddHTMLEntry("a/b/c/colon:colon.txt", false, 64, modtime)
    46  	d.AddHTMLEntry("\"quotes\".txt", false, 64, modtime)
    47  	assert.Equal(t, []DirEntry{
    48  		{remote: "", URL: "/", Leaf: "/", IsDir: true, Size: 0, ModTime: modtime},
    49  		{remote: "dir", URL: "dir/", Leaf: "dir/", IsDir: true, Size: 0, ModTime: modtime},
    50  		{remote: "a/b/c/d.txt", URL: "d.txt", Leaf: "d.txt", IsDir: false, Size: 64, ModTime: modtime},
    51  		{remote: "a/b/c/colon:colon.txt", URL: "./colon:colon.txt", Leaf: "colon:colon.txt", IsDir: false, Size: 64, ModTime: modtime},
    52  		{remote: "\"quotes\".txt", URL: "%22quotes%22.txt", Leaf: "\"quotes\".txt", Size: 64, IsDir: false, ModTime: modtime},
    53  	}, d.Entries)
    54  
    55  	// Now test with a query parameter
    56  	d = NewDirectory("z", GetTemplate(t)).SetQuery(url.Values{"potato": []string{"42"}})
    57  	d.AddHTMLEntry("file", false, 64, modtime)
    58  	d.AddHTMLEntry("dir", true, 0, modtime)
    59  	assert.Equal(t, []DirEntry{
    60  		{remote: "file", URL: "file?potato=42", Leaf: "file", IsDir: false, Size: 64, ModTime: modtime},
    61  		{remote: "dir", URL: "dir/?potato=42", Leaf: "dir/", IsDir: true, Size: 0, ModTime: modtime},
    62  	}, d.Entries)
    63  }
    64  
    65  func TestAddEntry(t *testing.T) {
    66  	var d = NewDirectory("z", GetTemplate(t))
    67  	d.AddEntry("", true)
    68  	d.AddEntry("dir", true)
    69  	d.AddEntry("a/b/c/d.txt", false)
    70  	d.AddEntry("a/b/c/colon:colon.txt", false)
    71  	d.AddEntry("\"quotes\".txt", false)
    72  	assert.Equal(t, []DirEntry{
    73  		{remote: "", URL: "/", Leaf: "/"},
    74  		{remote: "dir", URL: "dir/", Leaf: "dir/"},
    75  		{remote: "a/b/c/d.txt", URL: "d.txt", Leaf: "d.txt"},
    76  		{remote: "a/b/c/colon:colon.txt", URL: "./colon:colon.txt", Leaf: "colon:colon.txt"},
    77  		{remote: "\"quotes\".txt", URL: "%22quotes%22.txt", Leaf: "\"quotes\".txt"},
    78  	}, d.Entries)
    79  
    80  	// Now test with a query parameter
    81  	d = NewDirectory("z", GetTemplate(t)).SetQuery(url.Values{"potato": []string{"42"}})
    82  	d.AddEntry("file", false)
    83  	d.AddEntry("dir", true)
    84  	assert.Equal(t, []DirEntry{
    85  		{remote: "file", URL: "file?potato=42", Leaf: "file"},
    86  		{remote: "dir", URL: "dir/?potato=42", Leaf: "dir/"},
    87  	}, d.Entries)
    88  }
    89  
    90  func TestError(t *testing.T) {
    91  	w := httptest.NewRecorder()
    92  	err := errors.New("help")
    93  	Error("potato", w, "sausage", err)
    94  	resp := w.Result()
    95  	assert.Equal(t, http.StatusInternalServerError, resp.StatusCode)
    96  	body, _ := io.ReadAll(resp.Body)
    97  	assert.Equal(t, "sausage.\n", string(body))
    98  }
    99  
   100  func TestServe(t *testing.T) {
   101  	d := NewDirectory("aDirectory", GetTemplate(t))
   102  	d.AddEntry("file", false)
   103  	d.AddEntry("dir", true)
   104  
   105  	w := httptest.NewRecorder()
   106  	r := httptest.NewRequest("GET", "http://example.com/aDirectory/", nil)
   107  	d.Serve(w, r)
   108  	resp := w.Result()
   109  	assert.Equal(t, http.StatusOK, resp.StatusCode)
   110  	body, _ := io.ReadAll(resp.Body)
   111  	assert.Equal(t, `<!DOCTYPE html>
   112  <html lang="en">
   113  <head>
   114  <meta charset="utf-8">
   115  <title>Directory listing of /aDirectory</title>
   116  </head>
   117  <body>
   118  <h1>Directory listing of /aDirectory</h1>
   119  <a href="file">file</a><br />
   120  <a href="dir/">dir/</a><br />
   121  </body>
   122  </html>
   123  `, string(body))
   124  }