feat: articles pagination

This commit is contained in:
Florian Sylvain committed 2026-10-11 19:14:37 +02:00
1 parent a2d224240c
commit 73f4b539fe
45 files changed
+3528 -317

No files matched your search

+84
View File
@@ -7,6 +7,11 @@ import (
"sort"
"strings"
"testing"
"unicode"
"golang.org/x/text/runes"
"golang.org/x/text/transform"
"golang.org/x/text/unicode/norm"
)
type mockArticleRepo struct {
@@ -47,6 +52,85 @@ func (m *mockArticleRepo) FindByFilters(filters article.Filters) ([]article.Arti
return result, nil
}
func (m *mockArticleRepo) FindPage(filters article.Filters) (article.PageResult, error) {
if err := m.fail.trigger("FindPage"); err != nil {
return article.PageResult{}, err
}
matching := make([]article.Article, 0)
for _, a := range m.articles {
if filters.IsOnline != nil && a.IsOnline != *filters.IsOnline {
continue
}
if filters.Status == article.StatusOnline && !a.IsOnline {
continue
}
if filters.Status == article.StatusDraft && a.IsOnline {
continue
}
if filters.Q != "" && !strings.Contains(foldArticleSearch(a.Title), foldArticleSearch(filters.Q)) {
continue
}
matching = append(matching, a)
}
sort.Slice(matching, func(i, j int) bool { return articleSortsBefore(matching[i], matching[j], filters.Sort) })
start := min((filters.Page-1)*filters.Size, len(matching))
end := min(start+filters.Size, len(matching))
return article.PageResult{Items: matching[start:end], Total: len(matching)}, nil
}
func (m *mockArticleRepo) CountByVisibility(onlineOnly bool) (article.Counts, error) {
if err := m.fail.trigger("CountByVisibility"); err != nil {
return article.Counts{}, err
}
counts := article.Counts{}
for _, a := range m.articles {
if a.IsOnline {
counts.Online++
} else if !onlineOnly {
counts.Draft++
}
}
counts.All = counts.Online + counts.Draft
return counts, nil
}
func articleSortsBefore(left, right article.Article, order article.Sort) bool {
if order.Field == "" {
order = article.DefaultSort()
}
var comparison int
switch order.Field {
case article.SortByTitle:
comparison = strings.Compare(strings.ToLower(left.Title), strings.ToLower(right.Title))
case article.SortByStatus:
if left.IsOnline != right.IsOnline {
comparison = 1
if !left.IsOnline {
comparison = -1
}
}
case article.SortByCreatedAt:
comparison = left.CreatedAt.Compare(right.CreatedAt)
default:
comparison = left.UpdatedAt.Compare(right.UpdatedAt)
}
if order.Direction == article.SortDesc {
comparison = -comparison
}
if comparison != 0 {
return comparison < 0
}
return left.ID > right.ID
}
func foldArticleSearch(value string) string {
folded, _, err := transform.String(transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC), value)
if err != nil {
return strings.ToLower(value)
}
return strings.ToLower(folded)
}
func (m *mockArticleRepo) Get(id uint32) (article.Article, error) {
if err := m.fail.trigger("Get"); err != nil {
return article.Article{}, err