ducky/subscriptions

Paddy 2015-07-13 Parent:c4cfceb2f2fb Child:aab6ba5ae392

7:9e138933e4ce Go to Latest

ducky/subscriptions/subscription_store_test.go

Create a client for working with subscriptions. We mostly copied our code.secondbit.org/auth.hg/client package to create a simple client library for communicating with our Subscriptions API. Right now, the client only has support for creating a subscription. It remains untested, but it builds.

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 }