166 lines
5.9 KiB
Go
166 lines
5.9 KiB
Go
package rpc
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/iamxvbaba/td/clock"
|
|
"github.com/iamxvbaba/td/tg"
|
|
"go.uber.org/zap/zaptest"
|
|
|
|
appaccount "telesrv/internal/app/account"
|
|
appprivacy "telesrv/internal/app/privacy"
|
|
appusers "telesrv/internal/app/users"
|
|
"telesrv/internal/domain"
|
|
"telesrv/internal/store/memory"
|
|
)
|
|
|
|
func newPrivateRequirementRouter(t *testing.T, senderPremium bool) (*Router, *appaccount.Service, *appprivacy.Service, *memory.ContactStore, domain.User, domain.User) {
|
|
t.Helper()
|
|
ctx := context.Background()
|
|
usersStore := memory.NewUserStore()
|
|
aliceInput := domain.User{AccessHash: 11, Phone: "15550008101", FirstName: "Alice"}
|
|
if senderPremium {
|
|
aliceInput.PremiumUntil = int(time.Now().Add(time.Hour).Unix())
|
|
}
|
|
alice, err := usersStore.Create(ctx, aliceInput)
|
|
if err != nil {
|
|
t.Fatalf("create Alice: %v", err)
|
|
}
|
|
bob, err := usersStore.Create(ctx, domain.User{AccessHash: 22, Phone: "15550008102", FirstName: "Bob"})
|
|
if err != nil {
|
|
t.Fatalf("create Bob: %v", err)
|
|
}
|
|
users := appusers.NewService(usersStore)
|
|
contacts := memory.NewContactStore()
|
|
privacy := appprivacy.NewService(memory.NewPrivacyStore(), contacts).ConfigureReadModels(users, nil)
|
|
settingsStore := memory.NewPasswordStore()
|
|
account := appaccount.NewService(settingsStore, appaccount.WithAccountSettings(settingsStore))
|
|
router := New(Config{}, Deps{
|
|
Account: account,
|
|
Privacy: privacy,
|
|
Users: users,
|
|
Messages: &captureMessages{},
|
|
}, zaptest.NewLogger(t), clock.System)
|
|
return router, account, privacy, contacts, alice, bob
|
|
}
|
|
|
|
func TestPrivateContactRequirementUsesNoPaidMessagesReadModel(t *testing.T) {
|
|
ctx := context.Background()
|
|
r, account, privacy, contacts, alice, bob := newPrivateRequirementRouter(t, false)
|
|
if _, err := account.SetGlobalPrivacy(ctx, bob.ID, domain.GlobalPrivacy{NoncontactPeersPaidStars: 7}); err != nil {
|
|
t.Fatalf("set Bob paid requirement: %v", err)
|
|
}
|
|
full, err := r.onUsersGetFullUser(WithUserID(ctx, alice.ID), &tg.InputUser{
|
|
UserID: bob.ID, AccessHash: bob.AccessHash,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("get Bob full user: %v", err)
|
|
}
|
|
if stars, ok := full.FullUser.GetSendPaidMessagesStars(); !ok || stars != 7 {
|
|
t.Fatalf("full user paid stars = %d, %v; want 7, true", stars, ok)
|
|
}
|
|
projected, ok := full.Users[0].(*tg.User)
|
|
if !ok {
|
|
t.Fatalf("projected user = %T, want *tg.User", full.Users[0])
|
|
}
|
|
if stars, ok := projected.GetSendPaidMessagesStars(); !ok || stars != 7 {
|
|
t.Fatalf("user paid stars = %d, %v; want 7, true", stars, ok)
|
|
}
|
|
requirements, err := r.onUsersGetRequirementsToContact(WithUserID(ctx, alice.ID), []tg.InputUserClass{
|
|
&tg.InputUser{UserID: bob.ID, AccessHash: bob.AccessHash},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("get requirements: %v", err)
|
|
}
|
|
if paid, ok := requirements[0].(*tg.RequirementToContactPaidMessages); !ok || paid.StarsAmount != 7 {
|
|
t.Fatalf("requirement = %#v, want paid 7", requirements[0])
|
|
}
|
|
|
|
send := func(randomID int64, allow int64) error {
|
|
req := &tg.MessagesSendMessageRequest{
|
|
Peer: &tg.InputPeerUser{UserID: bob.ID, AccessHash: bob.AccessHash},
|
|
Message: "hello",
|
|
RandomID: randomID,
|
|
}
|
|
if allow != 0 {
|
|
req.SetAllowPaidStars(allow)
|
|
}
|
|
_, err := r.onMessagesSendMessage(WithUserID(ctx, alice.ID), req)
|
|
return err
|
|
}
|
|
|
|
if err := send(81001, 0); err == nil || !strings.Contains(err.Error(), "ALLOW_PAYMENT_REQUIRED") || !strings.Contains(err.Error(), "(7)") {
|
|
t.Fatalf("non-exempt send err = %v, want ALLOW_PAYMENT_REQUIRED 7", err)
|
|
}
|
|
if err := send(81002, 7); err == nil || !strings.Contains(err.Error(), "PAYMENT_UNSUPPORTED") {
|
|
t.Fatalf("authorized paid send err = %v, want explicit unsupported ledger", err)
|
|
}
|
|
|
|
if _, err := privacy.SetRules(ctx, bob.ID, domain.PrivacyKeyNoPaidMessages, []domain.PrivacyRule{{
|
|
Kind: domain.PrivacyRuleAllowUsers,
|
|
UserIDs: []int64{alice.ID},
|
|
}, {
|
|
Kind: domain.PrivacyRuleDisallowAll,
|
|
}}); err != nil {
|
|
t.Fatalf("allow Alice in NoPaidMessages: %v", err)
|
|
}
|
|
if err := send(81003, 0); err != nil {
|
|
t.Fatalf("explicit no-paid exception send: %v", err)
|
|
}
|
|
full, err = r.onUsersGetFullUser(WithUserID(ctx, alice.ID), &tg.InputUser{
|
|
UserID: bob.ID, AccessHash: bob.AccessHash,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("get exempt Bob full user: %v", err)
|
|
}
|
|
if _, ok := full.FullUser.GetSendPaidMessagesStars(); ok || full.FullUser.ContactRequirePremium {
|
|
t.Fatalf("exempt full user still carries contact restriction: %+v", full.FullUser)
|
|
}
|
|
|
|
if _, err := privacy.SetRules(ctx, bob.ID, domain.PrivacyKeyNoPaidMessages, []domain.PrivacyRule{{Kind: domain.PrivacyRuleDisallowAll}}); err != nil {
|
|
t.Fatalf("clear explicit exception: %v", err)
|
|
}
|
|
if _, err := contacts.Upsert(ctx, bob.ID, domain.ContactInput{
|
|
ContactUserID: alice.ID,
|
|
FirstName: "Alice",
|
|
}); err != nil {
|
|
t.Fatalf("Bob add Alice contact: %v", err)
|
|
}
|
|
if err := send(81004, 0); err != nil {
|
|
t.Fatalf("recipient contact must be free: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestPrivateContactRequirementPremiumGateUsesViewerFactsReadModel(t *testing.T) {
|
|
ctx := context.Background()
|
|
for _, tc := range []struct {
|
|
name string
|
|
senderPremium bool
|
|
wantErr bool
|
|
}{
|
|
{name: "non-premium blocked", wantErr: true},
|
|
{name: "premium allowed", senderPremium: true},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
r, account, _, _, alice, bob := newPrivateRequirementRouter(t, tc.senderPremium)
|
|
if _, err := account.SetGlobalPrivacy(ctx, bob.ID, domain.GlobalPrivacy{NewNoncontactPeersRequirePremium: true}); err != nil {
|
|
t.Fatalf("set premium requirement: %v", err)
|
|
}
|
|
_, err := r.onMessagesSendMessage(WithUserID(ctx, alice.ID), &tg.MessagesSendMessageRequest{
|
|
Peer: &tg.InputPeerUser{UserID: bob.ID, AccessHash: bob.AccessHash},
|
|
Message: "hello",
|
|
RandomID: 82001,
|
|
})
|
|
if tc.wantErr {
|
|
if err == nil || !strings.Contains(err.Error(), "PREMIUM_ACCOUNT_REQUIRED") {
|
|
t.Fatalf("send err = %v, want PREMIUM_ACCOUNT_REQUIRED", err)
|
|
}
|
|
} else if err != nil {
|
|
t.Fatalf("premium sender should pass: %v", err)
|
|
}
|
|
})
|
|
}
|
|
}
|