ducky/subscriptions

Paddy 2015-06-14 Parent:56a2bef197cd Child:61c4ce5850da

1:f1a22fc2321d Go to Latest

ducky/subscriptions/subscription_store_test.go

Implement PostgreSQL support, drop subscription IDs. Create a Postgres object that wraps database/sql, so we can attach methods to it and fulfill interfaces. Create a postgres_init.sql script that will create the subscriptions table in a PostgreSQL database. Make our period type fulfill the driver.Valuer and driver.Scanner types, so it can be stored in and retrieved from SQL databases. Create a SubscriptionStats type, and add a method to our subscriptionStore interface that will allow us to retrieve current stats about the Subscriptions it is storing. Deprecated the ID property of our Subscription type, and use the Subscription.UserID property instead as our primary key. Subscriptions should be unique per user and we generally will want to access Subscriptions in the context of the User they belong to, so the UserID is a better primary key. This also means we removed the getSubscriptionByUserID method (and implementations) from our subscriptionStore, as getSubscriptions now fills that role. Implement our getSubscriptionStats method in the memstore. Implement the subscriptionStore interface on our new Postgres type. Run the subscription store tests on our Postgres type, as well, if the PG_TEST_DB environment variable is set. Round all our timestamps in our tests to the nearest millisecond, as Postgres silently truncates all timestamps to the nearest millisecond, and it was causing false test failures. Remove the tests for our getSubscriptionStoreByUser method, as that was removed.

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@0 13 subscriptionChangeStripeCustomer = 1 << iota
paddy@0 14 subscriptionChangeAmount
paddy@0 15 subscriptionChangePeriod
paddy@0 16 subscriptionChangeBeginCharging
paddy@0 17 subscriptionChangeLastCharged
paddy@0 18 subscriptionChangeLastNotified
paddy@0 19 subscriptionChangeInLockout
paddy@0 20 )
paddy@0 21
paddy@1 22 func init() {
paddy@1 23 if os.Getenv("PG_TEST_DB") != "" {
paddy@1 24 p, err := NewPostgres(os.Getenv("PG_TEST_DB"))
paddy@1 25 if err != nil {
paddy@1 26 panic(err)
paddy@1 27 }
paddy@1 28 testSubscriptionStores = append(testSubscriptionStores, p)
paddy@1 29 }
paddy@1 30 }
paddy@1 31
paddy@0 32 var testSubscriptionStores = []subscriptionStore{
paddy@0 33 NewMemstore(),
paddy@0 34 }
paddy@0 35
paddy@0 36 func compareSubscriptions(sub1, sub2 Subscription) (bool, string, interface{}, interface{}) {
paddy@0 37 if !sub1.UserID.Equal(sub2.UserID) {
paddy@0 38 return false, "UserID", sub1.UserID, sub2.UserID
paddy@0 39 }
paddy@0 40 if sub1.StripeCustomer != sub2.StripeCustomer {
paddy@0 41 return false, "StripeCustomer", sub1.StripeCustomer, sub2.StripeCustomer
paddy@0 42 }
paddy@0 43 if sub1.Amount != sub2.Amount {
paddy@0 44 return false, "Amount", sub1.Amount, sub2.Amount
paddy@0 45 }
paddy@0 46 if sub1.Period != sub2.Period {
paddy@0 47 return false, "Period", sub1.Period, sub2.Period
paddy@0 48 }
paddy@0 49 if !sub1.Created.Equal(sub2.Created) {
paddy@0 50 return false, "Created", sub1.Created, sub2.Created
paddy@0 51 }
paddy@0 52 if !sub1.BeginCharging.Equal(sub2.BeginCharging) {
paddy@0 53 return false, "BeginCharging", sub1.BeginCharging, sub2.BeginCharging
paddy@0 54 }
paddy@0 55 if !sub1.LastCharged.Equal(sub2.LastCharged) {
paddy@0 56 return false, "LastCharged", sub1.LastCharged, sub2.LastCharged
paddy@0 57 }
paddy@0 58 if !sub1.LastNotified.Equal(sub2.LastNotified) {
paddy@0 59 return false, "LastNotified", sub1.LastNotified, sub2.LastNotified
paddy@0 60 }
paddy@0 61 if sub1.InLockout != sub2.InLockout {
paddy@0 62 return false, "InLockout", sub1.InLockout, sub2.InLockout
paddy@0 63 }
paddy@0 64 return true, "", nil, nil
paddy@0 65 }
paddy@0 66
paddy@0 67 func subscriptionMapContains(subscriptionMap map[string]Subscription, subscriptions ...Subscription) (bool, []Subscription) {
paddy@0 68 var missing []Subscription
paddy@0 69 for _, sub := range subscriptions {
paddy@1 70 if _, ok := subscriptionMap[sub.UserID.String()]; !ok {
paddy@0 71 missing = append(missing, sub)
paddy@0 72 }
paddy@0 73 }
paddy@0 74 if len(missing) > 0 {
paddy@0 75 return false, missing
paddy@0 76 }
paddy@0 77 return true, missing
paddy@0 78 }
paddy@0 79
paddy@0 80 func TestCreateSubscription(t *testing.T) {
paddy@0 81 for _, store := range testSubscriptionStores {
paddy@0 82 err := store.reset()
paddy@0 83 if err != nil {
paddy@0 84 t.Fatalf("Error resetting %T: %+v\n", store, err)
paddy@0 85 }
paddy@0 86 customerID := uuid.NewID()
paddy@0 87 sub := Subscription{
paddy@0 88 UserID: customerID,
paddy@0 89 StripeCustomer: "stripeCustomer1",
paddy@0 90 Amount: 200,
paddy@0 91 Period: MonthlyPeriod,
paddy@1 92 Created: time.Now().Round(time.Millisecond),
paddy@1 93 BeginCharging: time.Now().Round(time.Millisecond).Add(time.Hour),
paddy@0 94 }
paddy@0 95 err = store.createSubscription(sub)
paddy@0 96 if err != nil {
paddy@0 97 t.Errorf("Error creating subscription in %T: %+v\n", store, err)
paddy@0 98 }
paddy@1 99 retrieved, err := store.getSubscriptions([]uuid.ID{sub.UserID})
paddy@0 100 if err != nil {
paddy@0 101 t.Errorf("Error retrieving subscription from %T: %+v\n", store, err)
paddy@0 102 }
paddy@1 103 if _, returned := retrieved[sub.UserID.String()]; !returned {
paddy@1 104 t.Errorf("Error retrieving subscription from %T: %s wasn't in the results.", store, sub.UserID)
paddy@0 105 }
paddy@1 106 ok, field, expected, result := compareSubscriptions(sub, retrieved[sub.UserID.String()])
paddy@0 107 if !ok {
paddy@0 108 t.Errorf("Expected %s to be %v, got %v from %T\n", field, expected, result, store)
paddy@0 109 }
paddy@0 110 err = store.createSubscription(sub)
paddy@0 111 if err != ErrSubscriptionAlreadyExists {
paddy@0 112 t.Errorf("Unexpected error creating subscription in %T (wanted %+v): %+v\n", store, ErrSubscriptionAlreadyExists, err)
paddy@0 113 }
paddy@1 114 sub.UserID = uuid.NewID()
paddy@0 115 err = store.createSubscription(sub)
paddy@0 116 if err != ErrStripeCustomerAlreadyExists {
paddy@1 117 t.Errorf("Unexpected error creating subscription in %T (wanted %+v): %#+v\n", store, ErrStripeCustomerAlreadyExists, err)
paddy@0 118 }
paddy@0 119 sub.StripeCustomer = "stripeCustomer2"
paddy@0 120 err = store.createSubscription(sub)
paddy@0 121 if err != nil {
paddy@0 122 t.Errorf("Error creating subscription in %T: %+v\n", store, err)
paddy@0 123 }
paddy@0 124 }
paddy@0 125 }
paddy@0 126
paddy@0 127 func TestUpdateSubscription(t *testing.T) {
paddy@0 128 variations := 1 << 7
paddy@0 129 sub := Subscription{
paddy@0 130 UserID: uuid.NewID(),
paddy@0 131 StripeCustomer: "default",
paddy@0 132 Amount: -1,
paddy@0 133 Period: MonthlyPeriod,
paddy@1 134 Created: time.Now().Round(time.Millisecond).Add(time.Hour * -24),
paddy@1 135 BeginCharging: time.Now().Round(time.Millisecond).Add(time.Hour * -24),
paddy@1 136 LastCharged: time.Now().Round(time.Millisecond).Add(time.Hour * -24),
paddy@1 137 LastNotified: time.Now().Round(time.Millisecond).Add(time.Hour * -24),
paddy@0 138 InLockout: true,
paddy@0 139 }
paddy@0 140 sub2 := Subscription{
paddy@0 141 UserID: uuid.NewID(),
paddy@0 142 StripeCustomer: "stripeCustomer2",
paddy@0 143 Amount: -2,
paddy@0 144 Period: MonthlyPeriod,
paddy@1 145 Created: time.Now().Round(time.Millisecond),
paddy@1 146 BeginCharging: time.Now().Round(time.Millisecond),
paddy@1 147 LastCharged: time.Now().Round(time.Millisecond),
paddy@1 148 LastNotified: time.Now().Round(time.Millisecond),
paddy@0 149 InLockout: false,
paddy@0 150 }
paddy@0 151
paddy@0 152 for i := 1; i < variations; i++ {
paddy@0 153 var stripeCustomer string
paddy@0 154 var amount int
paddy@0 155 var inLockout bool
paddy@0 156 var per period
paddy@0 157 var beginCharging, lastCharged, lastNotified time.Time
paddy@0 158
paddy@0 159 change := SubscriptionChange{}
paddy@0 160 empty := change.IsEmpty()
paddy@0 161 if !empty {
paddy@0 162 t.Errorf("Expected empty to be %t, was %t\n", true, empty)
paddy@0 163 }
paddy@0 164 expectation := sub
paddy@0 165 result := sub
paddy@0 166 strI := strconv.Itoa(i)
paddy@0 167
paddy@0 168 if i&subscriptionChangeStripeCustomer != 0 {
paddy@0 169 stripeCustomer = "stripeCustomer-" + strI
paddy@0 170 change.StripeCustomer = &stripeCustomer
paddy@0 171 expectation.StripeCustomer = stripeCustomer
paddy@0 172 }
paddy@0 173
paddy@0 174 if i&subscriptionChangeAmount != 0 {
paddy@0 175 amount = i
paddy@0 176 change.Amount = &amount
paddy@0 177 expectation.Amount = amount
paddy@0 178 }
paddy@0 179
paddy@0 180 if i&subscriptionChangePeriod != 0 {
paddy@0 181 per = period("period-" + strI)
paddy@0 182 change.Period = &per
paddy@0 183 expectation.Period = per
paddy@0 184 }
paddy@0 185
paddy@0 186 if i&subscriptionChangeBeginCharging != 0 {
paddy@1 187 beginCharging = time.Now().Round(time.Millisecond).Add(time.Hour * time.Duration(i))
paddy@0 188 change.BeginCharging = &beginCharging
paddy@0 189 expectation.BeginCharging = beginCharging
paddy@0 190 }
paddy@0 191
paddy@0 192 if i&subscriptionChangeLastCharged != 0 {
paddy@1 193 lastCharged = time.Now().Round(time.Millisecond).Add(time.Hour * time.Duration(i))
paddy@0 194 change.LastCharged = &lastCharged
paddy@0 195 expectation.LastCharged = lastCharged
paddy@0 196 }
paddy@0 197
paddy@0 198 if i&subscriptionChangeLastNotified != 0 {
paddy@1 199 lastNotified = time.Now().Round(time.Millisecond).Add(time.Hour * time.Duration(i))
paddy@0 200 change.LastNotified = &lastNotified
paddy@0 201 expectation.LastNotified = lastNotified
paddy@0 202 }
paddy@0 203
paddy@0 204 if i&subscriptionChangeInLockout != 0 {
paddy@0 205 inLockout = i%2 == 0
paddy@0 206 change.InLockout = &inLockout
paddy@0 207 expectation.InLockout = inLockout
paddy@0 208 }
paddy@0 209
paddy@0 210 empty = change.IsEmpty()
paddy@0 211 if empty {
paddy@0 212 t.Errorf("Expected empty to be %t, was %t\n", false, empty)
paddy@0 213 }
paddy@0 214
paddy@0 215 result.ApplyChange(change)
paddy@0 216 match, field, expected, got := compareSubscriptions(expectation, result)
paddy@0 217 if !match {
paddy@0 218 t.Errorf("Expected field `%s` to be `%v`, got `%v`\n", field, expected, got)
paddy@0 219 }
paddy@0 220 for _, store := range testSubscriptionStores {
paddy@0 221 err := store.reset()
paddy@0 222 if err != nil {
paddy@0 223 t.Fatalf("Error resetting %T: %+v\n", store, err)
paddy@0 224 }
paddy@0 225 err = store.createSubscription(sub)
paddy@0 226 if err != nil {
paddy@0 227 t.Fatalf("Error saving subscription in %T: %s\n", store, err)
paddy@0 228 }
paddy@1 229 err = store.updateSubscription(sub.UserID, change)
paddy@0 230 if err != nil {
paddy@0 231 t.Errorf("Error updating subscription in %T: %s\n", store, err)
paddy@0 232 }
paddy@1 233 retrieved, err := store.getSubscriptions([]uuid.ID{sub.UserID})
paddy@0 234 if err != nil {
paddy@0 235 t.Errorf("Error getting subscription from %T: %s\n", store, err)
paddy@0 236 }
paddy@0 237 ok, missing := subscriptionMapContains(retrieved, sub)
paddy@0 238 if !ok {
paddy@1 239 t.Errorf("Expected to retrieve %s from %T, but missing was %+v\n", sub.UserID.String(), store, missing)
paddy@0 240 }
paddy@1 241 match, field, expected, got = compareSubscriptions(expectation, retrieved[sub.UserID.String()])
paddy@0 242 if !match {
paddy@0 243 t.Errorf("Expected field `%s` to be `%v`, got `%v` from %T\n", field, expected, got, store)
paddy@0 244 }
paddy@0 245 }
paddy@0 246 }
paddy@0 247 for _, store := range testSubscriptionStores {
paddy@0 248 err := store.reset()
paddy@0 249 if err != nil {
paddy@0 250 t.Fatalf("Error resetting %T: %+v\n", store, err)
paddy@0 251 }
paddy@0 252 err = store.createSubscription(sub)
paddy@0 253 if err != nil {
paddy@0 254 t.Fatalf("Error saving subscription in %T: %+v\n", store, err)
paddy@0 255 }
paddy@0 256 err = store.createSubscription(sub2)
paddy@0 257 if err != nil {
paddy@0 258 t.Fatalf("Error saving subscription in %T: %+v\n", store, err)
paddy@0 259 }
paddy@0 260 change := SubscriptionChange{}
paddy@1 261 err = store.updateSubscription(sub.UserID, change)
paddy@0 262 if err != ErrSubscriptionChangeEmpty {
paddy@0 263 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrSubscriptionChangeEmpty, err, store)
paddy@0 264 }
paddy@0 265 stripeCustomer := sub2.StripeCustomer
paddy@0 266 change.StripeCustomer = &stripeCustomer
paddy@0 267 err = store.updateSubscription(uuid.NewID(), change)
paddy@0 268 if err != ErrSubscriptionNotFound {
paddy@0 269 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrSubscriptionNotFound, err, store)
paddy@0 270 }
paddy@1 271 err = store.updateSubscription(sub.UserID, change)
paddy@0 272 if err != ErrStripeCustomerAlreadyExists {
paddy@0 273 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrStripeCustomerAlreadyExists, err, store)
paddy@0 274 }
paddy@0 275 }
paddy@0 276 }
paddy@0 277
paddy@0 278 func TestDeleteSubscription(t *testing.T) {
paddy@0 279 for _, store := range testSubscriptionStores {
paddy@0 280 err := store.reset()
paddy@0 281 if err != nil {
paddy@0 282 t.Fatalf("Error resetting %T: %+v\n", store, err)
paddy@0 283 }
paddy@0 284 sub1 := Subscription{
paddy@0 285 UserID: uuid.NewID(),
paddy@0 286 StripeCustomer: "stripeCustomer1",
paddy@0 287 }
paddy@0 288 sub2 := Subscription{
paddy@0 289 UserID: uuid.NewID(),
paddy@0 290 StripeCustomer: "stripeCustomer2",
paddy@0 291 }
paddy@0 292 err = store.createSubscription(sub1)
paddy@0 293 if err != nil {
paddy@0 294 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 295 }
paddy@0 296 err = store.createSubscription(sub2)
paddy@0 297 if err != nil {
paddy@0 298 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 299 }
paddy@1 300 err = store.deleteSubscription(sub1.UserID)
paddy@0 301 if err != nil {
paddy@0 302 t.Fatalf("Error deleting %+v in %T: %+v\n", sub1, store, err)
paddy@0 303 }
paddy@1 304 retrieved, err := store.getSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID})
paddy@0 305 if err != nil {
paddy@0 306 t.Errorf("Error retrieving subscriptions from %T: %+v\n", store, err)
paddy@0 307 }
paddy@0 308 ok, missing := subscriptionMapContains(retrieved, sub1)
paddy@0 309 if ok {
paddy@1 310 t.Errorf("Expected not to retrieve %s from %T, but missing was %+v\n", sub1.UserID.String(), store, missing)
paddy@0 311 }
paddy@0 312 ok, missing = subscriptionMapContains(retrieved, sub2)
paddy@0 313 if !ok {
paddy@1 314 t.Errorf("Expected to retrieve %s from %T, but missing was %+v\n", sub2.UserID.String(), store, missing)
paddy@0 315 }
paddy@1 316 err = store.deleteSubscription(sub1.UserID)
paddy@0 317 if err != ErrSubscriptionNotFound {
paddy@0 318 t.Errorf("Expected err to be %+v, but got %+v from %T\n", ErrSubscriptionNotFound, err, store)
paddy@0 319 }
paddy@0 320 }
paddy@0 321 }
paddy@0 322
paddy@0 323 func TestListSubscriptionsLastChargedBefore(t *testing.T) {
paddy@0 324 for _, store := range testSubscriptionStores {
paddy@0 325 err := store.reset()
paddy@0 326 if err != nil {
paddy@0 327 t.Fatalf("Error resetting %T: %+v\n", store, err)
paddy@0 328 }
paddy@0 329 sub1 := Subscription{
paddy@0 330 UserID: uuid.NewID(),
paddy@0 331 StripeCustomer: "stripeCustomer1",
paddy@0 332 Amount: 200,
paddy@0 333 Period: MonthlyPeriod,
paddy@1 334 Created: time.Now().Round(time.Millisecond).Add(time.Hour * -24 * 32),
paddy@1 335 BeginCharging: time.Now().Round(time.Millisecond).Add(time.Hour * -24),
paddy@1 336 LastCharged: time.Now().Round(time.Millisecond).Add(time.Hour * -24),
paddy@0 337 }
paddy@0 338 sub2 := Subscription{
paddy@0 339 UserID: uuid.NewID(),
paddy@0 340 StripeCustomer: "stripeCustomer2",
paddy@0 341 Amount: 300,
paddy@0 342 Period: MonthlyPeriod,
paddy@1 343 Created: time.Now().Round(time.Millisecond).Add(time.Hour * -24 * 61),
paddy@1 344 BeginCharging: time.Now().Round(time.Millisecond).Add(time.Hour * -24 * 31),
paddy@1 345 LastCharged: time.Now().Round(time.Millisecond).Add(time.Hour * -24 * 31),
paddy@0 346 }
paddy@0 347 sub3 := Subscription{
paddy@0 348 UserID: uuid.NewID(),
paddy@0 349 StripeCustomer: "stripeCustomer3",
paddy@0 350 Amount: 100,
paddy@0 351 Period: MonthlyPeriod,
paddy@1 352 Created: time.Now().Round(time.Millisecond).Add(time.Hour * -1),
paddy@1 353 BeginCharging: time.Now().Round(time.Millisecond).Add(time.Hour * 31),
paddy@0 354 LastCharged: time.Time{},
paddy@0 355 }
paddy@0 356 err = store.createSubscription(sub1)
paddy@0 357 if err != nil {
paddy@0 358 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 359 }
paddy@0 360 err = store.createSubscription(sub2)
paddy@0 361 if err != nil {
paddy@0 362 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 363 }
paddy@0 364 err = store.createSubscription(sub3)
paddy@0 365 if err != nil {
paddy@0 366 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 367 }
paddy@0 368 t.Logf("sub1: %+v\n", sub1)
paddy@0 369 t.Logf("sub2: %+v\n", sub2)
paddy@0 370 t.Logf("sub3: %+v\n", sub3)
paddy@0 371 // subscriptions last charged before right now
paddy@0 372 // should be sub1, sub2, and sub3
paddy@1 373 results, err := store.listSubscriptionsLastChargedBefore(time.Now().Round(time.Millisecond))
paddy@0 374 if err != nil {
paddy@0 375 t.Errorf("Unexpected error listing subscriptions in %T: %+v\n", store, err)
paddy@0 376 }
paddy@0 377 if len(results) != 3 {
paddy@0 378 t.Errorf("Expected three results from %T, got %+v\n", store, results)
paddy@0 379 }
paddy@0 380 ok, field, expected, result := compareSubscriptions(sub3, results[0])
paddy@0 381 if !ok {
paddy@0 382 t.Errorf("Expected %s in pos 0 to be %+v, got %+v from %T", field, expected, result, store)
paddy@0 383 }
paddy@0 384 ok, field, expected, result = compareSubscriptions(sub2, results[1])
paddy@0 385 if !ok {
paddy@0 386 t.Errorf("Expected %s in pos 1 to be %+v, got %+v from %T", field, expected, result, store)
paddy@0 387 }
paddy@0 388 ok, field, expected, result = compareSubscriptions(sub1, results[2])
paddy@0 389 if !ok {
paddy@0 390 t.Errorf("Expected %s in pos 2 to be %+v, got %+v from %T", field, expected, result, store)
paddy@0 391 }
paddy@0 392 // subscriptions last charged before a week ago
paddy@0 393 // should be sub2, sub3
paddy@1 394 results, err = store.listSubscriptionsLastChargedBefore(time.Now().Round(time.Millisecond).Add(time.Hour * -24 * 7))
paddy@0 395 if err != nil {
paddy@0 396 t.Errorf("Unexpected error listing subscriptions in %T: %+v\n", store, err)
paddy@0 397 }
paddy@0 398 if len(results) != 2 {
paddy@0 399 t.Errorf("Expected two results from %T, got %+v\n", store, results)
paddy@0 400 }
paddy@0 401 ok, field, expected, result = compareSubscriptions(sub3, results[0])
paddy@0 402 if !ok {
paddy@0 403 t.Errorf("Expected %s in pos 0 to be %+v, got %+v from %T", field, expected, result, store)
paddy@0 404 }
paddy@0 405 ok, field, expected, result = compareSubscriptions(sub2, results[1])
paddy@0 406 if !ok {
paddy@0 407 t.Errorf("Expected %s in pos 1 to be %+v, got %+v from %T", field, expected, result, store)
paddy@0 408 }
paddy@0 409 // subscriptions last charged before 32 days ago
paddy@0 410 // should be sub3
paddy@1 411 results, err = store.listSubscriptionsLastChargedBefore(time.Now().Round(time.Millisecond).Add(time.Hour * -24 * 32))
paddy@0 412 if err != nil {
paddy@0 413 t.Errorf("Unexpected error listing subscriptions in %T: %+v\n", store, err)
paddy@0 414 }
paddy@0 415 if len(results) != 1 {
paddy@0 416 t.Errorf("Expected one result from %T, got %+v\n", store, results)
paddy@0 417 }
paddy@0 418 ok, field, expected, result = compareSubscriptions(sub3, results[0])
paddy@0 419 if !ok {
paddy@0 420 t.Errorf("Expected %s in pos 0 to be %+v, got %+v from %T", field, expected, result, store)
paddy@0 421 }
paddy@0 422 }
paddy@0 423 }
paddy@0 424
paddy@0 425 func TestGetSubscriptions(t *testing.T) {
paddy@0 426 for _, store := range testSubscriptionStores {
paddy@0 427 err := store.reset()
paddy@0 428 if err != nil {
paddy@0 429 t.Fatalf("Error resetting %T: %+v\n", store, err)
paddy@0 430 }
paddy@0 431 sub1 := Subscription{
paddy@0 432 UserID: uuid.NewID(),
paddy@0 433 StripeCustomer: "stripeCustomer1",
paddy@0 434 Amount: 200,
paddy@0 435 Period: MonthlyPeriod,
paddy@1 436 Created: time.Now().Round(time.Millisecond),
paddy@1 437 BeginCharging: time.Now().Round(time.Millisecond).Add(time.Hour),
paddy@0 438 }
paddy@0 439 sub2 := Subscription{
paddy@0 440 UserID: uuid.NewID(),
paddy@0 441 StripeCustomer: "stripeCustomer2",
paddy@0 442 Amount: 300,
paddy@0 443 Period: MonthlyPeriod,
paddy@1 444 Created: time.Now().Round(time.Millisecond).Add(time.Hour * -720),
paddy@1 445 BeginCharging: time.Now().Round(time.Millisecond).Add(time.Hour*-720 + time.Hour*2),
paddy@1 446 LastCharged: time.Now().Round(time.Millisecond),
paddy@0 447 }
paddy@0 448 sub3 := Subscription{
paddy@0 449 UserID: uuid.NewID(),
paddy@0 450 StripeCustomer: "stripeCustomer3",
paddy@0 451 Amount: 100,
paddy@0 452 Period: MonthlyPeriod,
paddy@1 453 Created: time.Now().Round(time.Millisecond).Add(time.Hour * -1440),
paddy@1 454 BeginCharging: time.Now().Round(time.Millisecond).Add(time.Hour * -1440),
paddy@1 455 LastNotified: time.Now().Round(time.Millisecond).Add(time.Hour * -720),
paddy@0 456 InLockout: true,
paddy@0 457 }
paddy@0 458 err = store.createSubscription(sub1)
paddy@0 459 if err != nil {
paddy@0 460 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 461 }
paddy@0 462 err = store.createSubscription(sub2)
paddy@0 463 if err != nil {
paddy@0 464 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 465 }
paddy@0 466 err = store.createSubscription(sub3)
paddy@0 467 if err != nil {
paddy@0 468 t.Fatalf("Error creating %+v in %T: %+v\n", sub1, store, err)
paddy@0 469 }
paddy@0 470 retrieved, err := store.getSubscriptions([]uuid.ID{})
paddy@0 471 if err != ErrNoSubscriptionID {
paddy@0 472 t.Errorf("Error retrieving no subscriptions from %T. Expected %+v, got %+v\n", store, ErrNoSubscriptionID, err)
paddy@0 473 }
paddy@1 474 retrieved, err = store.getSubscriptions([]uuid.ID{sub1.UserID})
paddy@0 475 if err != nil {
paddy@1 476 t.Errorf("Error retrieving %s from %T: %+v\n", sub1.UserID, store, err)
paddy@0 477 }
paddy@0 478 ok, missing := subscriptionMapContains(retrieved, sub1)
paddy@0 479 if !ok {
paddy@0 480 t.Logf("Results: %+v\n", retrieved)
paddy@0 481 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 482 }
paddy@1 483 retrieved, err = store.getSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID})
paddy@0 484 if err != nil {
paddy@1 485 t.Errorf("Error retrieving %s and %s from %T: %+v\n", sub1.UserID, sub2.UserID, store, err)
paddy@0 486 }
paddy@0 487 ok, missing = subscriptionMapContains(retrieved, sub1, sub2)
paddy@0 488 if !ok {
paddy@0 489 t.Logf("Results: %+v\n", retrieved)
paddy@0 490 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 491 }
paddy@1 492 retrieved, err = store.getSubscriptions([]uuid.ID{sub1.UserID, sub3.UserID})
paddy@0 493 if err != nil {
paddy@1 494 t.Errorf("Error retrieving %s and %s from %T: %+v\n", sub1.UserID, sub3.UserID, store, err)
paddy@0 495 }
paddy@0 496 ok, missing = subscriptionMapContains(retrieved, sub1, sub3)
paddy@0 497 if !ok {
paddy@0 498 t.Logf("Results: %+v\n", retrieved)
paddy@0 499 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 500 }
paddy@1 501 retrieved, err = store.getSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID, sub3.UserID})
paddy@0 502 if err != nil {
paddy@1 503 t.Errorf("Error retrieving %s, %s, and %s from %T: %+v\n", sub1.UserID, sub2.UserID, sub3.UserID, store, err)
paddy@0 504 }
paddy@0 505 ok, missing = subscriptionMapContains(retrieved, sub1, sub2, sub3)
paddy@0 506 if !ok {
paddy@0 507 t.Logf("Results: %+v\n", retrieved)
paddy@0 508 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 509 }
paddy@1 510 retrieved, err = store.getSubscriptions([]uuid.ID{sub2.UserID})
paddy@0 511 if err != nil {
paddy@1 512 t.Errorf("Error retrieving %s from %T: %+v\n", sub2.UserID, store, err)
paddy@0 513 }
paddy@0 514 ok, missing = subscriptionMapContains(retrieved, sub2)
paddy@0 515 if !ok {
paddy@0 516 t.Logf("Results: %+v\n", retrieved)
paddy@0 517 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 518 }
paddy@1 519 retrieved, err = store.getSubscriptions([]uuid.ID{sub2.UserID, sub3.UserID})
paddy@0 520 if err != nil {
paddy@1 521 t.Errorf("Error retrieving %s and %s from %T: %+v\n", sub2.UserID, sub3.UserID, store, err)
paddy@0 522 }
paddy@0 523 ok, missing = subscriptionMapContains(retrieved, sub2, sub3)
paddy@0 524 if !ok {
paddy@0 525 t.Logf("Results: %+v\n", retrieved)
paddy@0 526 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 527 }
paddy@1 528 retrieved, err = store.getSubscriptions([]uuid.ID{sub3.UserID})
paddy@0 529 if err != nil {
paddy@1 530 t.Errorf("Error retrieving %s from %T: %+v\n", sub3.UserID, store, err)
paddy@0 531 }
paddy@0 532 ok, missing = subscriptionMapContains(retrieved, sub3)
paddy@0 533 if !ok {
paddy@0 534 t.Logf("Results: %+v\n", retrieved)
paddy@0 535 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 536 }
paddy@0 537 retrieved, err = store.getSubscriptions([]uuid.ID{uuid.NewID()})
paddy@0 538 if err != nil {
paddy@0 539 t.Errorf("Error retrieving non-existent ID from %T: %+v\n", store, err)
paddy@0 540 }
paddy@0 541 if len(retrieved) != 0 {
paddy@0 542 t.Errorf("Expected no results, %T returned %+v\n", store, retrieved)
paddy@0 543 }
paddy@1 544 retrieved, err = store.getSubscriptions([]uuid.ID{sub1.UserID, sub2.UserID, uuid.NewID(), sub3.UserID})
paddy@0 545 if err != nil {
paddy@0 546 t.Errorf("Error retrieving non-existent ID from %T: %+v\n", store, err)
paddy@0 547 }
paddy@0 548 if len(retrieved) != 3 {
paddy@0 549 t.Errorf("Expected 3 results, %T returned %+v\n", store, retrieved)
paddy@0 550 }
paddy@0 551 ok, missing = subscriptionMapContains(retrieved, sub1, sub2, sub3)
paddy@0 552 if !ok {
paddy@0 553 t.Logf("Results: %+v\n", retrieved)
paddy@0 554 t.Errorf("Expected %+v to be in the results, was not for %T.\n", missing, store)
paddy@0 555 }
paddy@0 556 }
paddy@0 557 }