github.com/blend/go-sdk@v1.20220411.3/web/view_cache_test.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package web
     9  
    10  import (
    11  	"bytes"
    12  	"fmt"
    13  	"html/template"
    14  	"net/http"
    15  	"testing"
    16  
    17  	"github.com/blend/go-sdk/assert"
    18  	"github.com/blend/go-sdk/ex"
    19  )
    20  
    21  func TestViewCacheProperties(t *testing.T) {
    22  	assert := assert.New(t)
    23  
    24  	vc, err := NewViewCache()
    25  	assert.Nil(err)
    26  	assert.NotNil(vc.FuncMap)
    27  
    28  	assert.Equal(DefaultTemplateNameBadRequest, vc.BadRequestTemplateName)
    29  	assert.Nil(OptViewCacheBadRequestTemplateName("foo")(vc))
    30  	assert.Equal("foo", vc.BadRequestTemplateName)
    31  
    32  	assert.Equal(DefaultTemplateNameInternalError, vc.InternalErrorTemplateName)
    33  	assert.Nil(OptViewCacheInternalErrorTemplateName("bar")(vc))
    34  	assert.Equal("bar", vc.InternalErrorTemplateName)
    35  
    36  	assert.Equal(DefaultTemplateNameNotFound, vc.NotFoundTemplateName)
    37  	assert.Nil(OptViewCacheNotFoundTemplateName("baz")(vc))
    38  	assert.Equal("baz", vc.NotFoundTemplateName)
    39  
    40  	assert.Equal(DefaultTemplateNameNotAuthorized, vc.NotAuthorizedTemplateName)
    41  	assert.Nil(OptViewCacheNotAuthorizedTemplateName("buzz")(vc))
    42  	assert.Equal("buzz", vc.NotAuthorizedTemplateName)
    43  
    44  	assert.Equal(DefaultTemplateNameStatus, vc.StatusTemplateName)
    45  	assert.Nil(OptViewCacheStatusTemplateName("fuzz")(vc))
    46  	assert.Equal("fuzz", vc.StatusTemplateName)
    47  
    48  	assert.Empty(vc.Paths)
    49  	assert.Nil(OptViewCachePaths("foo", "bar")(vc))
    50  	assert.NotEmpty(vc.Paths)
    51  
    52  	assert.Empty(vc.Literals)
    53  	assert.Nil(OptViewCacheLiterals("boo", "loo")(vc))
    54  	assert.NotEmpty(vc.Literals)
    55  }
    56  
    57  func TestViewCacheAddRawViews(t *testing.T) {
    58  	assert := assert.New(t)
    59  
    60  	vc := MustNewViewCache()
    61  	vc.AddLiterals(`{{ define "test" }}<h1> This is a test. </h1>{{ end }}`)
    62  
    63  	view, err := vc.Parse()
    64  	assert.Nil(err)
    65  	assert.NotNil(view)
    66  
    67  	buf := bytes.NewBuffer(nil)
    68  	assert.Nil(view.ExecuteTemplate(buf, "test", nil))
    69  	assert.NotEmpty(buf.String())
    70  
    71  	vc = MustNewViewCache()
    72  	vc.AddLiterals(`{{define "test"}}failure{{`)
    73  	_, err = vc.Parse()
    74  	assert.NotNil(err)
    75  
    76  	vc = MustNewViewCache()
    77  	vc.AddPaths("this path doesn't exist at all")
    78  	_, err = vc.Parse()
    79  	assert.NotNil(err)
    80  }
    81  
    82  func TestViewCacheCached(t *testing.T) {
    83  	assert := assert.New(t)
    84  
    85  	vc := MustNewViewCache()
    86  	assert.False(vc.LiveReload)
    87  	vc.AddLiterals(`{{ define "foo" }}bar{{ end }}`)
    88  	assert.Nil(vc.Initialize())
    89  
    90  	tmp, err := vc.Lookup("foo")
    91  	assert.Nil(err)
    92  	assert.NotNil(tmp)
    93  	buf := bytes.NewBuffer(nil)
    94  	assert.Nil(tmp.Execute(buf, nil))
    95  	assert.Equal("bar", buf.String())
    96  
    97  	vc.Literals = []string{`{{ define "foo" }}baz{{ end }}`}
    98  	tmp, err = vc.Lookup("foo")
    99  	assert.Nil(err)
   100  	assert.NotNil(tmp)
   101  	buf = bytes.NewBuffer(nil)
   102  	assert.Nil(tmp.Execute(buf, nil))
   103  	assert.Equal("bar", buf.String())
   104  
   105  	vc = MustNewViewCache()
   106  	vc.AddLiterals(`{{define "test"}}failure{{`)
   107  	_, err = vc.Lookup("foo")
   108  	assert.NotNil(err)
   109  }
   110  
   111  func TestViewCacheCachingDisabled(t *testing.T) {
   112  	assert := assert.New(t)
   113  
   114  	vc := MustNewViewCache(OptViewCacheLiveReload(true))
   115  	assert.True(vc.LiveReload)
   116  	vc.AddLiterals(`{{ define "foo" }}bar{{ end }}`)
   117  	assert.Nil(vc.Initialize())
   118  
   119  	tmp, err := vc.Lookup("foo")
   120  	assert.Nil(err)
   121  	assert.NotNil(tmp)
   122  	buf := bytes.NewBuffer(nil)
   123  	assert.Nil(tmp.Execute(buf, nil))
   124  	assert.Equal("bar", buf.String())
   125  
   126  	vc.Literals = []string{`{{ define "foo" }}baz{{ end }}`}
   127  	tmp, err = vc.Lookup("foo")
   128  	assert.Nil(err)
   129  	assert.NotNil(tmp)
   130  	buf = bytes.NewBuffer(nil)
   131  	assert.Nil(tmp.Execute(buf, nil))
   132  	assert.Equal("baz", buf.String())
   133  }
   134  
   135  func TestViewCacheBadRequest(t *testing.T) {
   136  	assert := assert.New(t)
   137  
   138  	vc := MustNewViewCache()
   139  	assert.Nil(vc.Initialize())
   140  	vr, _ := vc.BadRequest(ex.Class("only a test")).(*ViewResult)
   141  	assert.Equal(vc.BadRequestTemplateName, vr.ViewName)
   142  	assert.Equal(http.StatusBadRequest, vr.StatusCode)
   143  	assert.NotNil(vr.Views)
   144  	assert.NotNil(vr.ViewModel)
   145  
   146  	vc = MustNewViewCache()
   147  	vc.AddLiterals(`{{define "test"}}failure{{`)
   148  	vr, _ = vc.BadRequest(fmt.Errorf("err")).(*ViewResult)
   149  	assert.NotNil(vr.ViewModel)
   150  	_, ok := vr.ViewModel.(error)
   151  	assert.True(ok)
   152  }
   153  
   154  func TestViewCacheInternalError(t *testing.T) {
   155  	assert := assert.New(t)
   156  
   157  	vc := MustNewViewCache()
   158  	assert.Nil(vc.Initialize())
   159  
   160  	ler, _ := vc.InternalError(ex.Class("only a test")).(*LoggedErrorResult)
   161  	assert.NotNil(ler)
   162  	vr := ler.Result.(*ViewResult)
   163  	assert.Equal(vc.InternalErrorTemplateName, vr.ViewName)
   164  	assert.Equal(http.StatusInternalServerError, vr.StatusCode)
   165  	assert.NotNil(vr.Views)
   166  	assert.NotNil(vr.Template)
   167  	assert.NotNil(vr.ViewModel)
   168  
   169  	vc = MustNewViewCache()
   170  	vc.AddLiterals(`{{define "test"}}failure{{`)
   171  	vr, _ = vc.InternalError(fmt.Errorf("err")).(*ViewResult)
   172  	assert.NotNil(vr.ViewModel)
   173  	_, ok := vr.ViewModel.(error)
   174  	assert.True(ok)
   175  }
   176  
   177  func TestViewCacheNotFound(t *testing.T) {
   178  	assert := assert.New(t)
   179  
   180  	vc := MustNewViewCache()
   181  	assert.Nil(vc.Initialize())
   182  
   183  	vr, _ := vc.NotFound().(*ViewResult)
   184  	assert.NotNil(vr)
   185  	assert.Equal(vc.NotFoundTemplateName, vr.ViewName)
   186  	assert.Equal(http.StatusNotFound, vr.StatusCode)
   187  	assert.NotNil(vr.Views)
   188  	assert.NotNil(vr.Template)
   189  	assert.Nil(vr.ViewModel)
   190  
   191  	vc = MustNewViewCache()
   192  	vc.AddLiterals(`{{define "test"}}failure{{`)
   193  	vr, _ = vc.NotFound().(*ViewResult)
   194  	assert.NotNil(vr.ViewModel)
   195  	_, ok := vr.ViewModel.(error)
   196  	assert.True(ok)
   197  }
   198  
   199  func TestViewCacheNotAuthorized(t *testing.T) {
   200  	assert := assert.New(t)
   201  
   202  	vc := MustNewViewCache()
   203  	assert.Nil(vc.Initialize())
   204  
   205  	vr, _ := vc.NotAuthorized().(*ViewResult)
   206  	assert.NotNil(vr)
   207  	assert.Equal(vc.NotAuthorizedTemplateName, vr.ViewName)
   208  	assert.Equal(http.StatusUnauthorized, vr.StatusCode)
   209  	assert.NotNil(vr.Views)
   210  	assert.NotNil(vr.Template)
   211  	assert.Nil(vr.ViewModel)
   212  
   213  	vc = MustNewViewCache()
   214  	vc.AddLiterals(`{{define "test"}}failure{{`)
   215  	vr, _ = vc.NotAuthorized().(*ViewResult)
   216  	assert.NotNil(vr.ViewModel)
   217  	_, ok := vr.ViewModel.(error)
   218  	assert.True(ok)
   219  }
   220  
   221  func TestViewCacheStatus(t *testing.T) {
   222  	assert := assert.New(t)
   223  
   224  	vc := MustNewViewCache()
   225  	assert.Nil(vc.Initialize())
   226  
   227  	vr, _ := vc.Status(http.StatusFailedDependency, nil).(*ViewResult)
   228  	assert.NotNil(vr)
   229  	assert.Equal(vc.StatusTemplateName, vr.ViewName)
   230  	assert.Equal(http.StatusFailedDependency, vr.StatusCode)
   231  	assert.NotNil(vr.Views)
   232  	assert.NotNil(vr.Template)
   233  	assert.NotNil(vr.ViewModel)
   234  
   235  	vc = MustNewViewCache()
   236  	vc.AddLiterals(`{{define "test"}}failure{{`)
   237  	vr, _ = vc.Status(http.StatusPreconditionFailed, nil).(*ViewResult)
   238  	assert.NotNil(vr.ViewModel)
   239  	_, ok := vr.ViewModel.(error)
   240  	assert.True(ok)
   241  }
   242  
   243  func TestViewCacheViewStatus(t *testing.T) {
   244  	assert := assert.New(t)
   245  
   246  	vc := MustNewViewCache()
   247  	assert.Nil(vc.Initialize())
   248  
   249  	vc.AddLiterals(`{{define "test"}}failure{{`)
   250  	vr, _ := vc.ViewStatus(http.StatusPreconditionFailed, "", nil).(*ViewResult)
   251  	assert.NotNil(vr.ViewModel)
   252  	_, ok := vr.ViewModel.(error)
   253  	assert.True(ok)
   254  }
   255  
   256  func TestViewCacheView(t *testing.T) {
   257  	assert := assert.New(t)
   258  
   259  	vc := MustNewViewCache()
   260  	vc.AddLiterals(
   261  		`{{ define "test" }}{{.ViewModel}}{{end}}`,
   262  	)
   263  	assert.Nil(vc.Initialize())
   264  
   265  	vr, _ := vc.View("test", "foo").(*ViewResult)
   266  	assert.NotNil(vr)
   267  	assert.Equal("test", vr.ViewName)
   268  	assert.Equal(http.StatusOK, vr.StatusCode)
   269  	assert.Equal("foo", vr.ViewModel)
   270  	assert.NotNil(vr.Template)
   271  	assert.NotNil(vr.Views)
   272  
   273  	// handle if the view is not found ...
   274  	ler, _ := vc.View("not-test", "foo").(*LoggedErrorResult)
   275  	assert.NotNil(ler)
   276  	vr, _ = ler.Result.(*ViewResult)
   277  	assert.Equal(vc.InternalErrorTemplateName, vr.ViewName)
   278  	assert.Equal(http.StatusInternalServerError, vr.StatusCode)
   279  	assert.NotNil(vr.Template)
   280  	assert.NotNil(vr.Views)
   281  }
   282  
   283  func TestViewCacheViewError(t *testing.T) {
   284  	assert := assert.New(t)
   285  
   286  	vc := MustNewViewCache()
   287  
   288  	vcr := vc.viewError(ex.Class("test error")).(*ViewResult)
   289  	assert.NotNil(vcr)
   290  	assert.Equal(DefaultTemplateNameInternalError, vcr.ViewName)
   291  	assert.Equal(http.StatusInternalServerError, vcr.StatusCode)
   292  	assert.Equal(ex.Class("test error"), vcr.ViewModel)
   293  	assert.NotNil(vcr.Template)
   294  	assert.NotNil(vcr.Views)
   295  }
   296  
   297  func TestViewCacheFuncs(t *testing.T) {
   298  	assert := assert.New(t)
   299  
   300  	vc := MustNewViewCache()
   301  
   302  	f := func() {}
   303  
   304  	vc.FuncMap = nil
   305  	opt := OptViewCacheFunc("useless", f)
   306  	assert.NotNil(opt)
   307  	assert.Nil(opt(vc))
   308  	assert.NotEmpty(vc.FuncMap)
   309  	_, ok := vc.FuncMap["useless"]
   310  	assert.True(ok)
   311  
   312  	opt = OptViewCacheFuncMap(template.FuncMap{})
   313  	assert.Nil(opt(vc))
   314  	assert.Empty(vc.FuncMap)
   315  }