1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
package test
import (
"fmt"
"rss_parrot/dal"
"rss_parrot/logic"
"rss_parrot/shared"
"sort"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
type tootExtract struct {
postTime time.Time
postGuidHash int64
}
// setupFeedFollowerTest returns a feed follower on a fresh database, together
// with that database. Its check loop runs, but finds nothing due: the only
// account is the birb, which is never checked.
func setupFeedFollowerTest(t *testing.T) (dal.IRepo, logic.IFeedFollower) {
cfg := &shared.Config{
Host: "kakapo.example.com",
Birb: &shared.UserInfo{User: "birb", Published: time.Now()},
}
repo := newTestRepo(t, cfg)
ff := logic.NewFeedFollower(cfg, newTestLogger(), nopUserAgent{}, repo,
nil, nil, &fakeTexts{}, nil, nopMetrics{})
return repo, ff
}
func test_Feed_Follower_Purge_Old_Posts(t *testing.T,
postExtracts []tootExtract, fromBefore *time.Time, minCount int) {
repo, ff := setupFeedFollowerTest(t)
const handle = "some.site.com.feed"
if _, err := repo.AddAccountIfNotExist(&dal.Account{
CreatedAt: time.Now(), Handle: handle, UserUrl: "https://kakapo.example.com/u/" + handle,
}, ""); err != nil {
t.Fatal(err)
}
acct, err := repo.GetAccount(handle)
if err != nil {
t.Fatal(err)
}
for _, e := range postExtracts {
if err := repo.AddToot(acct.Id, &dal.Toot{
PostGuidHash: e.postGuidHash,
TootedAt: e.postTime,
StatusId: fmt.Sprintf("https://kakapo.example.com/u/%s/status/%d", handle, e.postGuidHash),
}); err != nil {
t.Fatal(err)
}
}
// Purge items beyond minCount that are older than 2 days
err = ff.PurgeOldPosts(acct, minCount, 2)
assert.Nil(t, err)
// Exactly the toots tooted after fromBefore must be left (all of them, if
// nothing was to be purged).
var want []int64
for _, e := range postExtracts {
if fromBefore == nil || e.postTime.After(*fromBefore) {
want = append(want, e.postGuidHash)
}
}
left, err := repo.GetTootExtracts(acct.Id)
if err != nil {
t.Fatal(err)
}
var got []int64
for _, toot := range left {
got = append(got, toot.PostGuidHash)
}
sort.Slice(want, func(i, j int) bool { return want[i] < want[j] })
sort.Slice(got, func(i, j int) bool { return got[i] < got[j] })
assert.Equal(t, want, got)
}
func Test_Feed_Follower_Purge_Old_Posts_Scenarios(t *testing.T) {
now := time.Now().UTC()
tootExtracts := []tootExtract{
{now.Add(-3 * time.Hour), int64(getNextId())},
{now.Add(-52 * time.Hour), int64(getNextId())},
{now.Add(-1 * time.Hour), int64(getNextId())},
{now.Add(-49 * time.Hour), int64(getNextId())},
{now.Add(-2 * time.Hour), int64(getNextId())},
}
test_Feed_Follower_Purge_Old_Posts(t, tootExtracts, nil, 5)
test_Feed_Follower_Purge_Old_Posts(t, tootExtracts, &tootExtracts[1].postTime, 4)
test_Feed_Follower_Purge_Old_Posts(t, tootExtracts, &tootExtracts[3].postTime, 3)
test_Feed_Follower_Purge_Old_Posts(t, tootExtracts, &tootExtracts[3].postTime, 2)
// A toot just after the cutoff must survive. Without it every other toot
// is hours away from the cutoff, so a purge that deleted slightly too much
// would go unnoticed.
justAfter := append(tootExtracts[:len(tootExtracts):len(tootExtracts)],
tootExtract{tootExtracts[1].postTime.Add(time.Minute), int64(getNextId())})
test_Feed_Follower_Purge_Old_Posts(t, justAfter, &tootExtracts[1].postTime, 5)
}
|