ducky/subscriptions

Paddy 2015-09-27 Parent:c4cfceb2f2fb Child:aab6ba5ae392

11:0ae1ff0ee306 Go to Latest

ducky/subscriptions/subscription_store_test.go

Add comments, move ChangingSystemProperties to the api package. Add comments to all our exported types and variables in subscription.go, both to make golint happy and because it's good to have comments. Move the subscriptions.ChangingSystemProperties helper to api.changingSystemProperties, because it returns API-specific strings and there's no real reason it has to be in the subscriptions package--everything it needs to work on is exported.

History
paddy@0 1 package subscriptions
paddy@0 2
paddy@0 3 import (
paddy@1 4 "os"
paddy@0 5 "strconv"
paddy@0 6 "testing"
paddy@0 7 "time"
paddy@0 8
paddy@0 9 "code.secondbit.org/uuid.hg"
paddy@0 10 )
paddy@0 11
paddy@0 12 const (
paddy@6 13 subscriptionChangeStripeSource = 1 << iota
paddy@6 14 subscriptionChangeEmail
paddy@6 15 subscriptionChangeStripeSubscription
paddy@2 16 subscriptionChangePlan
paddy@2 17 subscriptionChangeStatus
paddy@2 18 subscriptionChangeCanceling
paddy@2 19 subscriptionChangeTrialStart
paddy@2 20 subscriptionChangeTrialEnd
paddy@2 21 subscriptionChangePeriodStart
paddy@2 22 subscriptionChangePeriodEnd
paddy@2 23 subscriptionChangeCanceledAt
paddy@2 24 subscriptionChangeFailedChargeAttempts
paddy@2 25 subscriptionChangeLastFailedCharge
paddy@0 26 subscriptionChangeLastNotified
paddy@0 27 )
paddy@0 28
paddy@1 29 func init() {
paddy@1 30 if os.Getenv("PG_TEST_DB") != "" {
paddy@1 31 p, err := NewPostgres(os.Getenv("PG_TEST_DB"))
paddy@1 32 if err != nil {
paddy@1 33 panic(err)
paddy@1 34 }
paddy@1 35 testSubscriptionStores = append(testSubscriptionStores, p)
paddy@1 36 }
paddy@1 37 }
paddy@1 38
paddy@3 39 var testSubscriptionStores = []SubscriptionStore{
paddy@0 40 NewMemstore(),
paddy@0 41 }
paddy@0 42
paddy@0 43 func compareSubscriptions(sub1, sub2 Subscription) (bool, string, interface{}, interface{}) {
paddy@0 44 if !sub1.UserID.Equal(sub2.UserID) {
paddy@0 45 return false, "UserID", sub1.UserID, sub2.UserID
paddy@0 46 }
paddy@2 47 if sub1.StripeSubscription != sub2.StripeSubscription {
paddy@2 48 return false, "StripeSubscription", sub1.StripeSubscription, sub2.StripeSubscription
paddy@0 49 }
paddy@2 50 if sub1.Plan != sub2.Plan {
paddy@2 51 return false, "Plan", sub1.Plan, sub2.Plan
paddy@0 52 }
paddy@2 53 if sub1.Status != sub2.Status {
paddy@2 54 return false, "Status", sub1.Status, sub2.Status
paddy@2 55 }
paddy@2 56 if sub1.Canceling != sub2.Canceling {
paddy@2 57 return false, "Canceling", sub1.Canceling, sub2.Canceling
paddy@0 58 }
paddy@0 59 if !sub1.Created.Equal(sub2.Created) {
paddy@0 60 return false, "Created", sub1.Created, sub2.Created
paddy@0 61 }
paddy@2 62 if !sub1.TrialStart.Equal(sub2.TrialStart) {
paddy@2 63 return false, "TrialStart", sub1.TrialStart, sub2.TrialStart
paddy@0 64 }
paddy@2 65 if !sub1.TrialEnd.Equal(sub2.TrialEnd) {
paddy@2 66 return false, "TrialEnd", sub1.TrialEnd, sub2.TrialEnd
paddy@2 67 }
paddy@2 68 if !sub1.PeriodStart.Equal(sub2.PeriodStart) {
paddy@2 69 return false, "PeriodStart", sub1.PeriodStart, sub2.PeriodStart
paddy@2 70 }
paddy@2 71 if !sub1.PeriodEnd.Equal(sub2.PeriodEnd) {
paddy@2 72 return false, "PeriodEnd", sub1.PeriodEnd, sub2.PeriodEnd
paddy@2 73 }
paddy@2 74 if !sub1.CanceledAt.Equal(sub2.CanceledAt) {
paddy@2 75 return false, "CanceledAt", sub1.CanceledAt, sub2.CanceledAt
paddy@2 76 }
paddy@2 77 if sub1.FailedChargeAttempts != sub2.FailedChargeAttempts {
paddy@2 78 return false, "FailedChargeAttempts", sub1.FailedChargeAttempts, sub2.FailedChargeAttempts
paddy@2 79 }
paddy@2 80 if !sub1.LastFailedCharge.Equal(sub2.LastFailedCharge) {
paddy@2 81 return false, "LastFailedCharge", sub1.LastFailedCharge, sub2.LastFailedCharge
paddy@0 82 }
paddy@0 83 if !sub1.LastNotified.Equal(sub2.LastNotified) {
paddy@0 84 return false, "LastNotified", sub1.LastNotified, sub2.LastNotified
paddy@0 85 }
paddy@0 86 return true, "", nil, nil
paddy@0 87 }
paddy@0 88
paddy@0 89 func subscriptionMapContains(subscriptionMap map[string]Subscription, subscriptions ...Subscription) (bool, []Subscription) {
paddy@0 90 var missing []Subscription
paddy@0 91 for _, sub := range subscriptions {
paddy@1 92 if _, ok := subscriptionMap[sub.UserID.String()]; !ok {
paddy@0 93 missing = append(missing, sub)
paddy@0 94 }
paddy@0 95 }
paddy@0 96 if len(missing) > 0 {
paddy@0 97 return false, missing
paddy@0 98 }
paddy@0 99 return true, missing
paddy@0 100 }
paddy@0 101
paddy@2 102 func compareSubscriptionStats(stat1, stat2 SubscriptionStats) (bool, string, interface{}, interface{}) {
paddy@2 103 if stat1.Number != stat2.Number {
paddy@2 104 return false, "Number", stat1.Number, stat2.Number
paddy@2 105 }
paddy@2 106 if stat1.Canceling != stat2.Canceling {
paddy@2 107 return false, "Canceling", stat1.Canceling, stat2.Canceling
paddy@2 108 }
paddy@2 109 if stat1.Failing != stat2.Failing {
paddy@2 110 return false, "Failing", stat1.Failing, stat2.Failing
paddy@2 111 }
paddy@2 112 if len(stat1.Plans) != len(stat2.Plans) {
paddy@2 113 return false, "Plans", stat1.Plans, stat2.Plans
paddy@2 114 }
paddy@2 115 for key, count := range stat1.Plans {
paddy@2 116 count2, ok := stat2.Plans[key]
paddy@2 117 if !ok {
paddy@2 118 return false, "Plans", stat1.Plans, stat2.Plans
paddy@2 119 }
paddy@2 120 if count != count2 {
paddy@2 121 return false, "Plans", stat1.Plans, stat2.Plans
paddy@2 122 }
paddy@2 123 }
paddy@2 124 return true, "", nil, nil
paddy@2 125 }
paddy@2 126
paddy@0 127 func TestCreateSubscription(t *testing.T) {
paddy@0 128 for _, store := range testSubscriptionStores {
paddy@3 129 err := store.Reset()
paddy@0 130 if err != nil {
paddy@0 131 t.Fatalf("Error resetting %T: %+v\n", store, err)
paddy@0 132 }
paddy@0 133 customerID := uuid.NewID()
paddy@0 134 sub := Subscription{
paddy@2 135 UserID: customerID,
paddy@2 136 StripeSubscription: "stripeSubscription1",
paddy@2 137 Created: time.Now().Round(time.Millisecond),
paddy@2 138 TrialStart: time.Now().Round(time.Millisecond),
paddy@2 139 TrialEnd: time.Now().Round(time.Millisecond).Add(time.Hour * 24 * 31),
paddy@0 140 }
paddy@3 141 err = store.CreateSubscription(sub)
paddy@0 142 if err != nil {
paddy@0 143 t.Errorf("Error creating subscription in %T: %+v\n", store, err)
paddy@0 144 }
paddy@3 145 retrieved, err := store.GetSubscriptions([]uuid.ID{sub.UserID})
paddy@0 146 if err != nil {
paddy@0 147 t.Errorf("Error retrieving subscription from %T: %+v\n", store, err)
paddy@0 148 }
paddy@1 149 if _, returned := retrieved[sub.UserID.String()]; !returned {
paddy@1 150 t.Errorf("Error retrieving subscription from %T: %s wasn't in the results.", store, sub.UserID)
paddy@0 151 }
paddy@1 152 ok, field, expected, result := compareSubscriptions(sub, retrieved[sub.UserID.String()])
paddy@0 153 if !ok {
paddy@0 154 t.Errorf("Expected %s to be %v, got %v from %T\n", field, expected, result, store)
paddy@0 155 }
paddy@3 156 err = store.CreateSubscription(sub)
paddy@0 157 if err != ErrSubscriptionAlreadyExists {
paddy@0 158 t.Errorf("Unexpected error creating subscription in %T (wanted %+v): %+v\n", store, ErrSubscriptionAlreadyExists, err)
paddy@0 159 }
paddy@1 160 sub.UserID = uuid.NewID()
paddy@3 161 err = store.CreateSubscription(sub)
paddy@2 162 if err != ErrStripeSubscriptionAlreadyExists {
paddy@2 163 t.Errorf("Unexpected error creating subscription in %T (wanted %+v): %#+v\n", store, ErrStripeSubscriptionAlreadyExists, err)
paddy@0 164 }
paddy@2 165 sub.StripeSubscription = "stripeSubscription2"
paddy@3 166 err = store.CreateSubscription(sub)
paddy@0 167 if err != nil {
paddy@0 168 t.Errorf("Error creating subscription in %T: %+v\n", store, err)
paddy@0 169 }
paddy@0 170 }
paddy@0 171 }
paddy@0 172
paddy@0 173 func TestUpdateSubscription(t *testing.T) {
paddy@6 174 variations := 1 << 14
paddy@0 175 sub := Subscription{
paddy@2 176 UserID: uuid.NewID(),
paddy@2 177 StripeSubscription: "default",
paddy@2 178 Created: time.Now().Round(time.Millisecond).Add(time.Hour * -24 * -32),
paddy@2 179 TrialStart: time.Now().Round(time.Millisecond).Add(time.Hour * -24 * -32),
paddy@2 180 TrialEnd: time.Now().Round(time.Millisecond).Add(time.Hour * -24),
paddy@2 181 LastNotified: time.Now().Round(time.Millisecond).Add(time.Hour * -24),
paddy@0 182 }
paddy@0 183 sub2 := Subscription{
paddy@2 184 UserID: uuid.NewID(),
paddy@2 185 StripeSubscription: "stripeSubscription2",
paddy@2 186 Created: time.Now().Round(time.Millisecond),
paddy@2 187 TrialStart: time.Now().Round(time.Millisecond),
paddy@2 188 TrialEnd: time.Now().Round(time.Millisecond),
paddy@2 189 LastNotified: time.Now().Round(time.Millisecond),
paddy@0 190 }
paddy@0 191
paddy@2 192 for _, store := range testSubscriptionStores {
paddy@3 193 err := store.Reset()
paddy@2 194 if err != nil {
paddy@2 195 t.Fatalf("Error resetting %T: %+v\n", store, err)
paddy@2 196 }
paddy@3 197 err = store.CreateSubscription(sub)
paddy@2 198 if err != nil {
paddy@2 199 t.Fatalf("Error saving subscription in %T: %s\n", store, err)
paddy@2 200 }
paddy@2 201 for i := 1; i < variations; i++ {
paddy@6 202 var stripeSource, email, stripeSubscription, plan, status string
paddy@2 203 var canceling bool
paddy@2 204 var failedChargeAttempts int
paddy@2 205 var trialStart, trialEnd, periodStart, periodEnd, canceledAt, lastFailedCharge, lastNotified time.Time
paddy@0 206
paddy@2 207 change := SubscriptionChange{}
paddy@2 208 empty := change.IsEmpty()
paddy@2 209 if !empty {
paddy@2 210 t.Errorf("Expected empty to be %t, was %t\n", true, empty)
paddy@2 211 }
paddy@2 212 result := sub
paddy@2 213 strI := strconv.Itoa(i)
paddy@0 214
paddy@6 215 if i&subscriptionChangeStripeSource != 0 {
paddy@6 216 stripeSource = "stripeSource-" + strI
paddy@6 217 change.StripeSource = &stripeSource
paddy@6 218 }
paddy@6 219
paddy@6 220 if i&subscriptionChangeEmail != 0 {
paddy@6 221 email = "email-" + strI
paddy@6 222 change.Email = &email
paddy@6 223 }
paddy@6 224
paddy@2 225 if i&subscriptionChangeStripeSubscription != 0 {
paddy@2 226 stripeSubscription = "stripeSubscription-" + strI
paddy@2 227 change.StripeSubscription = &stripeSubscription
paddy@2 228 sub.StripeSubscription = stripeSubscription
paddy@2 229 }
paddy@0 230
paddy@2 231 if i&subscriptionChangePlan != 0 {
paddy@2 232 plan = "plan-" + strI
paddy@2 233 change.Plan = &plan
paddy@2 234 sub.Plan = plan
paddy@2 235 }
paddy@0 236
paddy@2 237 if i&subscriptionChangeStatus != 0 {
paddy@2 238 status = "status-" + strI
paddy@2 239 change.Status = &status
paddy@2 240 sub.Status = status
paddy@2 241 }
paddy@0 242
paddy@2 243 if i&subscriptionChangeCanceling != 0 {
paddy@2 244 canceling = i%2 == 0
paddy@2 245 change.Canceling = &canceling
paddy@2 246 sub.Canceling = canceling
paddy@2 247 }
paddy@0 248
paddy@2 249 if i&subscriptionChangeTrialStart != 0 {
paddy@2 250 trialStart = time.Now().Round(time.Millisecond).Add(time.Hour * time.Duration(i))
paddy@2 251 change.TrialStart = &trialStart
paddy@2 252 sub.TrialStart = trialStart
paddy@2 253 }
paddy@0 254
paddy@2 255 if i&subscriptionChangeTrialEnd != 0 {
paddy@2 256 trialEnd = time.Now().Round(time.Millisecond).Add(time.Hour * time.Duration(i))
paddy@2 257 change.TrialEnd = &trialEnd
paddy@2 258 sub.TrialEnd = trialEnd
paddy@2 259 }
paddy@0 260
paddy@2 261 if i&subscriptionChangePeriodStart != 0 {
paddy@2 262 periodStart = time.Now().Round(time.Millisecond).Add(time.Hour * time.Duration(i))
paddy@2 263 change.PeriodStart = &periodStart
paddy@2 264 sub.PeriodStart = periodStart
paddy@2 265 }
paddy@0 266
paddy@2 267 if i&subscriptionChangePeriodEnd != 0 {
paddy@2 268 periodEnd = time.Now().Round(time.Millisecond).Add(time.Hour * time.Duration(i))
paddy@2 269 change.PeriodEnd = &periodEnd
paddy@2 270 sub.PeriodEnd = periodEnd
paddy@2 271 }
paddy@0 272
paddy@2 273 if i&subscriptionChangeCanceledAt != 0 {
paddy@2 274 canceledAt = time.Now().Round(time.Millisecond).Add(time.Hour * time.Duration(i))
paddy@2 275 change.CanceledAt = &canceledAt
paddy@2 276 sub.CanceledAt = canceledAt
paddy@0 277 }
paddy@2 278
paddy@2 279 if i&subscriptionChangeFailedChargeAttempts != 0 {
paddy@2 280 failedChargeAttempts = i
paddy@2 281 change.FailedChargeAttempts = &failedChargeAttempts
paddy@2 282 sub.FailedChargeAttempts = failedChargeAttempts
paddy@2 283 }
paddy@2 284
paddy@2 285 if i&subscriptionChangeLastFailedCharge != 0 {
paddy@2 286 lastFailedCharge = time.Now().Round(time.Millisecond).Add(time.Hour * time.Duration(i))
paddy@2 287 change.LastFailedCharge = &lastFailedCharge
paddy@2 288 sub.LastFailedCharge = lastFailedCharge
paddy@2 289 }
paddy@2 290
paddy@2 291 if i&subscriptionChangeLastNotified != 0 {
paddy@2 292 lastNotified = time.Now().Round(time.Millisecond).Add(time.Hour * time.Duration(i))
paddy@2 293 change.LastNotified = &lastNotified
paddy@2 294 sub.LastNotified = lastNotified
paddy@2 295 }
paddy@2 296
paddy@2 297 empty = change.IsEmpty()
paddy@2 298 if empty {
paddy@2 299 t.Errorf("Expected empty to be %t, was %t\n", false, empty)
paddy@2 300 }
paddy@2 301
paddy@2 302 result.ApplyChange(change)
paddy@2 303 match, field, expected, got := compareSubscriptions(sub, result)
paddy@2 304 if !match {
paddy@2 305 t.Errorf("Expected field `%s` to be `%v`, got `%v`\n", field, expected, got)
paddy@0 306 }
paddy@3 307 err = store.UpdateSubscription(sub.UserID, change)
paddy@0 308 if err != nil {
paddy@0 309 t.Errorf("Error updating subscription in %T: %s\n", store, err)
paddy@0 310 }
paddy@3 311 retrieved, err := store.GetSubscriptions([]uuid.ID{sub.UserID})
paddy@0 312 if err != nil {
paddy@0 313 t.Errorf("Error getting subscription from %T: %s\n", store, err)
paddy@0 314 }
paddy@0 315 ok, missing := subscriptionMapContains(retrieved, sub)
paddy@0 316 if !ok {
paddy@1 317 t.Errorf("Expected to retrieve %s from %T, but missing was %+v\n", sub.UserID.String(), store, missing)
paddy@0 318 }
paddy@2 319 match, field, expected, got = compareSubscriptions(sub, retrieved[sub.UserID.String()])
paddy@0 320 if !match {
paddy@0 321 t.Errorf("Expected field `%s` to be `%v`, got `%v` from %T\n", field, expected, got, store)
paddy@0 322 }
paddy@2 323 sub = result
paddy@0 324 }
paddy@2 325
paddy@3 326 err = store.CreateSubscription(sub2)
paddy@0 327 if err != nil {
paddy@0 328 t.Fatalf("Error saving subscription in %T: %+v\n", store, err)
paddy@0 329 }
paddy@0 330 change := SubscriptionChange{}
paddy@3 331 err = store.UpdateSubscription(sub.UserID, change)
paddy@0 332 if err != ErrSubscriptionChangeEmpty {
paddy@0 333 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrSubscriptionChangeEmpty, err, store)
paddy@0 334 }
paddy@2 335 stripeSubscription := sub2.StripeSubscription
paddy@2 336 change.StripeSubscription = &stripeSubscription
paddy@3 337 err = store.UpdateSubscription(uuid.NewID(), change)
paddy@0 338 if err != ErrSubscriptionNotFound {
paddy@0 339 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrSubscriptionNotFound, err, store)
paddy@0 340 }
paddy@3 341 err = store.UpdateSubscription(sub.UserID, change)
paddy@2 342 if err != ErrStripeSubscriptionAlreadyExists {
paddy@2 343 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrStripeSubscriptionAlreadyExists, err, store)
paddy@0 344 }
paddy@0 345 }
paddy@0 346 }
paddy@0 347
paddy@0 348 func TestDeleteSubscription(t *testing.T) {
paddy@0 349 for _, store := range testSubscriptionStores {
paddy@3 350 err := store.Reset()
paddy@0 351 if err != nil {
paddy@0 352 t.Fatalf("Error resetting %T: %+v\n", store, err)
paddy@0 353 }
paddy@0 354 sub1 := Subscription{
paddy@2 355 UserID: uuid.NewID(),
paddy@2 356 StripeSubscription: "stripeSubscription1",
paddy@0 357 }
paddy@0 358 sub2 := Subscription{
paddy@2 359 UserID: uuid.NewID(),
paddy@2 360 StripeSubscription: "stripeSubscription2",
paddy@0 361 }
paddy@3 362 err = store.CreateSubscription(sub1)
paddy@0 363 if err != nil {
paddy@0 364 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 365 }
paddy@3 366 err = store.CreateSubscription(sub2)
paddy@0 367 if err != nil {
paddy@2 368 t.Fatalf("Error creating %+v in %T: %+v\n", sub2, store, err)
paddy@0 369 }
paddy@3 370 err = store.DeleteSubscription(sub1.UserID)
paddy@0 371 if err != nil {
paddy@0 372 t.Fatalf("Error deleting %+v in %T: %+v\n", sub1, store, err)
paddy@0 373 }
paddy@3 374 retrieved, err := store.GetSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID})
paddy@0 375 if err != nil {
paddy@0 376 t.Errorf("Error retrieving subscriptions from %T: %+v\n", store, err)
paddy@0 377 }
paddy@0 378 ok, missing := subscriptionMapContains(retrieved, sub1)
paddy@0 379 if ok {
paddy@1 380 t.Errorf("Expected not to retrieve %s from %T, but missing was %+v\n", sub1.UserID.String(), store, missing)
paddy@0 381 }
paddy@0 382 ok, missing = subscriptionMapContains(retrieved, sub2)
paddy@0 383 if !ok {
paddy@1 384 t.Errorf("Expected to retrieve %s from %T, but missing was %+v\n", sub2.UserID.String(), store, missing)
paddy@0 385 }
paddy@3 386 err = store.DeleteSubscription(sub1.UserID)
paddy@0 387 if err != ErrSubscriptionNotFound {
paddy@0 388 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrSubscriptionNotFound, err, store)
paddy@0 389 }
paddy@0 390 }
paddy@0 391 }
paddy@0 392
paddy@0 393 func TestGetSubscriptions(t *testing.T) {
paddy@0 394 for _, store := range testSubscriptionStores {
paddy@3 395 err := store.Reset()
paddy@0 396 if err != nil {
paddy@0 397 t.Fatalf("Error resetting %T: %+v\n", store, err)
paddy@0 398 }
paddy@0 399 sub1 := Subscription{
paddy@2 400 UserID: uuid.NewID(),
paddy@2 401 StripeSubscription: "stripeSubscription1",
paddy@2 402 Plan: "plan1",
paddy@2 403 Created: time.Now().Round(time.Millisecond),
paddy@2 404 TrialStart: time.Now().Round(time.Millisecond),
paddy@2 405 TrialEnd: time.Now().Round(time.Millisecond).Add(time.Hour * 24 * 32),
paddy@0 406 }
paddy@0 407 sub2 := Subscription{
paddy@2 408 UserID: uuid.NewID(),
paddy@2 409 StripeSubscription: "stripeSubscription2",
paddy@2 410 Plan: "plan2",
paddy@2 411 Created: time.Now().Round(time.Millisecond).Add(time.Hour * -720),
paddy@2 412 TrialStart: time.Now().Round(time.Millisecond).Add(time.Hour * -720),
paddy@2 413 TrialEnd: time.Now().Round(time.Millisecond),
paddy@0 414 }
paddy@0 415 sub3 := Subscription{
paddy@2 416 UserID: uuid.NewID(),
paddy@2 417 StripeSubscription: "stripeSubscription3",
paddy@2 418 Plan: "plan3",
paddy@2 419 Created: time.Now().Round(time.Millisecond).Add(time.Hour * -1440),
paddy@2 420 TrialStart: time.Now().Round(time.Millisecond).Add(time.Hour * -1440),
paddy@2 421 TrialEnd: time.Now().Round(time.Millisecond).Add(time.Hour * -720),
paddy@2 422 PeriodStart: time.Now().Round(time.Millisecond).Add(time.Hour * -720),
paddy@2 423 PeriodEnd: time.Now().Round(time.Millisecond),
paddy@2 424 Status: "unpaid",
paddy@0 425 }
paddy@3 426 err = store.CreateSubscription(sub1)
paddy@0 427 if err != nil {
paddy@0 428 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 429 }
paddy@3 430 err = store.CreateSubscription(sub2)
paddy@0 431 if err != nil {
paddy@0 432 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 433 }
paddy@3 434 err = store.CreateSubscription(sub3)
paddy@0 435 if err != nil {
paddy@0 436 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 437 }
paddy@3 438 retrieved, err := store.GetSubscriptions([]uuid.ID{})
paddy@0 439 if err != ErrNoSubscriptionID {
paddy@0 440 t.Errorf("Error retrieving no subscriptions from %T. Expected %+v, got %+v\n", store, ErrNoSubscriptionID, err)
paddy@0 441 }
paddy@3 442 retrieved, err = store.GetSubscriptions([]uuid.ID{sub1.UserID})
paddy@0 443 if err != nil {
paddy@1 444 t.Errorf("Error retrieving %s from %T: %+v\n", sub1.UserID, store, err)
paddy@0 445 }
paddy@0 446 ok, missing := subscriptionMapContains(retrieved, sub1)
paddy@0 447 if !ok {
paddy@0 448 t.Logf("Results: %+v\n", retrieved)
paddy@0 449 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 450 }
paddy@3 451 retrieved, err = store.GetSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID})
paddy@0 452 if err != nil {
paddy@1 453 t.Errorf("Error retrieving %s and %s from %T: %+v\n", sub1.UserID, sub2.UserID, store, err)
paddy@0 454 }
paddy@0 455 ok, missing = subscriptionMapContains(retrieved, sub1, sub2)
paddy@0 456 if !ok {
paddy@0 457 t.Logf("Results: %+v\n", retrieved)
paddy@0 458 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 459 }
paddy@3 460 retrieved, err = store.GetSubscriptions([]uuid.ID{sub1.UserID, sub3.UserID})
paddy@0 461 if err != nil {
paddy@1 462 t.Errorf("Error retrieving %s and %s from %T: %+v\n", sub1.UserID, sub3.UserID, store, err)
paddy@0 463 }
paddy@0 464 ok, missing = subscriptionMapContains(retrieved, sub1, sub3)
paddy@0 465 if !ok {
paddy@0 466 t.Logf("Results: %+v\n", retrieved)
paddy@0 467 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 468 }
paddy@3 469 retrieved, err = store.GetSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID, sub3.UserID})
paddy@0 470 if err != nil {
paddy@1 471 t.Errorf("Error retrieving %s, %s, and %s from %T: %+v\n", sub1.UserID, sub2.UserID, sub3.UserID, store, err)
paddy@0 472 }
paddy@0 473 ok, missing = subscriptionMapContains(retrieved, sub1, sub2, sub3)
paddy@0 474 if !ok {
paddy@0 475 t.Logf("Results: %+v\n", retrieved)
paddy@0 476 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 477 }
paddy@3 478 retrieved, err = store.GetSubscriptions([]uuid.ID{sub2.UserID})
paddy@0 479 if err != nil {
paddy@1 480 t.Errorf("Error retrieving %s from %T: %+v\n", sub2.UserID, store, err)
paddy@0 481 }
paddy@0 482 ok, missing = subscriptionMapContains(retrieved, sub2)
paddy@0 483 if !ok {
paddy@0 484 t.Logf("Results: %+v\n", retrieved)
paddy@0 485 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 486 }
paddy@3 487 retrieved, err = store.GetSubscriptions([]uuid.ID{sub2.UserID, sub3.UserID})
paddy@0 488 if err != nil {
paddy@1 489 t.Errorf("Error retrieving %s and %s from %T: %+v\n", sub2.UserID, sub3.UserID, store, err)
paddy@0 490 }
paddy@0 491 ok, missing = subscriptionMapContains(retrieved, sub2, sub3)
paddy@0 492 if !ok {
paddy@0 493 t.Logf("Results: %+v\n", retrieved)
paddy@0 494 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 495 }
paddy@3 496 retrieved, err = store.GetSubscriptions([]uuid.ID{sub3.UserID})
paddy@0 497 if err != nil {
paddy@1 498 t.Errorf("Error retrieving %s from %T: %+v\n", sub3.UserID, store, err)
paddy@0 499 }
paddy@0 500 ok, missing = subscriptionMapContains(retrieved, sub3)
paddy@0 501 if !ok {
paddy@0 502 t.Logf("Results: %+v\n", retrieved)
paddy@0 503 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 504 }
paddy@3 505 retrieved, err = store.GetSubscriptions([]uuid.ID{uuid.NewID()})
paddy@0 506 if err != nil {
paddy@0 507 t.Errorf("Error retrieving non-existent ID from %T: %+v\n", store, err)
paddy@0 508 }
paddy@0 509 if len(retrieved) != 0 {
paddy@0 510 t.Errorf("Expected no results, %T returned %+v\n", store, retrieved)
paddy@0 511 }
paddy@3 512 retrieved, err = store.GetSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID, uuid.NewID(), sub3.UserID})
paddy@0 513 if err != nil {
paddy@0 514 t.Errorf("Error retrieving non-existent ID from %T: %+v\n", store, err)
paddy@0 515 }
paddy@0 516 if len(retrieved) != 3 {
paddy@0 517 t.Errorf("Expected 3 results, %T returned %+v\n", store, retrieved)
paddy@0 518 }
paddy@0 519 ok, missing = subscriptionMapContains(retrieved, sub1, sub2, sub3)
paddy@0 520 if !ok {
paddy@0 521 t.Logf("Results: %+v\n", retrieved)
paddy@0 522 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 523 }
paddy@0 524 }
paddy@0 525 }
paddy@2 526
paddy@2 527 func TestGetSubscriptionStats(t *testing.T) {
paddy@2 528 for _, store := range testSubscriptionStores {
paddy@3 529 err := store.Reset()
paddy@2 530 if err != nil {
paddy@2 531 t.Fatalf("Error resetting %T: %+v\n", store, err)
paddy@2 532 }
paddy@2 533 sub1 := Subscription{
paddy@2 534 UserID: uuid.NewID(),
paddy@2 535 StripeSubscription: "stripeSubscription1",
paddy@2 536 Plan: "plan1",
paddy@2 537 Canceling: true,
paddy@2 538 }
paddy@2 539 sub2 := Subscription{
paddy@2 540 UserID: uuid.NewID(),
paddy@2 541 StripeSubscription: "stripeSubscription2",
paddy@2 542 Plan: "plan2",
paddy@2 543 Status: "past_due",
paddy@2 544 }
paddy@3 545 err = store.CreateSubscription(sub1)
paddy@2 546 if err != nil {
paddy@2 547 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@2 548 }
paddy@3 549 stats, err := store.GetSubscriptionStats()
paddy@2 550 if err != nil {
paddy@2 551 t.Errorf("Error getting stats from %T: %+v\n", store, err)
paddy@2 552 }
paddy@2 553 ok, field, expected, results := compareSubscriptionStats(SubscriptionStats{
paddy@2 554 Number: 1,
paddy@2 555 Canceling: 1,
paddy@2 556 Failing: 0,
paddy@2 557 Plans: map[string]int64{
paddy@2 558 "plan1": 1,
paddy@2 559 },
paddy@2 560 }, stats)
paddy@2 561 if !ok {
paddy@2 562 t.Errorf("Expected %s to be %+v, got %+v from %T\n", field, expected, results, store)
paddy@2 563 }
paddy@3 564 err = store.CreateSubscription(sub2)
paddy@2 565 if err != nil {
paddy@2 566 t.Fatalf("Error creating %+v in %T: %+v\n", sub2, store, err)
paddy@2 567 }
paddy@3 568 stats, err = store.GetSubscriptionStats()
paddy@2 569 if err != nil {
paddy@2 570 t.Errorf("Error getting status from %T: %+v\n", store, err)
paddy@2 571 }
paddy@2 572 ok, field, expected, results = compareSubscriptionStats(SubscriptionStats{
paddy@2 573 Number: 2,
paddy@2 574 Canceling: 1,
paddy@2 575 Failing: 1,
paddy@2 576 Plans: map[string]int64{
paddy@2 577 "plan1": 1,
paddy@2 578 "plan2": 1,
paddy@2 579 },
paddy@2 580 }, stats)
paddy@2 581 if !ok {
paddy@2 582 t.Errorf("Expected %s to be %+v, got %+v from %T\n", field, expected, results, store)
paddy@2 583 }
paddy@3 584 err = store.DeleteSubscription(sub1.UserID)
paddy@2 585 if err != nil {
paddy@2 586 t.Errorf("Error deleting subscription from %T: %+v\n", store, err)
paddy@2 587 }
paddy@3 588 stats, err = store.GetSubscriptionStats()
paddy@2 589 if err != nil {
paddy@2 590 t.Errorf("Error getting status from %T: %+v\n", store, err)
paddy@2 591 }
paddy@2 592 ok, field, expected, results = compareSubscriptionStats(SubscriptionStats{
paddy@2 593 Number: 1,
paddy@2 594 Canceling: 0,
paddy@2 595 Failing: 1,
paddy@2 596 Plans: map[string]int64{
paddy@2 597 "plan2": 1,
paddy@2 598 },
paddy@2 599 }, stats)
paddy@2 600 if !ok {
paddy@2 601 t.Errorf("Expected %s to be %+v, got %+v from %T\n", field, expected, results, store)
paddy@2 602 }
paddy@2 603 }
paddy@2 604 }