github.com/soulteary/pocket-bookcase@v0.0.0-20240428065142-0b5a9a0fc98a/internal/http/routes/bookmark_test.go (about) 1 package routes 2 3 import ( 4 "context" 5 "net/http" 6 "net/http/httptest" 7 "strconv" 8 "testing" 9 10 "github.com/gin-gonic/gin" 11 "github.com/sirupsen/logrus" 12 sctx "github.com/soulteary/pocket-bookcase/internal/http/context" 13 "github.com/soulteary/pocket-bookcase/internal/http/templates" 14 "github.com/soulteary/pocket-bookcase/internal/model" 15 "github.com/soulteary/pocket-bookcase/internal/testutil" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestBookmarkRoutesGetBookmark(t *testing.T) { 20 logger := logrus.New() 21 22 _, deps := testutil.GetTestConfigurationAndDependencies(t, context.TODO(), logger) 23 24 g := gin.Default() 25 templates.SetupTemplates(g) 26 w := httptest.NewRecorder() 27 28 // Create a private and a public bookmark to use in tests 29 publicBookmark := testutil.GetValidBookmark() 30 publicBookmark.Public = 1 31 bookmarks, err := deps.Database.SaveBookmarks(context.TODO(), true, []model.BookmarkDTO{ 32 *testutil.GetValidBookmark(), 33 *publicBookmark, 34 }...) 35 36 require.NoError(t, err) 37 38 router := NewBookmarkRoutes(logger, deps) 39 40 t.Run("bookmark ID is not present", func(t *testing.T) { 41 gctx := gin.CreateTestContextOnly(w, g) 42 c := sctx.NewContextFromGin(gctx) 43 _, err := router.getBookmark(c) 44 require.Error(t, err) 45 require.Equal(t, http.StatusBadRequest, c.Writer.Status()) 46 }) 47 48 t.Run("bookmark ID is not parsable number", func(t *testing.T) { 49 gctx := gin.CreateTestContextOnly(w, g) 50 c := sctx.NewContextFromGin(gctx) 51 c.Params = append(c.Params, gin.Param{Key: "id", Value: "not a number"}) 52 _, err := router.getBookmark(c) 53 require.Error(t, err) 54 require.Equal(t, http.StatusInternalServerError, c.Writer.Status()) 55 }) 56 57 t.Run("bookmark ID does not exist", func(t *testing.T) { 58 gctx := gin.CreateTestContextOnly(w, g) 59 c := sctx.NewContextFromGin(gctx) 60 c.Params = append(c.Params, gin.Param{Key: "id", Value: "99"}) 61 bookmark, err := router.getBookmark(c) 62 require.Equal(t, http.StatusNotFound, c.Writer.Status()) 63 require.Nil(t, bookmark) 64 require.Error(t, err) 65 }) 66 67 t.Run("bookmark ID exists but user is not logged in", func(t *testing.T) { 68 gctx := gin.CreateTestContextOnly(w, g) 69 c := sctx.NewContextFromGin(gctx) 70 c.Request = httptest.NewRequest(http.MethodGet, "/bookmark/1", nil) 71 c.Params = append(c.Params, gin.Param{Key: "id", Value: "1"}) 72 bookmark, err := router.getBookmark(c) 73 require.Equal(t, http.StatusFound, c.Writer.Status()) 74 require.Nil(t, bookmark) 75 require.Error(t, err) 76 }) 77 78 t.Run("bookmark ID exists and its public and user is not logged in", func(t *testing.T) { 79 gctx := gin.CreateTestContextOnly(w, g) 80 c := sctx.NewContextFromGin(gctx) 81 c.Request = httptest.NewRequest(http.MethodGet, "/bookmark/"+strconv.Itoa(bookmarks[0].ID), nil) 82 c.Params = append(c.Params, gin.Param{Key: "id", Value: strconv.Itoa(bookmarks[1].ID)}) 83 bookmark, err := router.getBookmark(c) 84 require.Equal(t, http.StatusOK, c.Writer.Status()) 85 require.NotNil(t, bookmark) 86 require.NoError(t, err) 87 }) 88 89 t.Run("bookmark ID exists and user is logged in", func(t *testing.T) { 90 g := gin.Default() 91 templates.SetupTemplates(g) 92 gctx := gin.CreateTestContextOnly(w, g) 93 c := sctx.NewContextFromGin(gctx) 94 c.Set(model.ContextAccountKey, &model.Account{}) 95 c.Request = httptest.NewRequest(http.MethodGet, "/bookmark/"+strconv.Itoa(bookmarks[0].ID), nil) 96 c.Params = append(c.Params, gin.Param{Key: "id", Value: strconv.Itoa(bookmarks[0].ID)}) 97 bookmark, err := router.getBookmark(c) 98 require.Equal(t, http.StatusOK, c.Writer.Status()) 99 require.NotNil(t, bookmark) 100 require.NoError(t, err) 101 }) 102 } 103 104 func TestBookmarkContentHandler(t *testing.T) { 105 logger := logrus.New() 106 107 _, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger) 108 109 bookmark := testutil.GetValidBookmark() 110 bookmark.HTML = "<html><body><h1>Bookmark HTML content</h1></body></html>" 111 boomkarks, err := deps.Database.SaveBookmarks(context.TODO(), true, *bookmark) 112 require.NoError(t, err) 113 114 bookmark = &boomkarks[0] 115 116 t.Run("not logged in", func(t *testing.T) { 117 g := gin.Default() 118 router := NewBookmarkRoutes(logger, deps) 119 router.Setup(g.Group("/")) 120 w := httptest.NewRecorder() 121 path := "/" + strconv.Itoa(bookmark.ID) + "/content" 122 req, _ := http.NewRequest("GET", path, nil) 123 g.ServeHTTP(w, req) 124 require.Equal(t, http.StatusFound, w.Code) 125 require.Equal(t, "/login?dst="+path, w.Header().Get("Location")) 126 }) 127 128 t.Run("get existing bookmark content", func(t *testing.T) { 129 g := gin.Default() 130 templates.SetupTemplates(g) 131 g.Use(func(c *gin.Context) { 132 c.Set(model.ContextAccountKey, "test") 133 }) 134 router := NewBookmarkRoutes(logger, deps) 135 router.Setup(g.Group("/")) 136 w := httptest.NewRecorder() 137 req, _ := http.NewRequest("GET", "/"+strconv.Itoa(bookmark.ID)+"/content", nil) 138 g.ServeHTTP(w, req) 139 t.Log(w.Header().Get("Location")) 140 require.Equal(t, 200, w.Code) 141 require.Contains(t, w.Body.String(), bookmark.HTML) 142 }) 143 } 144 145 func TestBookmarkFileHandlers(t *testing.T) { 146 logger := logrus.New() 147 148 _, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger) 149 150 bookmark := testutil.GetValidBookmark() 151 bookmark.HTML = "<html><body><h1>Bookmark HTML content</h1></body></html>" 152 bookmark.HasArchive = true 153 bookmark.CreateArchive = true 154 bookmark.CreateEbook = true 155 bookmarks, err := deps.Database.SaveBookmarks(context.TODO(), true, *bookmark) 156 require.NoError(t, err) 157 158 bookmark, err = deps.Domains.Archiver.DownloadBookmarkArchive(bookmarks[0]) 159 require.NoError(t, err) 160 161 bookmarks, err = deps.Database.SaveBookmarks(context.TODO(), false, *bookmark) 162 require.NoError(t, err) 163 bookmark = &bookmarks[0] 164 165 g := gin.Default() 166 templates.SetupTemplates(g) 167 g.Use(func(c *gin.Context) { 168 c.Set(model.ContextAccountKey, "test") 169 }) 170 router := NewBookmarkRoutes(logger, deps) 171 router.Setup(g.Group("/")) 172 173 t.Run("get existing bookmark archive", func(t *testing.T) { 174 w := httptest.NewRecorder() 175 req, _ := http.NewRequest("GET", "/"+strconv.Itoa(bookmark.ID)+"/archive", nil) 176 g.ServeHTTP(w, req) 177 require.Contains(t, w.Body.String(), "iframe") 178 require.Equal(t, 200, w.Code) 179 }) 180 181 t.Run("get existing bookmark thumbnail", func(t *testing.T) { 182 w := httptest.NewRecorder() 183 req, _ := http.NewRequest("GET", "/"+strconv.Itoa(bookmark.ID)+"/thumb", nil) 184 g.ServeHTTP(w, req) 185 require.Equal(t, 200, w.Code) 186 }) 187 188 t.Run("bookmark without archive", func(t *testing.T) { 189 bookmark := testutil.GetValidBookmark() 190 bookmarks, err := deps.Database.SaveBookmarks(context.TODO(), true, *bookmark) 191 require.NoError(t, err) 192 193 w := httptest.NewRecorder() 194 req, _ := http.NewRequest("GET", "/"+strconv.Itoa(bookmarks[0].ID)+"/archive", nil) 195 g.ServeHTTP(w, req) 196 require.Equal(t, http.StatusNotFound, w.Code) 197 }) 198 199 t.Run("get existing bookmark archive file", func(t *testing.T) { 200 w := httptest.NewRecorder() 201 req, _ := http.NewRequest("GET", "/"+strconv.Itoa(bookmark.ID)+"/archive/file/", nil) 202 g.ServeHTTP(w, req) 203 require.Equal(t, 200, w.Code) 204 }) 205 206 t.Run("bookmark with ebook", func(t *testing.T) { 207 w := httptest.NewRecorder() 208 req, _ := http.NewRequest("GET", "/"+strconv.Itoa(bookmarks[0].ID)+"/ebook", nil) 209 g.ServeHTTP(w, req) 210 require.Equal(t, http.StatusOK, w.Code) 211 }) 212 213 t.Run("bookmark without ebook", func(t *testing.T) { 214 bookmark := testutil.GetValidBookmark() 215 bookmarks, err := deps.Database.SaveBookmarks(context.TODO(), true, *bookmark) 216 require.NoError(t, err) 217 218 w := httptest.NewRecorder() 219 req, _ := http.NewRequest("GET", "/"+strconv.Itoa(bookmarks[0].ID)+"/ebook", nil) 220 g.ServeHTTP(w, req) 221 require.Equal(t, http.StatusNotFound, w.Code) 222 }) 223 }