From 082ca77097216bf318dcc9e8b115830c3ef85d21 Mon Sep 17 00:00:00 2001 From: IvanJGG Date: Thu, 13 Feb 2025 19:38:53 -0600 Subject: [PATCH 1/4] CAF-32 Create Interface to view and edit role permissions and test --- tests/cypress/e2e/roles.permissions.cy.js | 45 ++++++ tests/cypress/e2e/users.cy.js | 179 ++++++++++++++++++++++ views/roles/assets/permissions.js | 76 +++++++++ views/roles/permissions.html | 18 +++ views/users/script.js | 120 +++++++++++++++ 5 files changed, 438 insertions(+) create mode 100644 tests/cypress/e2e/roles.permissions.cy.js create mode 100644 tests/cypress/e2e/users.cy.js create mode 100644 views/roles/assets/permissions.js create mode 100644 views/roles/permissions.html create mode 100644 views/users/script.js diff --git a/tests/cypress/e2e/roles.permissions.cy.js b/tests/cypress/e2e/roles.permissions.cy.js new file mode 100644 index 0000000..757f272 --- /dev/null +++ b/tests/cypress/e2e/roles.permissions.cy.js @@ -0,0 +1,45 @@ +describe("Permissions Page", () => { + beforeEach(() => { + var id = 123; + + cy.intercept("GET", "/roles/123/nodes", { + body: { + message: "OK", + permissions: { + "Usuarios": ["Crear", "Editar", "Eliminar"], + "Roles": ["Asignar", "Modificar"] + } + } + }).as("getPermissions"); + + cy.intercept("POST", "/roles/123/nodes").as("savePermissions"); + + cy.visitWithToken(`/roles/permissions/?id=${id}`); + }); + + it("should load and display permissions", () => { + cy.wait("@getPermissions"); + + cy.get("#permissionsTable").should("be.visible"); + cy.contains("Usuarios").should("exist"); + cy.contains("Crear").should("exist"); + cy.contains("Editar").should("exist"); + cy.contains("Eliminar").should("exist"); + cy.contains("Roles").should("exist"); + cy.contains("Asignar").should("exist"); + cy.contains("Modificar").should("exist"); + }); + + it("should have checkboxes for permissions", () => { + cy.get("input[type='checkbox']").should("have.length", 5); + }); + + it("should allow selecting permissions", () => { + cy.get("input[type='checkbox']").first().check().should("be.checked"); + cy.get("input[type='checkbox']").eq(1).uncheck().should("not.be.checked"); + }); + + it("should have save button disabled initially", () => { + cy.get("#savePermissions").should("be.disabled"); + }); +}); diff --git a/tests/cypress/e2e/users.cy.js b/tests/cypress/e2e/users.cy.js new file mode 100644 index 0000000..a9a96c2 --- /dev/null +++ b/tests/cypress/e2e/users.cy.js @@ -0,0 +1,179 @@ +describe('Users', () => { + + beforeEach(() => { + cy.intercept({ method: 'GET', url: '/roles/' }, { + statusCode: 200, + body: [ + { id: 1, name: 'Administrador' }, + { id: 2, name: 'Usuario' } + ] + }).as("getRoles"); + + cy.intercept('GET', 'addresses', { + statusCode: 200, + body: [ + { id: 1, street: 'Calle Principal', number: '101' }, + { id: 2, street: 'Calle Secundaria', number: '202' }, + { id: 3, street: 'Calle Tercera', number: '303' }, + ], + }).as('getAddresses'); + + cy.intercept({ method: 'POST', url: 'users/register' }, { + statusCode: 200, + body: { + message: 'OK', + }, + }).as("registerUser"); + }); + + it('should create a new user successfully', () => { + cy.visit('http://localhost/users/add?disable-twig-cache=true'); + + cy.wait('@getAddresses'); + + cy.fixture('user.json').then(user => { + cy.get('[name=email]') + .should('have.id', 'txtEmail') + .should('have.attr', 'type', 'email') + .should('have.attr', 'required', 'required') + .type(user.email); + cy.get('[name=firstName]') + .should('have.id', 'txtFirstName') + .should('have.attr', 'type', 'text') + .should('have.attr', 'required', 'required') + .type(user.firstName); + cy.get('[name=secondName]') + .should('have.id', 'txtSecondName') + .should('have.attr', 'type', 'text') + .should('not.have.attr', 'required', 'required') + .type(user.secondName); + cy.get('[name=firstSurname]') + .should('have.id', 'txtFirstSurname') + .should('have.attr', 'type', 'text') + .should('have.attr', 'required', 'required') + .type(user.firstSurname); + cy.get('[name=secondSurname]') + .should('have.id', 'txtSecondSurname') + .should('have.attr', 'type', 'text') + .should('not.have.attr', 'required', 'required') + .type(user.secondSurname); + cy.get('[name=password]') + .should('have.id', 'txtPassword') + .should('have.attr', 'type', 'password') + .should('have.attr', 'required', 'required') + .type(user.password); + + cy.get('[name=phone]') + .should('have.id', 'txtPhone') + .should('have.attr', 'type', 'tel') + .should('have.attr', 'required', 'required') + .should('have.attr', 'maxlength', '10') + .type(user.phone); + cy.get('#txtAddress').select('Calle Tercera 303'); + + cy.wait('@getRoles'); + + cy.get('#txtRole') + .find('option') + .should('have.length', 3) + .then((options) => { + expect(options[1].text).to.equal('Administrador'); + expect(options[2].text).to.equal('Usuario'); + }); + + cy.get('#txtRole').select('Administrador'); + + cy.get('[type=submit]').click(); + + cy.wait("@registerUser"); + }); + }); + + it('should update an existing user successfully', () => { + const id = 1; + cy.fixture('update_user.json').then(fakeUser => { + cy.intercept({ method: 'GET', url: `users/${id}` }, { + statusCode: 200, + body: { + message: 'OK', + user: fakeUser + }, + }).as("getUser"); + + cy.intercept({ method: 'PATCH', url: `users/${id}` }, { + statusCode: 200, + body: { + message: 'Usuario actualizado correctamente', + }, + }).as("updateUser"); + + cy.visit(`http://localhost/users/add/?id=${id}&disable-twig-cache=true`); + + cy.wait('@getAddresses'); + cy.wait("@getUser"); + //Verificar que todos los campos tengas los valores de fakeUser + + cy.get('#txtEmail').should('have.value', fakeUser.email); + cy.get('#txtFirstName').should('have.value', fakeUser.firstName); + cy.get('#txtSecondName').should('have.value', fakeUser.secondName); + cy.get('#txtFirstSurname').should('have.value', fakeUser.lastname); + cy.get('#txtSecondSurname').should('have.value', fakeUser.secondLastname); + cy.get('#txtPhone').should('have.value', fakeUser.phoneNumber); + cy.get('#txtAddress').should('have.value', fakeUser.address); + + cy.get('#txtEmail').clear().type('ivan@example.com').should('have.value', 'ivan@example.com'); + cy.get('#txtFirstName').clear().type('John Doe').should('have.value', 'John Doe'); + + cy.get('#txtPassword').should('not.exist'); + + cy.wait('@getRoles'); + + cy.get('#txtRole') + .find('option') + .should('have.length', 3) + .then((options) => { + expect(options[1].text).to.equal('Administrador'); + expect(options[2].text).to.equal('Usuario'); + }); + + cy.get('#txtRole').select('Administrador'); + + cy.get('[type=submit]').click(); + + cy.wait("@updateUser"); + + cy.location('pathname').should('eq', '/users/'); + }); + }); + + it('should load the addresses into the dropdown', () => { + cy.visit('http://localhost/users/add?disable-twig-cache=true'); + + cy.wait('@getAddresses'); + + cy.get('#txtAddress') + .find('option') + .should('have.length', 4) + .then(options => { + expect(options[0].textContent).to.eq('Selecciona una dirección'); + expect(options[1].textContent).to.eq('Calle Principal 101'); + expect(options[2].textContent).to.eq('Calle Secundaria 202'); + expect(options[3].textContent).to.eq('Calle Tercera 303'); + }); + }); + + it('should have the correct values in the dropdown', () => { + cy.visit('http://localhost/users/add?disable-twig-cache=true'); + + cy.wait('@getAddresses'); + + cy.get('#txtAddress') + .find('option') + .then(options => { + expect(options).to.have.length(4); + expect(options[1].value).to.eq('Calle Principal 101'); + expect(options[2].value).to.eq('Calle Secundaria 202'); + expect(options[3].value).to.eq('Calle Tercera 303'); + }); + }); +}); diff --git a/views/roles/assets/permissions.js b/views/roles/assets/permissions.js new file mode 100644 index 0000000..fa30b01 --- /dev/null +++ b/views/roles/assets/permissions.js @@ -0,0 +1,76 @@ + +async function fetchPermissions(roleId) { + try { + const response = await apiRequest("GET", `roles/${roleId}/nodes`); + + return response.data; + } catch (error) { + console.error("Error al cargar permisos:", error); + return null; + } +} + +function createPermissionsTable(permissions) { + const permissionsTable = document.getElementById("permissionsTable"); + + Object.entries(permissions).forEach(([category, permissionList]) => { + const categoryRow = document.createElement("tr"); + const categoryCell = document.createElement("td"); + categoryCell.colSpan = 2; + categoryCell.textContent = category; + categoryCell.style.fontWeight = "bold"; + categoryRow.appendChild(categoryCell); + permissionsTable.appendChild(categoryRow); + + permissionList.forEach((permission) => { + const permissionRow = document.createElement("tr"); + + const permissionCell = document.createElement("td"); + permissionCell.textContent = permission; + + const checkboxCell = document.createElement("td"); + const checkbox = document.createElement("input"); + checkbox.type = "checkbox"; + checkbox.dataset.permissionName = permission; + checkboxCell.appendChild(checkbox); + + permissionRow.appendChild(permissionCell); + permissionRow.appendChild(checkboxCell); + permissionsTable.appendChild(permissionRow); + }); + }); +} + +async function savePermissions(roleId) { + const checkboxes = document.querySelectorAll("input[type='checkbox']"); + const updatedPermissions = Array.from(checkboxes).map((checkbox) => ({ + permission: checkbox.dataset.permissionName, + enabled: checkbox.checked, + })); + + try { + await apiRequest("POST", `roles/${roleId}/nodes`, updatedPermissions); + + alert("Permisos guardados con éxito."); + } catch (error) { + console.error("Error al guardar permisos:", error); + alert("Hubo un error al guardar los permisos."); + } +} + +window.addEventListener("load", async () => { + const urlParams = new URLSearchParams(window.location.search); + const roleId = urlParams.get("id"); + + const permissionsData = await fetchPermissions(roleId); + + if (permissionsData && permissionsData.message === "OK") { + createPermissionsTable(permissionsData.permissions); + } else { + alert(permissionsData?.message || "Error al cargar los permisos."); + } +}); + +document.getElementById("savePermissions").addEventListener("click", async () => { + await savePermissions(roleId); +}); diff --git a/views/roles/permissions.html b/views/roles/permissions.html new file mode 100644 index 0000000..a3e3cdc --- /dev/null +++ b/views/roles/permissions.html @@ -0,0 +1,18 @@ +
+
+
+ + + + + + + +
Permisos
+ + +
+
+
+ + diff --git a/views/users/script.js b/views/users/script.js new file mode 100644 index 0000000..64af289 --- /dev/null +++ b/views/users/script.js @@ -0,0 +1,120 @@ +window.addEventListener("load", async (event) => { + let id = document.getElementById("txtId").value; + if (id) { + const result = await fetch(`http://localhost:5033/users/${id}`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + }, + }); + let response = await result.json(); + let user = response.user; + document.getElementById("txtEmail").value = user.email; + document.getElementById("txtFirstName").value = user.firstName; + document.getElementById("txtSecondName").value = user.secondName; + document.getElementById("txtFirstSurname").value = user.lastname; + document.getElementById("txtSecondSurname").value = user.secondLastname; + document.getElementById("txtPhone").value = user.phoneNumber; + document.getElementById("txtAddress").value = user.address; + } +}); +async function handleSubmit(e, form) { + e.preventDefault(); + + const formData = new FormData(form); + + let jsonData = {}; + + formData.forEach(function (value, key) { + jsonData[key] = value; + }); + + try { + + const response = await fetch('http://localhost:5033/users/register', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(jsonData) + }); + + const result = await response.json(); + + if (response.ok) { + alert('Usuario registrado con éxito'); + location.reload(); + } else { + alert('Error: ' + result.message); + } + } catch (error) { + console.error('Error:', error); + alert('Hubo un problema al registrar el usuario.'); + } +} +async function loadUsersTable() { + try { + const result = await fetch('http://localhost:5033/users', { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + }); + + if (result.ok) { + const users = await result.json(); + + const userTable = document.getElementById('userTable'); + userTable.innerHTML = ''; + + users.forEach(user => { + const row = document.createElement('tr'); + + const addressCell = document.createElement('td'); + addressCell.textContent = user.address; + + const fullNameCell = document.createElement('td'); + fullNameCell.textContent = `${user.firstName} ${user.lastName}`; + + const phoneCell = document.createElement('td'); + phoneCell.textContent = user.phoneNumber || 'Sin teléfono'; + + const actionsCell = document.createElement('td'); + const editButton = document.createElement('button'); + editButton.className = 'btn btn-info btn-sm me-2'; + editButton.textContent = 'Editar'; + editButton.onclick = () => { + window.location.href = "/users/add"; + }; + + const deactivateButton = document.createElement('button'); + deactivateButton.className = 'btn btn-outline-secondary btn-sm'; + deactivateButton.textContent = 'Desactivar'; + deactivateButton.onclick = () => { + + }; + + actionsCell.appendChild(editButton); + actionsCell.appendChild(deactivateButton); + + row.appendChild(addressCell); + row.appendChild(fullNameCell); + row.appendChild(phoneCell); + row.appendChild(actionsCell); + + userTable.appendChild(row); + }); + } else { + console.error('Error al cargar la lista de usuarios'); + } + } catch (error) { + console.error('Error al cargar usuarios:', error); + } +} + +window.addEventListener('DOMContentLoaded', (event) => { + if (document.getElementById('userTable')) { + loadUsersTable(); + } +}); + From 8aee7a6edcba6e8ad761b53756716f521819e4f2 Mon Sep 17 00:00:00 2001 From: IvanJGG Date: Thu, 13 Feb 2025 19:48:19 -0600 Subject: [PATCH 2/4] CAF-32 Yarn prettier applied --- tests/cypress/e2e/roles.permissions.cy.js | 86 +++--- tests/cypress/e2e/users.cy.js | 353 ++++++++++++---------- views/roles/assets/permissions.js | 105 +++---- views/roles/permissions.html | 26 +- views/users/script.js | 206 +++++++------ 5 files changed, 396 insertions(+), 380 deletions(-) diff --git a/tests/cypress/e2e/roles.permissions.cy.js b/tests/cypress/e2e/roles.permissions.cy.js index 757f272..f4bc634 100644 --- a/tests/cypress/e2e/roles.permissions.cy.js +++ b/tests/cypress/e2e/roles.permissions.cy.js @@ -1,45 +1,45 @@ describe("Permissions Page", () => { - beforeEach(() => { - var id = 123; - - cy.intercept("GET", "/roles/123/nodes", { - body: { - message: "OK", - permissions: { - "Usuarios": ["Crear", "Editar", "Eliminar"], - "Roles": ["Asignar", "Modificar"] - } - } - }).as("getPermissions"); - - cy.intercept("POST", "/roles/123/nodes").as("savePermissions"); - - cy.visitWithToken(`/roles/permissions/?id=${id}`); - }); - - it("should load and display permissions", () => { - cy.wait("@getPermissions"); - - cy.get("#permissionsTable").should("be.visible"); - cy.contains("Usuarios").should("exist"); - cy.contains("Crear").should("exist"); - cy.contains("Editar").should("exist"); - cy.contains("Eliminar").should("exist"); - cy.contains("Roles").should("exist"); - cy.contains("Asignar").should("exist"); - cy.contains("Modificar").should("exist"); - }); - - it("should have checkboxes for permissions", () => { - cy.get("input[type='checkbox']").should("have.length", 5); - }); - - it("should allow selecting permissions", () => { - cy.get("input[type='checkbox']").first().check().should("be.checked"); - cy.get("input[type='checkbox']").eq(1).uncheck().should("not.be.checked"); - }); - - it("should have save button disabled initially", () => { - cy.get("#savePermissions").should("be.disabled"); - }); + beforeEach(() => { + var id = 123; + + cy.intercept("GET", "/roles/123/nodes", { + body: { + message: "OK", + permissions: { + Usuarios: ["Crear", "Editar", "Eliminar"], + Roles: ["Asignar", "Modificar"], + }, + }, + }).as("getPermissions"); + + cy.intercept("POST", "/roles/123/nodes").as("savePermissions"); + + cy.visitWithToken(`/roles/permissions/?id=${id}`); + }); + + it("should load and display permissions", () => { + cy.wait("@getPermissions"); + + cy.get("#permissionsTable").should("be.visible"); + cy.contains("Usuarios").should("exist"); + cy.contains("Crear").should("exist"); + cy.contains("Editar").should("exist"); + cy.contains("Eliminar").should("exist"); + cy.contains("Roles").should("exist"); + cy.contains("Asignar").should("exist"); + cy.contains("Modificar").should("exist"); + }); + + it("should have checkboxes for permissions", () => { + cy.get("input[type='checkbox']").should("have.length", 5); + }); + + it("should allow selecting permissions", () => { + cy.get("input[type='checkbox']").first().check().should("be.checked"); + cy.get("input[type='checkbox']").eq(1).uncheck().should("not.be.checked"); + }); + + it("should have save button disabled initially", () => { + cy.get("#savePermissions").should("be.disabled"); + }); }); diff --git a/tests/cypress/e2e/users.cy.js b/tests/cypress/e2e/users.cy.js index a9a96c2..98fefdc 100644 --- a/tests/cypress/e2e/users.cy.js +++ b/tests/cypress/e2e/users.cy.js @@ -1,179 +1,196 @@ -describe('Users', () => { - - beforeEach(() => { - cy.intercept({ method: 'GET', url: '/roles/' }, { - statusCode: 200, - body: [ - { id: 1, name: 'Administrador' }, - { id: 2, name: 'Usuario' } - ] - }).as("getRoles"); - - cy.intercept('GET', 'addresses', { - statusCode: 200, - body: [ - { id: 1, street: 'Calle Principal', number: '101' }, - { id: 2, street: 'Calle Secundaria', number: '202' }, - { id: 3, street: 'Calle Tercera', number: '303' }, - ], - }).as('getAddresses'); - - cy.intercept({ method: 'POST', url: 'users/register' }, { - statusCode: 200, - body: { - message: 'OK', - }, - }).as("registerUser"); - }); - - it('should create a new user successfully', () => { - cy.visit('http://localhost/users/add?disable-twig-cache=true'); - - cy.wait('@getAddresses'); - - cy.fixture('user.json').then(user => { - cy.get('[name=email]') - .should('have.id', 'txtEmail') - .should('have.attr', 'type', 'email') - .should('have.attr', 'required', 'required') - .type(user.email); - cy.get('[name=firstName]') - .should('have.id', 'txtFirstName') - .should('have.attr', 'type', 'text') - .should('have.attr', 'required', 'required') - .type(user.firstName); - cy.get('[name=secondName]') - .should('have.id', 'txtSecondName') - .should('have.attr', 'type', 'text') - .should('not.have.attr', 'required', 'required') - .type(user.secondName); - cy.get('[name=firstSurname]') - .should('have.id', 'txtFirstSurname') - .should('have.attr', 'type', 'text') - .should('have.attr', 'required', 'required') - .type(user.firstSurname); - cy.get('[name=secondSurname]') - .should('have.id', 'txtSecondSurname') - .should('have.attr', 'type', 'text') - .should('not.have.attr', 'required', 'required') - .type(user.secondSurname); - cy.get('[name=password]') - .should('have.id', 'txtPassword') - .should('have.attr', 'type', 'password') - .should('have.attr', 'required', 'required') - .type(user.password); - - cy.get('[name=phone]') - .should('have.id', 'txtPhone') - .should('have.attr', 'type', 'tel') - .should('have.attr', 'required', 'required') - .should('have.attr', 'maxlength', '10') - .type(user.phone); - cy.get('#txtAddress').select('Calle Tercera 303'); - - cy.wait('@getRoles'); - - cy.get('#txtRole') - .find('option') - .should('have.length', 3) - .then((options) => { - expect(options[1].text).to.equal('Administrador'); - expect(options[2].text).to.equal('Usuario'); - }); - - cy.get('#txtRole').select('Administrador'); - - cy.get('[type=submit]').click(); - - cy.wait("@registerUser"); +describe("Users", () => { + beforeEach(() => { + cy.intercept( + { method: "GET", url: "/roles/" }, + { + statusCode: 200, + body: [ + { id: 1, name: "Administrador" }, + { id: 2, name: "Usuario" }, + ], + }, + ).as("getRoles"); + + cy.intercept("GET", "addresses", { + statusCode: 200, + body: [ + { id: 1, street: "Calle Principal", number: "101" }, + { id: 2, street: "Calle Secundaria", number: "202" }, + { id: 3, street: "Calle Tercera", number: "303" }, + ], + }).as("getAddresses"); + + cy.intercept( + { method: "POST", url: "users/register" }, + { + statusCode: 200, + body: { + message: "OK", + }, + }, + ).as("registerUser"); + }); + + it("should create a new user successfully", () => { + cy.visit("http://localhost/users/add?disable-twig-cache=true"); + + cy.wait("@getAddresses"); + + cy.fixture("user.json").then((user) => { + cy.get("[name=email]") + .should("have.id", "txtEmail") + .should("have.attr", "type", "email") + .should("have.attr", "required", "required") + .type(user.email); + cy.get("[name=firstName]") + .should("have.id", "txtFirstName") + .should("have.attr", "type", "text") + .should("have.attr", "required", "required") + .type(user.firstName); + cy.get("[name=secondName]") + .should("have.id", "txtSecondName") + .should("have.attr", "type", "text") + .should("not.have.attr", "required", "required") + .type(user.secondName); + cy.get("[name=firstSurname]") + .should("have.id", "txtFirstSurname") + .should("have.attr", "type", "text") + .should("have.attr", "required", "required") + .type(user.firstSurname); + cy.get("[name=secondSurname]") + .should("have.id", "txtSecondSurname") + .should("have.attr", "type", "text") + .should("not.have.attr", "required", "required") + .type(user.secondSurname); + cy.get("[name=password]") + .should("have.id", "txtPassword") + .should("have.attr", "type", "password") + .should("have.attr", "required", "required") + .type(user.password); + + cy.get("[name=phone]") + .should("have.id", "txtPhone") + .should("have.attr", "type", "tel") + .should("have.attr", "required", "required") + .should("have.attr", "maxlength", "10") + .type(user.phone); + cy.get("#txtAddress").select("Calle Tercera 303"); + + cy.wait("@getRoles"); + + cy.get("#txtRole") + .find("option") + .should("have.length", 3) + .then((options) => { + expect(options[1].text).to.equal("Administrador"); + expect(options[2].text).to.equal("Usuario"); }); - }); - - it('should update an existing user successfully', () => { - const id = 1; - cy.fixture('update_user.json').then(fakeUser => { - cy.intercept({ method: 'GET', url: `users/${id}` }, { - statusCode: 200, - body: { - message: 'OK', - user: fakeUser - }, - }).as("getUser"); - - cy.intercept({ method: 'PATCH', url: `users/${id}` }, { - statusCode: 200, - body: { - message: 'Usuario actualizado correctamente', - }, - }).as("updateUser"); - - cy.visit(`http://localhost/users/add/?id=${id}&disable-twig-cache=true`); - - cy.wait('@getAddresses'); - cy.wait("@getUser"); - //Verificar que todos los campos tengas los valores de fakeUser - - cy.get('#txtEmail').should('have.value', fakeUser.email); - cy.get('#txtFirstName').should('have.value', fakeUser.firstName); - cy.get('#txtSecondName').should('have.value', fakeUser.secondName); - cy.get('#txtFirstSurname').should('have.value', fakeUser.lastname); - cy.get('#txtSecondSurname').should('have.value', fakeUser.secondLastname); - cy.get('#txtPhone').should('have.value', fakeUser.phoneNumber); - cy.get('#txtAddress').should('have.value', fakeUser.address); - - cy.get('#txtEmail').clear().type('ivan@example.com').should('have.value', 'ivan@example.com'); - cy.get('#txtFirstName').clear().type('John Doe').should('have.value', 'John Doe'); - cy.get('#txtPassword').should('not.exist'); + cy.get("#txtRole").select("Administrador"); - cy.wait('@getRoles'); + cy.get("[type=submit]").click(); - cy.get('#txtRole') - .find('option') - .should('have.length', 3) - .then((options) => { - expect(options[1].text).to.equal('Administrador'); - expect(options[2].text).to.equal('Usuario'); - }); - - cy.get('#txtRole').select('Administrador'); - - cy.get('[type=submit]').click(); - - cy.wait("@updateUser"); - - cy.location('pathname').should('eq', '/users/'); - }); + cy.wait("@registerUser"); }); + }); + + it("should update an existing user successfully", () => { + const id = 1; + cy.fixture("update_user.json").then((fakeUser) => { + cy.intercept( + { method: "GET", url: `users/${id}` }, + { + statusCode: 200, + body: { + message: "OK", + user: fakeUser, + }, + }, + ).as("getUser"); + + cy.intercept( + { method: "PATCH", url: `users/${id}` }, + { + statusCode: 200, + body: { + message: "Usuario actualizado correctamente", + }, + }, + ).as("updateUser"); + + cy.visit(`http://localhost/users/add/?id=${id}&disable-twig-cache=true`); + + cy.wait("@getAddresses"); + cy.wait("@getUser"); + //Verificar que todos los campos tengas los valores de fakeUser + + cy.get("#txtEmail").should("have.value", fakeUser.email); + cy.get("#txtFirstName").should("have.value", fakeUser.firstName); + cy.get("#txtSecondName").should("have.value", fakeUser.secondName); + cy.get("#txtFirstSurname").should("have.value", fakeUser.lastname); + cy.get("#txtSecondSurname").should("have.value", fakeUser.secondLastname); + cy.get("#txtPhone").should("have.value", fakeUser.phoneNumber); + cy.get("#txtAddress").should("have.value", fakeUser.address); + + cy.get("#txtEmail") + .clear() + .type("ivan@example.com") + .should("have.value", "ivan@example.com"); + cy.get("#txtFirstName") + .clear() + .type("John Doe") + .should("have.value", "John Doe"); + + cy.get("#txtPassword").should("not.exist"); + + cy.wait("@getRoles"); + + cy.get("#txtRole") + .find("option") + .should("have.length", 3) + .then((options) => { + expect(options[1].text).to.equal("Administrador"); + expect(options[2].text).to.equal("Usuario"); + }); - it('should load the addresses into the dropdown', () => { - cy.visit('http://localhost/users/add?disable-twig-cache=true'); - - cy.wait('@getAddresses'); - - cy.get('#txtAddress') - .find('option') - .should('have.length', 4) - .then(options => { - expect(options[0].textContent).to.eq('Selecciona una dirección'); - expect(options[1].textContent).to.eq('Calle Principal 101'); - expect(options[2].textContent).to.eq('Calle Secundaria 202'); - expect(options[3].textContent).to.eq('Calle Tercera 303'); - }); - }); + cy.get("#txtRole").select("Administrador"); - it('should have the correct values in the dropdown', () => { - cy.visit('http://localhost/users/add?disable-twig-cache=true'); + cy.get("[type=submit]").click(); - cy.wait('@getAddresses'); + cy.wait("@updateUser"); - cy.get('#txtAddress') - .find('option') - .then(options => { - expect(options).to.have.length(4); - expect(options[1].value).to.eq('Calle Principal 101'); - expect(options[2].value).to.eq('Calle Secundaria 202'); - expect(options[3].value).to.eq('Calle Tercera 303'); - }); + cy.location("pathname").should("eq", "/users/"); }); + }); + + it("should load the addresses into the dropdown", () => { + cy.visit("http://localhost/users/add?disable-twig-cache=true"); + + cy.wait("@getAddresses"); + + cy.get("#txtAddress") + .find("option") + .should("have.length", 4) + .then((options) => { + expect(options[0].textContent).to.eq("Selecciona una dirección"); + expect(options[1].textContent).to.eq("Calle Principal 101"); + expect(options[2].textContent).to.eq("Calle Secundaria 202"); + expect(options[3].textContent).to.eq("Calle Tercera 303"); + }); + }); + + it("should have the correct values in the dropdown", () => { + cy.visit("http://localhost/users/add?disable-twig-cache=true"); + + cy.wait("@getAddresses"); + + cy.get("#txtAddress") + .find("option") + .then((options) => { + expect(options).to.have.length(4); + expect(options[1].value).to.eq("Calle Principal 101"); + expect(options[2].value).to.eq("Calle Secundaria 202"); + expect(options[3].value).to.eq("Calle Tercera 303"); + }); + }); }); diff --git a/views/roles/assets/permissions.js b/views/roles/assets/permissions.js index fa30b01..b55e54a 100644 --- a/views/roles/assets/permissions.js +++ b/views/roles/assets/permissions.js @@ -1,76 +1,77 @@ - async function fetchPermissions(roleId) { - try { - const response = await apiRequest("GET", `roles/${roleId}/nodes`); + try { + const response = await apiRequest("GET", `roles/${roleId}/nodes`); - return response.data; - } catch (error) { - console.error("Error al cargar permisos:", error); - return null; - } + return response.data; + } catch (error) { + console.error("Error al cargar permisos:", error); + return null; + } } function createPermissionsTable(permissions) { - const permissionsTable = document.getElementById("permissionsTable"); + const permissionsTable = document.getElementById("permissionsTable"); - Object.entries(permissions).forEach(([category, permissionList]) => { - const categoryRow = document.createElement("tr"); - const categoryCell = document.createElement("td"); - categoryCell.colSpan = 2; - categoryCell.textContent = category; - categoryCell.style.fontWeight = "bold"; - categoryRow.appendChild(categoryCell); - permissionsTable.appendChild(categoryRow); + Object.entries(permissions).forEach(([category, permissionList]) => { + const categoryRow = document.createElement("tr"); + const categoryCell = document.createElement("td"); + categoryCell.colSpan = 2; + categoryCell.textContent = category; + categoryCell.style.fontWeight = "bold"; + categoryRow.appendChild(categoryCell); + permissionsTable.appendChild(categoryRow); - permissionList.forEach((permission) => { - const permissionRow = document.createElement("tr"); + permissionList.forEach((permission) => { + const permissionRow = document.createElement("tr"); - const permissionCell = document.createElement("td"); - permissionCell.textContent = permission; + const permissionCell = document.createElement("td"); + permissionCell.textContent = permission; - const checkboxCell = document.createElement("td"); - const checkbox = document.createElement("input"); - checkbox.type = "checkbox"; - checkbox.dataset.permissionName = permission; - checkboxCell.appendChild(checkbox); + const checkboxCell = document.createElement("td"); + const checkbox = document.createElement("input"); + checkbox.type = "checkbox"; + checkbox.dataset.permissionName = permission; + checkboxCell.appendChild(checkbox); - permissionRow.appendChild(permissionCell); - permissionRow.appendChild(checkboxCell); - permissionsTable.appendChild(permissionRow); - }); + permissionRow.appendChild(permissionCell); + permissionRow.appendChild(checkboxCell); + permissionsTable.appendChild(permissionRow); }); + }); } async function savePermissions(roleId) { - const checkboxes = document.querySelectorAll("input[type='checkbox']"); - const updatedPermissions = Array.from(checkboxes).map((checkbox) => ({ - permission: checkbox.dataset.permissionName, - enabled: checkbox.checked, - })); + const checkboxes = document.querySelectorAll("input[type='checkbox']"); + const updatedPermissions = Array.from(checkboxes).map((checkbox) => ({ + permission: checkbox.dataset.permissionName, + enabled: checkbox.checked, + })); - try { - await apiRequest("POST", `roles/${roleId}/nodes`, updatedPermissions); + try { + await apiRequest("POST", `roles/${roleId}/nodes`, updatedPermissions); - alert("Permisos guardados con éxito."); - } catch (error) { - console.error("Error al guardar permisos:", error); - alert("Hubo un error al guardar los permisos."); - } + alert("Permisos guardados con éxito."); + } catch (error) { + console.error("Error al guardar permisos:", error); + alert("Hubo un error al guardar los permisos."); + } } window.addEventListener("load", async () => { - const urlParams = new URLSearchParams(window.location.search); - const roleId = urlParams.get("id"); + const urlParams = new URLSearchParams(window.location.search); + const roleId = urlParams.get("id"); - const permissionsData = await fetchPermissions(roleId); + const permissionsData = await fetchPermissions(roleId); - if (permissionsData && permissionsData.message === "OK") { - createPermissionsTable(permissionsData.permissions); - } else { - alert(permissionsData?.message || "Error al cargar los permisos."); - } + if (permissionsData && permissionsData.message === "OK") { + createPermissionsTable(permissionsData.permissions); + } else { + alert(permissionsData?.message || "Error al cargar los permisos."); + } }); -document.getElementById("savePermissions").addEventListener("click", async () => { +document + .getElementById("savePermissions") + .addEventListener("click", async () => { await savePermissions(roleId); -}); + }); diff --git a/views/roles/permissions.html b/views/roles/permissions.html index a3e3cdc..f9f5075 100644 --- a/views/roles/permissions.html +++ b/views/roles/permissions.html @@ -1,17 +1,19 @@
-
- - - - - - - -
Permisos
- - -
+
+ + + + + + + +
Permisos
+ + +
diff --git a/views/users/script.js b/views/users/script.js index 64af289..2fbc6bb 100644 --- a/views/users/script.js +++ b/views/users/script.js @@ -1,120 +1,116 @@ window.addEventListener("load", async (event) => { - let id = document.getElementById("txtId").value; - if (id) { - const result = await fetch(`http://localhost:5033/users/${id}`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - }, - }); - let response = await result.json(); - let user = response.user; - document.getElementById("txtEmail").value = user.email; - document.getElementById("txtFirstName").value = user.firstName; - document.getElementById("txtSecondName").value = user.secondName; - document.getElementById("txtFirstSurname").value = user.lastname; - document.getElementById("txtSecondSurname").value = user.secondLastname; - document.getElementById("txtPhone").value = user.phoneNumber; - document.getElementById("txtAddress").value = user.address; - } + let id = document.getElementById("txtId").value; + if (id) { + const result = await fetch(`http://localhost:5033/users/${id}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + let response = await result.json(); + let user = response.user; + document.getElementById("txtEmail").value = user.email; + document.getElementById("txtFirstName").value = user.firstName; + document.getElementById("txtSecondName").value = user.secondName; + document.getElementById("txtFirstSurname").value = user.lastname; + document.getElementById("txtSecondSurname").value = user.secondLastname; + document.getElementById("txtPhone").value = user.phoneNumber; + document.getElementById("txtAddress").value = user.address; + } }); async function handleSubmit(e, form) { - e.preventDefault(); + e.preventDefault(); + + const formData = new FormData(form); - const formData = new FormData(form); + let jsonData = {}; - let jsonData = {}; + formData.forEach(function (value, key) { + jsonData[key] = value; + }); - formData.forEach(function (value, key) { - jsonData[key] = value; + try { + const response = await fetch("http://localhost:5033/users/register", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(jsonData), }); - try { - - const response = await fetch('http://localhost:5033/users/register', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(jsonData) - }); - - const result = await response.json(); - - if (response.ok) { - alert('Usuario registrado con éxito'); - location.reload(); - } else { - alert('Error: ' + result.message); - } - } catch (error) { - console.error('Error:', error); - alert('Hubo un problema al registrar el usuario.'); + const result = await response.json(); + + if (response.ok) { + alert("Usuario registrado con éxito"); + location.reload(); + } else { + alert("Error: " + result.message); } + } catch (error) { + console.error("Error:", error); + alert("Hubo un problema al registrar el usuario."); + } } async function loadUsersTable() { - try { - const result = await fetch('http://localhost:5033/users', { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - } - }); - - if (result.ok) { - const users = await result.json(); - - const userTable = document.getElementById('userTable'); - userTable.innerHTML = ''; - - users.forEach(user => { - const row = document.createElement('tr'); - - const addressCell = document.createElement('td'); - addressCell.textContent = user.address; - - const fullNameCell = document.createElement('td'); - fullNameCell.textContent = `${user.firstName} ${user.lastName}`; - - const phoneCell = document.createElement('td'); - phoneCell.textContent = user.phoneNumber || 'Sin teléfono'; - - const actionsCell = document.createElement('td'); - const editButton = document.createElement('button'); - editButton.className = 'btn btn-info btn-sm me-2'; - editButton.textContent = 'Editar'; - editButton.onclick = () => { - window.location.href = "/users/add"; - }; - - const deactivateButton = document.createElement('button'); - deactivateButton.className = 'btn btn-outline-secondary btn-sm'; - deactivateButton.textContent = 'Desactivar'; - deactivateButton.onclick = () => { - - }; - - actionsCell.appendChild(editButton); - actionsCell.appendChild(deactivateButton); - - row.appendChild(addressCell); - row.appendChild(fullNameCell); - row.appendChild(phoneCell); - row.appendChild(actionsCell); - - userTable.appendChild(row); - }); - } else { - console.error('Error al cargar la lista de usuarios'); - } - } catch (error) { - console.error('Error al cargar usuarios:', error); + try { + const result = await fetch("http://localhost:5033/users", { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + + if (result.ok) { + const users = await result.json(); + + const userTable = document.getElementById("userTable"); + userTable.innerHTML = ""; + + users.forEach((user) => { + const row = document.createElement("tr"); + + const addressCell = document.createElement("td"); + addressCell.textContent = user.address; + + const fullNameCell = document.createElement("td"); + fullNameCell.textContent = `${user.firstName} ${user.lastName}`; + + const phoneCell = document.createElement("td"); + phoneCell.textContent = user.phoneNumber || "Sin teléfono"; + + const actionsCell = document.createElement("td"); + const editButton = document.createElement("button"); + editButton.className = "btn btn-info btn-sm me-2"; + editButton.textContent = "Editar"; + editButton.onclick = () => { + window.location.href = "/users/add"; + }; + + const deactivateButton = document.createElement("button"); + deactivateButton.className = "btn btn-outline-secondary btn-sm"; + deactivateButton.textContent = "Desactivar"; + deactivateButton.onclick = () => {}; + + actionsCell.appendChild(editButton); + actionsCell.appendChild(deactivateButton); + + row.appendChild(addressCell); + row.appendChild(fullNameCell); + row.appendChild(phoneCell); + row.appendChild(actionsCell); + + userTable.appendChild(row); + }); + } else { + console.error("Error al cargar la lista de usuarios"); } + } catch (error) { + console.error("Error al cargar usuarios:", error); + } } -window.addEventListener('DOMContentLoaded', (event) => { - if (document.getElementById('userTable')) { - loadUsersTable(); - } +window.addEventListener("DOMContentLoaded", (event) => { + if (document.getElementById("userTable")) { + loadUsersTable(); + } }); - From c713cc65b7e6a469c28848865a2c95addbd206b4 Mon Sep 17 00:00:00 2001 From: IvanJGG Date: Fri, 14 Feb 2025 17:03:27 -0600 Subject: [PATCH 3/4] CAF-32 correct extra test --- tests/cypress/e2e/users.cy.js | 196 ---------------------------------- 1 file changed, 196 deletions(-) delete mode 100644 tests/cypress/e2e/users.cy.js diff --git a/tests/cypress/e2e/users.cy.js b/tests/cypress/e2e/users.cy.js deleted file mode 100644 index 98fefdc..0000000 --- a/tests/cypress/e2e/users.cy.js +++ /dev/null @@ -1,196 +0,0 @@ -describe("Users", () => { - beforeEach(() => { - cy.intercept( - { method: "GET", url: "/roles/" }, - { - statusCode: 200, - body: [ - { id: 1, name: "Administrador" }, - { id: 2, name: "Usuario" }, - ], - }, - ).as("getRoles"); - - cy.intercept("GET", "addresses", { - statusCode: 200, - body: [ - { id: 1, street: "Calle Principal", number: "101" }, - { id: 2, street: "Calle Secundaria", number: "202" }, - { id: 3, street: "Calle Tercera", number: "303" }, - ], - }).as("getAddresses"); - - cy.intercept( - { method: "POST", url: "users/register" }, - { - statusCode: 200, - body: { - message: "OK", - }, - }, - ).as("registerUser"); - }); - - it("should create a new user successfully", () => { - cy.visit("http://localhost/users/add?disable-twig-cache=true"); - - cy.wait("@getAddresses"); - - cy.fixture("user.json").then((user) => { - cy.get("[name=email]") - .should("have.id", "txtEmail") - .should("have.attr", "type", "email") - .should("have.attr", "required", "required") - .type(user.email); - cy.get("[name=firstName]") - .should("have.id", "txtFirstName") - .should("have.attr", "type", "text") - .should("have.attr", "required", "required") - .type(user.firstName); - cy.get("[name=secondName]") - .should("have.id", "txtSecondName") - .should("have.attr", "type", "text") - .should("not.have.attr", "required", "required") - .type(user.secondName); - cy.get("[name=firstSurname]") - .should("have.id", "txtFirstSurname") - .should("have.attr", "type", "text") - .should("have.attr", "required", "required") - .type(user.firstSurname); - cy.get("[name=secondSurname]") - .should("have.id", "txtSecondSurname") - .should("have.attr", "type", "text") - .should("not.have.attr", "required", "required") - .type(user.secondSurname); - cy.get("[name=password]") - .should("have.id", "txtPassword") - .should("have.attr", "type", "password") - .should("have.attr", "required", "required") - .type(user.password); - - cy.get("[name=phone]") - .should("have.id", "txtPhone") - .should("have.attr", "type", "tel") - .should("have.attr", "required", "required") - .should("have.attr", "maxlength", "10") - .type(user.phone); - cy.get("#txtAddress").select("Calle Tercera 303"); - - cy.wait("@getRoles"); - - cy.get("#txtRole") - .find("option") - .should("have.length", 3) - .then((options) => { - expect(options[1].text).to.equal("Administrador"); - expect(options[2].text).to.equal("Usuario"); - }); - - cy.get("#txtRole").select("Administrador"); - - cy.get("[type=submit]").click(); - - cy.wait("@registerUser"); - }); - }); - - it("should update an existing user successfully", () => { - const id = 1; - cy.fixture("update_user.json").then((fakeUser) => { - cy.intercept( - { method: "GET", url: `users/${id}` }, - { - statusCode: 200, - body: { - message: "OK", - user: fakeUser, - }, - }, - ).as("getUser"); - - cy.intercept( - { method: "PATCH", url: `users/${id}` }, - { - statusCode: 200, - body: { - message: "Usuario actualizado correctamente", - }, - }, - ).as("updateUser"); - - cy.visit(`http://localhost/users/add/?id=${id}&disable-twig-cache=true`); - - cy.wait("@getAddresses"); - cy.wait("@getUser"); - //Verificar que todos los campos tengas los valores de fakeUser - - cy.get("#txtEmail").should("have.value", fakeUser.email); - cy.get("#txtFirstName").should("have.value", fakeUser.firstName); - cy.get("#txtSecondName").should("have.value", fakeUser.secondName); - cy.get("#txtFirstSurname").should("have.value", fakeUser.lastname); - cy.get("#txtSecondSurname").should("have.value", fakeUser.secondLastname); - cy.get("#txtPhone").should("have.value", fakeUser.phoneNumber); - cy.get("#txtAddress").should("have.value", fakeUser.address); - - cy.get("#txtEmail") - .clear() - .type("ivan@example.com") - .should("have.value", "ivan@example.com"); - cy.get("#txtFirstName") - .clear() - .type("John Doe") - .should("have.value", "John Doe"); - - cy.get("#txtPassword").should("not.exist"); - - cy.wait("@getRoles"); - - cy.get("#txtRole") - .find("option") - .should("have.length", 3) - .then((options) => { - expect(options[1].text).to.equal("Administrador"); - expect(options[2].text).to.equal("Usuario"); - }); - - cy.get("#txtRole").select("Administrador"); - - cy.get("[type=submit]").click(); - - cy.wait("@updateUser"); - - cy.location("pathname").should("eq", "/users/"); - }); - }); - - it("should load the addresses into the dropdown", () => { - cy.visit("http://localhost/users/add?disable-twig-cache=true"); - - cy.wait("@getAddresses"); - - cy.get("#txtAddress") - .find("option") - .should("have.length", 4) - .then((options) => { - expect(options[0].textContent).to.eq("Selecciona una dirección"); - expect(options[1].textContent).to.eq("Calle Principal 101"); - expect(options[2].textContent).to.eq("Calle Secundaria 202"); - expect(options[3].textContent).to.eq("Calle Tercera 303"); - }); - }); - - it("should have the correct values in the dropdown", () => { - cy.visit("http://localhost/users/add?disable-twig-cache=true"); - - cy.wait("@getAddresses"); - - cy.get("#txtAddress") - .find("option") - .then((options) => { - expect(options).to.have.length(4); - expect(options[1].value).to.eq("Calle Principal 101"); - expect(options[2].value).to.eq("Calle Secundaria 202"); - expect(options[3].value).to.eq("Calle Tercera 303"); - }); - }); -}); From a22372a5431d41e10446e7298d7ddcc68728dbae Mon Sep 17 00:00:00 2001 From: IvanJGG Date: Fri, 14 Feb 2025 17:13:07 -0600 Subject: [PATCH 4/4] CAF-32 correct extra script --- views/users/script.js | 116 ------------------------------------------ 1 file changed, 116 deletions(-) delete mode 100644 views/users/script.js diff --git a/views/users/script.js b/views/users/script.js deleted file mode 100644 index 2fbc6bb..0000000 --- a/views/users/script.js +++ /dev/null @@ -1,116 +0,0 @@ -window.addEventListener("load", async (event) => { - let id = document.getElementById("txtId").value; - if (id) { - const result = await fetch(`http://localhost:5033/users/${id}`, { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - }); - let response = await result.json(); - let user = response.user; - document.getElementById("txtEmail").value = user.email; - document.getElementById("txtFirstName").value = user.firstName; - document.getElementById("txtSecondName").value = user.secondName; - document.getElementById("txtFirstSurname").value = user.lastname; - document.getElementById("txtSecondSurname").value = user.secondLastname; - document.getElementById("txtPhone").value = user.phoneNumber; - document.getElementById("txtAddress").value = user.address; - } -}); -async function handleSubmit(e, form) { - e.preventDefault(); - - const formData = new FormData(form); - - let jsonData = {}; - - formData.forEach(function (value, key) { - jsonData[key] = value; - }); - - try { - const response = await fetch("http://localhost:5033/users/register", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(jsonData), - }); - - const result = await response.json(); - - if (response.ok) { - alert("Usuario registrado con éxito"); - location.reload(); - } else { - alert("Error: " + result.message); - } - } catch (error) { - console.error("Error:", error); - alert("Hubo un problema al registrar el usuario."); - } -} -async function loadUsersTable() { - try { - const result = await fetch("http://localhost:5033/users", { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - }); - - if (result.ok) { - const users = await result.json(); - - const userTable = document.getElementById("userTable"); - userTable.innerHTML = ""; - - users.forEach((user) => { - const row = document.createElement("tr"); - - const addressCell = document.createElement("td"); - addressCell.textContent = user.address; - - const fullNameCell = document.createElement("td"); - fullNameCell.textContent = `${user.firstName} ${user.lastName}`; - - const phoneCell = document.createElement("td"); - phoneCell.textContent = user.phoneNumber || "Sin teléfono"; - - const actionsCell = document.createElement("td"); - const editButton = document.createElement("button"); - editButton.className = "btn btn-info btn-sm me-2"; - editButton.textContent = "Editar"; - editButton.onclick = () => { - window.location.href = "/users/add"; - }; - - const deactivateButton = document.createElement("button"); - deactivateButton.className = "btn btn-outline-secondary btn-sm"; - deactivateButton.textContent = "Desactivar"; - deactivateButton.onclick = () => {}; - - actionsCell.appendChild(editButton); - actionsCell.appendChild(deactivateButton); - - row.appendChild(addressCell); - row.appendChild(fullNameCell); - row.appendChild(phoneCell); - row.appendChild(actionsCell); - - userTable.appendChild(row); - }); - } else { - console.error("Error al cargar la lista de usuarios"); - } - } catch (error) { - console.error("Error al cargar usuarios:", error); - } -} - -window.addEventListener("DOMContentLoaded", (event) => { - if (document.getElementById("userTable")) { - loadUsersTable(); - } -});