diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b5fc7c..3da7faf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,3 +18,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [unreleased]: https://github.com/frlp-utn-ingsoft/shopp/compare/v1.0.0...HEAD [1.0.0]: https://github.com/frlp-utn-ingsoft/shopp/releases/tag/v1.0.0 + +## [1.2.6] - 2022-06-22 + +### Added +Footer con datos de contacto +Descripción de todos los producto + + +### Fixed: +Se añadió la traducción de las categorías +Se anadió el mensaje de carrito vacío +Se eliminó el botón anterior de la primer página +Se eliminó el botón siguiente de la última página +Se corrigió el bug del package de deploy +Se corrigieron las dependencias a utilizar + +### Metrics: +Performance inicial: 87% / Performance final: 100% +Accessibility inicial: 91% / Accessibility final: 100% +Best Practices inicial: 83% / Best Practices final: 100% +SEO inicial: 92% / SEO final: 92% diff --git a/fixtures/products.json b/fixtures/products.json index 6c8111a..3d0da31 100644 --- a/fixtures/products.json +++ b/fixtures/products.json @@ -3,72 +3,84 @@ "discount": 5, "name": "Placard", "price": 50000, + "description":"Placard de algarrobo de 1.90 x 0.30 x 2.5", "type": "home" }, { "discount": 10, "name": "Mesa", "price": 25000, + "description":"Mesa de pino de 1.60 x 0.80", "type": "home" }, { "discount": 0, "name": "Silla", "price": 5000, + "description":"Silla de pino 'confy', ideal para el estudiante", "type": "home" }, { "discount": 0, "name": "Mesa de Luz", "price": 8000, + "description":"Mesa de pino de 1.60 x 0.80", "type": "home" }, { "discount": 0, "name": "Sillon", "price": 85000, + "description":"Sillon sofa 2 cuerpos", "type": "home" }, { "discount": 0, "name": "Cama", "price": 45000, + "description":"Cama dos plazas king", "type": "home" }, { "discount": 0, "name": "Rack TV", "price": 25000, + "description":"Rack TV nordico ", "type": "home" }, { "discount": 0, "name": "TV", "price": 55000, + "description":"Smart TV 45 pulgadas", "type": "electronics" }, { "discount": 0, "name": "PS4", "price": 75000, + "description":"Sony PS4 edición Destiny - Incluye destiny 2 de regalo", "type": "electronics" }, { "discount": 0, "name": "PS5", "price": 175000, + "description":"Nueva PS5 con 3 juegos de regalo. Edición física", "type": "electronics" }, { "discount": 0, "name": "Barra de sonido", "price": 35000, + "description": "Barra de sonido Skull Candy con bluetoth de última generación", "type": "electronics" }, { "discount": 0, "name": "Laptop", "price": 350000, + "description": "Laptop MSI de 15.2 pulgadas, intel core I7, 16 GB de ram y placa de video Nvidia GTX 1660", "type": "electronics" } ] diff --git a/package-lock.json b/package-lock.json index b9c8f7b..0611860 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "body-parser": "^1.20.0", "cypress": "^9.7.0", + "detect-port": "^1.3.0", "express": "^4.18.1", "jest-environment-jsdom": "^28.1.0", "morgan": "^1.10.0", @@ -23,7 +24,6 @@ "@testing-library/dom": "^8.13.0", "@testing-library/jest-dom": "^5.16.4", "babel-jest": "^28.1.0", - "detect-port": "^1.3.0", "eslint": "^8.15.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-jest": "^26.1.5", @@ -2214,7 +2214,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/address/-/address-1.2.0.tgz", "integrity": "sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig==", - "dev": true, "engines": { "node": ">= 10.0.0" } @@ -3954,7 +3953,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", - "dev": true, "dependencies": { "address": "^1.0.1", "debug": "^2.6.0" @@ -3971,7 +3969,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -3979,8 +3976,7 @@ "node_modules/detect-port/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "node_modules/diff-sequences": { "version": "27.5.1", @@ -14399,8 +14395,7 @@ "address": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/address/-/address-1.2.0.tgz", - "integrity": "sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig==", - "dev": true + "integrity": "sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig==" }, "agent-base": { "version": "6.0.2", @@ -15714,7 +15709,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", - "dev": true, "requires": { "address": "^1.0.1", "debug": "^2.6.0" @@ -15724,7 +15718,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -15732,8 +15725,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, diff --git a/package.json b/package.json index d7d237d..4884644 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "src/index.js", "scripts": { "db:fixture": "node ./fixtures/index.js", - "start": "node ./src/index.js", + "start": "node ./fixtures/index.js && node ./src/index.js", "dev": "nodemon ./src/index.js -e js,css,html", "test": "jest", "test:coverage": "jest --collectCoverage", @@ -33,14 +33,14 @@ "morgan": "^1.10.0", "nunjucks": "^3.2.3", "sequelize": "^6.19.0", - "sqlite3": "^5.0.8" + "sqlite3": "^5.0.8", + "detect-port": "^1.3.0" }, "devDependencies": { "@lhci/cli": "^0.9.0", "@testing-library/jest-dom": "^5.16.4", "@testing-library/dom": "^8.13.0", "babel-jest": "^28.1.0", - "detect-port": "^1.3.0", "eslint": "^8.15.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-jest": "^26.1.5", diff --git a/src/models/product.js b/src/models/product.js index 1ec4c23..446b3a4 100644 --- a/src/models/product.js +++ b/src/models/product.js @@ -26,6 +26,10 @@ const Product = db.define( allowNull: false, values: ProductType.types, }, + description : { + type: Sequelize.STRING, + allowNull: false, + }, discount: { type: Sequelize.NUMBER, allowNull: false, @@ -85,8 +89,9 @@ const createProduct = ({ price = 0.0, type = ProductType.HOME, discount = 0.0, + description ='', } = {}) => { - return Product.create({ name, price, type, discount }); + return Product.create({ name, price, type, discount, description }); }; /** @@ -97,12 +102,12 @@ const createProduct = ({ */ const updateProduct = async ( id, - { name = '', price = 0.0, type = ProductType.HOME, discount = 0.0 } = {} + { name = '', price = 0.0, type = ProductType.HOME, discount = 0.0, description='' } = {} ) => { const product = await findById(id); if (product != null) { - return product.update({ name, price, type, discount }); + return product.update({ name, price, type, discount, description }); } return null; }; diff --git a/src/public/css/style.css b/src/public/css/style.css index 0a86094..44daa24 100644 --- a/src/public/css/style.css +++ b/src/public/css/style.css @@ -25,3 +25,48 @@ body { list-style: none; display: flex; } + +footer{ + width: 100%; + padding: 50px 0px; +} + +.container_footer{ + display: flex; + flex-wrap: wrap; + justify-content: space-between; + max-width: 1200px; + margin: auto; + margin-top: 10px; +} + +.box__footer{ + display: flex; + flex-direction: column; + padding: 40px; + +} + +.box__footer h2{ + margin-bottom: 30px; + color:black; + font-weight: 700; +} + +.box__footer p{ + margin-top: 10px; + color: black; + font-weight: 600; +} + +.box__footer p:hover{ + opacity: 0.8; +} + +p { + color: black; +} + +.black { + color: black; +} \ No newline at end of file diff --git a/src/views/_nav.html b/src/views/_nav.html index 35e7308..2e028ed 100644 --- a/src/views/_nav.html +++ b/src/views/_nav.html @@ -11,14 +11,14 @@ aria-describedby="search-btn"> - Carrito + Carrito diff --git a/src/views/_pagination.html b/src/views/_pagination.html index 4bde4b5..34219ab 100644 --- a/src/views/_pagination.html +++ b/src/views/_pagination.html @@ -2,7 +2,9 @@ diff --git a/src/views/_product-card.html b/src/views/_product-card.html index f3126b5..3c7c06c 100644 --- a/src/views/_product-card.html +++ b/src/views/_product-card.html @@ -2,21 +2,30 @@
foto de un {{ product.name }}
{{ product.name }}

