1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-11 18:20:33 +09:00

Merge pull request #1304 from anyproto/go-3597-decrease-payment-cache-ttl

GO-3597 Decrease cache TTL
This commit is contained in:
Kirill Stonozhenko 2024-06-11 21:02:47 +02:00 committed by GitHub
commit 2c699ac7c2
Signed by: github
GPG key ID: B5690EEEBB952194
6 changed files with 153 additions and 105 deletions

View file

@ -10,11 +10,13 @@ import (
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/logger"
proto "github.com/anyproto/any-sync/paymentservice/paymentserviceproto"
"github.com/dgraph-io/badger/v4"
"go.uber.org/zap"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/datastore"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
)
const CName = "cache"
@ -33,7 +35,10 @@ var (
// it will cause cache to be dropped and recreated
const cacheLastVersion = 6
const cacheLifetimeDur = 24 * time.Hour
const (
cacheLifetimeDurExplorer = 24 * time.Hour
cacheLifetimeDurOther = 10 * time.Minute
)
var dbKey = "payments/subscription/v" + strconv.Itoa(cacheLastVersion)
@ -81,7 +86,7 @@ type CacheService interface {
// if cache is disabled -> will return no error
// if cache is expired -> will return no error
// status or tiers can be nil depending on what you want to update
CacheSet(status *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, subscriptionEnds time.Time) (err error)
CacheSet(status *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error)
IsCacheEnabled() (enabled bool)
@ -163,12 +168,25 @@ func (s *cacheservice) CacheGet() (status *pb.RpcMembershipGetStatusResponse, ti
return &ss.SubscriptionStatus, &ss.TiersData, nil
}
func getCacheExpireTime(dateEnds time.Time) time.Time {
// dateEnds can be 0
isExpired := time.Now().UTC().After(dateEnds)
func getExpireTime(latestStatus *model.Membership) time.Time {
var (
tier = uint32(proto.SubscriptionTier_TierUnknown)
dateEnds = time.Unix(0, 0)
now = time.Now().UTC()
)
timeNow := time.Now().UTC()
timeNext := timeNow.Add(cacheLifetimeDur)
if latestStatus != nil {
tier = latestStatus.Tier
dateEnds = time.Unix(int64(latestStatus.DateEnds), 0)
}
if tier == uint32(proto.SubscriptionTier_TierExplorer) {
return now.Add(cacheLifetimeDurExplorer)
}
// dateEnds can be 0
isExpired := now.After(dateEnds)
timeNext := now.Add(cacheLifetimeDurOther)
// sub end < now OR no sub end provided (unlimited)
if isExpired {
@ -177,7 +195,7 @@ func getCacheExpireTime(dateEnds time.Time) time.Time {
}
// sub end >= now
// return min(sub end, now + 24h)
// return min(sub end, now + timeout)
if dateEnds.Before(timeNext) {
log.Debug("incrementing cache lifetime because membership ends soon")
return dateEnds
@ -185,26 +203,29 @@ func getCacheExpireTime(dateEnds time.Time) time.Time {
return timeNext
}
func (s *cacheservice) CacheSet(status *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, subscriptionEnds time.Time) (err error) {
expireTime := getCacheExpireTime(subscriptionEnds)
func (s *cacheservice) CacheSet(status *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
var latestStatus *model.Membership
// 1 - get existing storage
ss, err := s.get()
if err != nil {
// if there is no record in the cache, let's create it
ss = newStorageStruct()
} else {
latestStatus = ss.SubscriptionStatus.Data
}
// 2 - update storage
if status != nil {
ss.SubscriptionStatus = *status
latestStatus = status.Data
}
if tiers != nil {
ss.TiersData = *tiers
}
ss.ExpireTime = expireTime
ss.ExpireTime = getExpireTime(latestStatus)
// 3 - save to storage
return s.set(ss)

View file

@ -6,15 +6,18 @@ import (
"time"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/dgraph-io/badger/v4"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
psp "github.com/anyproto/any-sync/paymentservice/paymentserviceproto"
)
const delta = 1 * time.Second
var ctx = context.Background()
type fixture struct {
@ -33,7 +36,7 @@ func newFixture(t *testing.T) *fixture {
require.NoError(t, err)
fx.db = db
//fx.a.Register(fx.ts)
// fx.a.Register(fx.ts)
require.NoError(t, fx.a.Start(ctx))
return fx
@ -42,7 +45,7 @@ func newFixture(t *testing.T) *fixture {
func (fx *fixture) finish(t *testing.T) {
assert.NoError(t, fx.a.Close(ctx))
//assert.NoError(t, fx.db.Close())
// assert.NoError(t, fx.db.Close())
}
func TestPayments_EnableCache(t *testing.T) {
@ -139,9 +142,6 @@ func TestPayments_ClearCache(t *testing.T) {
fx := newFixture(t)
defer fx.finish(t)
timeNow := time.Now().UTC()
timePlus5Hours := timeNow.Add(5 * time.Hour)
err := fx.CacheSet(&pb.RpcMembershipGetStatusResponse{
Data: &model.Membership{
Tier: uint32(psp.SubscriptionTier_TierExplorer),
@ -151,7 +151,6 @@ func TestPayments_ClearCache(t *testing.T) {
&pb.RpcMembershipGetTiersResponse{
Tiers: []*model.MembershipTierData{},
},
timePlus5Hours,
)
require.NoError(t, err)
@ -177,9 +176,6 @@ func TestPayments_CacheGetSubscriptionStatus(t *testing.T) {
fx := newFixture(t)
defer fx.finish(t)
timeNow := time.Now().UTC()
timePlus5Hours := timeNow.Add(5 * time.Hour)
err := fx.CacheSet(&pb.RpcMembershipGetStatusResponse{
Data: &model.Membership{
Tier: uint32(psp.SubscriptionTier_TierExplorer),
@ -189,7 +185,7 @@ func TestPayments_CacheGetSubscriptionStatus(t *testing.T) {
&pb.RpcMembershipGetTiersResponse{
Tiers: []*model.MembershipTierData{},
},
timePlus5Hours)
)
require.NoError(t, err)
out, _, err := fx.CacheGet()
@ -207,7 +203,7 @@ func TestPayments_CacheGetSubscriptionStatus(t *testing.T) {
&pb.RpcMembershipGetTiersResponse{
Tiers: []*model.MembershipTierData{},
},
timePlus5Hours)
)
require.NoError(t, err)
out, _, err = fx.CacheGet()
@ -229,9 +225,6 @@ func TestPayments_CacheGetSubscriptionStatus(t *testing.T) {
en = fx.IsCacheEnabled()
require.Equal(t, false, en)
timeNow := time.Now().UTC()
timePlus5Hours := timeNow.Add(5 * time.Hour)
err = fx.CacheSet(&pb.RpcMembershipGetStatusResponse{
Data: &model.Membership{
Tier: uint32(psp.SubscriptionTier_TierExplorer),
@ -241,7 +234,7 @@ func TestPayments_CacheGetSubscriptionStatus(t *testing.T) {
&pb.RpcMembershipGetTiersResponse{
Tiers: []*model.MembershipTierData{},
},
timePlus5Hours)
)
require.NoError(t, err)
out, _, err := fx.CacheGet()
@ -264,9 +257,6 @@ func TestPayments_CacheGetSubscriptionStatus(t *testing.T) {
fx := newFixture(t)
defer fx.finish(t)
timeNow := time.Now().UTC()
timePlus5Hours := timeNow.Add(5 * time.Hour)
err := fx.CacheSet(&pb.RpcMembershipGetStatusResponse{
Data: &model.Membership{
Tier: uint32(psp.SubscriptionTier_TierExplorer),
@ -276,7 +266,7 @@ func TestPayments_CacheGetSubscriptionStatus(t *testing.T) {
&pb.RpcMembershipGetTiersResponse{
Tiers: []*model.MembershipTierData{},
},
timePlus5Hours)
)
require.NoError(t, err)
err = fx.CacheClear()
@ -292,9 +282,6 @@ func TestPayments_CacheSetSubscriptionStatus(t *testing.T) {
fx := newFixture(t)
defer fx.finish(t)
timeNow := time.Now().UTC()
timePlus5Hours := timeNow.Add(5 * time.Hour)
err := fx.CacheSet(&pb.RpcMembershipGetStatusResponse{
Data: &model.Membership{
Tier: uint32(psp.SubscriptionTier_TierExplorer),
@ -304,7 +291,7 @@ func TestPayments_CacheSetSubscriptionStatus(t *testing.T) {
&pb.RpcMembershipGetTiersResponse{
Tiers: []*model.MembershipTierData{},
},
timePlus5Hours)
)
require.Equal(t, nil, err)
out, _, err := fx.CacheGet()
@ -320,9 +307,6 @@ func TestPayments_CacheSetSubscriptionStatus(t *testing.T) {
err := fx.CacheDisableForNextMinutes(10)
require.NoError(t, err)
timeNow := time.Now().UTC()
timePlus5Hours := timeNow.Add(5 * time.Hour)
err = fx.CacheSet(&pb.RpcMembershipGetStatusResponse{
Data: &model.Membership{
Tier: uint32(psp.SubscriptionTier_TierExplorer),
@ -332,7 +316,7 @@ func TestPayments_CacheSetSubscriptionStatus(t *testing.T) {
&pb.RpcMembershipGetTiersResponse{
Tiers: []*model.MembershipTierData{},
},
timePlus5Hours)
)
require.Equal(t, nil, err)
})
@ -343,9 +327,6 @@ func TestPayments_CacheSetSubscriptionStatus(t *testing.T) {
err := fx.CacheClear()
require.NoError(t, err)
timeNow := time.Now().UTC()
timePlus5Hours := timeNow.Add(5 * time.Hour)
err = fx.CacheSet(&pb.RpcMembershipGetStatusResponse{
Data: &model.Membership{
Tier: uint32(psp.SubscriptionTier_TierExplorer),
@ -355,7 +336,7 @@ func TestPayments_CacheSetSubscriptionStatus(t *testing.T) {
&pb.RpcMembershipGetTiersResponse{
Tiers: []*model.MembershipTierData{},
},
timePlus5Hours)
)
require.Equal(t, nil, err)
})
@ -366,8 +347,6 @@ func TestPayments_CacheSetSubscriptionStatus(t *testing.T) {
err := fx.CacheClear()
require.NoError(t, err)
timeNull := time.Time{}
err = fx.CacheSet(&pb.RpcMembershipGetStatusResponse{
Data: &model.Membership{
Tier: uint32(psp.SubscriptionTier_TierExplorer),
@ -377,10 +356,45 @@ func TestPayments_CacheSetSubscriptionStatus(t *testing.T) {
&pb.RpcMembershipGetTiersResponse{
Tiers: []*model.MembershipTierData{},
},
timeNull)
)
require.Equal(t, nil, err)
_, _, err = fx.CacheGet()
require.Equal(t, nil, err)
})
}
func assertTimeNear(actual, expected time.Time, delta time.Duration) bool {
// actual ∊ [expected - delta; expected + delta]
return actual.After(expected.Add(-1*delta)) && expected.Add(delta).After(actual)
}
func TestGetExpireTime(t *testing.T) {
for _, tc := range []struct {
name string
status *model.Membership
duration time.Duration
}{
{"should return 10 minutes in case of nil", nil, cacheLifetimeDurOther},
{"should return 24 hours in case of Explorer", &model.Membership{Tier: 1}, cacheLifetimeDurExplorer},
{"should return 10 minutes in case of other", &model.Membership{Tier: 3}, cacheLifetimeDurOther},
{"should return dateEnds in case it is earlier than 10 minutes",
&model.Membership{Tier: 4, DateEnds: uint64(time.Now().UTC().Add(3 * time.Minute).Unix())}, 3 * time.Minute},
{"should return 10 minutes in case dateEnds is expired",
&model.Membership{Tier: 3, DateEnds: uint64(time.Now().UTC().Add(-10 * time.Hour).Unix())}, cacheLifetimeDurOther},
{"should return 10 minutes in case dateEnds is 0",
&model.Membership{Tier: 3, DateEnds: uint64(time.Unix(0, 0).Unix())}, cacheLifetimeDurOther},
} {
t.Run(tc.name, func(t *testing.T) {
// given
fx := newFixture(t)
defer fx.finish(t)
// when
expire := getExpireTime(tc.status)
// then
assert.True(t, assertTimeNear(expire, time.Now().UTC().Add(tc.duration), delta))
})
}
}

View file

@ -8,8 +8,6 @@ import (
mock "github.com/stretchr/testify/mock"
pb "github.com/anyproto/anytype-heart/pb"
time "time"
)
// MockCacheService is an autogenerated mock type for the CacheService type
@ -227,17 +225,17 @@ func (_c *MockCacheService_CacheGet_Call) RunAndReturn(run func() (*pb.RpcMember
return _c
}
// CacheSet provides a mock function with given fields: status, tiers, ExpireTime
func (_m *MockCacheService) CacheSet(status *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, ExpireTime time.Time) error {
ret := _m.Called(status, tiers, ExpireTime)
// CacheSet provides a mock function with given fields: status, tiers
func (_m *MockCacheService) CacheSet(status *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) error {
ret := _m.Called(status, tiers)
if len(ret) == 0 {
panic("no return value specified for CacheSet")
}
var r0 error
if rf, ok := ret.Get(0).(func(*pb.RpcMembershipGetStatusResponse, *pb.RpcMembershipGetTiersResponse, time.Time) error); ok {
r0 = rf(status, tiers, ExpireTime)
if rf, ok := ret.Get(0).(func(*pb.RpcMembershipGetStatusResponse, *pb.RpcMembershipGetTiersResponse) error); ok {
r0 = rf(status, tiers)
} else {
r0 = ret.Error(0)
}
@ -253,14 +251,13 @@ type MockCacheService_CacheSet_Call struct {
// CacheSet is a helper method to define mock.On call
// - status *pb.RpcMembershipGetStatusResponse
// - tiers *pb.RpcMembershipGetTiersResponse
// - ExpireTime time.Time
func (_e *MockCacheService_Expecter) CacheSet(status interface{}, tiers interface{}, ExpireTime interface{}) *MockCacheService_CacheSet_Call {
return &MockCacheService_CacheSet_Call{Call: _e.mock.On("CacheSet", status, tiers, ExpireTime)}
func (_e *MockCacheService_Expecter) CacheSet(status interface{}, tiers interface{}) *MockCacheService_CacheSet_Call {
return &MockCacheService_CacheSet_Call{Call: _e.mock.On("CacheSet", status, tiers)}
}
func (_c *MockCacheService_CacheSet_Call) Run(run func(status *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, ExpireTime time.Time)) *MockCacheService_CacheSet_Call {
func (_c *MockCacheService_CacheSet_Call) Run(run func(status *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse)) *MockCacheService_CacheSet_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*pb.RpcMembershipGetStatusResponse), args[1].(*pb.RpcMembershipGetTiersResponse), args[2].(time.Time))
run(args[0].(*pb.RpcMembershipGetStatusResponse), args[1].(*pb.RpcMembershipGetTiersResponse))
})
return _c
}
@ -270,7 +267,7 @@ func (_c *MockCacheService_CacheSet_Call) Return(err error) *MockCacheService_Ca
return _c
}
func (_c *MockCacheService_CacheSet_Call) RunAndReturn(run func(*pb.RpcMembershipGetStatusResponse, *pb.RpcMembershipGetTiersResponse, time.Time) error) *MockCacheService_CacheSet_Call {
func (_c *MockCacheService_CacheSet_Call) RunAndReturn(run func(*pb.RpcMembershipGetStatusResponse, *pb.RpcMembershipGetTiersResponse) error) *MockCacheService_CacheSet_Call {
_c.Call.Return(run)
return _c
}

View file

@ -33,7 +33,7 @@ var log = logging.Logger(CName).Desugar()
const (
refreshIntervalSecs = 10
timeout = 10 * time.Second
initialStatus = -1
cacheDisableMinutes = 30
)
var (
@ -266,27 +266,11 @@ func (s *service) GetSubscriptionStatus(ctx context.Context, req *pb.RpcMembersh
}
}
out := pb.RpcMembershipGetStatusResponse{
Data: &model.Membership{},
Error: &pb.RpcMembershipGetStatusResponseError{
Code: pb.RpcMembershipGetStatusResponseError_NULL,
},
}
out := convertMembershipStatus(status)
out.Data.Tier = status.Tier
out.Data.Status = model.MembershipStatus(status.Status)
out.Data.DateStarted = status.DateStarted
out.Data.DateEnds = status.DateEnds
out.Data.IsAutoRenew = status.IsAutoRenew
out.Data.PaymentMethod = PaymentMethodToModel(status.PaymentMethod)
out.Data.NsName, out.Data.NsNameType = nameservice.FullNameToNsName(status.RequestedAnyName)
out.Data.UserEmail = status.UserEmail
out.Data.SubscribeToNewsletter = status.SubscribeToNewsletter
// 5. Save to cache. Lifetime - min(subscription ends, now + 24h)
// 5. Save to cache. Lifetime - min(subscription ends, now + TTL)
// update only status, not tiers
// truncate nseconds here
err = s.cache.CacheSet(&out, nil, time.Unix(int64(status.DateEnds), 0))
err = s.cache.CacheSet(&out, nil)
if err != nil {
log.Error("can not save subscription status to cache", zap.Error(err))
return nil, ErrCacheProblem
@ -331,7 +315,17 @@ func (s *service) GetSubscriptionStatus(ctx context.Context, req *pb.RpcMembersh
log.Error("update limits", zap.Error(err))
}
// 9. Enable cache again if status is active
// 9. Disable cache in case status is Pending
if status.Status == proto.SubscriptionStatus_StatusPending {
log.Info("disabling cache to wait for Active state")
err = s.cache.CacheDisableForNextMinutes(cacheDisableMinutes)
if err != nil {
log.Error("can not disable cache", zap.Error(err))
return nil, ErrCacheProblem
}
}
// 10. Enable cache again if status is active
isFinished := status.Status == proto.SubscriptionStatus_StatusActive
if isFinished {
log.Info("enabling cache again")
@ -540,9 +534,9 @@ func (s *service) RegisterPaymentRequest(ctx context.Context, req *pb.RpcMembers
}
// 2 - disable cache for 30 minutes
log.Debug("disabling cache for 30 minutes after payment URL was received")
log.Debug("disabling cache for 30 minutes after payment request is created on payment node")
err = s.cache.CacheDisableForNextMinutes(30)
err = s.cache.CacheDisableForNextMinutes(cacheDisableMinutes)
if err != nil {
log.Error("can not disable cache", zap.Error(err))
return nil, ErrCacheProblem
@ -589,7 +583,7 @@ func (s *service) GetPortalLink(ctx context.Context, req *pb.RpcMembershipGetPor
// 2 - disable cache for 30 minutes
log.Debug("disabling cache for 30 minutes after portal link was received")
err = s.cache.CacheDisableForNextMinutes(30)
err = s.cache.CacheDisableForNextMinutes(cacheDisableMinutes)
if err != nil {
log.Error("can not disable cache", zap.Error(err))
return nil, ErrCacheProblem
@ -673,7 +667,7 @@ func (s *service) VerifyEmailCode(ctx context.Context, req *pb.RpcMembershipVeri
// 2 - clear cache
log.Debug("disabling cache after email verification code was confirmed")
err = s.cache.CacheDisableForNextMinutes(30)
err = s.cache.CacheDisableForNextMinutes(cacheDisableMinutes)
if err != nil {
log.Error("can not disable cache", zap.Error(err))
return nil, ErrCacheProblem
@ -723,7 +717,7 @@ func (s *service) FinalizeSubscription(ctx context.Context, req *pb.RpcMembershi
// 2 - clear cache
log.Debug("disable cache after subscription was finalized")
err = s.cache.CacheDisableForNextMinutes(30)
err = s.cache.CacheDisableForNextMinutes(cacheDisableMinutes)
if err != nil {
log.Error("can not disable cache", zap.Error(err))
return nil, ErrCacheProblem
@ -771,7 +765,7 @@ func (s *service) GetTiers(ctx context.Context, req *pb.RpcMembershipGetTiersReq
func (s *service) getAllTiers(ctx context.Context, req *pb.RpcMembershipGetTiersRequest) (*pb.RpcMembershipGetTiersResponse, error) {
// 1 - check in cache
// status var. is unused here
cachedStatus, cachedTiers, err := s.cache.CacheGet()
_, cachedTiers, err := s.cache.CacheGet()
// if NoCache -> skip returning from cache
if !req.NoCache && (err == nil) && (cachedTiers != nil) && (cachedTiers.Tiers != nil) {
@ -856,12 +850,7 @@ func (s *service) getAllTiers(ctx context.Context, req *pb.RpcMembershipGetTiers
}
// 3 - update tiers, not status
var ends time.Time = time.Unix(0, 0)
if (cachedStatus != nil) && (cachedStatus.Data != nil) {
ends = time.Unix(int64(cachedStatus.Data.DateEnds), 0)
}
err = s.cache.CacheSet(nil, &out, ends)
err = s.cache.CacheSet(nil, &out)
if err != nil {
log.Error("can not save tiers to cache", zap.Error(err))
return nil, ErrCacheProblem

View file

@ -131,7 +131,7 @@ func TestGetStatus(t *testing.T) {
}).MinTimes(1)
fx.cache.EXPECT().CacheGet().Return(nil, nil, cache.ErrCacheExpired)
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return nil
})
// fx.cache.EXPECT().CacheEnable().Return(nil)
@ -155,7 +155,7 @@ func TestGetStatus(t *testing.T) {
}).MinTimes(1)
fx.cache.EXPECT().CacheGet().Return(nil, nil, cache.ErrCacheExpired)
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return nil
})
// fx.cache.EXPECT().CacheEnable().Return(nil)
@ -220,7 +220,7 @@ func TestGetStatus(t *testing.T) {
// >>> here:
fx.cache.EXPECT().CacheGet().Return(nil, nil, nil)
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return nil
})
@ -376,7 +376,7 @@ func TestGetStatus(t *testing.T) {
}).MinTimes(1)
fx.cache.EXPECT().CacheGet().Return(&psgsr, nil, cache.ErrCacheExpired)
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return nil
})
// fx.cache.EXPECT().CacheEnable().Return(nil)
@ -427,7 +427,7 @@ func TestGetStatus(t *testing.T) {
// here: cache is disabled
fx.cache.EXPECT().CacheGet().Return(&psgsr, nil, cache.ErrCacheDisabled)
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return nil
})
// fx.cache.EXPECT().CacheEnable().Return(nil)
@ -480,7 +480,7 @@ func TestGetStatus(t *testing.T) {
}).MinTimes(1)
fx.cache.EXPECT().CacheGet().Return(&psgsr, nil, cache.ErrCacheExpired)
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return errors.New("can not write to cache!")
})
@ -558,7 +558,7 @@ func TestGetStatus(t *testing.T) {
}).MinTimes(1)
fx.cache.EXPECT().CacheGet().Return(nil, nil, cache.ErrCacheExpired)
fx.cache.EXPECT().CacheSet(&psgsr, mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(&psgsr, mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return nil
})
fx.cache.EXPECT().CacheEnable().Return(nil)
@ -617,7 +617,7 @@ func TestGetStatus(t *testing.T) {
// return real struct and error
fx.cache.EXPECT().CacheGet().Return(nil, nil, cache.ErrCacheDisabled)
fx.cache.EXPECT().CacheSet(&psgsr2, mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(&psgsr2, mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return nil
})
@ -887,7 +887,7 @@ func TestGetTiers(t *testing.T) {
defer fx.finish(t)
fx.cache.EXPECT().CacheGet().Return(nil, nil, cache.ErrCacheExpired)
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return nil
})
@ -924,7 +924,7 @@ func TestGetTiers(t *testing.T) {
defer fx.finish(t)
fx.cache.EXPECT().CacheGet().Return(nil, nil, cache.ErrCacheExpired)
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return nil
})
@ -1025,7 +1025,7 @@ func TestGetTiers(t *testing.T) {
},
}
fx.cache.EXPECT().CacheGet().Return(&psgsr, nil, nil)
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return nil
})
@ -1212,7 +1212,7 @@ func TestGetTiers(t *testing.T) {
}
fx.cache.EXPECT().CacheGet().Return(nil, &tgr, nil)
// should call it to save status
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse"), mock.AnythingOfType("time.Time")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse, expire time.Time) (err error) {
fx.cache.EXPECT().CacheSet(mock.AnythingOfType("*pb.RpcMembershipGetStatusResponse"), mock.AnythingOfType("*pb.RpcMembershipGetTiersResponse")).RunAndReturn(func(in *pb.RpcMembershipGetStatusResponse, tiers *pb.RpcMembershipGetTiersResponse) (err error) {
return nil
})
fx.cache.EXPECT().CacheEnable().Return(nil)

View file

@ -5,6 +5,12 @@ import (
"github.com/pkg/errors"
"golang.org/x/net/idna"
"github.com/anyproto/any-sync/paymentservice/paymentserviceproto"
"github.com/anyproto/anytype-heart/core/nameservice"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
)
var (
@ -63,3 +69,24 @@ func normalizeAnyName(name string) (string, error) {
return name, nil
}
func convertMembershipStatus(status *paymentserviceproto.GetSubscriptionResponse) pb.RpcMembershipGetStatusResponse {
out := pb.RpcMembershipGetStatusResponse{
Data: &model.Membership{},
Error: &pb.RpcMembershipGetStatusResponseError{
Code: pb.RpcMembershipGetStatusResponseError_NULL,
},
}
out.Data.Tier = status.Tier
out.Data.Status = model.MembershipStatus(status.Status)
out.Data.DateStarted = status.DateStarted
out.Data.DateEnds = status.DateEnds
out.Data.IsAutoRenew = status.IsAutoRenew
out.Data.PaymentMethod = PaymentMethodToModel(status.PaymentMethod)
out.Data.NsName, out.Data.NsNameType = nameservice.FullNameToNsName(status.RequestedAnyName)
out.Data.UserEmail = status.UserEmail
out.Data.SubscribeToNewsletter = status.SubscribeToNewsletter
return out
}