-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from cieslarmichal/feature/list-users
add get users endpoint
- Loading branch information
Showing
12 changed files
with
354 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
...modules/userModule/api/httpControllers/adminUserHttpController/schemas/findUsersSchema.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { type Static, Type } from '@sinclair/typebox'; | ||
|
||
import type * as contracts from '@common/contracts'; | ||
|
||
import { type TypeExtends } from '../../../../../../common/types/schemaExtends.js'; | ||
import { userDTOSchema } from '../../common/userDTO.js'; | ||
|
||
export const findUsersQueryParamsDTOSchema = Type.Object({ | ||
page: Type.Optional(Type.Integer({ minimum: 1 })), | ||
pageSize: Type.Optional(Type.Integer({ minimum: 1 })), | ||
}); | ||
|
||
export type FindUsersQueryParamsDTO = TypeExtends< | ||
Static<typeof findUsersQueryParamsDTOSchema>, | ||
contracts.FindUsersQueryParams | ||
>; | ||
|
||
export const findUsersResponseBodyDTOSchema = Type.Object({ | ||
data: Type.Array(userDTOSchema), | ||
metadata: Type.Object({ | ||
page: Type.Integer(), | ||
pageSize: Type.Integer(), | ||
totalPages: Type.Integer(), | ||
}), | ||
}); | ||
|
||
export type FindUsersResponseBodyDTO = TypeExtends< | ||
Static<typeof findUsersResponseBodyDTOSchema>, | ||
contracts.FindUsersResponseBody | ||
>; |
14 changes: 14 additions & 0 deletions
14
...dules/userModule/application/queryHandlers/findUsersQueryHandler/findUsersQueryHandler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { type QueryHandler } from '../../../../../common/types/queryHandler.js'; | ||
import { type User } from '../../../domain/entities/user/user.js'; | ||
|
||
export interface FindUsersQueryHandlerPayload { | ||
readonly page: number; | ||
readonly pageSize: number; | ||
} | ||
|
||
export interface FindUsersQueryHandlerResult { | ||
readonly users: User[]; | ||
readonly totalUsers: number; | ||
} | ||
|
||
export type FindUsersQueryHandler = QueryHandler<FindUsersQueryHandlerPayload, FindUsersQueryHandlerResult>; |
77 changes: 77 additions & 0 deletions
77
...ication/queryHandlers/findUsersQueryHandler/findUsersQueryHandlerImpl.integration.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { beforeEach, afterEach, expect, it, describe } from 'vitest'; | ||
|
||
import { type FindUsersQueryHandler } from './findUsersQueryHandler.js'; | ||
import { Application } from '../../../../../core/application.js'; | ||
import { type SqliteDatabaseClient } from '../../../../../core/database/sqliteDatabaseClient/sqliteDatabaseClient.js'; | ||
import { coreSymbols } from '../../../../../core/symbols.js'; | ||
import { symbols } from '../../../symbols.js'; | ||
import { UserTestUtils } from '../../../tests/utils/userTestUtils/userTestUtils.js'; | ||
|
||
describe('FindUsersQueryHandler', () => { | ||
let findUsersQueryHandler: FindUsersQueryHandler; | ||
|
||
let sqliteDatabaseClient: SqliteDatabaseClient; | ||
|
||
let userTestUtils: UserTestUtils; | ||
|
||
beforeEach(async () => { | ||
const container = Application.createContainer(); | ||
|
||
findUsersQueryHandler = container.get<FindUsersQueryHandler>(symbols.findUsersQueryHandler); | ||
|
||
sqliteDatabaseClient = container.get<SqliteDatabaseClient>(coreSymbols.sqliteDatabaseClient); | ||
|
||
userTestUtils = new UserTestUtils(sqliteDatabaseClient); | ||
|
||
await userTestUtils.truncate(); | ||
}); | ||
|
||
afterEach(async () => { | ||
await userTestUtils.truncate(); | ||
|
||
await sqliteDatabaseClient.destroy(); | ||
}); | ||
|
||
it('finds Users', async () => { | ||
const user1 = await userTestUtils.createAndPersist(); | ||
|
||
const user2 = await userTestUtils.createAndPersist(); | ||
|
||
const result = await findUsersQueryHandler.execute({ | ||
page: 1, | ||
pageSize: 10, | ||
}); | ||
|
||
expect(result.users[0]?.getId()).toEqual(user1.id); | ||
|
||
expect(result.users[1]?.getId()).toEqual(user2.id); | ||
|
||
expect(result.totalUsers).toBe(2); | ||
}); | ||
|
||
it('paginates Users', async () => { | ||
const user1 = await userTestUtils.createAndPersist(); | ||
|
||
await userTestUtils.createAndPersist(); | ||
|
||
const result = await findUsersQueryHandler.execute({ | ||
page: 1, | ||
pageSize: 1, | ||
}); | ||
|
||
expect(result.users[0]?.getId()).toEqual(user1.id); | ||
|
||
expect(result.totalUsers).toBe(2); | ||
}); | ||
|
||
it('returns empty array if no Users found', async () => { | ||
const result = await findUsersQueryHandler.execute({ | ||
page: 1, | ||
pageSize: 10, | ||
}); | ||
|
||
expect(result.users).toEqual([]); | ||
|
||
expect(result.totalUsers).toBe(0); | ||
}); | ||
}); |
27 changes: 27 additions & 0 deletions
27
...s/userModule/application/queryHandlers/findUsersQueryHandler/findUsersQueryHandlerImpl.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { | ||
type FindUsersQueryHandler, | ||
type FindUsersQueryHandlerPayload, | ||
type FindUsersQueryHandlerResult, | ||
} from './findUsersQueryHandler.js'; | ||
import { type UserRepository } from '../../../domain/repositories/userRepository/userRepository.js'; | ||
|
||
export class FindUsersQueryHandlerImpl implements FindUsersQueryHandler { | ||
public constructor(private readonly userRepository: UserRepository) {} | ||
|
||
public async execute(payload: FindUsersQueryHandlerPayload): Promise<FindUsersQueryHandlerResult> { | ||
const { page, pageSize } = payload; | ||
|
||
const [users, totalUsers] = await Promise.all([ | ||
this.userRepository.findUsers({ | ||
page, | ||
pageSize, | ||
}), | ||
this.userRepository.countUsers(), | ||
]); | ||
|
||
return { | ||
users, | ||
totalUsers, | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.