satellite: rearrange marketing package (#2268)

* move offer out of marketing package and remove marketing package

* fix imports

* fix rename errors

* remove offer service

* change package name from offers to rewards

* fix linting

* remove unused code and use appropriate comment
This commit is contained in:
Yingrong Zhao 2019-06-24 16:51:54 -04:00 committed by Dennis Coyle
parent 30f790a040
commit bbedff12a6
13 changed files with 143 additions and 288 deletions

View File

@ -26,7 +26,7 @@ import (
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/console/consoleweb"
"storj.io/storj/satellite/mailservice"
"storj.io/storj/satellite/marketing/marketingweb"
"storj.io/storj/satellite/marketingweb"
"storj.io/storj/satellite/metainfo"
"storj.io/storj/satellite/orders"
"storj.io/storj/satellite/satellitedb"

View File

@ -1,9 +0,0 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information
package marketing
// DB contains access to all marketing related databases
type DB interface {
Offers() Offers
}

View File

@ -1,107 +0,0 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information
package marketing
import (
"context"
"time"
"github.com/zeebo/errs"
"go.uber.org/zap"
monkit "gopkg.in/spacemonkeygo/monkit.v2"
)
var (
// Error the default offers errs class
Error = errs.Class("marketing error")
mon = monkit.Package()
)
// Service allows access to offers info in the db
type Service struct {
log *zap.Logger
db DB
}
// NewService creates a new offers db
func NewService(log *zap.Logger, db DB) (*Service, error) {
if log == nil {
return nil, Error.New("log can't be nil")
}
return &Service{
log: log,
db: db,
}, nil
}
// ListAllOffers returns all available offers in the db
func (s *Service) ListAllOffers(ctx context.Context) (offers []Offer, err error) {
defer mon.Task()(&ctx)(&err)
offers, err = s.db.Offers().ListAll(ctx)
if err != nil {
return offers, Error.Wrap(err)
}
return offers, nil
}
// GetCurrentOfferByType returns current active offer
func (s *Service) GetCurrentOfferByType(ctx context.Context, offerType OfferType) (offer *Offer, err error) {
defer mon.Task()(&ctx)(&err)
offer, err = s.db.Offers().GetCurrentByType(ctx, offerType)
if err != nil {
return nil, Error.Wrap(err)
}
return offer, nil
}
// InsertNewOffer inserts a new offer into the db
func (s *Service) InsertNewOffer(ctx context.Context, offer *NewOffer) (o *Offer, err error) {
defer mon.Task()(&ctx)(&err)
if offer.Status == Default {
offer.ExpiresAt = time.Now().UTC().AddDate(100, 0, 0)
offer.RedeemableCap = 1
}
o, err = s.db.Offers().Create(ctx, offer)
if err != nil {
return nil, Error.Wrap(err)
}
return o, nil
}
// RedeemOffer adds 1 to the number of redeemed for an offer
func (s *Service) RedeemOffer(ctx context.Context, uo *UpdateOffer) (err error) {
defer mon.Task()(&ctx)(&err)
if uo.Status == Default {
return nil
}
err = s.db.Offers().Redeem(ctx, uo.ID)
if err != nil {
return Error.Wrap(err)
}
return nil
}
// FinishOffer updates an active offer's status to be Done and its expiration time to be now
func (s *Service) FinishOffer(ctx context.Context, oID int) (err error) {
defer mon.Task()(&ctx)(&err)
err = s.db.Offers().Finish(ctx, oID)
if err != nil {
return Error.Wrap(err)
}
return nil
}

View File

@ -19,13 +19,13 @@ import (
// Error is satellite marketing error type
var Error = errs.Class("satellite marketing error")
// Config contains configuration for marketing offersweb server
// Config contains configuration for marketingweb server
type Config struct {
Address string `help:"server address of the marketing Admin GUI" default:"127.0.0.1:8090"`
StaticDir string `help:"path to static resources" default:""`
}
// Server represents marketing offersweb server
// Server represents marketingweb server
type Server struct {
log *zap.Logger
@ -52,7 +52,7 @@ func (s *Server) commonPages() []string {
}
}
// NewServer creates new instance of offersweb server
// NewServer creates new instance of marketingweb server
func NewServer(logger *zap.Logger, config Config, listener net.Listener) (*Server, error) {
s := &Server{
log: logger,

View File

@ -49,13 +49,13 @@ import (
"storj.io/storj/satellite/inspector"
"storj.io/storj/satellite/mailservice"
"storj.io/storj/satellite/mailservice/simulate"
"storj.io/storj/satellite/marketing"
"storj.io/storj/satellite/marketing/marketingweb"
"storj.io/storj/satellite/marketingweb"
"storj.io/storj/satellite/metainfo"
"storj.io/storj/satellite/orders"
"storj.io/storj/satellite/payments"
"storj.io/storj/satellite/payments/localpayments"
"storj.io/storj/satellite/payments/stripepayments"
"storj.io/storj/satellite/rewards"
"storj.io/storj/satellite/vouchers"
"storj.io/storj/storage"
"storj.io/storj/storage/boltdb"
@ -91,8 +91,8 @@ type DB interface {
Irreparable() irreparable.DB
// Console returns database for satellite console
Console() console.DB
// Marketing returns database for marketing admin GUI
Marketing() marketing.DB
// returns database for marketing admin GUI
Rewards() rewards.DB
// Orders returns database for orders
Orders() orders.DB
// Containment returns database for containment

View File

@ -1,24 +1,19 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information
package marketing
package rewards
import (
"context"
"time"
"github.com/zeebo/errs"
)
// OffersErr creates offer error class
var OffersErr = errs.Class("offers error")
// Offers holds information about offer
type Offers interface {
// DB holds information about offer
type DB interface {
ListAll(ctx context.Context) ([]Offer, error)
GetCurrentByType(ctx context.Context, offerType OfferType) (*Offer, error)
Create(ctx context.Context, offer *NewOffer) (*Offer, error)
Redeem(ctx context.Context, offerID int) error
Redeem(ctx context.Context, offerID int, isDefault bool) error
Finish(ctx context.Context, offerID int) error
}

View File

@ -1,7 +1,7 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information
package marketing_test
package rewards_test
import (
"testing"
@ -11,7 +11,7 @@ import (
"storj.io/storj/internal/testcontext"
"storj.io/storj/internal/testplanet"
"storj.io/storj/satellite/marketing"
"storj.io/storj/satellite/rewards"
)
func TestOffer_Database(t *testing.T) {
@ -19,7 +19,7 @@ func TestOffer_Database(t *testing.T) {
SatelliteCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
// Happy path
validOffers := []marketing.NewOffer{
validOffers := []rewards.NewOffer{
{
Name: "test",
Description: "test offer 1",
@ -29,8 +29,8 @@ func TestOffer_Database(t *testing.T) {
InviteeCreditDurationDays: 30,
RedeemableCap: 50,
ExpiresAt: time.Now().UTC().Add(time.Hour * 1),
Status: marketing.Active,
Type: marketing.Referral,
Status: rewards.Active,
Type: rewards.Referral,
},
{
Name: "test",
@ -41,47 +41,48 @@ func TestOffer_Database(t *testing.T) {
InviteeCreditDurationDays: 30,
RedeemableCap: 50,
ExpiresAt: time.Now().UTC().Add(time.Hour * 1),
Status: marketing.Default,
Type: marketing.FreeCredit,
Status: rewards.Default,
Type: rewards.FreeCredit,
},
}
for i := range validOffers {
new, err := planet.Satellites[0].DB.Marketing().Offers().Create(ctx, &validOffers[i])
new, err := planet.Satellites[0].DB.Rewards().Create(ctx, &validOffers[i])
require.NoError(t, err)
all, err := planet.Satellites[0].DB.Marketing().Offers().ListAll(ctx)
all, err := planet.Satellites[0].DB.Rewards().ListAll(ctx)
require.NoError(t, err)
require.Contains(t, all, *new)
c, err := planet.Satellites[0].DB.Marketing().Offers().GetCurrentByType(ctx, new.Type)
c, err := planet.Satellites[0].DB.Rewards().GetCurrentByType(ctx, new.Type)
require.NoError(t, err)
require.Equal(t, new, c)
update := &marketing.UpdateOffer{
update := &rewards.UpdateOffer{
ID: new.ID,
Status: marketing.Done,
Status: rewards.Done,
ExpiresAt: time.Now(),
}
err = planet.Satellites[0].DB.Marketing().Offers().Redeem(ctx, update.ID)
isDefault := update.Status == rewards.Default
err = planet.Satellites[0].DB.Rewards().Redeem(ctx, update.ID, isDefault)
require.NoError(t, err)
err = planet.Satellites[0].DB.Marketing().Offers().Finish(ctx, update.ID)
err = planet.Satellites[0].DB.Rewards().Finish(ctx, update.ID)
require.NoError(t, err)
current, err := planet.Satellites[0].DB.Marketing().Offers().ListAll(ctx)
current, err := planet.Satellites[0].DB.Rewards().ListAll(ctx)
require.NoError(t, err)
if new.Status == marketing.Default {
if new.Status == rewards.Default {
require.Equal(t, new.NumRedeemed, current[i].NumRedeemed)
} else {
require.Equal(t, new.NumRedeemed+1, current[i].NumRedeemed)
}
require.Equal(t, marketing.Done, current[i].Status)
require.Equal(t, rewards.Done, current[i].Status)
}
// create with expired offer
expiredOffers := []marketing.NewOffer{
expiredOffers := []rewards.NewOffer{
{
Name: "test",
Description: "test offer",
@ -91,8 +92,8 @@ func TestOffer_Database(t *testing.T) {
InviteeCreditDurationDays: 30,
RedeemableCap: 50,
ExpiresAt: time.Now().UTC().Add(time.Hour * -1),
Status: marketing.Active,
Type: marketing.FreeCredit,
Status: rewards.Active,
Type: rewards.FreeCredit,
},
{
Name: "test",
@ -103,13 +104,13 @@ func TestOffer_Database(t *testing.T) {
InviteeCreditDurationDays: 30,
RedeemableCap: 50,
ExpiresAt: time.Now().UTC().Add(time.Hour * -1),
Status: marketing.Default,
Type: marketing.Referral,
Status: rewards.Default,
Type: rewards.Referral,
},
}
for i := range expiredOffers {
output, err := planet.Satellites[0].DB.Marketing().Offers().Create(ctx, &expiredOffers[i])
output, err := planet.Satellites[0].DB.Rewards().Create(ctx, &expiredOffers[i])
require.Error(t, err)
require.Nil(t, output)
}

View File

@ -18,8 +18,8 @@ import (
"storj.io/storj/satellite"
"storj.io/storj/satellite/attribution"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/marketing"
"storj.io/storj/satellite/orders"
"storj.io/storj/satellite/rewards"
dbx "storj.io/storj/satellite/satellitedb/dbx"
)
@ -136,12 +136,9 @@ func (db *DB) Console() console.DB {
}
}
// Marketing returns database for storing offers and credits
func (db *DB) Marketing() marketing.DB {
return &MarketingDB{
db: db.db,
methods: db.db,
}
// Rewards returns database for storing offers
func (db *DB) Rewards() rewards.DB {
return &offersDB{db: db.db}
}
// Orders returns database for storing orders

View File

@ -25,8 +25,8 @@ import (
"storj.io/storj/satellite"
"storj.io/storj/satellite/attribution"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/marketing"
"storj.io/storj/satellite/orders"
"storj.io/storj/satellite/rewards"
)
// locked implements a locking wrapper around satellite.DB.
@ -681,61 +681,6 @@ func (m *lockedIrreparable) IncrementRepairAttempts(ctx context.Context, segment
return m.db.IncrementRepairAttempts(ctx, segmentInfo)
}
// Marketing returns database for marketing admin GUI
func (m *locked) Marketing() marketing.DB {
m.Lock()
defer m.Unlock()
return &lockedMarketing{m.Locker, m.db.Marketing()}
}
// lockedMarketing implements locking wrapper for marketing.DB
type lockedMarketing struct {
sync.Locker
db marketing.DB
}
func (m *lockedMarketing) Offers() marketing.Offers {
m.Lock()
defer m.Unlock()
return &lockedOffers{m.Locker, m.db.Offers()}
}
// lockedOffers implements locking wrapper for marketing.Offers
type lockedOffers struct {
sync.Locker
db marketing.Offers
}
func (m *lockedOffers) Create(ctx context.Context, offer *marketing.NewOffer) (*marketing.Offer, error) {
m.Lock()
defer m.Unlock()
return m.db.Create(ctx, offer)
}
func (m *lockedOffers) Finish(ctx context.Context, offerID int) error {
m.Lock()
defer m.Unlock()
return m.db.Finish(ctx, offerID)
}
func (m *lockedOffers) GetCurrentByType(ctx context.Context, offerType marketing.OfferType) (*marketing.Offer, error) {
m.Lock()
defer m.Unlock()
return m.db.GetCurrentByType(ctx, offerType)
}
func (m *lockedOffers) ListAll(ctx context.Context) ([]marketing.Offer, error) {
m.Lock()
defer m.Unlock()
return m.db.ListAll(ctx)
}
func (m *lockedOffers) Redeem(ctx context.Context, offerID int) error {
m.Lock()
defer m.Unlock()
return m.db.Redeem(ctx, offerID)
}
// Orders returns database for orders
func (m *locked) Orders() orders.DB {
m.Lock()
@ -998,6 +943,49 @@ func (m *lockedRepairQueue) SelectN(ctx context.Context, limit int) ([]pb.Injure
return m.db.SelectN(ctx, limit)
}
// returns database for marketing admin GUI
func (m *locked) Rewards() rewards.DB {
m.Lock()
defer m.Unlock()
return &lockedRewards{m.Locker, m.db.Rewards()}
}
// lockedRewards implements locking wrapper for rewards.DB
type lockedRewards struct {
sync.Locker
db rewards.DB
}
func (m *lockedRewards) Create(ctx context.Context, offer *rewards.NewOffer) (*rewards.Offer, error) {
m.Lock()
defer m.Unlock()
return m.db.Create(ctx, offer)
}
func (m *lockedRewards) Finish(ctx context.Context, offerID int) error {
m.Lock()
defer m.Unlock()
return m.db.Finish(ctx, offerID)
}
func (m *lockedRewards) GetCurrentByType(ctx context.Context, offerType rewards.OfferType) (*rewards.Offer, error) {
m.Lock()
defer m.Unlock()
return m.db.GetCurrentByType(ctx, offerType)
}
func (m *lockedRewards) ListAll(ctx context.Context) ([]rewards.Offer, error) {
m.Lock()
defer m.Unlock()
return m.db.ListAll(ctx)
}
func (m *lockedRewards) Redeem(ctx context.Context, offerID int, isDefault bool) error {
m.Lock()
defer m.Unlock()
return m.db.Redeem(ctx, offerID, isDefault)
}
// StoragenodeAccounting returns database for storing information about storagenode use
func (m *locked) StoragenodeAccounting() accounting.StoragenodeAccounting {
m.Lock()

View File

@ -1,21 +0,0 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information
package satellitedb
import (
"storj.io/storj/satellite/marketing"
dbx "storj.io/storj/satellite/satellitedb/dbx"
)
// MarketingDB contains access to different satellite databases
type MarketingDB struct {
db *dbx.DB
methods dbx.Methods
}
// Offers returns access to offers table
func (db *MarketingDB) Offers() marketing.Offers {
return &offers{db.db}
}

View File

@ -10,26 +10,31 @@ import (
"github.com/zeebo/errs"
"storj.io/storj/satellite/marketing"
"storj.io/storj/satellite/rewards"
dbx "storj.io/storj/satellite/satellitedb/dbx"
)
type offers struct {
var (
// offerErr is the default offer errors class
offerErr = errs.Class("offers error")
)
type offersDB struct {
db *dbx.DB
}
// ListAll returns all offers from the db
func (offers *offers) ListAll(ctx context.Context) ([]marketing.Offer, error) {
offersDbx, err := offers.db.All_Offer(ctx)
// ListAll returns all offersDB from the db
func (db *offersDB) ListAll(ctx context.Context) ([]rewards.Offer, error) {
offersDbx, err := db.db.All_Offer(ctx)
if err != nil {
return nil, marketing.OffersErr.Wrap(err)
return nil, offerErr.Wrap(err)
}
return offersFromDBX(offersDbx)
}
// GetCurrent returns an offer that has not expired based on offer type
func (offers *offers) GetCurrentByType(ctx context.Context, offerType marketing.OfferType) (*marketing.Offer, error) {
func (db *offersDB) GetCurrentByType(ctx context.Context, offerType rewards.OfferType) (*rewards.Offer, error) {
var statement string
const columns = "id, name, description, award_credit_in_cents, invitee_credit_in_cents, award_credit_duration_days, invitee_credit_duration_days, redeemable_cap, num_redeemed, expires_at, created_at, status, type"
statement = `
@ -44,40 +49,45 @@ func (offers *offers) GetCurrentByType(ctx context.Context, offerType marketing.
SELECT id FROM o
) order by created_at desc;`
rows := offers.db.DB.QueryRowContext(ctx, offers.db.Rebind(statement), marketing.Active, offerType, time.Now().UTC(), offerType, marketing.Default)
rows := db.db.DB.QueryRowContext(ctx, db.db.Rebind(statement), rewards.Active, offerType, time.Now().UTC(), offerType, rewards.Default)
o := marketing.Offer{}
o := rewards.Offer{}
err := rows.Scan(&o.ID, &o.Name, &o.Description, &o.AwardCreditInCents, &o.InviteeCreditInCents, &o.AwardCreditDurationDays, &o.InviteeCreditDurationDays, &o.RedeemableCap, &o.NumRedeemed, &o.ExpiresAt, &o.CreatedAt, &o.Status, &o.Type)
if err == sql.ErrNoRows {
return nil, marketing.OffersErr.New("no current offer")
return nil, offerErr.New("no current offer")
}
if err != nil {
return nil, marketing.OffersErr.Wrap(err)
return nil, offerErr.Wrap(err)
}
return &o, nil
}
// Create inserts a new offer into the db
func (offers *offers) Create(ctx context.Context, o *marketing.NewOffer) (*marketing.Offer, error) {
func (db *offersDB) Create(ctx context.Context, o *rewards.NewOffer) (*rewards.Offer, error) {
currentTime := time.Now()
if o.ExpiresAt.Before(currentTime) {
return nil, marketing.OffersErr.New("expiration time: %v can't be before: %v", o.ExpiresAt, currentTime)
return nil, offerErr.New("expiration time: %v can't be before: %v", o.ExpiresAt, currentTime)
}
tx, err := offers.db.Open(ctx)
if o.Status == rewards.Default {
o.ExpiresAt = time.Now().UTC().AddDate(100, 0, 0)
o.RedeemableCap = 1
}
tx, err := db.db.Open(ctx)
if err != nil {
return nil, marketing.OffersErr.Wrap(err)
return nil, offerErr.Wrap(err)
}
// If there's an existing current offer, update its status to Done and set its expires_at to be NOW()
statement := offers.db.Rebind(`
statement := db.db.Rebind(`
UPDATE offers SET status=?, expires_at=?
WHERE status=? AND type=? AND expires_at>?;
`)
_, err = tx.Tx.ExecContext(ctx, statement, marketing.Done, currentTime, o.Status, o.Type, currentTime)
_, err = tx.Tx.ExecContext(ctx, statement, rewards.Done, currentTime, o.Status, o.Type, currentTime)
if err != nil {
return nil, marketing.OffersErr.Wrap(errs.Combine(err, tx.Rollback()))
return nil, offerErr.Wrap(errs.Combine(err, tx.Rollback()))
}
offerDbx, err := tx.Create_Offer(ctx,
@ -93,51 +103,55 @@ func (offers *offers) Create(ctx context.Context, o *marketing.NewOffer) (*marke
dbx.Offer_Type(int(o.Type)),
)
if err != nil {
return nil, marketing.OffersErr.Wrap(errs.Combine(err, tx.Rollback()))
return nil, offerErr.Wrap(errs.Combine(err, tx.Rollback()))
}
newOffer, err := convertDBOffer(offerDbx)
if err != nil {
return nil, marketing.OffersErr.Wrap(errs.Combine(err, tx.Rollback()))
return nil, offerErr.Wrap(errs.Combine(err, tx.Rollback()))
}
return newOffer, marketing.OffersErr.Wrap(tx.Commit())
return newOffer, offerErr.Wrap(tx.Commit())
}
// Redeem adds 1 to the amount of offers redeemed based on offer id
func (offers *offers) Redeem(ctx context.Context, oID int) error {
statement := offers.db.Rebind(
func (db *offersDB) Redeem(ctx context.Context, oID int, isDefault bool) error {
if isDefault {
return nil
}
statement := db.db.Rebind(
`UPDATE offers SET num_redeemed = num_redeemed + 1 where id = ? AND status = ? AND num_redeemed < redeemable_cap`,
)
_, err := offers.db.DB.ExecContext(ctx, statement, oID, marketing.Active)
_, err := db.db.DB.ExecContext(ctx, statement, oID, rewards.Active)
if err != nil {
return marketing.OffersErr.Wrap(err)
return offerErr.Wrap(err)
}
return nil
}
// Finish changes the offer status to be Done and its expiration date to be now based on offer id
func (offers *offers) Finish(ctx context.Context, oID int) error {
func (db *offersDB) Finish(ctx context.Context, oID int) error {
updateFields := dbx.Offer_Update_Fields{
Status: dbx.Offer_Status(int(marketing.Done)),
Status: dbx.Offer_Status(int(rewards.Done)),
ExpiresAt: dbx.Offer_ExpiresAt(time.Now().UTC()),
}
offerID := dbx.Offer_Id(oID)
_, err := offers.db.Update_Offer_By_Id(ctx, offerID, updateFields)
_, err := db.db.Update_Offer_By_Id(ctx, offerID, updateFields)
if err != nil {
return marketing.OffersErr.Wrap(err)
return offerErr.Wrap(err)
}
return nil
}
func offersFromDBX(offersDbx []*dbx.Offer) ([]marketing.Offer, error) {
var offers []marketing.Offer
var errList errs.Group
func offersFromDBX(offersDbx []*dbx.Offer) ([]rewards.Offer, error) {
var offers []rewards.Offer
errList := new(errs.Group)
for _, offerDbx := range offersDbx {
@ -152,12 +166,12 @@ func offersFromDBX(offersDbx []*dbx.Offer) ([]marketing.Offer, error) {
return offers, errList.Err()
}
func convertDBOffer(offerDbx *dbx.Offer) (*marketing.Offer, error) {
func convertDBOffer(offerDbx *dbx.Offer) (*rewards.Offer, error) {
if offerDbx == nil {
return nil, marketing.OffersErr.New("offerDbx parameter is nil")
return nil, offerErr.New("offerDbx parameter is nil")
}
o := marketing.Offer{
o := rewards.Offer{
ID: offerDbx.Id,
Name: offerDbx.Name,
Description: offerDbx.Description,
@ -169,8 +183,8 @@ func convertDBOffer(offerDbx *dbx.Offer) (*marketing.Offer, error) {
AwardCreditDurationDays: offerDbx.AwardCreditDurationDays,
InviteeCreditDurationDays: offerDbx.InviteeCreditDurationDays,
CreatedAt: offerDbx.CreatedAt,
Status: marketing.OfferStatus(offerDbx.Status),
Type: marketing.OfferType(offerDbx.Type),
Status: rewards.OfferStatus(offerDbx.Status),
Type: rewards.OfferType(offerDbx.Type),
}
return &o, nil

View File

@ -10,15 +10,12 @@ import (
"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/console"
"storj.io/storj/satellite/rewards"
"storj.io/storj/satellite/satellitedb/satellitedbtest"
)
@ -166,9 +163,9 @@ func TestUsercredits(t *testing.T) {
})
}
func setupData(ctx context.Context, t *testing.T, db satellite.DB) (user *console.User, referrer *console.User, offer *marketing.Offer) {
func setupData(ctx context.Context, t *testing.T, db satellite.DB) (user *console.User, referrer *console.User, offer *rewards.Offer) {
consoleDB := db.Console()
marketingDB := db.Marketing()
offersDB := db.Rewards()
// create user
var userPassHash [8]byte
_, err := rand.Read(userPassHash[:])
@ -197,7 +194,7 @@ func setupData(ctx context.Context, t *testing.T, db satellite.DB) (user *consol
require.NoError(t, err)
// create offer
offer, err = marketingDB.Offers().Create(ctx, &marketing.NewOffer{
offer, err = offersDB.Create(ctx, &rewards.NewOffer{
Name: "test",
Description: "test offer 1",
AwardCreditInCents: 100,
@ -206,8 +203,8 @@ func setupData(ctx context.Context, t *testing.T, db satellite.DB) (user *consol
InviteeCreditDurationDays: 30,
RedeemableCap: 50,
ExpiresAt: time.Now().UTC().Add(time.Hour * 1),
Status: marketing.Active,
Type: marketing.Referral,
Status: rewards.Active,
Type: rewards.Referral,
})
require.NoError(t, err)

View File

@ -52,7 +52,7 @@ func main() {
Mode: packages.LoadAllSyntax,
}
code.Wrapped = map[string]bool{}
code.AdditionalNesting = map[string]int{"Console": 1, "Marketing": 1}
code.AdditionalNesting = map[string]int{"Console": 1}
// e.g. storj.io/storj/satellite.DB
p := strings.LastIndexByte(typeFullyQualifedName, '.')