chore: test ticket service and ticket message

This commit is contained in:
mahyargdz
2025-01-29 16:08:18 +03:30
parent 5e9561b417
commit 8fb587f976
7 changed files with 70 additions and 41 deletions
@@ -67,7 +67,7 @@ export class AnnouncementService {
const [announcements, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount(); const [announcements, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount();
return { announcements, count }; return { announcements, count, paginate: true };
} }
async getAllAnnouncementsByUser(queryDto: SearchAnnouncementQueryDto, userId: string) { async getAllAnnouncementsByUser(queryDto: SearchAnnouncementQueryDto, userId: string) {
@@ -52,6 +52,7 @@ export class CriticismsService {
return { return {
criticisms, criticisms,
count, count,
paginate: true,
}; };
} }
@@ -75,7 +75,7 @@ export class DanakServicesService {
const [categories, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount(); const [categories, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount();
return { categories, count }; return { categories, count, paginate: true };
} }
/******************************************** */ /******************************************** */
@@ -3,6 +3,8 @@ import { Not } from "typeorm";
import { ParamDto } from "../../../common/DTO/param.dto"; import { ParamDto } from "../../../common/DTO/param.dto";
import { CommonMessage, TicketMessageEnum } from "../../../common/enums/message.enum"; import { CommonMessage, TicketMessageEnum } from "../../../common/enums/message.enum";
import { Role } from "../../users/entities/role.entity";
import { RoleEnum } from "../../users/enums/role.enum";
import { UsersService } from "../../users/providers/users.service"; import { UsersService } from "../../users/providers/users.service";
import { PaginationUtils } from "../../utils/providers/pagination.utils"; import { PaginationUtils } from "../../utils/providers/pagination.utils";
import { CreateTicketCategoryDto } from "../DTO/create-ticket-category.dto"; import { CreateTicketCategoryDto } from "../DTO/create-ticket-category.dto";
@@ -12,6 +14,7 @@ import { SearchTicketCategoryDto } from "../DTO/search-ticket-category.dto";
import { SearchTicketQueryDto } from "../DTO/search-ticket-query.dto"; import { SearchTicketQueryDto } from "../DTO/search-ticket-query.dto";
import { UpdateTicketCategoryDto } from "../DTO/update-ticket-category.dto"; import { UpdateTicketCategoryDto } from "../DTO/update-ticket-category.dto";
import { TicketMessage } from "../entities/ticket-message.entity"; import { TicketMessage } from "../entities/ticket-message.entity";
import { Ticket } from "../entities/ticket.entity";
import { TicketStatus } from "../enums/ticket-status.enum"; import { TicketStatus } from "../enums/ticket-status.enum";
import { TicketCategoryRepository } from "../repositories/tickets-category.repository"; import { TicketCategoryRepository } from "../repositories/tickets-category.repository";
import { TicketMessagesRepository } from "../repositories/tickets-message.repository"; import { TicketMessagesRepository } from "../repositories/tickets-message.repository";
@@ -27,7 +30,7 @@ export class TicketsService {
) {} ) {}
//******************************** */ //******************************** */
async getTicketCategories() { async getTicketCategories() {
const ticketCategories = await this.ticketsCategoryRepository.find({ relations: { group: true } }); const ticketCategories = await this.ticketsCategoryRepository.find({});
return { return {
ticketCategories, ticketCategories,
}; };
@@ -56,7 +59,7 @@ export class TicketsService {
const [categories, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount(); const [categories, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount();
return { categories, count }; return { categories, count, paginate: true };
} }
//******************************** */ //******************************** */
async createTicketCategory(createDto: CreateTicketCategoryDto) { async createTicketCategory(createDto: CreateTicketCategoryDto) {
@@ -115,7 +118,6 @@ export class TicketsService {
return { return {
message: TicketMessageEnum.CREATED, message: TicketMessageEnum.CREATED,
ticket,
}; };
} }
@@ -131,7 +133,7 @@ export class TicketsService {
}, },
relations: { relations: {
category: true, category: true,
user: true, // user: true,
}, },
order: { order: {
createdAt: "DESC" as const, createdAt: "DESC" as const,
@@ -142,18 +144,23 @@ export class TicketsService {
const [tickets, count] = await this.ticketsRepository.findAndCount(findOptions); const [tickets, count] = await this.ticketsRepository.findAndCount(findOptions);
return { return { tickets, count, paginate: true };
tickets,
count,
};
} }
//******************************** */ //******************************** */
async createTicketMessage(ticketId: string, createDto: CreateTicketMessageDto, userId: string) { async createTicketMessage(ticketId: string, createDto: CreateTicketMessageDto, userId: string, role: Role) {
const ticket = await this.ticketsRepository.findTicketById(ticketId, userId); const userRole = role as unknown as RoleEnum;
let ticket: null | Ticket = null;
if (userRole === RoleEnum.ADMIN) {
ticket = await this.ticketsRepository.findTicketById(ticketId);
} else {
ticket = await this.ticketsRepository.findTicketById(ticketId, userId);
}
if (!ticket) throw new BadRequestException(TicketMessageEnum.TICKET_NOT_FOUND); if (!ticket) throw new BadRequestException(TicketMessageEnum.TICKET_NOT_FOUND);
//
const { user } = await this.usersService.findOneById(userId); const { user } = await this.usersService.findOneById(userId);
const ticketMessage = this.ticketMessagesRepository.create({ ...createDto, author: user, ticket }); const ticketMessage = this.ticketMessagesRepository.create({ ...createDto, author: user, ticket });
@@ -162,26 +169,43 @@ export class TicketsService {
return { return {
message: TicketMessageEnum.MESSAGE_CREATED, message: TicketMessageEnum.MESSAGE_CREATED,
ticketMessage, // ticketMessage,
}; };
} }
//******************************** */ //******************************** */
async getTicketMessages(ticketId: string, userId: string) { async getTicketMessages(ticketId: string, userId: string, role: Role) {
const ticket = await this.ticketsRepository.findTicketById(ticketId, userId); const userRole = role as unknown as RoleEnum;
let ticket: null | Ticket = null;
//
if (userRole === RoleEnum.ADMIN) {
ticket = await this.ticketsRepository.findTicketById(ticketId);
} else {
ticket = await this.ticketsRepository.findTicketById(ticketId, userId);
}
if (!ticket) throw new BadRequestException(TicketMessageEnum.TICKET_NOT_FOUND); if (!ticket) throw new BadRequestException(TicketMessageEnum.TICKET_NOT_FOUND);
const messages = await this.ticketMessagesRepository.findMessagesByTicketId(ticketId); const messages = await this.ticketMessagesRepository.findMessagesByTicketId(ticketId);
return { return {
ticket,
messages, messages,
}; };
} }
//******************************** */ //******************************** */
async closeTicketByUser(ticketId: string, userId: string) { async closeTicketByUser(ticketId: string, userId: string, role: Role) {
const ticket = await this.ticketsRepository.findTicketById(ticketId, userId); const userRole = role as unknown as RoleEnum;
let ticket: null | Ticket = null;
if (userRole === RoleEnum.ADMIN) {
ticket = await this.ticketsRepository.findTicketById(ticketId);
} else {
ticket = await this.ticketsRepository.findTicketById(ticketId, userId);
}
if (!ticket) throw new BadRequestException(TicketMessageEnum.TICKET_NOT_FOUND); if (!ticket) throw new BadRequestException(TicketMessageEnum.TICKET_NOT_FOUND);
ticket.status = TicketStatus.CLOSED; ticket.status = TicketStatus.CLOSED;
@@ -14,19 +14,23 @@ export class TicketMessagesRepository extends Repository<TicketMessage> {
return this.find({ return this.find({
relations: { relations: {
author: true, author: true,
ticket: true, // ticket: true,
},
select: {
id: true,
content: true,
attachmentUrl: true,
createdAt: true,
author: {
id: true,
firstName: true,
lastName: true,
role: {
id: true,
name: false,
},
},
}, },
// select: {
// id: true,
// content: true,
// attachmentUrl: true,
// createdAt: true,
// author: {
// id: true,
// firstName: true,
// lastName: true,
// },
// },
where: { ticket: { id: ticketId } }, where: { ticket: { id: ticketId } },
order: { createdAt: "DESC" }, order: { createdAt: "DESC" },
}); });
@@ -10,7 +10,7 @@ export class TicketsRepository extends Repository<Ticket> {
super(ticketsRepository.target, ticketsRepository.manager, ticketsRepository.queryRunner); super(ticketsRepository.target, ticketsRepository.manager, ticketsRepository.queryRunner);
} }
async findTicketById(id: string, userId: string): Promise<Ticket | null> { async findTicketById(id: string, userId?: string): Promise<Ticket | null> {
return this.findOneBy({ id, user: { id: userId } }); return this.findOneBy({ id, ...(userId && { user: { id: userId } }) });
} }
} }
+9 -9
View File
@@ -39,9 +39,9 @@ export class TicketsController {
return this.ticketsService.updateCategory(paramDto, updateCategoryDto); return this.ticketsService.updateCategory(paramDto, updateCategoryDto);
} }
@ApiOperation({ summary: "Get ticket categories => admin route" }) @ApiOperation({ summary: "Get ticket categories " })
@AuthGuards() @AuthGuards()
@Roles(RoleEnum.ADMIN) @Roles(RoleEnum.ADMIN, RoleEnum.USER)
@Get("categories") @Get("categories")
getTicketCategories() { getTicketCategories() {
return this.ticketsService.getTicketCategories(); return this.ticketsService.getTicketCategories();
@@ -89,22 +89,22 @@ export class TicketsController {
@Roles(RoleEnum.USER, RoleEnum.ADMIN) @Roles(RoleEnum.USER, RoleEnum.ADMIN)
@Post(":id/messages") @Post(":id/messages")
createTicketMessage(@Param() paramDto: ParamDto, @Body() createDto: CreateTicketMessageDto, @UserDec() user: User) { createTicketMessage(@Param() paramDto: ParamDto, @Body() createDto: CreateTicketMessageDto, @UserDec() user: User) {
return this.ticketsService.createTicketMessage(paramDto.id, createDto, user.id); return this.ticketsService.createTicketMessage(paramDto.id, createDto, user.id, user.role);
} }
@ApiOperation({ summary: "Get all ticket messages of user ==> user route" }) @ApiOperation({ summary: "Get all ticket messages of user" })
@AuthGuards() @AuthGuards()
@Roles(RoleEnum.USER) @Roles(RoleEnum.USER, RoleEnum.ADMIN)
@Get(":id/messages") @Get(":id/messages")
getTicketMessages(@Param() paramDto: ParamDto, @UserDec() user: User) { getTicketMessages(@Param() paramDto: ParamDto, @UserDec() user: User) {
return this.ticketsService.getTicketMessages(paramDto.id, user.id); return this.ticketsService.getTicketMessages(paramDto.id, user.id, user.role);
} }
@ApiOperation({ summary: "close ticket by user ==> user route" }) @ApiOperation({ summary: "close ticket by user or admin" })
@AuthGuards() @AuthGuards()
@Roles(RoleEnum.USER) @Roles(RoleEnum.USER, RoleEnum.ADMIN)
@Get(":id/close") @Get(":id/close")
closedTicketByUser(@Param() paramDto: ParamDto, @UserDec() user: User) { closedTicketByUser(@Param() paramDto: ParamDto, @UserDec() user: User) {
return this.ticketsService.closeTicketByUser(paramDto.id, user.id); return this.ticketsService.closeTicketByUser(paramDto.id, user.id, user.role);
} }
} }