ducky/subscriptions

Paddy 2015-10-04 Parent:aab6ba5ae392

17:7eef47ecc01c Go to Latest

ducky/subscriptions/subscription_store_test.go

Document our client to make golint happy. Take care of all the documentation warnings in the client subpackage, which means golint now returns successfully.

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.Logf("Change %d: %+v\n", i, change)
298 if p, ok := store.(Postgres); ok {
299 query := p.updateSubscriptionSQL(sub.UserID, change)
300 t.Log(query.String())
301 t.Log(query.Args...)
302 }
303 t.Errorf("Error updating subscription in %T: %s\n", store, err)
304 }
305 retrieved, err := store.GetSubscriptions([]uuid.ID{sub.UserID})
306 if err != nil {
307 t.Errorf("Error getting subscription from %T: %s\n", store, err)
308 }
309 ok, missing := subscriptionMapContains(retrieved, sub)
310 if !ok {
311 t.Errorf("Expected to retrieve %s from %T, but missing was %+v\n", sub.UserID.String(), store, missing)
312 }
313 match, field, expected, got = compareSubscriptions(sub, retrieved[sub.UserID.String()])
314 if !match {
315 t.Errorf("Expected field `%s` to be `%v`, got `%v` from %T\n", field, expected, got, store)
316 }
317 sub = result
318 }
320 err = store.CreateSubscription(sub2)
321 if err != nil {
322 t.Fatalf("Error saving subscription in %T: %+v\n", store, err)
323 }
324 change := SubscriptionChange{}
325 err = store.UpdateSubscription(sub.UserID, change)
326 if err != ErrSubscriptionChangeEmpty {
327 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrSubscriptionChangeEmpty, err, store)
328 }
329 stripeSubscription := sub2.StripeSubscription
330 change.StripeSubscription = &stripeSubscription
331 err = store.UpdateSubscription(uuid.NewID(), change)
332 if err != ErrSubscriptionNotFound {
333 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrSubscriptionNotFound, err, store)
334 }
335 err = store.UpdateSubscription(sub.UserID, change)
336 if err != ErrStripeSubscriptionAlreadyExists {
337 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrStripeSubscriptionAlreadyExists, err, store)
338 }
339 }
340 }
342 func TestDeleteSubscription(t *testing.T) {
343 for _, store := range testSubscriptionStores {
344 err := store.Reset()
345 if err != nil {
346 t.Fatalf("Error resetting %T: %+v\n", store, err)
347 }
348 sub1 := Subscription{
349 UserID: uuid.NewID(),
350 StripeSubscription: "stripeSubscription1",
351 }
352 sub2 := Subscription{
353 UserID: uuid.NewID(),
354 StripeSubscription: "stripeSubscription2",
355 }
356 err = store.CreateSubscription(sub1)
357 if err != nil {
358 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
359 }
360 err = store.CreateSubscription(sub2)
361 if err != nil {
362 t.Fatalf("Error creating %+v in %T: %+v\n", sub2, store, err)
363 }
364 err = store.DeleteSubscription(sub1.UserID)
365 if err != nil {
366 t.Fatalf("Error deleting %+v in %T: %+v\n", sub1, store, err)
367 }
368 retrieved, err := store.GetSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID})
369 if err != nil {
370 t.Errorf("Error retrieving subscriptions from %T: %+v\n", store, err)
371 }
372 ok, missing := subscriptionMapContains(retrieved, sub1)
373 if ok {
374 t.Errorf("Expected not to retrieve %s from %T, but missing was %+v\n", sub1.UserID.String(), store, missing)
375 }
376 ok, missing = subscriptionMapContains(retrieved, sub2)
377 if !ok {
378 t.Errorf("Expected to retrieve %s from %T, but missing was %+v\n", sub2.UserID.String(), store, missing)
379 }
380 err = store.DeleteSubscription(sub1.UserID)
381 if err != ErrSubscriptionNotFound {
382 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrSubscriptionNotFound, err, store)
383 }
384 }
385 }
387 func TestGetSubscriptions(t *testing.T) {
388 for _, store := range testSubscriptionStores {
389 err := store.Reset()
390 if err != nil {
391 t.Fatalf("Error resetting %T: %+v\n", store, err)
392 }
393 sub1 := Subscription{
394 UserID: uuid.NewID(),
395 StripeSubscription: "stripeSubscription1",
396 Plan: "plan1",
397 Created: time.Now().Round(time.Millisecond),
398 TrialStart: time.Now().Round(time.Millisecond),
399 TrialEnd: time.Now().Round(time.Millisecond).Add(time.Hour * 24 * 32),
400 }
401 sub2 := Subscription{
402 UserID: uuid.NewID(),
403 StripeSubscription: "stripeSubscription2",
404 Plan: "plan2",
405 Created: time.Now().Round(time.Millisecond).Add(time.Hour * -720),
406 TrialStart: time.Now().Round(time.Millisecond).Add(time.Hour * -720),
407 TrialEnd: time.Now().Round(time.Millisecond),
408 }
409 sub3 := Subscription{
410 UserID: uuid.NewID(),
411 StripeSubscription: "stripeSubscription3",
412 Plan: "plan3",
413 Created: time.Now().Round(time.Millisecond).Add(time.Hour * -1440),
414 TrialStart: time.Now().Round(time.Millisecond).Add(time.Hour * -1440),
415 TrialEnd: time.Now().Round(time.Millisecond).Add(time.Hour * -720),
416 PeriodStart: time.Now().Round(time.Millisecond).Add(time.Hour * -720),
417 PeriodEnd: time.Now().Round(time.Millisecond),
418 Status: "unpaid",
419 }
420 err = store.CreateSubscription(sub1)
421 if err != nil {
422 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
423 }
424 err = store.CreateSubscription(sub2)
425 if err != nil {
426 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
427 }
428 err = store.CreateSubscription(sub3)
429 if err != nil {
430 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
431 }
432 retrieved, err := store.GetSubscriptions([]uuid.ID{})
433 if err != ErrNoSubscriptionID {
434 t.Errorf("Error retrieving no subscriptions from %T. Expected %+v, got %+v\n", store, ErrNoSubscriptionID, err)
435 }
436 retrieved, err = store.GetSubscriptions([]uuid.ID{sub1.UserID})
437 if err != nil {
438 t.Errorf("Error retrieving %s from %T: %+v\n", sub1.UserID, store, err)
439 }
440 ok, missing := subscriptionMapContains(retrieved, sub1)
441 if !ok {
442 t.Logf("Results: %+v\n", retrieved)
443 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
444 }
445 retrieved, err = store.GetSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID})
446 if err != nil {
447 t.Errorf("Error retrieving %s and %s from %T: %+v\n", sub1.UserID, sub2.UserID, store, err)
448 }
449 ok, missing = subscriptionMapContains(retrieved, sub1, sub2)
450 if !ok {
451 t.Logf("Results: %+v\n", retrieved)
452 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
453 }
454 retrieved, err = store.GetSubscriptions([]uuid.ID{sub1.UserID, sub3.UserID})
455 if err != nil {
456 t.Errorf("Error retrieving %s and %s from %T: %+v\n", sub1.UserID, sub3.UserID, store, err)
457 }
458 ok, missing = subscriptionMapContains(retrieved, sub1, sub3)
459 if !ok {
460 t.Logf("Results: %+v\n", retrieved)
461 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
462 }
463 retrieved, err = store.GetSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID, sub3.UserID})
464 if err != nil {
465 t.Errorf("Error retrieving %s, %s, and %s from %T: %+v\n", sub1.UserID, sub2.UserID, sub3.UserID, store, err)
466 }
467 ok, missing = subscriptionMapContains(retrieved, sub1, sub2, sub3)
468 if !ok {
469 t.Logf("Results: %+v\n", retrieved)
470 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
471 }
472 retrieved, err = store.GetSubscriptions([]uuid.ID{sub2.UserID})
473 if err != nil {
474 t.Errorf("Error retrieving %s from %T: %+v\n", sub2.UserID, store, err)
475 }
476 ok, missing = subscriptionMapContains(retrieved, sub2)
477 if !ok {
478 t.Logf("Results: %+v\n", retrieved)
479 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
480 }
481 retrieved, err = store.GetSubscriptions([]uuid.ID{sub2.UserID, sub3.UserID})
482 if err != nil {
483 t.Errorf("Error retrieving %s and %s from %T: %+v\n", sub2.UserID, sub3.UserID, store, err)
484 }
485 ok, missing = subscriptionMapContains(retrieved, sub2, sub3)
486 if !ok {
487 t.Logf("Results: %+v\n", retrieved)
488 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
489 }
490 retrieved, err = store.GetSubscriptions([]uuid.ID{sub3.UserID})
491 if err != nil {
492 t.Errorf("Error retrieving %s from %T: %+v\n", sub3.UserID, store, err)
493 }
494 ok, missing = subscriptionMapContains(retrieved, sub3)
495 if !ok {
496 t.Logf("Results: %+v\n", retrieved)
497 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
498 }
499 retrieved, err = store.GetSubscriptions([]uuid.ID{uuid.NewID()})
500 if err != nil {
501 t.Errorf("Error retrieving non-existent ID from %T: %+v\n", store, err)
502 }
503 if len(retrieved) != 0 {
504 t.Errorf("Expected no results, %T returned %+v\n", store, retrieved)
505 }
506 retrieved, err = store.GetSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID, uuid.NewID(), sub3.UserID})
507 if err != nil {
508 t.Errorf("Error retrieving non-existent ID from %T: %+v\n", store, err)
509 }
510 if len(retrieved) != 3 {
511 t.Errorf("Expected 3 results, %T returned %+v\n", store, retrieved)
512 }
513 ok, missing = subscriptionMapContains(retrieved, sub1, sub2, sub3)
514 if !ok {
515 t.Logf("Results: %+v\n", retrieved)
516 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
517 }
518 }
519 }
521 func TestGetSubscriptionStats(t *testing.T) {
522 for _, store := range testSubscriptionStores {
523 err := store.Reset()
524 if err != nil {
525 t.Fatalf("Error resetting %T: %+v\n", store, err)
526 }
527 sub1 := Subscription{
528 UserID: uuid.NewID(),
529 StripeSubscription: "stripeSubscription1",
530 Plan: "plan1",
531 Canceling: true,
532 }
533 sub2 := Subscription{
534 UserID: uuid.NewID(),
535 StripeSubscription: "stripeSubscription2",
536 Plan: "plan2",
537 Status: "past_due",
538 }
539 err = store.CreateSubscription(sub1)
540 if err != nil {
541 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
542 }
543 stats, err := store.GetSubscriptionStats()
544 if err != nil {
545 t.Errorf("Error getting stats from %T: %+v\n", store, err)
546 }
547 ok, field, expected, results := compareSubscriptionStats(SubscriptionStats{
548 Number: 1,
549 Canceling: 1,
550 Failing: 0,
551 Plans: map[string]int64{
552 "plan1": 1,
553 },
554 }, stats)
555 if !ok {
556 t.Errorf("Expected %s to be %+v, got %+v from %T\n", field, expected, results, store)
557 }
558 err = store.CreateSubscription(sub2)
559 if err != nil {
560 t.Fatalf("Error creating %+v in %T: %+v\n", sub2, store, err)
561 }
562 stats, err = store.GetSubscriptionStats()
563 if err != nil {
564 t.Errorf("Error getting status from %T: %+v\n", store, err)
565 }
566 ok, field, expected, results = compareSubscriptionStats(SubscriptionStats{
567 Number: 2,
568 Canceling: 1,
569 Failing: 1,
570 Plans: map[string]int64{
571 "plan1": 1,
572 "plan2": 1,
573 },
574 }, stats)
575 if !ok {
576 t.Errorf("Expected %s to be %+v, got %+v from %T\n", field, expected, results, store)
577 }
578 err = store.DeleteSubscription(sub1.UserID)
579 if err != nil {
580 t.Errorf("Error deleting subscription from %T: %+v\n", store, err)
581 }
582 stats, err = store.GetSubscriptionStats()
583 if err != nil {
584 t.Errorf("Error getting status from %T: %+v\n", store, err)
585 }
586 ok, field, expected, results = compareSubscriptionStats(SubscriptionStats{
587 Number: 1,
588 Canceling: 0,
589 Failing: 1,
590 Plans: map[string]int64{
591 "plan2": 1,
592 },
593 }, stats)
594 if !ok {
595 t.Errorf("Expected %s to be %+v, got %+v from %T\n", field, expected, results, store)
596 }
597 }
598 }