mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	chore: new method that considers users updated at the same time (#10723)
We could have users updated at the exact same time, so we need to
include that timestamp in the next fetch to avoid missing users, but
also include the latest user id so we can exclude the ones already
fetched.
The following test shows how to process pages with this new method:
c03df86ee0/src/lib/features/users/user-updates-read-model.test.ts (L39-L65)
			
			
This commit is contained in:
		
							parent
							
								
									1e5de5b8b7
								
							
						
					
					
						commit
						a927f1f42b
					
				
							
								
								
									
										65
									
								
								src/lib/features/users/user-updates-read-model.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/lib/features/users/user-updates-read-model.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | ||||
| import dbInit, { | ||||
|     type ITestDb, | ||||
| } from '../../../test/e2e/helpers/database-init.js'; | ||||
| 
 | ||||
| let db: ITestDb; | ||||
| const TABLE = 'users'; | ||||
| const INSERT_INSTANT = new Date(); | ||||
| beforeAll(async () => { | ||||
|     db = await dbInit(); | ||||
| 
 | ||||
|     for (let i = 0; i < 10; i += 1) { | ||||
|         await db.rawDatabase(TABLE).insert({ | ||||
|             name: `test-user-${i}`, | ||||
|             username: `test-user-${i}`, | ||||
|             email: `test-user-${i}@example.com`, | ||||
|             created_at: INSERT_INSTANT, | ||||
|             updated_at: INSERT_INSTANT, | ||||
|         }); | ||||
|     } | ||||
| }); | ||||
| 
 | ||||
| test('returns all users if page is large enough', async () => { | ||||
|     const userUpdatesReadModel = db.stores.userUpdatesReadModel; | ||||
| 
 | ||||
|     const users = | ||||
|         await userUpdatesReadModel.getUsersUpdatedAfterOrEqual(INSERT_INSTANT); | ||||
|     expect(users).toHaveLength(10); | ||||
| }); | ||||
| 
 | ||||
| test('returns 0 if no users updated after timestamp', async () => { | ||||
|     const userUpdatesReadModel = db.stores.userUpdatesReadModel; | ||||
| 
 | ||||
|     const users = await userUpdatesReadModel.getUsersUpdatedAfterOrEqual( | ||||
|         new Date(INSERT_INSTANT.getTime() + 1), | ||||
|     ); | ||||
|     expect(users).toHaveLength(0); | ||||
| }); | ||||
| 
 | ||||
| test('returns the users in pages', async () => { | ||||
|     const userUpdatesReadModel = db.stores.userUpdatesReadModel; | ||||
|     const pageSize = 4; | ||||
| 
 | ||||
|     const usersPage1 = await userUpdatesReadModel.getUsersUpdatedAfterOrEqual( | ||||
|         INSERT_INSTANT, | ||||
|         pageSize, | ||||
|     ); | ||||
|     expect(usersPage1).toHaveLength(4); | ||||
|     expect(usersPage1[0].username).toBe('test-user-0'); | ||||
| 
 | ||||
|     const usersPage2 = await userUpdatesReadModel.getUsersUpdatedAfterOrEqual( | ||||
|         INSERT_INSTANT, | ||||
|         pageSize, | ||||
|         usersPage1[usersPage1.length - 1].id, | ||||
|     ); | ||||
|     expect(usersPage2).toHaveLength(4); | ||||
|     expect(usersPage2[0].username).toBe('test-user-4'); | ||||
| 
 | ||||
|     const usersPage3 = await userUpdatesReadModel.getUsersUpdatedAfterOrEqual( | ||||
|         INSERT_INSTANT, | ||||
|         pageSize, | ||||
|         usersPage2[usersPage2.length - 1].id, | ||||
|     ); | ||||
|     expect(usersPage3).toHaveLength(2); | ||||
|     expect(usersPage3[1].username).toBe('test-user-9'); | ||||
| }); | ||||
| @ -50,9 +50,18 @@ export class UserUpdatesReadModel { | ||||
|         return result ? result.last_updated_at : null; | ||||
|     } | ||||
| 
 | ||||
|     /** @deprecated */ | ||||
|     async getUsersUpdatedAfter( | ||||
|         date: Date, | ||||
|         limit: number = 100, | ||||
|     ): Promise<UpdatedUser[]> { | ||||
|         return this.getUsersUpdatedAfterOrEqual(date, limit, 0); | ||||
|     } | ||||
| 
 | ||||
|     async getUsersUpdatedAfterOrEqual( | ||||
|         date: Date, | ||||
|         limit: number = 100, | ||||
|         afterId: number = 0, | ||||
|     ): Promise<UpdatedUser[]> { | ||||
|         const result = await this.db(USERS_TABLE) | ||||
|             .where({ | ||||
| @ -60,8 +69,15 @@ export class UserUpdatesReadModel { | ||||
|                 is_system: false, | ||||
|                 is_service: false, | ||||
|             }) | ||||
|             .where('updated_at', '>', date) | ||||
|             .where((builder) => { | ||||
|                 builder.where('updated_at', '>', date).orWhere((subBuilder) => { | ||||
|                     subBuilder | ||||
|                         .where('updated_at', '=', date) | ||||
|                         .where('id', '>', afterId); | ||||
|                 }); | ||||
|             }) | ||||
|             .orderBy('updated_at', 'asc') | ||||
|             .orderBy('id', 'asc') | ||||
|             .select([ | ||||
|                 ...USER_COLUMNS_PUBLIC, | ||||
|                 'created_at', | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user