Skip to content

Commit e4b5a17

Browse files
author
Jeff Yanta
committed
activity: add store tests
1 parent 2939297 commit e4b5a17

File tree

7 files changed

+155
-11
lines changed

7 files changed

+155
-11
lines changed

activity/memory/store.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func (m *InMemoryStore) GetLatestNotifications(ctx context.Context, activityFeed
7676
res := protoutil.SliceClone(m.notifications[string(userID.Value)])
7777

7878
sorted := NotificationsByTimestamp(res)
79-
sort.Sort(sorted)
79+
sort.Sort(sort.Reverse(sorted))
8080

8181
if len(sorted) > limit {
8282
sorted = sorted[:limit]

activity/notifications.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,27 @@ import (
1616
type NotificationBuilder func() (*activitypb.Notification, error)
1717

1818
// SendNotification sends a notification to a user's activity feed
19-
func SendNotification(ctx context.Context, activityFeeds Store, activityFeedType activitypb.ActivityFeedType, userID *commonpb.UserId, builder NotificationBuilder) error {
19+
func SendNotification(ctx context.Context, activityFeeds Store, activityFeedType activitypb.ActivityFeedType, userID *commonpb.UserId, builder NotificationBuilder) (*activitypb.Notification, error) {
2020
if activityFeedType != activitypb.ActivityFeedType_TRANSACTION_HISTORY {
21-
return errors.New("unsupported activity feed type")
21+
return nil, errors.New("unsupported activity feed type")
2222
}
2323

2424
notification, err := builder()
2525
if err != nil {
26-
return err
26+
return nil, err
2727
}
2828

2929
if len(notification.LocalizedText) > 0 {
30-
return errors.New("cannot set localized text")
30+
return nil, errors.New("cannot set localized text")
3131
}
3232

3333
notification.LocalizedText = "placeholder" // To pass proto validation
3434
if err := notification.Validate(); err != nil {
35-
return err
35+
return nil, err
3636
}
3737
notification.LocalizedText = ""
3838

39-
_, err = activityFeeds.SaveNotification(ctx, activityFeedType, userID, notification)
40-
return err
39+
return activityFeeds.SaveNotification(ctx, activityFeedType, userID, notification)
4140
}
4241

4342
func NewWelcomeBonusNotificationBuilder(ctx context.Context, userID *commonpb.UserId, quarks uint64, ts time.Time) NotificationBuilder {

activity/postgres/model.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
activitypb "github.com/code-payments/flipchat-protobuf-api/generated/go/activity/v1"
1212
commonpb "github.com/code-payments/flipchat-protobuf-api/generated/go/common/v1"
13+
1314
"github.com/code-payments/flipchat-server/activity"
1415
pg "github.com/code-payments/flipchat-server/database/postgres"
1516
)
@@ -99,7 +100,7 @@ func fromModel(m *model) (*activitypb.Notification, error) {
99100
}
100101

101102
func (m *model) dbSave(ctx context.Context, pool *pgxpool.Pool) error {
102-
query := `INSERT INTO ` + activityFeedsTableName + `(` + allActivityFeedFields + `) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW()) ON CONFLICT ("id") DO NOTHING RETURNING ` + allActivityFeedFields
103+
query := `INSERT INTO ` + activityFeedsTableName + `(` + allActivityFeedFields + `) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW()) ON CONFLICT ("id") DO UPDATE SET "updatedAt" = NOW() WHERE ` + activityFeedsTableName + `."id" = $1 RETURNING ` + allActivityFeedFields
103104
return pgxscan.Get(
104105
ctx,
105106
pool,

activity/tests/server.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
package tests
22

33
import (
4+
"context"
45
"testing"
56

7+
"go.uber.org/zap"
8+
"google.golang.org/grpc"
9+
10+
activitypb "github.com/code-payments/flipchat-protobuf-api/generated/go/activity/v1"
11+
"github.com/stretchr/testify/require"
12+
613
"github.com/code-payments/flipchat-server/account"
714
"github.com/code-payments/flipchat-server/activity"
15+
"github.com/code-payments/flipchat-server/auth"
816
"github.com/code-payments/flipchat-server/chat"
17+
"github.com/code-payments/flipchat-server/model"
918
"github.com/code-payments/flipchat-server/profile"
19+
"github.com/code-payments/flipchat-server/protoutil"
20+
"github.com/code-payments/flipchat-server/testutil"
1021
)
1122

1223
func RunServerTests(t *testing.T, accounts account.Store, activityFeeds activity.Store, chats chat.Store, profiles profile.Store, teardown func()) {
@@ -19,4 +30,36 @@ func RunServerTests(t *testing.T, accounts account.Store, activityFeeds activity
1930
}
2031

2132
func testActivityServer_HappyPath(t *testing.T, accounts account.Store, activityFeeds activity.Store, chats chat.Store, profiles profile.Store) {
33+
log := zap.Must(zap.NewDevelopment())
34+
35+
userID := model.MustGenerateUserID()
36+
keyPair := model.MustGenerateKeyPair()
37+
_, _ = accounts.Bind(context.Background(), userID, keyPair.Proto())
38+
_ = accounts.SetRegistrationFlag(context.Background(), userID, true)
39+
40+
serv := activity.NewServer(
41+
log,
42+
account.NewAuthorizer(log, accounts, auth.NewKeyPairAuthenticator()),
43+
activityFeeds,
44+
chats,
45+
profiles,
46+
)
47+
48+
cc := testutil.RunGRPCServer(t, testutil.WithService(func(s *grpc.Server) {
49+
activitypb.RegisterActivityFeedServer(s, serv)
50+
}))
51+
52+
client := activitypb.NewActivityFeedClient(cc)
53+
54+
t.Run("Empty", func(t *testing.T) {
55+
req := &activitypb.GetLatestNotificationsRequest{
56+
Type: activitypb.ActivityFeedType_TRANSACTION_HISTORY,
57+
MaxItems: 100,
58+
}
59+
require.NoError(t, keyPair.Auth(req, &req.Auth))
60+
61+
resp, err := client.GetLatestNotifications(context.Background(), req)
62+
require.NoError(t, err)
63+
require.NoError(t, protoutil.ProtoEqualError(&activitypb.GetLatestNotificationsResponse{}, resp))
64+
})
2265
}

activity/tests/store.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
package tests
22

33
import (
4+
"context"
45
"testing"
6+
"time"
7+
8+
"github.com/stretchr/testify/require"
9+
"google.golang.org/protobuf/types/known/timestamppb"
10+
11+
activitypb "github.com/code-payments/flipchat-protobuf-api/generated/go/activity/v1"
512

613
"github.com/code-payments/flipchat-server/activity"
14+
"github.com/code-payments/flipchat-server/model"
15+
"github.com/code-payments/flipchat-server/protoutil"
716
)
817

918
func RunStoreTests(t *testing.T, s activity.Store, teardown func()) {
@@ -16,4 +25,96 @@ func RunStoreTests(t *testing.T, s activity.Store, teardown func()) {
1625
}
1726

1827
func testActivityStore_HappyPath(t *testing.T, store activity.Store) {
28+
userID := model.MustGenerateUserID()
29+
var allExpected []*activitypb.Notification
30+
31+
t.Run("Empty", func(t *testing.T) {
32+
actual, err := store.GetLatestNotifications(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, 10)
33+
require.NoError(t, err)
34+
require.Empty(t, actual)
35+
})
36+
37+
t.Run("Welcome Bonus", func(t *testing.T) {
38+
expected, err := activity.NewWelcomeBonusNotificationBuilder(context.Background(), userID, 123, time.Unix(1, 0))()
39+
require.NoError(t, err)
40+
allExpected = append([]*activitypb.Notification{expected}, allExpected...)
41+
42+
actual, err := store.SaveNotification(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, expected)
43+
require.NoError(t, err)
44+
require.NoError(t, protoutil.ProtoEqualError(expected, actual))
45+
46+
allActual, err := store.GetLatestNotifications(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, 1)
47+
require.NoError(t, err)
48+
require.Len(t, allActual, 1)
49+
require.NoError(t, protoutil.ProtoEqualError(expected, allActual[0]))
50+
51+
other, err := activity.NewWelcomeBonusNotificationBuilder(context.Background(), userID, 42, time.Unix(123456789, 0))()
52+
require.NoError(t, err)
53+
54+
actual, err = store.SaveNotification(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, other)
55+
require.NoError(t, err)
56+
require.NoError(t, protoutil.ProtoEqualError(expected, actual))
57+
58+
allActual, err = store.GetLatestNotifications(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, 1)
59+
require.NoError(t, err)
60+
require.Len(t, allActual, 1)
61+
require.NoError(t, protoutil.ProtoEqualError(expected, allActual[0]))
62+
})
63+
64+
t.Run("Weekly Bonus", func(t *testing.T) {
65+
expected, err := activity.NewWeeklyBonusNotificationBuilder(context.Background(), userID, 456, time.Unix(2, 0))()
66+
require.NoError(t, err)
67+
allExpected = append([]*activitypb.Notification{expected}, allExpected...)
68+
69+
actual, err := store.SaveNotification(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, expected)
70+
require.NoError(t, err)
71+
require.NoError(t, protoutil.ProtoEqualError(expected, actual))
72+
73+
allActual, err := store.GetLatestNotifications(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, 1)
74+
require.NoError(t, err)
75+
require.Len(t, allActual, 1)
76+
require.NoError(t, protoutil.ProtoEqualError(expected, allActual[0]))
77+
78+
other, err := activity.NewWeeklyBonusNotificationBuilder(context.Background(), userID, 42, time.Unix(3, 0))()
79+
require.NoError(t, err)
80+
81+
actual, err = store.SaveNotification(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, other)
82+
require.NoError(t, err)
83+
require.NoError(t, protoutil.ProtoEqualError(expected, actual))
84+
85+
allActual, err = store.GetLatestNotifications(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, 1)
86+
require.NoError(t, err)
87+
require.Len(t, allActual, 1)
88+
require.NoError(t, protoutil.ProtoEqualError(expected, allActual[0]))
89+
})
90+
91+
t.Run("Get Latest Notifications", func(t *testing.T) {
92+
allActual, err := store.GetLatestNotifications(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, 100)
93+
require.NoError(t, err)
94+
require.NoError(t, protoutil.SliceEqualError(allExpected, allActual))
95+
96+
allActual, err = store.GetLatestNotifications(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, len(allExpected)/2)
97+
require.NoError(t, err)
98+
require.NoError(t, protoutil.SliceEqualError(allExpected[:len(allExpected)/2], allActual))
99+
})
100+
101+
t.Run("Invalid Activity Feed", func(t *testing.T) {
102+
expected, err := activity.NewWelcomeBonusNotificationBuilder(context.Background(), userID, 123, time.Unix(1, 0))()
103+
require.NoError(t, err)
104+
105+
_, err = store.SaveNotification(context.Background(), activitypb.ActivityFeedType_UNKNOWN, userID, expected)
106+
require.Equal(t, activity.ErrInvalidActivityFeedType, err)
107+
108+
_, err = store.GetLatestNotifications(context.Background(), activitypb.ActivityFeedType_UNKNOWN, userID, 100)
109+
require.Equal(t, activity.ErrInvalidActivityFeedType, err)
110+
})
111+
112+
t.Run("Invalid Notification", func(t *testing.T) {
113+
_, err := store.SaveNotification(context.Background(), activitypb.ActivityFeedType_TRANSACTION_HISTORY, userID, &activitypb.Notification{
114+
Id: &activitypb.NotificationId{Value: make([]byte, 32)},
115+
AdditionalMetadata: nil,
116+
Ts: timestamppb.Now(),
117+
})
118+
require.Equal(t, activity.ErrInvalidNotificationType, err)
119+
})
19120
}

airdrop/integration.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func (i *FlipchatIntegration) OnSuccess(ctx context.Context, owners ...*codecomm
121121
}
122122

123123
for _, userID := range userIDs {
124-
err := activity.SendNotification(
124+
_, err := activity.SendNotification(
125125
ctx,
126126
i.activityFeeds,
127127
activitypb.ActivityFeedType_TRANSACTION_HISTORY,

iap/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func (s *Server) OnPurchaseCompleted(ctx context.Context, req *iappb.OnPurchaseC
127127
}
128128

129129
// todo: Need a hook into the Code Airdrop RPC, so for now this is the best place
130-
err = activity.SendNotification(
130+
_, err = activity.SendNotification(
131131
ctx,
132132
s.activityFeeds,
133133
activitypb.ActivityFeedType_TRANSACTION_HISTORY,

0 commit comments

Comments
 (0)