html_list_errors_test.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package controller
  2. import (
  3. "errors"
  4. "html/template"
  5. "net/http"
  6. "net/http/httptest"
  7. "strings"
  8. "testing"
  9. "git.aetherial.dev/aeth/keiji/pkg/storage"
  10. "github.com/gin-gonic/gin"
  11. )
  12. type htmlLegacyRepo struct {
  13. storage.DocumentIO
  14. category string
  15. }
  16. func (r *htmlLegacyRepo) GetDocument(storage.Identifier) (storage.Document, error) {
  17. return storage.Document{Title: "post"}, nil
  18. }
  19. func (r *htmlLegacyRepo) GetByCategory(category string) []storage.Document {
  20. r.category = category
  21. return nil
  22. }
  23. func (r *htmlLegacyRepo) GetImagesByCategory(category string) []storage.Image {
  24. r.category = category
  25. return nil
  26. }
  27. func (r *htmlLegacyRepo) GetNavBarLinks() []storage.NavBarItem { return nil }
  28. func (r *htmlLegacyRepo) GetDropdownElements() []storage.LinkPair { return nil }
  29. type htmlErrorRepo struct {
  30. *htmlLegacyRepo
  31. storage.DocumentListReader
  32. fail string
  33. }
  34. func (r *htmlErrorRepo) listError(name string) error {
  35. if r.fail == name {
  36. return errors.New("list failure: " + name)
  37. }
  38. return nil
  39. }
  40. func (r *htmlErrorRepo) GetByCategoryWithError(category string) ([]storage.Document, error) {
  41. r.category = category
  42. return nil, r.listError("documents")
  43. }
  44. func (r *htmlErrorRepo) GetImagesByCategoryWithError(category string) ([]storage.Image, error) {
  45. r.category = category
  46. return nil, r.listError("images")
  47. }
  48. func (r *htmlErrorRepo) GetNavBarLinksWithError() ([]storage.NavBarItem, error) {
  49. return nil, r.listError("navbar")
  50. }
  51. func (r *htmlErrorRepo) GetDropdownElementsWithError() ([]storage.LinkPair, error) {
  52. return nil, r.listError("menu")
  53. }
  54. func htmlTestRouter(repo storage.DocumentIO) *gin.Engine {
  55. r := gin.New()
  56. r.SetHTMLTemplate(template.Must(template.New("test").Parse(`{{define "home"}}{{.default.Body}}{{end}}{{define "writing"}}writing{{end}}{{define "digital_art"}}digital{{end}}{{define "blogpost"}}{{.Title}}{{end}}`)))
  57. c := &Controller{database: repo}
  58. r.GET("/", c.ServeHome)
  59. r.GET("/blog", c.ServeBlog)
  60. r.GET("/creative", c.ServeCreative)
  61. r.GET("/digital", c.ServeDigitalArt)
  62. r.GET("/writing/:id", c.ServePost)
  63. return r
  64. }
  65. func TestHTMLListFailures(t *testing.T) {
  66. gin.SetMode(gin.TestMode)
  67. for _, tc := range []struct{ path, failure string }{
  68. {"/", "documents"}, {"/", "navbar"}, {"/", "menu"},
  69. {"/blog", "documents"}, {"/creative", "documents"},
  70. {"/digital", "images"}, {"/digital", "navbar"}, {"/digital", "menu"},
  71. {"/writing/id", "navbar"}, {"/writing/id", "menu"},
  72. } {
  73. t.Run(tc.path+"/"+tc.failure, func(t *testing.T) {
  74. repo := &htmlErrorRepo{htmlLegacyRepo: &htmlLegacyRepo{}, fail: tc.failure}
  75. response := httptest.NewRecorder()
  76. htmlTestRouter(repo).ServeHTTP(response, httptest.NewRequest(http.MethodGet, tc.path, nil))
  77. if response.Code != http.StatusInternalServerError || !strings.Contains(response.Body.String(), "Could not load content") {
  78. t.Fatalf("got status %d body %q", response.Code, response.Body.String())
  79. }
  80. })
  81. }
  82. }
  83. func TestHTMLListEmptyAndLegacyCompatibility(t *testing.T) {
  84. gin.SetMode(gin.TestMode)
  85. for _, legacy := range []bool{false, true} {
  86. for _, tc := range []struct{ path, category, body string }{
  87. {"/", storage.HOMEPAGE, "Under construction. Sry :("},
  88. {"/blog", storage.BLOG, "writing"}, {"/creative", storage.CREATIVE, "writing"},
  89. {"/digital", storage.DIGITAL_ART, "digital"}, {"/writing/id", "", "post"},
  90. } {
  91. t.Run(tc.path+map[bool]string{true: "/legacy", false: "/error-reader"}[legacy], func(t *testing.T) {
  92. base := &htmlLegacyRepo{}
  93. var repo storage.DocumentIO = base
  94. if !legacy {
  95. repo = &htmlErrorRepo{htmlLegacyRepo: base}
  96. }
  97. response := httptest.NewRecorder()
  98. htmlTestRouter(repo).ServeHTTP(response, httptest.NewRequest(http.MethodGet, tc.path, nil))
  99. if response.Code != http.StatusOK || !strings.Contains(response.Body.String(), tc.body) || base.category != tc.category {
  100. t.Fatalf("got status %d body %q category %q", response.Code, response.Body.String(), base.category)
  101. }
  102. })
  103. }
  104. }
  105. }
  106. func (r *htmlErrorRepo) GetAssetsWithError() ([]storage.Asset, error) {
  107. return nil, r.listError("assets")
  108. }
  109. func (r *htmlLegacyRepo) GetAssets() []storage.Asset { return nil }
  110. func TestAssetListFailureReturns500(t *testing.T) {
  111. gin.SetMode(gin.TestMode)
  112. r := gin.New()
  113. repo := &htmlErrorRepo{htmlLegacyRepo: &htmlLegacyRepo{}, fail: "assets"}
  114. c := &Controller{database: repo}
  115. r.GET("/assets/:file", c.ServeAsset)
  116. rec := httptest.NewRecorder()
  117. r.ServeHTTP(rec, httptest.NewRequest("GET", "/assets/test.png", nil))
  118. if rec.Code != http.StatusInternalServerError || !strings.Contains(rec.Body.String(), "Could not load content") {
  119. t.Fatalf("%d %s", rec.Code, rec.Body.String())
  120. }
  121. }