- {{ product.type }} + + {% if product.type == 'home' %} + Hogar + {% elif product.type == 'electronics'%} + Electrónicos + {% endif %} +

+

{{ product.description }}

$ {{ product.price }}

{% if (product.discount > 0) %} -

{{ product.discount }} %

+

{{ product.discount }} %

{% endif %}
@@ -25,7 +34,7 @@
{{ product.name }}
{% if (not product.CartProduct ) %}
- +
{% else %}
diff --git a/src/views/cart.html b/src/views/cart.html index 2c70a21..c6d03a5 100644 --- a/src/views/cart.html +++ b/src/views/cart.html @@ -6,12 +6,30 @@
{% for product in products %} {{ productCard.productCard(product) }} - {% endfor %} + {% endfor %}
+ +{% if (products.length == 0)%} +

No posee productos en el carritos

+{% else %}
-
+
Total $ {{ cart.total }}
+{% endif %} +
+ +
+
+
+
{% endblock %} diff --git a/src/views/home.html b/src/views/home.html index 83ee750..5a0d2f5 100644 --- a/src/views/home.html +++ b/src/views/home.html @@ -16,4 +16,19 @@ _pagination.pagination(pagination.totalPages, pagination.currentPage) }}
+
+ +
{% endblock %} diff --git a/tests/e2e/specs/cart.spec.js b/tests/e2e/specs/cart.spec.js index a70de47..9ed2b6f 100644 --- a/tests/e2e/specs/cart.spec.js +++ b/tests/e2e/specs/cart.spec.js @@ -53,4 +53,22 @@ describe('Cart', () => { cy.get('.product:nth-child(2) [data-testid="discount"]') .should('have.text', '10 %') }); + + it('Deberia mostrar un mensaje si el carrito no contiene ningín Item', () => { + cy.visit('/cart'); + + cy.get('h2').should( + 'contain.text', + 'No posee productos en el carrito' + ); + }); + + it('Debería contener el footer', () => { + cy.visit('/cart'); + cy.get('footer').should( + 'contain.text', + 'shopp@gmail.com' + ); + }); + }); diff --git a/tests/e2e/specs/home.spec.js b/tests/e2e/specs/home.spec.js index 56e5703..0ffdce7 100644 --- a/tests/e2e/specs/home.spec.js +++ b/tests/e2e/specs/home.spec.js @@ -44,4 +44,12 @@ describe('Home Test', () => { .should('contain.text', '5 %'); }); + it('Debería contener el footer', () => { + cy.visit('/'); + cy.get('footer').should( + 'contain.text', + 'shopp@gmail.com' + ); + }); + }); diff --git a/tests/unit/models/product.spec.js b/tests/unit/models/product.spec.js index 85b6190..0bcd298 100644 --- a/tests/unit/models/product.spec.js +++ b/tests/unit/models/product.spec.js @@ -10,6 +10,7 @@ test('Crear producto', async () => { price: 50000.0, type: ProductType.HOME, name: 'Placard', + description:'test', }; // Creamos el producto @@ -18,6 +19,7 @@ test('Crear producto', async () => { expect(product.price).toBe(productData.price); expect(product.type).toBe(productData.type); expect(product.name).toBe(productData.name); + expect(product.description).toBe(productData.description); }); test('Crear producto sin tipo', async () => { @@ -32,7 +34,7 @@ test('Crear producto sin tipo', async () => { expect(product.price).toBe(productData.price); expect(product.type).toBe(ProductType.HOME); expect(product.name).toBe(productData.name); -}); + }); test('Listar productos sin resultados', async () => { const products = await ProductModel.getAll(); diff --git a/tests/unit/ui/pagination.spec.js b/tests/unit/ui/pagination.spec.js index a8badfd..451c8c1 100644 --- a/tests/unit/ui/pagination.spec.js +++ b/tests/unit/ui/pagination.spec.js @@ -4,7 +4,7 @@ const utils = require('../../ui-utils.js') -const { getByText } = require('@testing-library/dom'); +const { getByText, TestingLibraryElementError } = require('@testing-library/dom'); require('@testing-library/jest-dom'); function renderPagination(pagination) { @@ -85,4 +85,18 @@ describe('Paginación', () => { expect(prevLink).toBeVisible(); expect(prevLink.getAttribute('href')).toBe(`?page=${pagination.currentPage - 1}`); }); + + test('No debería mostrarse el boton anterior en la primera página', async () => { + const pagination = { + totalPages: 10, + currentPage: 1 + } + const html = renderPagination(pagination); + + document.body.innerHTML = html; + + expect(() => { + getByText(document.body, '< Anterior');}).toThrowError(TestingLibraryElementError); + }); + }); diff --git a/tests/unit/ui/product-card.spec.js b/tests/unit/ui/product-card.spec.js index 666b300..b039bf8 100644 --- a/tests/unit/ui/product-card.spec.js +++ b/tests/unit/ui/product-card.spec.js @@ -41,7 +41,7 @@ describe('Tarjeta de producto', () => { }); document.body.innerHTML = html; - expect(getByText(document.body, 'home')).toBeVisible(); + expect(getByText(document.body, 'Hogar')).toBeVisible(); }); test('Deberia tener el precio del producto', async () => { @@ -128,4 +128,31 @@ describe('Tarjeta de producto', () => { getByTestId(document.body, 'discount'); }).toThrowError(TestingLibraryElementError) }); + test('Deberia tener el tipo de producto traducido al español', async () => { + const product = { + name: 'Placard', + type: 'home', + price: 50000, + }; + const html = renderProduct(product); + document.body.innerHTML = html; + + const btn = getByText(document.body, 'Hogar'); + expect(btn).toBeVisible(); + + }); + + + test('Deberia tener la descripcion del producto', async () => { + const html = renderProduct({ + name: 'Placard', + type: 'home', + price: 100, + description: 'ejemplo', + }); + document.body.innerHTML = html; + + expect(getByText(document.body, 'ejemplo')).toBeVisible(); + }); + });