@@ -13,6 +13,8 @@ import (
13
13
"github.com/gitpod-io/gitpod/usage/pkg/db/dbtest"
14
14
"github.com/google/uuid"
15
15
"github.com/stretchr/testify/require"
16
+ "google.golang.org/grpc/codes"
17
+ "google.golang.org/grpc/status"
16
18
"gorm.io/gorm"
17
19
)
18
20
@@ -58,26 +60,143 @@ func TestCostCenterManager_GetOrCreateCostCenter(t *testing.T) {
58
60
59
61
func TestCostCenterManager_UpdateCostCenter (t * testing.T ) {
60
62
conn := dbtest .ConnectForTests (t )
61
- mnr := db .NewCostCenterManager (conn , db.DefaultSpendingLimit {
62
- ForTeams : 0 ,
63
- ForUsers : 500 ,
63
+ limits := db.DefaultSpendingLimit {
64
+ ForTeams : 0 ,
65
+ ForUsers : 500 ,
66
+ MinForIndividualsOnStripe : 1000 ,
67
+ }
68
+
69
+ t .Run ("prevents updates to negative spending limit" , func (t * testing.T ) {
70
+ mnr := db .NewCostCenterManager (conn , limits )
71
+ userAttributionID := db .NewUserAttributionID (uuid .New ().String ())
72
+ teamAttributionID := db .NewTeamAttributionID (uuid .New ().String ())
73
+ cleanUp (t , conn , userAttributionID , teamAttributionID )
74
+
75
+ _ , err := mnr .UpdateCostCenter (context .Background (), db.CostCenter {
76
+ ID : userAttributionID ,
77
+ BillingStrategy : db .CostCenter_Other ,
78
+ SpendingLimit : - 1 ,
79
+ })
80
+ require .Error (t , err )
81
+ require .Equal (t , codes .InvalidArgument , status .Code (err ))
82
+
83
+ _ , err = mnr .UpdateCostCenter (context .Background (), db.CostCenter {
84
+ ID : teamAttributionID ,
85
+ BillingStrategy : db .CostCenter_Stripe ,
86
+ SpendingLimit : - 1 ,
87
+ })
88
+ require .Error (t , err )
89
+ require .Equal (t , codes .InvalidArgument , status .Code (err ))
64
90
})
65
- team := db .NewTeamAttributionID (uuid .New ().String ())
66
- cleanUp (t , conn , team )
67
- teamCC , err := mnr .GetOrCreateCostCenter (context .Background (), team )
68
- t .Cleanup (func () {
69
- conn .Model (& db.CostCenter {}).Delete (teamCC )
91
+
92
+ t .Run ("individual user on Other billing strategy cannot change spending limit of 500" , func (t * testing.T ) {
93
+ mnr := db .NewCostCenterManager (conn , limits )
94
+ userAttributionID := db .NewUserAttributionID (uuid .New ().String ())
95
+ cleanUp (t , conn , userAttributionID )
96
+
97
+ _ , err := mnr .UpdateCostCenter (context .Background (), db.CostCenter {
98
+ ID : userAttributionID ,
99
+ BillingStrategy : db .CostCenter_Other ,
100
+ SpendingLimit : 501 ,
101
+ })
102
+ require .Error (t , err )
103
+ require .Equal (t , codes .FailedPrecondition , status .Code (err ))
104
+
70
105
})
71
- require .NoError (t , err )
72
- require .Equal (t , int32 (0 ), teamCC .SpendingLimit )
73
106
74
- teamCC .SpendingLimit = 2000
75
- teamCC , err = mnr .UpdateCostCenter (context .Background (), teamCC )
76
- require .NoError (t , err )
77
- t .Cleanup (func () {
78
- conn .Model (& db.CostCenter {}).Delete (teamCC )
107
+ t .Run ("individual user upgrading to stripe gets default limit of 1000 and can increase, but not decrease" , func (t * testing.T ) {
108
+ mnr := db .NewCostCenterManager (conn , limits )
109
+ userAttributionID := db .NewUserAttributionID (uuid .New ().String ())
110
+ cleanUp (t , conn , userAttributionID )
111
+
112
+ // Upgrading to Stripe requires spending limit
113
+ res , err := mnr .UpdateCostCenter (context .Background (), db.CostCenter {
114
+ ID : userAttributionID ,
115
+ BillingStrategy : db .CostCenter_Stripe ,
116
+ SpendingLimit : 1000 ,
117
+ })
118
+ require .NoError (t , err )
119
+ requireCostCenterEqual (t , db.CostCenter {
120
+ ID : userAttributionID ,
121
+ SpendingLimit : 1000 ,
122
+ BillingStrategy : db .CostCenter_Stripe ,
123
+ }, res )
124
+
125
+ // Try to lower the spending limit below configured limit
126
+ _ , err = mnr .UpdateCostCenter (context .Background (), db.CostCenter {
127
+ ID : userAttributionID ,
128
+ BillingStrategy : db .CostCenter_Stripe ,
129
+ SpendingLimit : 999 ,
130
+ })
131
+ require .Error (t , err , "lowering spending limit below configured value is not allowed for user subscriptions" )
132
+
133
+ // Try to update the cost center to higher usage limit
134
+ res , err = mnr .UpdateCostCenter (context .Background (), db.CostCenter {
135
+ ID : userAttributionID ,
136
+ BillingStrategy : db .CostCenter_Stripe ,
137
+ SpendingLimit : 1001 ,
138
+ })
139
+ require .NoError (t , err )
140
+ requireCostCenterEqual (t , db.CostCenter {
141
+ ID : userAttributionID ,
142
+ SpendingLimit : 1001 ,
143
+ BillingStrategy : db .CostCenter_Stripe ,
144
+ }, res )
145
+ })
146
+
147
+ t .Run ("team on Other billing strategy get a spending limit of 0, and cannot change it" , func (t * testing.T ) {
148
+ mnr := db .NewCostCenterManager (conn , limits )
149
+ teamAttributionID := db .NewTeamAttributionID (uuid .New ().String ())
150
+ cleanUp (t , conn , teamAttributionID )
151
+
152
+ // Allows udpating cost center as long as spending limit remains as configured
153
+ res , err := mnr .UpdateCostCenter (context .Background (), db.CostCenter {
154
+ ID : teamAttributionID ,
155
+ BillingStrategy : db .CostCenter_Other ,
156
+ SpendingLimit : limits .ForTeams ,
157
+ })
158
+ require .NoError (t , err )
159
+ requireCostCenterEqual (t , db.CostCenter {
160
+ ID : teamAttributionID ,
161
+ SpendingLimit : limits .ForTeams ,
162
+ BillingStrategy : db .CostCenter_Other ,
163
+ }, res )
164
+
165
+ // Prevents updating when spending limit changes
166
+ _ , err = mnr .UpdateCostCenter (context .Background (), db.CostCenter {
167
+ ID : teamAttributionID ,
168
+ BillingStrategy : db .CostCenter_Other ,
169
+ SpendingLimit : 1 ,
170
+ })
171
+ require .Error (t , err )
172
+ })
173
+
174
+ t .Run ("team on Stripe billing strategy can set arbitrary positive spending limit" , func (t * testing.T ) {
175
+ mnr := db .NewCostCenterManager (conn , limits )
176
+ teamAttributionID := db .NewTeamAttributionID (uuid .New ().String ())
177
+ cleanUp (t , conn , teamAttributionID )
178
+
179
+ // Allows udpating cost center as long as spending limit remains as configured
180
+ res , err := mnr .UpdateCostCenter (context .Background (), db.CostCenter {
181
+ ID : teamAttributionID ,
182
+ BillingStrategy : db .CostCenter_Stripe ,
183
+ SpendingLimit : limits .ForTeams ,
184
+ })
185
+ require .NoError (t , err )
186
+ requireCostCenterEqual (t , db.CostCenter {
187
+ ID : teamAttributionID ,
188
+ BillingStrategy : db .CostCenter_Stripe ,
189
+ SpendingLimit : limits .ForTeams ,
190
+ }, res )
191
+
192
+ // Allows updating cost center to any positive value
193
+ _ , err = mnr .UpdateCostCenter (context .Background (), db.CostCenter {
194
+ ID : teamAttributionID ,
195
+ BillingStrategy : db .CostCenter_Stripe ,
196
+ SpendingLimit : 10 ,
197
+ })
198
+ require .NoError (t , err )
79
199
})
80
- require .Equal (t , int32 (2000 ), teamCC .SpendingLimit )
81
200
}
82
201
83
202
func TestSaveCostCenterMovedToStripe (t * testing.T ) {
@@ -116,3 +235,12 @@ func cleanUp(t *testing.T, conn *gorm.DB, attributionIds ...db.AttributionID) {
116
235
}
117
236
})
118
237
}
238
+
239
+ func requireCostCenterEqual (t * testing.T , expected , actual db.CostCenter ) {
240
+ t .Helper ()
241
+
242
+ // ignore timestamps in comparsion
243
+ require .Equal (t , expected .ID , actual .ID )
244
+ require .EqualValues (t , expected .SpendingLimit , actual .SpendingLimit )
245
+ require .Equal (t , expected .BillingStrategy , actual .BillingStrategy )
246
+ }
0 commit comments