7
7
"database/sql"
8
8
"encoding/json"
9
9
"fmt"
10
- "maps"
11
10
"sort"
12
11
"testing"
13
12
"time"
@@ -2411,12 +2410,9 @@ func TestGetUserStatusCounts(t *testing.T) {
2411
2410
db , _ := dbtestutil .NewDB (t )
2412
2411
ctx := testutil .Context (t , testutil .WaitShort )
2413
2412
2414
- end := dbtime .Now ()
2415
- start := end .Add (- 30 * 24 * time .Hour )
2416
-
2417
2413
counts , err := db .GetUserStatusCounts (ctx , database.GetUserStatusCountsParams {
2418
- StartTime : start ,
2419
- EndTime : end ,
2414
+ StartTime : createdAt ,
2415
+ EndTime : today ,
2420
2416
})
2421
2417
require .NoError (t , err )
2422
2418
require .Empty (t , counts , "should return no results when there are no users" )
@@ -2457,23 +2453,31 @@ func TestGetUserStatusCounts(t *testing.T) {
2457
2453
UpdatedAt : createdAt ,
2458
2454
})
2459
2455
2460
- // Query for the last 30 days
2461
2456
userStatusChanges , err := db .GetUserStatusCounts (ctx , database.GetUserStatusCountsParams {
2462
- StartTime : createdAt ,
2463
- EndTime : today ,
2457
+ StartTime : dbtime . StartOfDay ( createdAt ) ,
2458
+ EndTime : dbtime . StartOfDay ( today ) ,
2464
2459
})
2465
2460
require .NoError (t , err )
2466
- require .NotEmpty (t , userStatusChanges , "should return results" )
2467
2461
2468
- require .Len (t , userStatusChanges , 2 , "should have 1 entry per status change plus and 1 entry for the end of the range = 2 entries" )
2469
-
2470
- require .Equal (t , userStatusChanges [0 ].Status , tc .status , "should have the correct status" )
2471
- require .Equal (t , userStatusChanges [0 ].Count , int64 (1 ), "should have 1 user" )
2472
- require .True (t , userStatusChanges [0 ].Date .Equal (createdAt ), "should have the correct date" )
2473
-
2474
- require .Equal (t , userStatusChanges [1 ].Status , tc .status , "should have the correct status" )
2475
- require .Equal (t , userStatusChanges [1 ].Count , int64 (1 ), "should have 1 user" )
2476
- require .True (t , userStatusChanges [1 ].Date .Equal (today ), "should have the correct date" )
2462
+ numDays := int (dbtime .StartOfDay (today ).Sub (dbtime .StartOfDay (createdAt )).Hours () / 24 )
2463
+ require .Len (t , userStatusChanges , numDays + 1 , "should have 1 entry per day between the start and end time, including the end time" )
2464
+
2465
+ for i , row := range userStatusChanges {
2466
+ require .Equal (t , tc .status , row .Status , "should have the correct status" )
2467
+ require .True (
2468
+ t ,
2469
+ row .Date .In (location ).Equal (dbtime .StartOfDay (createdAt ).AddDate (0 , 0 , i )),
2470
+ "expected date %s, but got %s for row %n" ,
2471
+ dbtime .StartOfDay (createdAt ).AddDate (0 , 0 , i ),
2472
+ row .Date .In (location ).String (),
2473
+ i ,
2474
+ )
2475
+ if row .Date .Before (createdAt ) {
2476
+ require .Equal (t , int64 (0 ), row .Count , "should have 0 users before creation" )
2477
+ } else {
2478
+ require .Equal (t , int64 (1 ), row .Count , "should have 1 user after creation" )
2479
+ }
2480
+ }
2477
2481
})
2478
2482
}
2479
2483
})
@@ -2627,24 +2631,38 @@ func TestGetUserStatusCounts(t *testing.T) {
2627
2631
2628
2632
// Query for the last 5 days
2629
2633
userStatusChanges , err := db .GetUserStatusCounts (ctx , database.GetUserStatusCountsParams {
2630
- StartTime : createdAt ,
2631
- EndTime : today ,
2634
+ StartTime : dbtime . StartOfDay ( createdAt ) ,
2635
+ EndTime : dbtime . StartOfDay ( today ) ,
2632
2636
})
2633
2637
require .NoError (t , err )
2634
- require .NotEmpty (t , userStatusChanges , "should return results" )
2635
2638
2636
- gotCounts := map [time.Time ]map [database.UserStatus ]int64 {}
2637
- for _ , row := range userStatusChanges {
2638
- gotDateInLocation := row .Date .In (location )
2639
- if _ , ok := gotCounts [gotDateInLocation ]; ! ok {
2640
- gotCounts [gotDateInLocation ] = map [database.UserStatus ]int64 {}
2639
+ for i , row := range userStatusChanges {
2640
+ require .True (
2641
+ t ,
2642
+ row .Date .In (location ).Equal (dbtime .StartOfDay (createdAt ).AddDate (0 , 0 , i / 2 )),
2643
+ "expected date %s, but got %s for row %n" ,
2644
+ dbtime .StartOfDay (createdAt ).AddDate (0 , 0 , i / 2 ),
2645
+ row .Date .In (location ).String (),
2646
+ i ,
2647
+ )
2648
+ if row .Date .Before (createdAt ) {
2649
+ require .Equal (t , int64 (0 ), row .Count )
2650
+ } else if row .Date .Before (firstTransitionTime ) {
2651
+ if row .Status == tc .initialStatus {
2652
+ require .Equal (t , int64 (1 ), row .Count )
2653
+ } else if row .Status == tc .targetStatus {
2654
+ require .Equal (t , int64 (0 ), row .Count )
2655
+ }
2656
+ } else if ! row .Date .After (today ) {
2657
+ if row .Status == tc .initialStatus {
2658
+ require .Equal (t , int64 (0 ), row .Count )
2659
+ } else if row .Status == tc .targetStatus {
2660
+ require .Equal (t , int64 (1 ), row .Count )
2661
+ }
2662
+ } else {
2663
+ t .Errorf ("date %q beyond expected range end %q" , row .Date , today )
2641
2664
}
2642
- if _ , ok := gotCounts [gotDateInLocation ][row.Status ]; ! ok {
2643
- gotCounts [gotDateInLocation ][row.Status ] = 0
2644
- }
2645
- gotCounts [gotDateInLocation ][row.Status ] += row .Count
2646
2665
}
2647
- require .Equal (t , tc .expectedCounts , gotCounts )
2648
2666
})
2649
2667
}
2650
2668
})
@@ -2725,6 +2743,7 @@ func TestGetUserStatusCounts(t *testing.T) {
2725
2743
tc := tc
2726
2744
t .Run (tc .name , func (t * testing.T ) {
2727
2745
t .Parallel ()
2746
+
2728
2747
db , _ := dbtestutil .NewDB (t )
2729
2748
ctx := testutil .Context (t , testutil .WaitShort )
2730
2749
@@ -2756,66 +2775,48 @@ func TestGetUserStatusCounts(t *testing.T) {
2756
2775
require .NoError (t , err )
2757
2776
2758
2777
userStatusChanges , err := db .GetUserStatusCounts (ctx , database.GetUserStatusCountsParams {
2759
- StartTime : createdAt ,
2760
- EndTime : today ,
2778
+ StartTime : dbtime . StartOfDay ( createdAt ) ,
2779
+ EndTime : dbtime . StartOfDay ( today ) ,
2761
2780
})
2762
2781
require .NoError (t , err )
2763
2782
require .NotEmpty (t , userStatusChanges )
2764
- gotCounts := map [time.Time ]map [database.UserStatus ]int64 {
2765
- createdAt .In (location ): {},
2766
- firstTransitionTime .In (location ): {},
2767
- secondTransitionTime .In (location ): {},
2768
- today .In (location ): {},
2769
- }
2783
+ gotCounts := map [time.Time ]map [database.UserStatus ]int64 {}
2770
2784
for _ , row := range userStatusChanges {
2771
2785
dateInLocation := row .Date .In (location )
2772
- switch {
2773
- case dateInLocation .Equal (createdAt .In (location )):
2774
- gotCounts [createdAt ][row.Status ] = row .Count
2775
- case dateInLocation .Equal (firstTransitionTime .In (location )):
2776
- gotCounts [firstTransitionTime ][row.Status ] = row .Count
2777
- case dateInLocation .Equal (secondTransitionTime .In (location )):
2778
- gotCounts [secondTransitionTime ][row.Status ] = row .Count
2779
- case dateInLocation .Equal (today .In (location )):
2780
- gotCounts [today ][row.Status ] = row .Count
2781
- default :
2782
- t .Fatalf ("unexpected date %s" , row .Date )
2786
+ if gotCounts [dateInLocation ] == nil {
2787
+ gotCounts [dateInLocation ] = map [database.UserStatus ]int64 {}
2783
2788
}
2789
+ gotCounts [dateInLocation ][row.Status ] = row .Count
2784
2790
}
2785
2791
2786
2792
expectedCounts := map [time.Time ]map [database.UserStatus ]int64 {}
2787
- for _ , status := range []database.UserStatus {
2788
- tc .user1Transition .from ,
2789
- tc .user1Transition .to ,
2790
- tc .user2Transition .from ,
2791
- tc .user2Transition .to ,
2792
- } {
2793
- if _ , ok := expectedCounts [createdAt ]; ! ok {
2794
- expectedCounts [createdAt ] = map [database.UserStatus ]int64 {}
2793
+ for d := dbtime .StartOfDay (createdAt ); ! d .After (dbtime .StartOfDay (today )); d = d .AddDate (0 , 0 , 1 ) {
2794
+ expectedCounts [d ] = map [database.UserStatus ]int64 {}
2795
+
2796
+ // Default values
2797
+ expectedCounts [d ][tc .user1Transition .from ] = 0
2798
+ expectedCounts [d ][tc .user1Transition .to ] = 0
2799
+ expectedCounts [d ][tc .user2Transition .from ] = 0
2800
+ expectedCounts [d ][tc .user2Transition .to ] = 0
2801
+
2802
+ // Counted Values
2803
+ if d .Before (createdAt ) {
2804
+ continue
2805
+ } else if d .Before (firstTransitionTime ) {
2806
+ expectedCounts [d ][tc .user1Transition .from ]++
2807
+ expectedCounts [d ][tc .user2Transition .from ]++
2808
+ } else if d .Before (secondTransitionTime ) {
2809
+ expectedCounts [d ][tc .user1Transition .to ]++
2810
+ expectedCounts [d ][tc .user2Transition .from ]++
2811
+ } else if d .Before (today ) {
2812
+ expectedCounts [d ][tc .user1Transition .to ]++
2813
+ expectedCounts [d ][tc .user2Transition .to ]++
2814
+ } else {
2815
+ t .Fatalf ("date %q beyond expected range end %q" , d , today )
2795
2816
}
2796
- expectedCounts [createdAt ][status ] = 0
2797
2817
}
2798
2818
2799
- expectedCounts [createdAt ][tc .user1Transition .from ]++
2800
- expectedCounts [createdAt ][tc .user2Transition .from ]++
2801
-
2802
- expectedCounts [firstTransitionTime ] = map [database.UserStatus ]int64 {}
2803
- maps .Copy (expectedCounts [firstTransitionTime ], expectedCounts [createdAt ])
2804
- expectedCounts [firstTransitionTime ][tc .user1Transition .from ]--
2805
- expectedCounts [firstTransitionTime ][tc .user1Transition .to ]++
2806
-
2807
- expectedCounts [secondTransitionTime ] = map [database.UserStatus ]int64 {}
2808
- maps .Copy (expectedCounts [secondTransitionTime ], expectedCounts [firstTransitionTime ])
2809
- expectedCounts [secondTransitionTime ][tc .user2Transition .from ]--
2810
- expectedCounts [secondTransitionTime ][tc .user2Transition .to ]++
2811
-
2812
- expectedCounts [today ] = map [database.UserStatus ]int64 {}
2813
- maps .Copy (expectedCounts [today ], expectedCounts [secondTransitionTime ])
2814
-
2815
- require .Equal (t , expectedCounts [createdAt ], gotCounts [createdAt ])
2816
- require .Equal (t , expectedCounts [firstTransitionTime ], gotCounts [firstTransitionTime ])
2817
- require .Equal (t , expectedCounts [secondTransitionTime ], gotCounts [secondTransitionTime ])
2818
- require .Equal (t , expectedCounts [today ], gotCounts [today ])
2819
+ require .Equal (t , expectedCounts , gotCounts )
2819
2820
})
2820
2821
}
2821
2822
})
@@ -2832,16 +2833,23 @@ func TestGetUserStatusCounts(t *testing.T) {
2832
2833
})
2833
2834
2834
2835
userStatusChanges , err := db .GetUserStatusCounts (ctx , database.GetUserStatusCountsParams {
2835
- StartTime : createdAt .Add (time .Hour * 24 ),
2836
- EndTime : today ,
2836
+ StartTime : dbtime . StartOfDay ( createdAt .Add (time .Hour * 24 ) ),
2837
+ EndTime : dbtime . StartOfDay ( today ) ,
2837
2838
})
2838
2839
require .NoError (t , err )
2839
2840
2840
- require .Len (t , userStatusChanges , 2 )
2841
- require .Equal (t , userStatusChanges [0 ].Count , int64 (1 ))
2842
- require .Equal (t , userStatusChanges [0 ].Status , database .UserStatusActive )
2843
- require .Equal (t , userStatusChanges [1 ].Count , int64 (1 ))
2844
- require .Equal (t , userStatusChanges [1 ].Status , database .UserStatusActive )
2841
+ for i , row := range userStatusChanges {
2842
+ require .True (
2843
+ t ,
2844
+ row .Date .In (location ).Equal (dbtime .StartOfDay (createdAt ).AddDate (0 , 0 , 1 + i )),
2845
+ "expected date %s, but got %s for row %n" ,
2846
+ dbtime .StartOfDay (createdAt ).AddDate (0 , 0 , 1 + i ),
2847
+ row .Date .In (location ).String (),
2848
+ i ,
2849
+ )
2850
+ require .Equal (t , database .UserStatusActive , row .Status )
2851
+ require .Equal (t , int64 (1 ), row .Count )
2852
+ }
2845
2853
})
2846
2854
2847
2855
t .Run ("User deleted before query range" , func (t * testing.T ) {
@@ -2881,16 +2889,28 @@ func TestGetUserStatusCounts(t *testing.T) {
2881
2889
require .NoError (t , err )
2882
2890
2883
2891
userStatusChanges , err := db .GetUserStatusCounts (ctx , database.GetUserStatusCountsParams {
2884
- StartTime : createdAt ,
2885
- EndTime : today .Add (time .Hour * 24 ),
2892
+ StartTime : dbtime . StartOfDay ( createdAt ) ,
2893
+ EndTime : dbtime . StartOfDay ( today .Add (time .Hour * 24 ) ),
2886
2894
})
2887
2895
require .NoError (t , err )
2888
- require .Equal (t , userStatusChanges [0 ].Count , int64 (1 ))
2889
- require .Equal (t , userStatusChanges [0 ].Status , database .UserStatusActive )
2890
- require .Equal (t , userStatusChanges [1 ].Count , int64 (0 ))
2891
- require .Equal (t , userStatusChanges [1 ].Status , database .UserStatusActive )
2892
- require .Equal (t , userStatusChanges [2 ].Count , int64 (0 ))
2893
- require .Equal (t , userStatusChanges [2 ].Status , database .UserStatusActive )
2896
+ for i , row := range userStatusChanges {
2897
+ require .True (
2898
+ t ,
2899
+ row .Date .In (location ).Equal (dbtime .StartOfDay (createdAt ).AddDate (0 , 0 , i )),
2900
+ "expected date %s, but got %s for row %n" ,
2901
+ dbtime .StartOfDay (createdAt ).AddDate (0 , 0 , i ),
2902
+ row .Date .In (location ).String (),
2903
+ i ,
2904
+ )
2905
+ require .Equal (t , database .UserStatusActive , row .Status )
2906
+ if row .Date .Before (createdAt ) {
2907
+ require .Equal (t , int64 (0 ), row .Count )
2908
+ } else if i == len (userStatusChanges )- 1 {
2909
+ require .Equal (t , int64 (0 ), row .Count )
2910
+ } else {
2911
+ require .Equal (t , int64 (1 ), row .Count )
2912
+ }
2913
+ }
2894
2914
})
2895
2915
})
2896
2916
}
0 commit comments