@@ -23,6 +23,7 @@ import (
23
23
"github.com/coder/coder/v2/coderd/coderdtest"
24
24
"github.com/coder/coder/v2/coderd/database"
25
25
"github.com/coder/coder/v2/coderd/database/dbauthz"
26
+ "github.com/coder/coder/v2/coderd/database/dbgen"
26
27
"github.com/coder/coder/v2/coderd/database/dbtime"
27
28
"github.com/coder/coder/v2/coderd/rbac"
28
29
"github.com/coder/coder/v2/coderd/util/slice"
@@ -1699,7 +1700,7 @@ func TestSuspendedPagination(t *testing.T) {
1699
1700
// them using different page sizes.
1700
1701
func TestPaginatedUsers (t * testing.T ) {
1701
1702
t .Parallel ()
1702
- client := coderdtest .New (t ,nil )
1703
+ client , db := coderdtest .NewWithDatabase (t ,nil )
1703
1704
coderdtest .CreateFirstUser (t ,client )
1704
1705
1705
1706
// This test takes longer than a long time.
@@ -1708,15 +1709,17 @@ func TestPaginatedUsers(t *testing.T) {
1708
1709
1709
1710
me ,err := client .User (ctx ,codersdk .Me )
1710
1711
require .NoError (t ,err )
1711
- orgID := me .OrganizationIDs [0 ]
1712
1712
1713
1713
// When 50 users exist
1714
1714
total := 50
1715
- allUsers := make ([]codersdk.User ,total + 1 )// +1 forme
1716
- allUsers [0 ]= me
1717
- specialUsers := make ([]codersdk.User ,total / 2 )
1715
+ allUsers := make ([]database.User ,total + 1 )
1716
+ allUsers [0 ]= database.User {
1717
+ Email :me .Email ,
1718
+ Username :me .Username ,
1719
+ }
1720
+ specialUsers := make ([]database.User ,total / 2 )
1718
1721
1719
- eg ,egCtx := errgroup .WithContext (ctx )
1722
+ eg ,_ := errgroup .WithContext (ctx )
1720
1723
// Create users
1721
1724
for i := 0 ;i < total ;i ++ {
1722
1725
i := i
@@ -1730,21 +1733,14 @@ func TestPaginatedUsers(t *testing.T) {
1730
1733
if i % 3 == 0 {
1731
1734
username = strings .ToUpper (username )
1732
1735
}
1733
- // One side effect of having to use the api vs the db calls directly, is you cannot
1734
- // mock time. Ideally I could pass in mocked times and space these users out.
1735
- //
1736
- // But this also serves as a good test. Postgres has microsecond precision on its timestamps.
1737
- // If 2 users share the same created_at, that could cause an issue if you are strictly paginating via
1738
- // timestamps. The pagination goes by timestamps and uuids.
1739
- newUser ,err := client .CreateUser (egCtx , codersdk.CreateUserRequest {
1740
- Email :email ,
1741
- Username :username ,
1742
- Password :"MySecurePassword!" ,
1743
- OrganizationID :orgID ,
1736
+
1737
+ // We used to use the API to ceate users, but that is slow.
1738
+ // Instead, we create them directly in the database now
1739
+ // to prevent timeout flakes.
1740
+ newUser := dbgen .User (t ,db , database.User {
1741
+ Email :email ,
1742
+ Username :username ,
1744
1743
})
1745
- if err != nil {
1746
- return err
1747
- }
1748
1744
allUsers [i + 1 ]= newUser
1749
1745
if i % 2 == 0 {
1750
1746
specialUsers [i / 2 ]= newUser
@@ -1757,8 +1753,8 @@ func TestPaginatedUsers(t *testing.T) {
1757
1753
require .NoError (t ,err ,"create users failed" )
1758
1754
1759
1755
// Sorting the users will sort by username.
1760
- sortUsers (allUsers )
1761
- sortUsers (specialUsers )
1756
+ sortDatabaseUsers (allUsers )
1757
+ sortDatabaseUsers (specialUsers )
1762
1758
1763
1759
gmailSearch := func (request codersdk.UsersRequest ) codersdk.UsersRequest {
1764
1760
request .Search = "gmail"
@@ -1772,7 +1768,7 @@ func TestPaginatedUsers(t *testing.T) {
1772
1768
tests := []struct {
1773
1769
name string
1774
1770
limit int
1775
- allUsers []codersdk .User
1771
+ allUsers []database .User
1776
1772
opt func (request codersdk.UsersRequest ) codersdk.UsersRequest
1777
1773
}{
1778
1774
{name :"all users" ,limit :10 ,allUsers :allUsers },
@@ -1800,7 +1796,7 @@ func TestPaginatedUsers(t *testing.T) {
1800
1796
// Assert pagination will page through the list of all users using the given
1801
1797
// limit for each page. The 'allUsers' is the expected full list to compare
1802
1798
// against.
1803
- func assertPagination (ctx context.Context ,t * testing.T ,client * codersdk.Client ,limit int ,allUsers []codersdk .User ,
1799
+ func assertPagination (ctx context.Context ,t * testing.T ,client * codersdk.Client ,limit int ,allUsers []database .User ,
1804
1800
opt func (request codersdk.UsersRequest ) codersdk.UsersRequest ,
1805
1801
) {
1806
1802
var count int
@@ -1817,7 +1813,7 @@ func assertPagination(ctx context.Context, t *testing.T, client *codersdk.Client
1817
1813
},
1818
1814
}))
1819
1815
require .NoError (t ,err ,"first page" )
1820
- require .Equalf (t ,page .Users , allUsers [:limit ],"first page, limit=%d" ,limit )
1816
+ require .Equalf (t ,onlyUsernames ( page .Users ), onlyUsernames ( allUsers [:limit ]) ,"first page, limit=%d" ,limit )
1821
1817
count += len (page .Users )
1822
1818
1823
1819
for {
@@ -1846,14 +1842,14 @@ func assertPagination(ctx context.Context, t *testing.T, client *codersdk.Client
1846
1842
}))
1847
1843
require .NoError (t ,err ,"next offset page" )
1848
1844
1849
- var expected []codersdk .User
1845
+ var expected []database .User
1850
1846
if count + limit > len (allUsers ) {
1851
1847
expected = allUsers [count :]
1852
1848
}else {
1853
1849
expected = allUsers [count :count + limit ]
1854
1850
}
1855
- require .Equalf (t ,page .Users , expected ,"next users, after=%s, limit=%d" ,afterCursor ,limit )
1856
- require .Equalf (t ,offsetPage .Users , expected ,"offset users, offset=%d, limit=%d" ,count ,limit )
1851
+ require .Equalf (t ,onlyUsernames ( page .Users ), onlyUsernames ( expected ) ,"next users, after=%s, limit=%d" ,afterCursor ,limit )
1852
+ require .Equalf (t ,onlyUsernames ( offsetPage .Users ), onlyUsernames ( expected ) ,"offset users, offset=%d, limit=%d" ,count ,limit )
1857
1853
1858
1854
// Also check the before
1859
1855
prevPage ,err := client .Users (ctx ,opt (codersdk.UsersRequest {
@@ -1863,7 +1859,7 @@ func assertPagination(ctx context.Context, t *testing.T, client *codersdk.Client
1863
1859
},
1864
1860
}))
1865
1861
require .NoError (t ,err ,"prev page" )
1866
- require .Equal (t ,allUsers [count - limit :count ], prevPage .Users ,"prev users" )
1862
+ require .Equal (t ,onlyUsernames ( allUsers [count - limit :count ]), onlyUsernames ( prevPage .Users ) ,"prev users" )
1867
1863
count += len (page .Users )
1868
1864
}
1869
1865
}
@@ -1875,6 +1871,25 @@ func sortUsers(users []codersdk.User) {
1875
1871
})
1876
1872
}
1877
1873
1874
+ func sortDatabaseUsers (users []database.User ) {
1875
+ slices .SortFunc (users ,func (a ,b database.User )int {
1876
+ return slice .Ascending (strings .ToLower (a .Username ),strings .ToLower (b .Username ))
1877
+ })
1878
+ }
1879
+
1880
+ func onlyUsernames [U codersdk.User | database.User ](users []U ) []string {
1881
+ var out []string
1882
+ for _ ,u := range users {
1883
+ switch u := (any (u )).(type ) {
1884
+ case codersdk.User :
1885
+ out = append (out ,u .Username )
1886
+ case database.User :
1887
+ out = append (out ,u .Username )
1888
+ }
1889
+ }
1890
+ return out
1891
+ }
1892
+
1878
1893
func BenchmarkUsersMe (b * testing.B ) {
1879
1894
client := coderdtest .New (b ,nil )
1880
1895
_ = coderdtest .CreateFirstUser (b ,client )