goyave.dev/goyave/v5@v5.0.0-rc9.0.20240517145003-d3f977d0b9f3/database/paginator_test.go (about) 1 package database 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/assert" 7 "github.com/stretchr/testify/require" 8 "gorm.io/driver/sqlite" 9 "gorm.io/gorm" 10 "goyave.dev/goyave/v5/config" 11 ) 12 13 type TestArticle struct { 14 Author *TestUser `gorm:"foreignKey:AuthorID"` 15 16 Title string `gorm:"type:varchar(255)"` 17 Content string `gorm:"type:text"` 18 ID uint `gorm:"primaryKey"` 19 AuthorID uint 20 } 21 22 func articleGenerator() *TestArticle { 23 return &TestArticle{ 24 Title: "lorem ipsum", 25 Content: "lorem ipsum sit dolor amet", 26 } 27 } 28 29 func preparePaginatorTestDB() (*gorm.DB, []*TestArticle) { 30 cfg := config.LoadDefault() 31 cfg.Set("app.debug", false) 32 cfg.Set("database.connection", "sqlite3_paginator_test") 33 cfg.Set("database.name", "paginator_test.db") 34 cfg.Set("database.options", "mode=memory") 35 db, err := New(cfg, nil) 36 if err != nil { 37 panic(err) 38 } 39 40 if err := db.AutoMigrate(&TestUser{}, &TestArticle{}); err != nil { 41 panic(err) 42 } 43 44 author := userGenerator() 45 if err := db.Create(author).Error; err != nil { 46 panic(err) 47 } 48 49 factory := NewFactory(articleGenerator) 50 factory.Override(&TestArticle{AuthorID: author.ID}) 51 52 articles := factory.Save(db, 11) 53 return db, articles 54 } 55 56 func TestPaginator(t *testing.T) { 57 RegisterDialect("sqlite3_paginator_test", "file:{name}?{options}", sqlite.Open) 58 t.Cleanup(func() { 59 mu.Lock() 60 delete(dialects, "sqlite3_paginator_test") 61 mu.Unlock() 62 }) 63 64 t.Run("UpdatePageInfo", func(t *testing.T) { 65 db, _ := preparePaginatorTestDB() 66 articles := []*TestArticle{} 67 p := NewPaginator(db, 2, 5, &articles) 68 69 assert.Equal(t, db, p.DB) 70 assert.Equal(t, 2, p.CurrentPage) 71 assert.Equal(t, 5, p.PageSize) 72 assert.Equal(t, &articles, p.Records) 73 74 err := p.UpdatePageInfo() 75 require.NoError(t, err) 76 77 assert.Equal(t, int64(11), p.Total) 78 assert.Equal(t, int64(3), p.MaxPage) 79 assert.True(t, p.loadedPageInfo) 80 }) 81 82 t.Run("Find", func(t *testing.T) { 83 db, srcArticles := preparePaginatorTestDB() 84 articles := []*TestArticle{} 85 p := NewPaginator(db, 2, 5, &articles) 86 87 assert.Equal(t, db, p.DB) 88 assert.Equal(t, 2, p.CurrentPage) 89 assert.Equal(t, 5, p.PageSize) 90 assert.Equal(t, &articles, p.Records) 91 92 err := p.Find() 93 require.NoError(t, err) 94 95 assert.Equal(t, int64(11), p.Total) 96 assert.Equal(t, int64(3), p.MaxPage) 97 assert.True(t, p.loadedPageInfo) 98 assert.Equal(t, srcArticles[5:10], *p.Records) 99 }) 100 101 t.Run("Find_no_record", func(t *testing.T) { 102 cfg := config.LoadDefault() 103 cfg.Set("app.debug", false) 104 cfg.Set("database.connection", "sqlite3_paginator_test") 105 cfg.Set("database.name", "paginator_test.db") 106 cfg.Set("database.options", "mode=memory") 107 db, err := New(cfg, nil) 108 if err != nil { 109 panic(err) 110 } 111 112 if err := db.AutoMigrate(&TestUser{}, &TestArticle{}); err != nil { 113 panic(err) 114 } 115 116 articles := []*TestArticle{} 117 p := NewPaginator(db, 2, 5, &articles) 118 119 err = p.Find() 120 require.NoError(t, err) 121 122 assert.Equal(t, int64(0), p.Total) 123 assert.Equal(t, int64(1), p.MaxPage) 124 assert.True(t, p.loadedPageInfo) 125 assert.Empty(t, *p.Records) 126 }) 127 128 t.Run("UpdatePageInfo_error", func(t *testing.T) { 129 db, _ := preparePaginatorTestDB() 130 articles := []*TestArticle{} 131 132 db = db.Where("not_a_column", 1) 133 p := NewPaginator(db, 2, 5, &articles) 134 135 err := p.Find() // updatePageInfo is called because the page info is not called yet 136 require.Error(t, err) 137 assert.False(t, p.loadedPageInfo) 138 }) 139 140 t.Run("Find_error", func(t *testing.T) { 141 db, _ := preparePaginatorTestDB() 142 articles := []*TestArticle{} 143 144 db = db.Where("not_a_column", 1) 145 p := NewPaginator(db, 2, 5, &articles) 146 p.loadedPageInfo = true // Let's assume the page info has already been loaded 147 148 err := p.Find() 149 require.Error(t, err) 150 assert.False(t, p.loadedPageInfo) // Page info invalidated 151 }) 152 153 t.Run("select_where_preload", func(t *testing.T) { 154 db, _ := preparePaginatorTestDB() 155 articles := []*TestArticle{} 156 157 db = db.Select("id", "title", "author_id").Where("id > ?", 9).Preload("Author") 158 p := NewPaginator(db, 1, 5, &articles) 159 160 err := p.Find() 161 require.NoError(t, err) 162 163 assert.Equal(t, int64(2), p.Total) 164 assert.Equal(t, int64(1), p.MaxPage) 165 assert.True(t, p.loadedPageInfo) 166 167 author := userGenerator() 168 author.ID = 1 169 expected := []*TestArticle{ 170 {ID: 10, Title: "lorem ipsum", AuthorID: 1, Author: author}, 171 {ID: 11, Title: "lorem ipsum", AuthorID: 1, Author: author}, 172 } 173 assert.Equal(t, expected, *p.Records) 174 }) 175 176 t.Run("Raw", func(t *testing.T) { 177 db, _ := preparePaginatorTestDB() 178 articles := []*TestArticle{} 179 p := NewPaginator(db, 1, 5, &articles) 180 181 query := `SELECT id, title FROM test_articles WHERE id > ?` 182 queryVars := []any{9} 183 countQuery := `SELECT COUNT(*) FROM test_articles WHERE id > ?` 184 assert.Equal(t, p, p.Raw(query, queryVars, countQuery, queryVars)) 185 186 err := p.Find() 187 require.NoError(t, err) 188 189 assert.Equal(t, int64(2), p.Total) 190 assert.Equal(t, int64(1), p.MaxPage) 191 assert.True(t, p.loadedPageInfo) 192 193 expected := []*TestArticle{ 194 {ID: 10, Title: "lorem ipsum"}, 195 {ID: 11, Title: "lorem ipsum"}, 196 } 197 assert.Equal(t, expected, *p.Records) 198 199 // Get page 2 (no results expected) 200 articles = []*TestArticle{} 201 p = NewPaginator(db, 2, 5, &articles) 202 p.Raw(query, queryVars, countQuery, queryVars) 203 err = p.Find() 204 require.NoError(t, err) 205 assert.Equal(t, int64(2), p.Total) 206 assert.Equal(t, int64(1), p.MaxPage) 207 assert.True(t, p.loadedPageInfo) 208 assert.Empty(t, *p.Records) 209 }) 210 }