storj/satellite/satellitedb/usercredits_test.go

214 lines
5.6 KiB
Go
Raw Normal View History

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package satellitedb_test
import (
"context"
"crypto/rand"
"testing"
"time"
"github.com/skyrings/skyring-common/tools/uuid"
"storj.io/storj/satellite/marketing"
"github.com/stretchr/testify/require"
"storj.io/storj/satellite/console"
"storj.io/storj/internal/testcontext"
"storj.io/storj/satellite"
"storj.io/storj/satellite/satellitedb/satellitedbtest"
)
func TestUsercredits(t *testing.T) {
t.Parallel()
satellitedbtest.Run(t, func(t *testing.T, db satellite.DB) {
ctx := testcontext.New(t)
defer ctx.Cleanup()
consoleDB := db.Console()
user, referrer, offer := setupData(ctx, t, db)
randomID, err := uuid.New()
require.NoError(t, err)
// test foreign key constraint for inserting a new user credit entry with randomID
var invalidUserCredits = []console.UserCredit{
{
UserID: *randomID,
OfferID: offer.ID,
ReferredBy: referrer.ID,
CreditsEarnedInCents: 100,
ExpiresAt: time.Now().UTC().AddDate(0, 1, 0),
},
{
UserID: user.ID,
OfferID: 10,
ReferredBy: referrer.ID,
CreditsEarnedInCents: 100,
ExpiresAt: time.Now().UTC().AddDate(0, 1, 0),
},
{
UserID: user.ID,
OfferID: offer.ID,
ReferredBy: *randomID,
CreditsEarnedInCents: 100,
ExpiresAt: time.Now().UTC().AddDate(0, 1, 0),
},
}
for _, ivc := range invalidUserCredits {
_, err := consoleDB.UserCredits().Create(ctx, ivc)
require.Error(t, err)
}
type result struct {
remainingCharge int
availableCredits int
hasErr bool
}
var validUserCredits = []struct {
userCredit console.UserCredit
chargedCredits int
expected result
}{
{
userCredit: console.UserCredit{
UserID: user.ID,
OfferID: offer.ID,
ReferredBy: referrer.ID,
CreditsEarnedInCents: 100,
ExpiresAt: time.Now().UTC().AddDate(0, 1, 0),
},
chargedCredits: 120,
expected: result{
remainingCharge: 20,
availableCredits: 0,
hasErr: false,
},
},
{
// simulate a credit that's already expired
userCredit: console.UserCredit{
UserID: user.ID,
OfferID: offer.ID,
ReferredBy: referrer.ID,
CreditsEarnedInCents: 100,
ExpiresAt: time.Now().UTC().AddDate(0, 0, -5),
},
chargedCredits: 60,
expected: result{
remainingCharge: 60,
availableCredits: 0,
hasErr: true,
},
},
{
// simulate a credit that's not expired
userCredit: console.UserCredit{
UserID: user.ID,
OfferID: offer.ID,
ReferredBy: referrer.ID,
CreditsEarnedInCents: 100,
ExpiresAt: time.Now().UTC().AddDate(0, 0, 5),
},
chargedCredits: 80,
expected: result{
remainingCharge: 0,
availableCredits: 20,
hasErr: false,
},
},
}
for i, vc := range validUserCredits {
_, err = consoleDB.UserCredits().Create(ctx, vc.userCredit)
require.NoError(t, err)
{
referredCount, err := consoleDB.UserCredits().TotalReferredCount(ctx, vc.userCredit.ReferredBy)
if err != nil {
require.True(t, uuid.Equal(*randomID, vc.userCredit.ReferredBy))
continue
}
require.NoError(t, err)
require.Equal(t, int64(i+1), referredCount)
}
{
remainingCharge, err := consoleDB.UserCredits().UpdateAvailableCredits(ctx, vc.chargedCredits, vc.userCredit.UserID, time.Now().UTC())
if vc.expected.hasErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
require.Equal(t, vc.expected.remainingCharge, remainingCharge)
}
{
availableCredits, err := consoleDB.UserCredits().GetAvailableCredits(ctx, vc.userCredit.UserID, time.Now().UTC())
require.NoError(t, err)
var sum int
for i := range availableCredits {
sum += availableCredits[i].CreditsEarnedInCents - availableCredits[i].CreditsUsedInCents
}
require.NoError(t, err)
require.Equal(t, vc.expected.availableCredits, sum)
}
}
})
}
func setupData(ctx context.Context, t *testing.T, db satellite.DB) (user *console.User, referrer *console.User, offer *marketing.Offer) {
consoleDB := db.Console()
marketingDB := db.Marketing()
// create user
var userPassHash [8]byte
_, err := rand.Read(userPassHash[:])
require.NoError(t, err)
var referrerPassHash [8]byte
_, err = rand.Read(referrerPassHash[:])
require.NoError(t, err)
// create an user
user, err = consoleDB.Users().Insert(ctx, &console.User{
FullName: "John Doe",
Email: "john@mail.test",
PasswordHash: userPassHash[:],
Status: console.Active,
})
require.NoError(t, err)
//create an user as referrer
referrer, err = consoleDB.Users().Insert(ctx, &console.User{
FullName: "referrer",
Email: "referrer@mail.test",
PasswordHash: referrerPassHash[:],
Status: console.Active,
})
require.NoError(t, err)
// create offer
offer, err = marketingDB.Offers().Create(ctx, &marketing.NewOffer{
Name: "test",
Description: "test offer 1",
AwardCreditInCents: 100,
InviteeCreditInCents: 50,
AwardCreditDurationDays: 60,
InviteeCreditDurationDays: 30,
RedeemableCap: 50,
ExpiresAt: time.Now().UTC().Add(time.Hour * 1),
Status: marketing.Active,
Type: marketing.Referral,
})
require.NoError(t, err)
return user, referrer, offer
}