satellite/{console,accountfreeze}: test freeze effects
This change adds more tests to the autofreeze chore and the freeze service according to the testplan linked in the issue below. Issue: https://github.com/storj/storj/issues/5738 Change-Id: Ib2afaa283961b2e7ef6fb6e5613ee083ac7d79eb
This commit is contained in:
parent
816c3d31ac
commit
260b71e70c
@ -98,6 +98,24 @@ type Config struct {
|
||||
HubSpot HubSpotConfig
|
||||
}
|
||||
|
||||
// FreezeTracker is an interface for account freeze event tracking methods.
|
||||
type FreezeTracker interface {
|
||||
// TrackAccountFrozen sends an account frozen event to Segment.
|
||||
TrackAccountFrozen(userID uuid.UUID, email string)
|
||||
|
||||
// TrackAccountUnfrozen sends an account unfrozen event to Segment.
|
||||
TrackAccountUnfrozen(userID uuid.UUID, email string)
|
||||
|
||||
// TrackAccountUnwarned sends an account unwarned event to Segment.
|
||||
TrackAccountUnwarned(userID uuid.UUID, email string)
|
||||
|
||||
// TrackAccountFreezeWarning sends an account freeze warning event to Segment.
|
||||
TrackAccountFreezeWarning(userID uuid.UUID, email string)
|
||||
|
||||
// TrackLargeUnpaidInvoice sends an event to Segment indicating that a user has not paid a large invoice.
|
||||
TrackLargeUnpaidInvoice(invID string, userID uuid.UUID, email string)
|
||||
}
|
||||
|
||||
// Service for sending analytics.
|
||||
//
|
||||
// architecture: Service
|
||||
|
@ -63,16 +63,16 @@ type AccountFreezeService struct {
|
||||
freezeEventsDB AccountFreezeEvents
|
||||
usersDB Users
|
||||
projectsDB Projects
|
||||
analytics *analytics.Service
|
||||
tracker analytics.FreezeTracker
|
||||
}
|
||||
|
||||
// NewAccountFreezeService creates a new account freeze service.
|
||||
func NewAccountFreezeService(freezeEventsDB AccountFreezeEvents, usersDB Users, projectsDB Projects, analytics *analytics.Service) *AccountFreezeService {
|
||||
func NewAccountFreezeService(freezeEventsDB AccountFreezeEvents, usersDB Users, projectsDB Projects, tracker analytics.FreezeTracker) *AccountFreezeService {
|
||||
return &AccountFreezeService{
|
||||
freezeEventsDB: freezeEventsDB,
|
||||
usersDB: usersDB,
|
||||
projectsDB: projectsDB,
|
||||
analytics: analytics,
|
||||
tracker: tracker,
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ func (s *AccountFreezeService) FreezeUser(ctx context.Context, userID uuid.UUID)
|
||||
}
|
||||
}
|
||||
|
||||
s.analytics.TrackAccountFrozen(userID, user.Email)
|
||||
s.tracker.TrackAccountFrozen(userID, user.Email)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -212,7 +212,7 @@ func (s *AccountFreezeService) UnfreezeUser(ctx context.Context, userID uuid.UUI
|
||||
return err
|
||||
}
|
||||
|
||||
s.analytics.TrackAccountUnfrozen(userID, user.Email)
|
||||
s.tracker.TrackAccountUnfrozen(userID, user.Email)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -233,7 +233,7 @@ func (s *AccountFreezeService) WarnUser(ctx context.Context, userID uuid.UUID) (
|
||||
return ErrAccountFreeze.Wrap(err)
|
||||
}
|
||||
|
||||
s.analytics.TrackAccountFreezeWarning(userID, user.Email)
|
||||
s.tracker.TrackAccountFreezeWarning(userID, user.Email)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -256,7 +256,7 @@ func (s *AccountFreezeService) UnWarnUser(ctx context.Context, userID uuid.UUID)
|
||||
return err
|
||||
}
|
||||
|
||||
s.analytics.TrackAccountUnwarned(userID, user.Email)
|
||||
s.tracker.TrackAccountUnwarned(userID, user.Email)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -271,3 +271,8 @@ func (s *AccountFreezeService) GetAll(ctx context.Context, userID uuid.UUID) (fr
|
||||
|
||||
return freeze, warning, nil
|
||||
}
|
||||
|
||||
// TestChangeFreezeTracker changes the freeze tracker service for tests.
|
||||
func (s *AccountFreezeService) TestChangeFreezeTracker(t analytics.FreezeTracker) {
|
||||
s.tracker = t
|
||||
}
|
||||
|
@ -8,9 +8,13 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"storj.io/common/memory"
|
||||
"storj.io/common/testcontext"
|
||||
"storj.io/common/testrand"
|
||||
"storj.io/storj/private/testplanet"
|
||||
"storj.io/storj/satellite"
|
||||
"storj.io/storj/satellite/console"
|
||||
)
|
||||
|
||||
@ -242,3 +246,76 @@ func TestAccountFreezeAlreadyFrozen(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestFreezeEffects(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1, StorageNodeCount: 2, UplinkCount: 2,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
config.AccountFreeze.Enabled = true
|
||||
},
|
||||
},
|
||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||
sat := planet.Satellites[0]
|
||||
usersDB := sat.DB.Console().Users()
|
||||
projectsDB := sat.DB.Console().Projects()
|
||||
consoleService := sat.API.Console.Service
|
||||
freezeService := console.NewAccountFreezeService(sat.DB.Console().AccountFreezeEvents(), usersDB, projectsDB, sat.API.Analytics.Service)
|
||||
|
||||
uplink1 := planet.Uplinks[0]
|
||||
user1, _, err := consoleService.GetUserByEmailWithUnverified(ctx, uplink1.User[sat.ID()].Email)
|
||||
require.NoError(t, err)
|
||||
|
||||
bucketName := "testbucket"
|
||||
path := "test/path"
|
||||
|
||||
expectedData := testrand.Bytes(50 * memory.KiB)
|
||||
|
||||
shouldUploadAndDownload := func(testT *testing.T) {
|
||||
// Should be able to upload because account is not warned nor frozen.
|
||||
err = uplink1.Upload(ctx, sat, bucketName, path, expectedData)
|
||||
require.NoError(testT, err)
|
||||
|
||||
// Should be able to download because account is not frozen.
|
||||
data, err := uplink1.Download(ctx, sat, bucketName, path)
|
||||
require.NoError(testT, err)
|
||||
require.Equal(testT, expectedData, data)
|
||||
}
|
||||
|
||||
t.Run("Freeze effect on project owner", func(t *testing.T) {
|
||||
shouldUploadAndDownload(t)
|
||||
|
||||
err = freezeService.WarnUser(ctx, user1.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Should be able to download because account is not frozen.
|
||||
data, err := uplink1.Download(ctx, sat, bucketName, path)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expectedData, data)
|
||||
|
||||
err = freezeService.FreezeUser(ctx, user1.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Should not be able to upload because account is frozen.
|
||||
err = uplink1.Upload(ctx, sat, bucketName, path, expectedData)
|
||||
require.Error(t, err)
|
||||
|
||||
// Should not be able to download because account is frozen.
|
||||
_, err = uplink1.Download(ctx, sat, bucketName, path)
|
||||
require.Error(t, err)
|
||||
|
||||
// Should not be able to create bucket because account is frozen.
|
||||
err = uplink1.CreateBucket(ctx, sat, "anotherBucket")
|
||||
require.Error(t, err)
|
||||
|
||||
// Should be able to list even if frozen.
|
||||
objects, err := uplink1.ListObjects(ctx, sat, bucketName)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, objects, 1)
|
||||
|
||||
// Should be able to delete even if frozen.
|
||||
err = uplink1.DeleteObject(ctx, sat, bucketName, path)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -188,6 +188,11 @@ func (chore *Chore) TestSetNow(f func() time.Time) {
|
||||
chore.nowFn = f
|
||||
}
|
||||
|
||||
// TestSetFreezeService changes the freeze service for tests.
|
||||
func (chore *Chore) TestSetFreezeService(service *console.AccountFreezeService) {
|
||||
chore.freezeService = service
|
||||
}
|
||||
|
||||
// Close closes the chore.
|
||||
func (chore *Chore) Close() error {
|
||||
chore.Loop.Close()
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
"storj.io/common/testcontext"
|
||||
"storj.io/common/uuid"
|
||||
"storj.io/storj/private/testplanet"
|
||||
"storj.io/storj/satellite"
|
||||
"storj.io/storj/satellite/console"
|
||||
@ -33,8 +34,9 @@ func TestAutoFreezeChore(t *testing.T) {
|
||||
customerDB := sat.Core.DB.StripeCoinPayments().Customers()
|
||||
usersDB := sat.DB.Console().Users()
|
||||
projectsDB := sat.DB.Console().Projects()
|
||||
service := console.NewAccountFreezeService(sat.DB.Console().AccountFreezeEvents(), usersDB, projectsDB, sat.API.Analytics.Service)
|
||||
service := console.NewAccountFreezeService(sat.DB.Console().AccountFreezeEvents(), usersDB, projectsDB, newFreezeTrackerMock(t))
|
||||
chore := sat.Core.Payments.AccountFreeze
|
||||
chore.TestSetFreezeService(service)
|
||||
|
||||
user, err := sat.AddUser(ctx, console.CreateUser{
|
||||
FullName: "Test User",
|
||||
@ -49,6 +51,8 @@ func TestAutoFreezeChore(t *testing.T) {
|
||||
curr := string(stripe.CurrencyUSD)
|
||||
|
||||
t.Run("No freeze event for paid invoice", func(t *testing.T) {
|
||||
// AnalyticsMock tests that events are sent once.
|
||||
service.TestChangeFreezeTracker(newFreezeTrackerMock(t))
|
||||
item, err := stripeClient.InvoiceItems().New(&stripe.InvoiceItemParams{
|
||||
Params: stripe.Params{Context: ctx},
|
||||
Amount: &amount,
|
||||
@ -102,6 +106,8 @@ func TestAutoFreezeChore(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Freeze event for failed invoice", func(t *testing.T) {
|
||||
// AnalyticsMock tests that events are sent once.
|
||||
service.TestChangeFreezeTracker(newFreezeTrackerMock(t))
|
||||
// reset chore clock
|
||||
chore.TestSetNow(time.Now)
|
||||
|
||||
@ -160,3 +166,46 @@ func TestAutoFreezeChore(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
type freezeTrackerMock struct {
|
||||
t *testing.T
|
||||
freezeCounts map[string]int
|
||||
warnCounts map[string]int
|
||||
}
|
||||
|
||||
func newFreezeTrackerMock(t *testing.T) *freezeTrackerMock {
|
||||
return &freezeTrackerMock{
|
||||
t: t,
|
||||
freezeCounts: map[string]int{},
|
||||
warnCounts: map[string]int{},
|
||||
}
|
||||
}
|
||||
|
||||
// The following functions are implemented from analytics.FreezeTracker.
|
||||
// They mock/test to make sure freeze events are sent just once.
|
||||
|
||||
func (mock *freezeTrackerMock) TrackAccountFrozen(_ uuid.UUID, email string) {
|
||||
mock.freezeCounts[email]++
|
||||
// make sure this tracker has not been called already for this email.
|
||||
require.Equal(mock.t, 1, mock.freezeCounts[email])
|
||||
}
|
||||
|
||||
func (mock *freezeTrackerMock) TrackAccountUnfrozen(_ uuid.UUID, email string) {
|
||||
mock.freezeCounts[email]--
|
||||
// make sure this tracker has not been called already for this email.
|
||||
require.Equal(mock.t, 0, mock.freezeCounts[email])
|
||||
}
|
||||
|
||||
func (mock *freezeTrackerMock) TrackAccountUnwarned(_ uuid.UUID, email string) {
|
||||
mock.warnCounts[email]--
|
||||
// make sure this tracker has not been called already for this email.
|
||||
require.Equal(mock.t, 0, mock.warnCounts[email])
|
||||
}
|
||||
|
||||
func (mock *freezeTrackerMock) TrackAccountFreezeWarning(_ uuid.UUID, email string) {
|
||||
mock.warnCounts[email]++
|
||||
// make sure this tracker has not been called already for this email.
|
||||
require.Equal(mock.t, 1, mock.warnCounts[email])
|
||||
}
|
||||
|
||||
func (mock *freezeTrackerMock) TrackLargeUnpaidInvoice(_ string, _ uuid.UUID, _ string) {}
|
||||
|
Loading…
Reference in New Issue
Block a user