testsuite/ui: Add coupon tests
Add some testing around adding/replacing promotional coupons and what the user sees in the UI depending on their coupon status. Change-Id: Ice6c0a0644d05af0c30c87a93ba963c0bb09e32d
This commit is contained in:
parent
8d18033a99
commit
9c8b6c3fc3
@ -41,7 +41,29 @@ var mocks = struct {
|
||||
m: make(map[storj.NodeID]*mockStripeState),
|
||||
}
|
||||
|
||||
const testPromoCode string = "testpromocode"
|
||||
var (
|
||||
testPromoCodes = map[string]*stripe.PromotionCode{
|
||||
"promo1": {
|
||||
ID: "p1",
|
||||
Coupon: &stripe.Coupon{
|
||||
AmountOff: 500,
|
||||
Currency: stripe.CurrencyUSD,
|
||||
Name: "Test Promo Code 1",
|
||||
},
|
||||
},
|
||||
"promo2": {
|
||||
ID: "p2",
|
||||
Coupon: &stripe.Coupon{
|
||||
PercentOff: 50,
|
||||
Name: "Test Promo Code 2",
|
||||
},
|
||||
},
|
||||
}
|
||||
promoIDs = map[string]*stripe.PromotionCode{
|
||||
"p1": testPromoCodes["promo1"],
|
||||
"p2": testPromoCodes["promo2"],
|
||||
}
|
||||
)
|
||||
|
||||
// mockStripeState Stripe client mock.
|
||||
type mockStripeState struct {
|
||||
@ -80,9 +102,6 @@ func NewStripeMock(id storj.NodeID, customersDB CustomersDB, usersDB console.Use
|
||||
|
||||
state, ok := mocks.m[id]
|
||||
if !ok {
|
||||
promoCodes := make(map[string][]*stripe.PromotionCode)
|
||||
promoCodes[testPromoCode] = []*stripe.PromotionCode{{}}
|
||||
|
||||
state = &mockStripeState{
|
||||
customers: &mockCustomersState{},
|
||||
paymentMethods: newMockPaymentMethods(),
|
||||
@ -91,7 +110,7 @@ func NewStripeMock(id storj.NodeID, customersDB CustomersDB, usersDB console.Use
|
||||
customerBalanceTransactions: newMockCustomerBalanceTransactions(),
|
||||
charges: &mockCharges{},
|
||||
promoCodes: &mockPromoCodes{
|
||||
promoCodes: promoCodes,
|
||||
promoCodes: testPromoCodes,
|
||||
},
|
||||
}
|
||||
mocks.m[id] = state
|
||||
@ -262,8 +281,8 @@ func (m *mockCustomers) Update(id string, params *stripe.CustomerParams) (*strip
|
||||
if params.Metadata != nil {
|
||||
customer.Metadata = params.Metadata
|
||||
}
|
||||
if params.PromotionCode != nil {
|
||||
customer.Discount = &stripe.Discount{Coupon: &stripe.Coupon{}}
|
||||
if params.PromotionCode != nil && promoIDs[*params.PromotionCode] != nil {
|
||||
customer.Discount = &stripe.Discount{Coupon: promoIDs[*params.PromotionCode].Coupon}
|
||||
}
|
||||
|
||||
// TODO update customer with more params as necessary
|
||||
@ -471,7 +490,7 @@ func (m *mockCharges) List(listParams *stripe.ChargeListParams) *charge.Iter {
|
||||
}
|
||||
|
||||
type mockPromoCodes struct {
|
||||
promoCodes map[string][]*stripe.PromotionCode
|
||||
promoCodes map[string]*stripe.PromotionCode
|
||||
}
|
||||
|
||||
func (m *mockPromoCodes) List(params *stripe.PromotionCodeListParams) *promotioncode.Iter {
|
||||
@ -479,15 +498,15 @@ func (m *mockPromoCodes) List(params *stripe.PromotionCodeListParams) *promotion
|
||||
defer mocks.Unlock()
|
||||
|
||||
query := stripe.Query(func(p *stripe.Params, b *form.Values) ([]interface{}, stripe.ListContainer, error) {
|
||||
promoCodes := m.promoCodes[*params.Code]
|
||||
ret := make([]interface{}, len(promoCodes))
|
||||
|
||||
for i, v := range promoCodes {
|
||||
ret[i] = v
|
||||
promoCode := m.promoCodes[*params.Code]
|
||||
if promoCode == nil {
|
||||
return make([]interface{}, 0), &stripe.ListMeta{TotalCount: 0}, nil
|
||||
}
|
||||
ret := make([]interface{}, 1)
|
||||
ret[0] = promoCode
|
||||
|
||||
listMeta := &stripe.ListMeta{
|
||||
TotalCount: uint32(len(promoCodes)),
|
||||
TotalCount: 1,
|
||||
}
|
||||
|
||||
lc := newListContainer(listMeta)
|
||||
|
123
testsuite/ui/satellite/billing_coupon_test.go
Normal file
123
testsuite/ui/satellite/billing_coupon_test.go
Normal file
@ -0,0 +1,123 @@
|
||||
// Copyright (C) 2021 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package satellite_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-rod/rod"
|
||||
"github.com/go-rod/rod/lib/input"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"storj.io/common/testcontext"
|
||||
"storj.io/storj/private/testplanet"
|
||||
"storj.io/storj/testsuite/ui/uitest"
|
||||
)
|
||||
|
||||
func TestCouponCodes(t *testing.T) {
|
||||
uitest.Run(t, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet, browser *rod.Browser) {
|
||||
signupPageURL := planet.Satellites[0].ConsoleURL() + "/signup"
|
||||
fullName := "John Doe"
|
||||
emailAddress := "test@email.com"
|
||||
password := "qazwsx123"
|
||||
|
||||
page := openPage(browser, signupPageURL)
|
||||
|
||||
// first time User signs up
|
||||
page.MustElement("[aria-roledescription=name] input").MustInput(fullName)
|
||||
page.MustElement("[aria-roledescription=email] input").MustInput(emailAddress)
|
||||
page.MustElement("[aria-roledescription=password] input").MustInput(password)
|
||||
page.MustElement("[aria-roledescription=retype-password] input").MustInput(password)
|
||||
page.MustElement(".checkmark").MustClick()
|
||||
page.Keyboard.MustPress(input.Enter)
|
||||
waitVueTick(page)
|
||||
confirmAccountEmailMessage := page.MustElement("[aria-roledescription=title]").MustText()
|
||||
require.Contains(t, confirmAccountEmailMessage, "You're almost there!")
|
||||
|
||||
// first time user logs in
|
||||
page.MustElement("[href=\"/login\"]").MustClick()
|
||||
waitVueTick(page)
|
||||
page.MustElement("[aria-roledescription=email] input").MustInput(emailAddress)
|
||||
page.MustElement("[aria-roledescription=password] input").MustInput(password)
|
||||
page.Keyboard.MustPress(input.Enter)
|
||||
// waitVueTick(page)
|
||||
|
||||
// skip onboarding process
|
||||
page.MustElement("[href=\"/project-dashboard\"]").MustClick()
|
||||
dashboardTitle := page.MustElement("[aria-roledescription=title]").MustText()
|
||||
require.Contains(t, dashboardTitle, "Dashboard")
|
||||
|
||||
// go to billing page
|
||||
page.MustElement(".settings-selection").MustClick()
|
||||
page.MustElementX("(//p[text()=\" Billing \"])").MustClick()
|
||||
// waitVueTick(page)
|
||||
|
||||
couponText := page.MustElement(".coupon-area__container__text-container").MustText()
|
||||
require.Contains(t, couponText, "Add a Coupon to Get Started")
|
||||
require.Contains(t, couponText, "Your coupon will show up here.")
|
||||
|
||||
// Adding a valid promo code (promo1 and promo2 are defined in satellite/payments/stripecoinpayments/stripemock.go)
|
||||
{
|
||||
page.MustElementR("span", "Add Coupon Code").MustClick()
|
||||
page.MustElement("input[placeholder=\"Enter Coupon Code\"]").MustInput("promo1")
|
||||
page.MustElementR("span", "Apply Coupon Code").MustClick()
|
||||
page.MustElementR("p", "Successfully applied coupon code")
|
||||
|
||||
page.MustElement(".add-coupon__close-icon").MustClick()
|
||||
couponText := page.MustElement(".coupon-area__container__text-container").MustText()
|
||||
require.Contains(t, couponText, "Test Promo Code 1")
|
||||
require.Contains(t, couponText, "$5 off")
|
||||
}
|
||||
|
||||
// Attempting replace with invalid promo code
|
||||
{
|
||||
page.MustElementR("span", "Add Coupon Code").MustClick()
|
||||
page.MustElement("input[placeholder=\"Enter Coupon Code\"]").MustInput("notpromo1")
|
||||
page.MustElementR("span", "Apply Coupon Code").MustClick()
|
||||
|
||||
page.MustElementR(".add-coupon__confirm-message", "Are you sure.*remove.*current coupon.*replace.*new coupon")
|
||||
page.MustElementR("span", "Back").MustClick()
|
||||
|
||||
page.MustElement("input[placeholder=\"Enter Coupon Code\"]").MustInput("notpromo1")
|
||||
page.MustElementR("span", "Apply Coupon Code").MustClick()
|
||||
page.MustElementR(".add-coupon__confirm-message", "Are you sure.*remove.*current coupon.*replace.*new coupon")
|
||||
page.MustElementR("span", "Yes").MustClick()
|
||||
|
||||
page.MustElementR("p", "Could not apply coupon code")
|
||||
|
||||
// old coupon should still be applied
|
||||
page.MustElement(".add-coupon__close-icon").MustClick()
|
||||
couponText := page.MustElement(".coupon-area__container__text-container").MustText()
|
||||
require.Contains(t, couponText, "Test Promo Code 1")
|
||||
require.Contains(t, couponText, "$5 off")
|
||||
}
|
||||
|
||||
// Replacing with a valid promo code
|
||||
{
|
||||
page.MustElementR("span", "Add Coupon Code").MustClick()
|
||||
page.MustElement("input[placeholder=\"Enter Coupon Code\"]").MustInput("promo2")
|
||||
page.MustElementR("span", "Apply Coupon Code").MustClick()
|
||||
page.MustElementR(".add-coupon__confirm-message", "Are you sure.*remove.*current coupon.*replace.*new coupon")
|
||||
page.MustElementR("span", "Yes").MustClick()
|
||||
page.MustElementR("p", "Successfully applied coupon code")
|
||||
|
||||
page.MustElement(".add-coupon__close-icon").MustClick()
|
||||
couponText := page.MustElement(".coupon-area__container__text-container").MustText()
|
||||
require.Contains(t, couponText, "Test Promo Code 2")
|
||||
require.Contains(t, couponText, "50% off")
|
||||
|
||||
}
|
||||
|
||||
// Rate limit
|
||||
{
|
||||
page.MustElementR("span", "Add Coupon Code").MustClick()
|
||||
for i := 0; i < 3; i++ {
|
||||
page.MustElement("input[placeholder=\"Enter Coupon Code\"]").MustInput("promo1")
|
||||
page.MustElementR("span", "Apply Coupon Code").MustClick()
|
||||
page.MustElementR("span", "Yes").MustClick()
|
||||
}
|
||||
page.MustElementR("p", "You've exceeded limit of attempts")
|
||||
}
|
||||
})
|
||||
}
|
@ -40,6 +40,7 @@ func Run(t *testing.T, test Test) {
|
||||
config.Console.StaticDir = dir
|
||||
}
|
||||
config.Console.NewOnboarding = true
|
||||
config.Console.CouponCodeBillingUIEnabled = true
|
||||
},
|
||||
},
|
||||
NonParallel: true,
|
||||
|
Loading…
Reference in New Issue
Block a user