diff --git a/src/controllers/FlowController.js b/src/controllers/FlowController.js index 2065d18d..f20f98c1 100644 --- a/src/controllers/FlowController.js +++ b/src/controllers/FlowController.js @@ -6,6 +6,7 @@ import FlowUser from "../models/FlowUser.js"; import FlowProcess from "../models/FlowProcess.js"; import { QueryTypes } from "sequelize"; import { tokenToUser } from "../middleware/authMiddleware.js"; +import { filterByName } from "../utils/filters.js"; class FlowController { static #stagesSequencesFromFlowStages(flowStages) { @@ -143,10 +144,15 @@ class FlowController { let where; if (req.headers.test !== "ok") { const { idUnit, idRole } = await tokenToUser(req); - where = idRole === 5 ? {} : { idUnit }; + const unitFilter = idRole === 5 ? {} : { idUnit }; + where = { + ...filterByName(req), + ...unitFilter, + }; } else { where = {}; } + const { limit, offset } = req.query; const flows = limit diff --git a/src/controllers/ProcessController.js b/src/controllers/ProcessController.js index 88421a87..5a8c2b49 100644 --- a/src/controllers/ProcessController.js +++ b/src/controllers/ProcessController.js @@ -7,6 +7,7 @@ import Stage from "../models/Stage.js"; import Database from "../database/index.js"; import { QueryTypes } from "sequelize"; import { tokenToUser } from "../middleware/authMiddleware.js"; +import { filterByNicknameAndRecord } from "../utils/filters.js"; const isRecordValid = (record) => { const regex = /^\d{20}$/; @@ -49,7 +50,11 @@ class ProcessController { let where; if (req.headers.test !== "ok") { const { idUnit, idRole } = await tokenToUser(req); - where = idRole === 5 ? {} : { idUnit }; + const unitFilter = idRole === 5 ? {} : { idUnit }; + where = { + ...filterByNicknameAndRecord(req), + ...unitFilter, + }; } else { where = {}; } @@ -247,7 +252,7 @@ class ProcessController { type: QueryTypes.SELECT, } ); - + const totalCount = countQuery[0].total; const totalPages = Math.ceil(totalCount / limit) || 0; @@ -291,9 +296,9 @@ class ProcessController { const startingProcess = process.status === "notStarted" && status === "inProgress" ? { - idStage: flowStages[0].idStageA, - effectiveDate: new Date(), - } + idStage: flowStages[0].idStageA, + effectiveDate: new Date(), + } : {}; let tempProgress = []; if (process.status === "notStarted" && status === "inProgress") { @@ -305,7 +310,7 @@ class ProcessController { const stageEndDate = new Date(stageStartDate); stageEndDate.setDate( stageEndDate.getDate() + - handleVerifyDate(stageStartDate, currentStage.duration) + handleVerifyDate(stageStartDate, currentStage.duration) ); const progressData = { @@ -347,7 +352,6 @@ class ProcessController { return res.status(200).json({ process, flows: flowProcesses }); } catch (error) { - console.log(error); return res.status(500).json(error); } } @@ -430,7 +434,7 @@ class ProcessController { const stageEndDate = new Date(stageStartDate); stageEndDate.setDate( stageEndDate.getDate() + - handleVerifyDate(stageStartDate, currentToStage.duration) + handleVerifyDate(stageStartDate, currentToStage.duration) ); maturityDate = stageEndDate; @@ -482,7 +486,6 @@ class ProcessController { message: `Impossível atualizar processo '${record}' para etapa '${to}`, }); } catch (error) { - console.log(error); return res.status(500).json({ error, message: `Erro ao atualizar processo '${record}' para etapa '${to}`, diff --git a/src/controllers/StageController.js b/src/controllers/StageController.js index 9c767d5e..a985e920 100644 --- a/src/controllers/StageController.js +++ b/src/controllers/StageController.js @@ -2,13 +2,18 @@ import Stage from "../models/Stage.js"; import FlowStage from "../models/FlowStage.js"; import { Op } from "sequelize"; import { tokenToUser } from "../middleware/authMiddleware.js"; +import { filterByName } from "../utils/filters.js"; class StageController { async index(req, res) { let where; if (req.headers.test !== "ok") { const { idUnit, idRole } = await tokenToUser(req); - where = idRole === 5 ? {} : { idUnit }; + const unitFilter = idRole === 5 ? {} : { idUnit }; + where = { + ...filterByName(req), + ...unitFilter, + }; } else { where = {}; } diff --git a/src/controllers/UnitController.js b/src/controllers/UnitController.js index e4dcb711..7942fa64 100644 --- a/src/controllers/UnitController.js +++ b/src/controllers/UnitController.js @@ -1,15 +1,20 @@ import Unit from "../models/Unit.js"; import User from "../models/User.js"; import { ROLE } from "../schemas/role.js"; +import { filterByName } from "../utils/filters.js"; class UnitController { async index(req, res) { try { + const where = { + ...filterByName(req), + }; const units = await Unit.findAll({ + where, offset: req.query.offset, limit: req.query.limit, }); - const totalCount = await Unit.count(); + const totalCount = await Unit.count({ where }); const totalPages = Math.ceil(totalCount / parseInt(req.query.limit, 10)); return res.json({ units: units || [], totalPages }); } catch (error) { diff --git a/src/controllers/UserContoller.js b/src/controllers/UserContoller.js index 1a204617..4ccdc43f 100644 --- a/src/controllers/UserContoller.js +++ b/src/controllers/UserContoller.js @@ -2,6 +2,7 @@ import { tokenToUser } from "../middleware/authMiddleware.js"; import { Op } from "sequelize"; import User from "../models/User.js"; import jwt from "jsonwebtoken"; +import { filterByFullName } from "../utils/filters.js"; const cpfFilter = (cpf) => cpf.replace(/[^0-9]/g, ""); const jwtToken = process.env.JWT_SECRET || "ABC"; @@ -11,6 +12,7 @@ const generateToken = (id) => { expiresIn: "3d", }); }; + class UserController { async login(req, res) { try { @@ -81,7 +83,11 @@ class UserController { let where; if (req.headers.test !== "ok") { const { idUnit, idRole } = await tokenToUser(req); - where = idRole === 5 ? {} : { idUnit }; + const unitFilter = idRole === 5 ? {} : { idUnit }; + where = { + ...filterByFullName(req), + ...unitFilter, + }; } else { where = {}; } diff --git a/src/routes.js b/src/routes.js index f29dd5d2..9e856e01 100644 --- a/src/routes.js +++ b/src/routes.js @@ -10,7 +10,7 @@ import { ROLE } from "./schemas/role.js"; const routes = Router(); -routes.get("/", (req, res) => { +routes.get("/", (_req, res) => { res.json({ status: "OK", message: "Up and running", @@ -21,6 +21,7 @@ routes.get("/priorities", ProcessController.getPriorities); //Rotas de processos routes.get("/processes", ProcessController.index); +routes.get("/processes/:filter", ProcessController.index); routes.get( "/processes/:idFlow", protect, @@ -68,6 +69,8 @@ routes.get("/flows/process/:record", FlowController.indexByRecord); routes.get("/flows", FlowController.index); +routes.get("/flows/:filter", FlowController.index); + routes.get("/flow/:idFlow", FlowController.getById); routes.get("/flowStages", FlowController.getFlowStages); @@ -88,6 +91,8 @@ routes.post("/newStage", StageController.store); routes.get("/stages", StageController.index); +routes.get("/stages/:filter", StageController.index); + routes.get("/stage/:id", StageController.getById); routes.delete("/deleteStage/:id", StageController.delete); @@ -97,6 +102,8 @@ routes.post("/newUnit", UnitController.store); routes.get("/units", UnitController.index); +routes.get("/units/:filter", UnitController.index); + routes.put("/setUnitAdmin", UnitController.setUnitAdmin); routes.put("/removeUnitAdmin", UnitController.removeUnitAdmin); diff --git a/src/tests/__tests__/test_filters.js b/src/tests/__tests__/test_filters.js new file mode 100644 index 00000000..3d4dc109 --- /dev/null +++ b/src/tests/__tests__/test_filters.js @@ -0,0 +1,89 @@ +import { Op } from "sequelize"; +import { + filterByNicknameAndRecord, + filterByName, + filterByFullName, +} from "../../utils/filters.js"; + +describe("filters", () => { + describe("filterByNicknameAndRecord", () => { + it("should return the correct filter object when filter is provided", () => { + const req = { + query: { + filter: "John", + }, + }; + + const result = filterByNicknameAndRecord(req); + + expect(result).toEqual({ + [Op.or]: [ + { record: { [Op.like]: "%John%" } }, + { nickname: { [Op.like]: "%John%" } }, + ], + }); + }); + + it("should return an empty object when filter is not provided", () => { + const req = { + query: {}, + }; + + const result = filterByNicknameAndRecord(req); + + expect(result).toEqual({}); + }); + }); + + describe("filterByName", () => { + it("should return the correct filter object when filter is provided", () => { + const req = { + query: { + filter: "Smith", + }, + }; + + const result = filterByName(req); + + expect(result).toEqual({ + [Op.or]: [{ name: { [Op.like]: "%Smith%" } }], + }); + }); + + it("should return an empty object when filter is not provided", () => { + const req = { + query: {}, + }; + + const result = filterByName(req); + + expect(result).toEqual({}); + }); + }); + + describe("filterByFullName", () => { + it("should return the correct filter object when filter is provided", () => { + const req = { + query: { + filter: "John Doe", + }, + }; + + const result = filterByFullName(req); + + expect(result).toEqual({ + [Op.or]: [{ fullName: { [Op.like]: "%John Doe%" } }], + }); + }); + + it("should return an empty object when filter is not provided", () => { + const req = { + query: {}, + }; + + const result = filterByFullName(req); + + expect(result).toEqual({}); + }); + }); +}); diff --git a/src/tests/__tests__/test_user_routes.js b/src/tests/__tests__/test_user_routes.js index 87df0bdc..372b442d 100644 --- a/src/tests/__tests__/test_user_routes.js +++ b/src/tests/__tests__/test_user_routes.js @@ -774,6 +774,32 @@ describe("user endpoints", () => { expect(response.body.message).toBe("Usuário inexistente"); }); + it("should return error for wrong password", async () => { + const testUser = { + fullName: "Nomen Nomes", + cpf: "86891382424", + email: "aaa@bb.com", + password: "spw123456", + idUnit: 1, + idRole: 3, + }; + + await supertest(app).post("/newUser").send(testUser); + + await supertest(app).post(`/acceptRequest/${testUser.cpf}`); + + const response = await supertest(app) + .post("/login") + .send({ + cpf: testUser.cpf, + password: "senha_qualquer", + }) + .expect(401); + + expect(response.body.message).toBe("Senha ou usuário incorretos"); + expect(response.body.error).toBe("Impossível autenticar"); + }); + test("get all users", async () => { const testUser = { fullName: "Nomenni Nomesos", diff --git a/src/utils/filters.js b/src/utils/filters.js new file mode 100644 index 00000000..69c6e7a4 --- /dev/null +++ b/src/utils/filters.js @@ -0,0 +1,28 @@ +import { Op } from "sequelize"; + +export function filterByNicknameAndRecord(req) { + return req.query.filter + ? { + [Op.or]: [ + { record: { [Op.like]: `%${req.query.filter}%` } }, + { nickname: { [Op.like]: `%${req.query.filter}%` } }, + ], + } + : {}; +} + +export function filterByName(req) { + return req.query.filter + ? { + [Op.or]: [{ name: { [Op.like]: `%${req.query.filter}%` } }], + } + : {}; +} + +export function filterByFullName(req) { + return req.query.filter + ? { + [Op.or]: [{ fullName: { [Op.like]: `%${req.query.filter}%` } }], + } + : {}; +}