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  }