ducky/subscriptions

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

8:61583c1d3886 Go to Latest

ducky/subscriptions/subscription_store_test.go

Create a listener that will create subscriptions. We need a listener (as discussed in c4cfceb2f2fb) that will create a Subscription whenever an auth.Profile is created. This is the beginning of that effort. It hasn't been tested, and all the pieces aren't in place, but it's a rough skeleton. We have a Dockerfile that will correctly build a minimal container for the listener. We have a build-docker.sh script that will correctly build a binary that will be used in the Dockerfile. We have a ca-certificates.crt, which are pulled from Ubuntu, and are necessary before we can safely consume SSL endpoints. We created a small consumer script that listens for events off NSQ, and calls the appropriate endpoint for our Subscriptions API. This is untested, and it doesn't build at the moment, but that's awaiting changes in the code.secondbit.org/auth.hg package. Finally, we have a wrapper.sh file that will expose the Stripe secret key being used from a Kubernetes secret file as an environment variable, instead.

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