snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
This commit is contained in:
311
server/store/tests/reminders_test.go
Normal file
311
server/store/tests/reminders_test.go
Normal file
@@ -0,0 +1,311 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/cortezaproject/corteza/server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza/server/pkg/id"
|
||||
"github.com/cortezaproject/corteza/server/pkg/rand"
|
||||
"github.com/cortezaproject/corteza/server/store"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
"github.com/stretchr/testify/require"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func testReminders(t *testing.T, s store.Reminders) {
|
||||
var (
|
||||
ctx = context.Background()
|
||||
|
||||
makeNew = func(nn ...string) *types.Reminder {
|
||||
// minimum data set for new user
|
||||
name := strings.Join(nn, "")
|
||||
thisID := id.Next()
|
||||
return &types.Reminder{
|
||||
ID: thisID,
|
||||
Resource: "resource+" + name,
|
||||
AssignedTo: thisID,
|
||||
CreatedAt: time.Now(),
|
||||
AssignedAt: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
truncAndCreate = func(t *testing.T) (*require.Assertions, *types.Reminder) {
|
||||
req := require.New(t)
|
||||
req.NoError(s.TruncateReminders(ctx))
|
||||
reminder := makeNew()
|
||||
req.NoError(s.CreateReminder(ctx, reminder))
|
||||
return req, reminder
|
||||
}
|
||||
|
||||
truncAndFill = func(t *testing.T, l int) (*require.Assertions, types.ReminderSet) {
|
||||
req := require.New(t)
|
||||
req.NoError(s.TruncateReminders(ctx))
|
||||
|
||||
set := make([]*types.Reminder, l)
|
||||
|
||||
for i := 0; i < l; i++ {
|
||||
set[i] = makeNew(string(rand.Bytes(10)))
|
||||
}
|
||||
|
||||
req.NoError(s.CreateReminder(ctx, set...))
|
||||
return req, set
|
||||
}
|
||||
)
|
||||
|
||||
t.Run("create", func(t *testing.T) {
|
||||
req := require.New(t)
|
||||
req.NoError(s.CreateReminder(ctx, makeNew()))
|
||||
})
|
||||
|
||||
t.Run("lookup by ID", func(t *testing.T) {
|
||||
req, reminder := truncAndCreate(t)
|
||||
fetched, err := s.LookupReminderByID(ctx, reminder.ID)
|
||||
req.NoError(err)
|
||||
req.Equal(reminder.ID, fetched.ID)
|
||||
req.NotNil(fetched.CreatedAt)
|
||||
req.Nil(fetched.UpdatedAt)
|
||||
req.Nil(fetched.DeletedAt)
|
||||
})
|
||||
|
||||
t.Run("update", func(t *testing.T) {
|
||||
req, reminder := truncAndCreate(t)
|
||||
req.NoError(s.UpdateReminder(ctx, reminder))
|
||||
})
|
||||
|
||||
t.Run("search", func(t *testing.T) {
|
||||
t.Run("by ID", func(t *testing.T) {
|
||||
req, prefill := truncAndFill(t, 5)
|
||||
|
||||
set, f, err := s.SearchReminders(ctx, types.ReminderFilter{ReminderID: []uint64{prefill[0].ID}})
|
||||
req.NoError(err)
|
||||
req.Equal([]uint64{prefill[0].ID}, f.ReminderID)
|
||||
req.Len(set, 1)
|
||||
})
|
||||
|
||||
t.Run("by resource", func(t *testing.T) {
|
||||
req, prefill := truncAndFill(t, 5)
|
||||
|
||||
set, _, err := s.SearchReminders(ctx, types.ReminderFilter{Resource: prefill[0].Resource})
|
||||
req.NoError(err)
|
||||
req.Len(set, 1)
|
||||
})
|
||||
|
||||
t.Run("by assigned to", func(t *testing.T) {
|
||||
req, prefill := truncAndFill(t, 5)
|
||||
set, f, err := s.SearchReminders(ctx, types.ReminderFilter{AssignedTo: prefill[0].AssignedTo})
|
||||
req.NoError(err)
|
||||
req.Equal(prefill[0].AssignedTo, f.AssignedTo)
|
||||
req.Len(set, 1)
|
||||
})
|
||||
|
||||
t.Run("by dismissed", func(t *testing.T) {
|
||||
req, prefill := truncAndFill(t, 5)
|
||||
|
||||
prefill[0].DismissedAt = &(prefill[0].CreatedAt)
|
||||
s.UpdateReminder(ctx, prefill[0])
|
||||
|
||||
set, _, err := s.SearchReminders(ctx, types.ReminderFilter{ExcludeDismissed: true})
|
||||
req.NoError(err)
|
||||
req.Len(set, 4)
|
||||
})
|
||||
|
||||
t.Run("by scheduled", func(t *testing.T) {
|
||||
req, prefill := truncAndFill(t, 5)
|
||||
|
||||
prefill[0].RemindAt = &(prefill[0].CreatedAt)
|
||||
s.UpdateReminder(ctx, prefill[0])
|
||||
|
||||
set, _, err := s.SearchReminders(ctx, types.ReminderFilter{ScheduledOnly: true})
|
||||
req.NoError(err)
|
||||
req.Len(set, 1)
|
||||
})
|
||||
|
||||
t.Run("with check", func(t *testing.T) {
|
||||
req, prefill := truncAndFill(t, 5)
|
||||
set, _, err := s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Check: func(user *types.Reminder) (bool, error) {
|
||||
// simple check that matches with the first user from prefill
|
||||
return user.ID == prefill[0].ID, nil
|
||||
},
|
||||
})
|
||||
req.NoError(err)
|
||||
req.Len(set, 1)
|
||||
req.Equal(prefill[0].ID, set[0].ID)
|
||||
})
|
||||
|
||||
t.Run("paging with check", func(t *testing.T) {
|
||||
// hide every third reminder from the check fn
|
||||
hide := func(prefill types.ReminderSet) (map[uint64]bool, int) {
|
||||
hidden, visible := make(map[uint64]bool), 0
|
||||
for i, r := range prefill {
|
||||
if i%3 == 0 {
|
||||
hidden[r.ID] = true
|
||||
} else {
|
||||
visible++
|
||||
}
|
||||
}
|
||||
return hidden, visible
|
||||
}
|
||||
|
||||
t.Run("page holds no more than the limit and no duplicates", func(t *testing.T) {
|
||||
req, prefill := truncAndFill(t, 20)
|
||||
hidden, _ := hide(prefill)
|
||||
|
||||
set, _, err := s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Paging: filter.Paging{Limit: 5},
|
||||
Check: func(r *types.Reminder) (bool, error) { return !hidden[r.ID], nil },
|
||||
})
|
||||
req.NoError(err)
|
||||
req.Len(set, 5)
|
||||
|
||||
seen := make(map[uint64]bool)
|
||||
for _, r := range set {
|
||||
req.False(seen[r.ID], "reminder %d returned twice", r.ID)
|
||||
seen[r.ID] = true
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("walking every page yields each visible item once", func(t *testing.T) {
|
||||
req, prefill := truncAndFill(t, 20)
|
||||
hidden, visible := hide(prefill)
|
||||
|
||||
var (
|
||||
cursor *filter.PagingCursor
|
||||
seen = make(map[uint64]int)
|
||||
)
|
||||
|
||||
for page := 0; page < 30; page++ {
|
||||
set, f, err := s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Paging: filter.Paging{Limit: 3, PageCursor: cursor},
|
||||
Check: func(r *types.Reminder) (bool, error) { return !hidden[r.ID], nil },
|
||||
})
|
||||
req.NoError(err)
|
||||
|
||||
for _, r := range set {
|
||||
req.False(hidden[r.ID], "hidden reminder %d was returned", r.ID)
|
||||
seen[r.ID]++
|
||||
}
|
||||
|
||||
if f.NextPage == nil {
|
||||
break
|
||||
}
|
||||
cursor = f.NextPage
|
||||
}
|
||||
|
||||
req.Len(seen, visible)
|
||||
for id, times := range seen {
|
||||
req.Equal(1, times, "reminder %d returned %d times", id, times)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("fills a page past a long run of rejected items", func(t *testing.T) {
|
||||
req, prefill := truncAndFill(t, 200)
|
||||
|
||||
// hide everything but the last 5
|
||||
hidden := make(map[uint64]bool)
|
||||
for _, r := range prefill[:len(prefill)-5] {
|
||||
hidden[r.ID] = true
|
||||
}
|
||||
|
||||
set, _, err := s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Paging: filter.Paging{Limit: 3},
|
||||
Check: func(r *types.Reminder) (bool, error) { return !hidden[r.ID], nil },
|
||||
})
|
||||
req.NoError(err)
|
||||
req.Len(set, 3)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("total", func(t *testing.T) {
|
||||
t.Run("omitted when not requested", func(t *testing.T) {
|
||||
req, _ := truncAndFill(t, 5)
|
||||
|
||||
set, f, err := s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Paging: filter.Paging{Limit: 2},
|
||||
})
|
||||
req.NoError(err)
|
||||
req.Len(set, 2)
|
||||
req.Equal(uint(0), f.Total)
|
||||
})
|
||||
|
||||
t.Run("without limit", func(t *testing.T) {
|
||||
req, _ := truncAndFill(t, 5)
|
||||
|
||||
set, f, err := s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Paging: filter.Paging{IncTotal: true},
|
||||
})
|
||||
req.NoError(err)
|
||||
req.Len(set, 5)
|
||||
req.Equal(uint(5), f.Total)
|
||||
})
|
||||
|
||||
t.Run("with limit above count", func(t *testing.T) {
|
||||
req, _ := truncAndFill(t, 5)
|
||||
|
||||
set, f, err := s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Paging: filter.Paging{Limit: 10, IncTotal: true},
|
||||
})
|
||||
req.NoError(err)
|
||||
req.Len(set, 5)
|
||||
req.Equal(uint(5), f.Total)
|
||||
})
|
||||
|
||||
t.Run("with limit equal to count", func(t *testing.T) {
|
||||
req, _ := truncAndFill(t, 5)
|
||||
|
||||
set, f, err := s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Paging: filter.Paging{Limit: 5, IncTotal: true},
|
||||
})
|
||||
req.NoError(err)
|
||||
req.Len(set, 5)
|
||||
req.Equal(uint(5), f.Total)
|
||||
})
|
||||
|
||||
t.Run("with limit below count", func(t *testing.T) {
|
||||
req, _ := truncAndFill(t, 5)
|
||||
|
||||
set, f, err := s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Paging: filter.Paging{Limit: 2, IncTotal: true},
|
||||
})
|
||||
req.NoError(err)
|
||||
req.Len(set, 2)
|
||||
req.Equal(uint(5), f.Total)
|
||||
})
|
||||
|
||||
t.Run("counts only what check keeps", func(t *testing.T) {
|
||||
req, prefill := truncAndFill(t, 5)
|
||||
|
||||
set, f, err := s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Paging: filter.Paging{Limit: 2, IncTotal: true},
|
||||
Check: func(r *types.Reminder) (bool, error) {
|
||||
return r.ID != prefill[0].ID && r.ID != prefill[1].ID, nil
|
||||
},
|
||||
})
|
||||
req.NoError(err)
|
||||
req.Len(set, 2)
|
||||
req.Equal(uint(3), f.Total)
|
||||
})
|
||||
|
||||
t.Run("refused with a page cursor", func(t *testing.T) {
|
||||
req, _ := truncAndFill(t, 5)
|
||||
|
||||
_, f, err := s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Paging: filter.Paging{Limit: 2},
|
||||
})
|
||||
req.NoError(err)
|
||||
req.NotNil(f.NextPage)
|
||||
|
||||
_, _, err = s.SearchReminders(ctx, types.ReminderFilter{
|
||||
Paging: filter.Paging{Limit: 2, IncTotal: true, PageCursor: f.NextPage},
|
||||
})
|
||||
req.Error(err)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("ordered search", func(t *testing.T) {
|
||||
t.Skip("not implemented")
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user