ducky/subscriptions

Paddy 2015-06-22 Parent:61c4ce5850da Child:c4cfceb2f2fb

3:b240b6123548 Go to Latest

ducky/subscriptions/subscription_store_test.go

Export all subscriptionStore methods. We're not going to wrap all our subscriptionStore interactions in a Context type, so we need to expose all the functions so other packages can call them. Also, it's now SubscriptionStore. Also creates a SubscriptionRequest type that is used to create a new Subscription instance, along with a Validate method on it, to detect errors when creating a SubscriptionRequest. Update our CreateSubscription function to be New, and have it take a SubscriptionRequest, a Stripe instance, and a SubscriptionStore as arguments. It'll create the Subscription in the SubscriptionStore, create a customer in Stripe, and create the subscription in Stripe, then associate the Stripe subscription with the created Subscription. Also, fix our StripeSubscriptionChange function to correctly equate a missing/zero Unix timestamp from Stripe with a missing/zero time.Time.

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