From fdfe7491343fa15a048526ad1d80183cb829e041 Mon Sep 17 00:00:00 2001 From: JAVI Date: Mon, 26 Feb 2024 12:56:49 +0100 Subject: [PATCH 01/27] primera modificacion --- .gitignore | 29 +++++ package.json | 20 +++ src/config/db.js | 12 ++ src/controllers/productController.js | 174 +++++++++++++++++++++++++++ src/index.js | 18 +++ src/models/Product.js | 14 +++ src/routes/productRoutes.js | 29 +++++ 7 files changed, 296 insertions(+) create mode 100644 .gitignore create mode 100644 package.json create mode 100644 src/config/db.js create mode 100644 src/controllers/productController.js create mode 100644 src/index.js create mode 100644 src/models/Product.js create mode 100644 src/routes/productRoutes.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..980dd5c5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Node.js +node_modules/ +# npm +*.log +*.lock +npm-debug.log* +yarn-debug.log* +yarn-error.log* +package-lock.json +# Environment variables +.env +# Editor +.vscode/ +.idea/ +# Logs and databases +*.log +*.sqlite +*.sqlite3 +*.db +*.sql +# Build output +/build/ +/dist/ +/out/ +/public/ +/build-output/ +# OS-generated files +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..f2e2a44a --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "backend-project-break", + "version": "1.0.0", + "description": "Vamos a montar una tienda de ropa con un catálogo de productos y un dashboard para el administrador. Los productos se guardarán en una base de datos de mongo en Atlas. Podemos usar como referencia el pdf [web_ejemplo.pdf](web_ejemplo.pdf) que contiene un ejemplo de cómo podría ser la interfaz de la tienda y el dashboard.", + "main": "index.js", + "directories": { + "test": "test" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "dotenv": "16.4.5", + "express": "4.18.2", + "mongoose": "8.2.0" + } +} diff --git a/src/config/db.js b/src/config/db.js new file mode 100644 index 00000000..246f0347 --- /dev/null +++ b/src/config/db.js @@ -0,0 +1,12 @@ +const mongoose = require('mongoose'); +require('dotenv').config(); + +const dbConnection = async () => { + try { + await mongoose.connect(process.env.MONGO_URI) + console.log('Base de datos conectada con éxito') + } catch (error) { + console.log(error) + } +} +module.exports = dbConnection; \ No newline at end of file diff --git a/src/controllers/productController.js b/src/controllers/productController.js new file mode 100644 index 00000000..31de6af9 --- /dev/null +++ b/src/controllers/productController.js @@ -0,0 +1,174 @@ +const Product = require('../models/Product') + + +const htmlHead = ` + + + + + Document + + `; + +function getNavBar() { + html = `
+ + +

${product.name}

+ ${product.name} +

${product.description}

+

${product.price}€

+ Ver detalle + + + ` + } + return html; +} + +const ProductController = { + async showProducts(req, res) { + try { + // controlar con dashboard + const products = await Product.find(); + const productCards = getProductCards(products); + const html = htmlHead + getNavBar() + productCards + res.send(html); + } catch (error) { + console.error(error) + res.status(500).send('error de busqueda de productos') + } + }, + async showProductById(req, res) { + try { + // controlar con dashboard + const idProduct = req.params._id; + const product = await Product.findById(idProduct); + const productCards = getProductCards(product) + const html = htmlHead + getNavBar() + productCards + res.send(html); + + + } catch (error) { + console.error(error) + res.status(500).send('error de busqueda de producto por ID') + } + }, + async showNewProduct(req, res) { + try { + const form = ` +

Crear nuevo producto

+
+ +
+ +
+ +
+ +
+ + + +
+ +
+ + + `; + + html = htmlHead + getNavBar() + form + + res.send(html) + ; + + } catch (error) { + console.error(error) + res.status(500).send('error de articulo nuevo') + } + }, + async createProduct(req, res) { + + const product = await Product.create({ ...req.body }); + res.redirect('/products'); + + }, + async showEditProduct(req, res) { + try { + + + + } catch (error) { + console.error(error) + res.status(500).send('error de edicion articulo nuevo') + } + }, + + + async updateProduct(req, res) { + try { + const idProduct = req.params._id; + const updateProduct = await Product.findByIdAndUpdate( + id, { + name, + description, + imagen, + category, + size, + price + }, { new: true } + ) + res.send(updateProduct) + if (!updateProduct) { + return res.status(404).json({ mensaje: 'Product id not found' }) + } + + + + } catch (error) { + console.error(error) + res.status(500).send('error de actualización articulo') + } + }, + async deleteProduct(req, res) { + try { + + + + } catch (error) { + console.error(error) + res.status(500).send('error de eliminacion articulo') + } + } +} + + +module.exports = ProductController \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 00000000..9be8c26a --- /dev/null +++ b/src/index.js @@ -0,0 +1,18 @@ +const express = require('express'); +const dbConnection = require('./config/db'); +const app = express(); +require('dotenv').config(); + +const PORT = process.env.PORT || 3000 +const router = require('./routes/productRoutes.js'); + +app.use(express.json()); +app.use(express.urlencoded({ extended: true })) + +app.use('/', router); + +dbConnection() + +app.listen(PORT, () => { + console.log(`Express está escuchando en el puerto http://localhost:${PORT}`) +}) \ No newline at end of file diff --git a/src/models/Product.js b/src/models/Product.js new file mode 100644 index 00000000..56e54910 --- /dev/null +++ b/src/models/Product.js @@ -0,0 +1,14 @@ +const mongoose = require('mongoose'); + +const ProductSchema = new mongoose.Schema({ + name: String, + description: String, + image: String, + category: String, + size: String, + price: String +}, { timestamps: true }); + +const Product = mongoose.model('Product', ProductSchema); + +module.exports = Product \ No newline at end of file diff --git a/src/routes/productRoutes.js b/src/routes/productRoutes.js new file mode 100644 index 00000000..7888bd44 --- /dev/null +++ b/src/routes/productRoutes.js @@ -0,0 +1,29 @@ +const express = require('express'); +const router = express.Router(); +const ProductController = require('../controllers/productController.js'); +const Product = require('../models/Product.js') + +router.get('/', ProductController.showProducts); +router.get('/products', ProductController.showProducts); +router.get('/products/:productId', ProductController.showProductById); + +//router.get('/products/:category', ProductController.showProductCategory); + +// dashboard + +router.get('/dashboard', ProductController.showProducts); +router.get('/dashboard/new', ProductController.showNewProduct); + +router.post('/dashboard', ProductController.createProduct); +router.get('/dashboard/productId', ProductController.showProductById); + +router.get('/dashboard/:productId/edit', ProductController.showEditProduct); +router.put('/dashboard/:productId', ProductController.updateProduct); + + +router.delete('/dashboard/:productId/delete', ProductController.deleteProduct); + + + + +module.exports = router; \ No newline at end of file From 8d17707a375ce8abfb432d32919aad93f44953a0 Mon Sep 17 00:00:00 2001 From: JAVI Date: Mon, 26 Feb 2024 20:12:48 +0100 Subject: [PATCH 02/27] segunda modificacion --- src/controllers/productController.js | 88 ++++++++++++++++++++++------ src/index.js | 5 ++ src/routes/productRoutes.js | 3 +- 3 files changed, 75 insertions(+), 21 deletions(-) diff --git a/src/controllers/productController.js b/src/controllers/productController.js index 31de6af9..f8823310 100644 --- a/src/controllers/productController.js +++ b/src/controllers/productController.js @@ -6,13 +6,16 @@ const htmlHead = ` + Document `; +const htmlEnd = `` + function getNavBar() { html = `
- - ` } return html; } function getProductCards(products) { + console.log('products dash', dash) + let option; let html = `
`; + if (token){option = 'dashboard'}else{option = 'products'} for (let product of products) { html += `

${product.name}

${product.name} -

${product.description}

-

${product.price}€

- Ver detalle + Ver detalle +
` } @@ -55,30 +56,35 @@ function getProductCards(products) { } function getProductOneCard(product) { + let html = `

${product.name}

${product.name}

${product.description}

${product.price}€

- Ver detalle -
- - - ` - +

${product.size}

+

${product.category}

+ ` + if (token){ + html += ` + actualizar + eliminar + ` + } + + return html + '
'; } const ProductController = { async showProducts(req, res) { try { // controlar con dashboard - let path = req.path; - path.substr(0, 10) == '/dashboard' ? dash = true : dash = false - + console.log('showproducts token', token) + const products = await Product.find(); - const productCards = getProductCards(products); + const productCards = getProductCards(products, token); const html = htmlHead + getNavBar() + productCards + htmlEnd res.send(html); } catch (error) { @@ -89,11 +95,10 @@ const ProductController = { async showProductById(req, res) { try { // controlar con dashboard - let path = req.path; - path.substr(0, 10) == '/dashboard' ? dash = true : dash = false const idProduct = req.params.productId; - const product = [await Product.findById(idProduct)]; - const productCards = getProductCards(product) + const product = await Product.findById(idProduct); + console.log('product', product) + const productCards = getProductOneCard(product, token) const html = htmlHead + getNavBar() + productCards + htmlEnd res.send(html); @@ -108,7 +113,7 @@ const ProductController = { try { const form = `

Crear nuevo producto

-
+
@@ -132,7 +137,7 @@ const ProductController = {
- +
@@ -148,6 +153,23 @@ const ProductController = { res.status(500).send('error de articulo nuevo') } }, + async showProductCategory(req, res) { + try { + const tipo = req.params; + console.log('TIPO', tipo); + const productCategory = await Product.find({ category: tipo.category }); + console.log('productCategory', productCategory) + const productCards = getProductCards(productCategory); + const html = htmlHead + getNavBar() + productCards + htmlEnd + res.send(html); + + + } catch (error) { + console.error(error) + res.status(500).send('error de articulo nuevo') + } + + }, async createProduct(req, res) { const product = await Product.create({ ...req.body }); @@ -161,24 +183,28 @@ const ProductController = { const form = `

Actualizar producto

-
+
+ -
+ -
+ -
+ -
- + + + + - + +
`; @@ -209,21 +236,17 @@ const ProductController = { async updateProduct(req, res) { try { const idProduct = req.params.productId; + const pBody = req.body + console.log('pBody', pBody) const updateProduct = await Product.findByIdAndUpdate( - idProduct, { - name: req.body.name, - description: req.body.description, - image: req.body.image, - category: req.body.category, - size: req.body.size, - price: req.body.price - }, { new: true } - ) + idProduct, { pBody + }, { new: true }) console.log('UpDate', updateProduct); if (!updateProduct) { return res.status(404).json({ mensaje: 'Product id not found' }) } - res.send(updateProduct) + + res.redirect(`${idProduct}`) @@ -248,6 +271,15 @@ const ProductController = { console.error(error) res.status(500).send('error de eliminacion articulo') } + }, + async login(req, res){ + token = true; + res.redirect('/dashboard') + }, + + async logout(req, res){ + token=false; + res.redirect('/products') } } diff --git a/src/routes/productRoutes.js b/src/routes/productRoutes.js index cfbb6661..06d06228 100644 --- a/src/routes/productRoutes.js +++ b/src/routes/productRoutes.js @@ -1,27 +1,28 @@ const express = require('express'); const router = express.Router(); const ProductController = require('../controllers/productController.js'); -const Product = require('../models/Product.js') +const verifyToken = require('../middlewares/authControl.js') +let token; router.get('/', ProductController.showProducts); router.get('/products', ProductController.showProducts); router.get('/products/:productId', ProductController.showProductById); -//router.get('/products/:category', ProductController.showProductCategory); +router.get('/products/category/:category', ProductController.showProductCategory); // dashboard - -router.get('/dashboard', ProductController.showProducts); +router.get('/login', ProductController.login) +router.get('/dashboard', ProductController.showProducts); router.get('/dashboard/new', ProductController.showNewProduct); router.post('/dashboard', ProductController.createProduct); -router.get('/dashboard/productId', ProductController.showProductById); +router.get('/dashboard/:productId', ProductController.showProductById); -router.get('/dashboard/:productId/edit', ProductController.showEditProduct); +router.get('/dashboard/:productId/edit', ProductController.showEditProduct); router.post('/dashboard/:productId', ProductController.updateProduct); -router.get('/dashboard/:productId/delete', ProductController.deleteProduct); - +router.get('/dashboard/:productId/delete', ProductController.deleteProduct); +router.get('/logout', ProductController.logout) From 631ec6a3012c851de7b72028f6532380ca3c575b Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Tue, 27 Feb 2024 13:10:31 +0100 Subject: [PATCH 06/27] martes locos m --- src/middlewares/authControl.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/middlewares/authControl.js diff --git a/src/middlewares/authControl.js b/src/middlewares/authControl.js new file mode 100644 index 00000000..23767077 --- /dev/null +++ b/src/middlewares/authControl.js @@ -0,0 +1,11 @@ + +function verifyToken (req, res, next){ + const token = req.token; + console.log(token) + if(!token){ + res.send('token invalido') + } + next(); +} + +module.exports = verifyToken \ No newline at end of file From f189a7f86f3a9b97d0657985612c5e71b00e0366 Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Tue, 27 Feb 2024 19:10:00 +0100 Subject: [PATCH 07/27] working --- public/styles.css | 21 +++++- src/controllers/productController.js | 100 +++++++++++++++------------ 2 files changed, 77 insertions(+), 44 deletions(-) diff --git a/public/styles.css b/public/styles.css index fe6d4d9b..9f9ca9c7 100644 --- a/public/styles.css +++ b/public/styles.css @@ -136,7 +136,8 @@ a { } img { - width: 300px + width: 300px; + height: 300px; } h2{ @@ -163,6 +164,7 @@ h2{ .cardContainer { display: flex; justify-content: center; + flex-wrap: wrap; gap: 10px; } @@ -181,6 +183,8 @@ h2{ background-color:#1239ff; color: #fff; border-radius: 10px; + align-self: center; + border: none; } .formContainer{ display: flex; @@ -193,4 +197,19 @@ h2{ gap:5px; width: 300px; margin-top: 10px; +} + +.formcategory{ + display: flex; + flex-direction: column; + font-size: 12px; +} +input{ + border-radius: 10px; + padding: 5px; +} + +select{ + border-radius: 10px; + padding: 5px; } \ No newline at end of file diff --git a/src/controllers/productController.js b/src/controllers/productController.js index 22d78bf9..f5a81c7a 100644 --- a/src/controllers/productController.js +++ b/src/controllers/productController.js @@ -1,5 +1,5 @@ const Product = require('../models/Product') -let dash, token; +let token; const htmlHead = ` @@ -38,7 +38,7 @@ function getNavBar() { } function getProductCards(products) { - console.log('products dash', dash) + let option; let html = `
`; if (token){option = 'dashboard'}else{option = 'products'} @@ -62,11 +62,10 @@ function getProductOneCard(product) {

${product.name}

${product.name}

${product.description}

-

${product.price}€

-

${product.size}

-

${product.category}

+

Precio: ${product.price}€

+

Talla: ${product.size.toString().toUpperCase()}

+

Categoria: ${product.category}

` - if (token){ html += ` actualizar @@ -81,8 +80,7 @@ const ProductController = { async showProducts(req, res) { try { // controlar con dashboard - console.log('showproducts token', token) - + const products = await Product.find(); const productCards = getProductCards(products, token); const html = htmlHead + getNavBar() + productCards + htmlEnd @@ -97,7 +95,7 @@ const ProductController = { // controlar con dashboard const idProduct = req.params.productId; const product = await Product.findById(idProduct); - console.log('product', product) + const productCards = getProductOneCard(product, token) const html = htmlHead + getNavBar() + productCards + htmlEnd @@ -113,15 +111,16 @@ const ProductController = { try { const form = `

Crear nuevo producto

+
-
+ -
+ -
+ -
+ - + - - - - - - + + +
+

Categoria:

+ + + + + + + + + + +

+
+

Tallas:

+ + + + + + + + + + + + + + +

-
- +
`; html = htmlHead + getNavBar() + form + htmlEnd - res.send(html) @@ -237,11 +248,15 @@ const ProductController = { try { const idProduct = req.params.productId; const pBody = req.body - console.log('pBody', pBody) const updateProduct = await Product.findByIdAndUpdate( - idProduct, { pBody - }, { new: true }) - console.log('UpDate', updateProduct); + idProduct, { + name: pBody.name, + description: pBody.description, + category: pBody.category, + price: pBody.price, + image: pBody.image, + size: pBody.size + }, { new: true }) if (!updateProduct) { return res.status(404).json({ mensaje: 'Product id not found' }) } @@ -258,7 +273,6 @@ const ProductController = { async deleteProduct(req, res) { try { const idProduct = req.params.productId; - console.log('delete', req.params.productId) const deletedProduct = await Product.findByIdAndDelete(idProduct) if (!deletedProduct) { return res.status(404).json({ mensaje: 'Product with that idProduct not found' }) From 9ef6294f05f0d1abed7b6641d1591b69af867b4a Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Wed, 28 Feb 2024 09:57:01 +0100 Subject: [PATCH 08/27] update styles --- public/styles.css | 18 ++++++++++++------ src/controllers/productController.js | 3 +++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/public/styles.css b/public/styles.css index 9f9ca9c7..b6962ad2 100644 --- a/public/styles.css +++ b/public/styles.css @@ -130,7 +130,11 @@ table { } /*---------*/ - +body{ + font-family: "Poppins", sans-serif; + font-weight: 400; + font-style: normal; +} a { text-decoration: none; } @@ -141,8 +145,7 @@ img { } h2{ - font-size: 16px; - font-family:Verdana, Geneva, Tahoma, sans-serif; + font-size: 16px; font-weight: bold; text-align: center; @@ -152,8 +155,8 @@ h2{ display: flex; justify-content: center; padding: 15px; - background-color: #000; - gap: 10px; + background-color: #062acd; + gap: 15px; margin-bottom: 15px; } @@ -171,11 +174,14 @@ h2{ .productCard { display: flex; flex-direction: column; - border: 1px solid rgb(132, 131, 131); + border: 1px solid rgb(178, 176, 176); border-radius: 10px; width: 300px; padding: 10px; gap: 5px; + -webkit-box-shadow: 6px 6px 5px 0px rgba(128,126,128,1); + -moz-box-shadow: 6px 6px 5px 0px rgba(128,126,128,1); + box-shadow: 6px 6px 5px 0px rgba(128,126,128,1); } .boton{ diff --git a/src/controllers/productController.js b/src/controllers/productController.js index f5a81c7a..ecaa573b 100644 --- a/src/controllers/productController.js +++ b/src/controllers/productController.js @@ -7,6 +7,9 @@ const htmlHead = ` + + + Document `; From cf67f8f38e45ad8f32a6e8916fa271c5161018e2 Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Wed, 28 Feb 2024 12:13:20 +0100 Subject: [PATCH 09/27] updating testing --- package.json | 3 ++- public/styles.css | 25 +++++++++++++------- src/controllers/productController.js | 34 ++++++++++++++++++++-------- src/index.js | 2 +- src/routes/productRoutes.js | 4 +--- test/productController.test.js | 31 +++++++++++++++++++++++++ 6 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 test/productController.test.js diff --git a/package.json b/package.json index d01ad019..67bdf521 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "test": "test" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test": "jest", "dev": "nodemon src/index.js" }, "keywords": [], @@ -16,6 +16,7 @@ "dependencies": { "dotenv": "16.4.5", "express": "4.18.2", + "jest": "29.7.0", "mongoose": "8.2.0" }, "devDependencies": { diff --git a/public/styles.css b/public/styles.css index b6962ad2..d5e4ecc6 100644 --- a/public/styles.css +++ b/public/styles.css @@ -184,14 +184,7 @@ h2{ box-shadow: 6px 6px 5px 0px rgba(128,126,128,1); } -.boton{ - padding: 10px; - background-color:#1239ff; - color: #fff; - border-radius: 10px; - align-self: center; - border: none; -} + .formContainer{ display: flex; justify-content: center; @@ -218,4 +211,20 @@ input{ select{ border-radius: 10px; padding: 5px; +} +.containerBoton{ + display: flex; + justify-content: center; + gap: 10px; +} + +.boton{ + padding: 8px; + background-color:#1239ff; + color: #fff; + border-radius: 10px; + text-align: center; + border: none; + width: 100px; + } \ No newline at end of file diff --git a/src/controllers/productController.js b/src/controllers/productController.js index ecaa573b..fff0ae4d 100644 --- a/src/controllers/productController.js +++ b/src/controllers/productController.js @@ -41,7 +41,9 @@ function getNavBar() { } function getProductCards(products) { - + if (!products){ + throw new Error ('El producto esta vacio o nulo') + } let option; let html = `
`; if (token){option = 'dashboard'}else{option = 'products'} @@ -49,9 +51,10 @@ function getProductCards(products) { html += `

${product.name}

- ${product.name} + ${product.name} +
` } @@ -59,20 +62,24 @@ function getProductCards(products) { } function getProductOneCard(product) { - + if(!product){ + throw new Error ('El producto esta vacio o nulo') + } let html = `

${product.name}

- ${product.name} + ${product.name}

${product.description}

Precio: ${product.price}€

Talla: ${product.size.toString().toUpperCase()}

Categoria: ${product.category}

` if (token){ - html += ` + html += ` + ` } @@ -97,8 +104,11 @@ const ProductController = { try { // controlar con dashboard const idProduct = req.params.productId; - const product = await Product.findById(idProduct); + const product = await Product.findById(idProduct); + if(!product){ + throw new Error('El producto no exite') + } const productCards = getProductOneCard(product, token) const html = htmlHead + getNavBar() + productCards + htmlEnd @@ -278,7 +288,7 @@ const ProductController = { const idProduct = req.params.productId; const deletedProduct = await Product.findByIdAndDelete(idProduct) if (!deletedProduct) { - return res.status(404).json({ mensaje: 'Product with that idProduct not found' }) + throw new Error('Producto no encontrado') } let message = `

Producto eliminado correctamente

` html = htmlHead + getNavBar() + message + htmlEnd @@ -301,4 +311,8 @@ const ProductController = { } -module.exports = ProductController \ No newline at end of file +module.exports = { + ProductController, + getProductOneCard, + getProductCards +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index af026e63..f1ffca06 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ const express = require('express'); const dbConnection = require('./config/db'); const app = express(); -const path = require('path'); +const path = require('node:path'); require('dotenv').config(); diff --git a/src/routes/productRoutes.js b/src/routes/productRoutes.js index 06d06228..25525a50 100644 --- a/src/routes/productRoutes.js +++ b/src/routes/productRoutes.js @@ -1,8 +1,6 @@ const express = require('express'); const router = express.Router(); -const ProductController = require('../controllers/productController.js'); -const verifyToken = require('../middlewares/authControl.js') -let token; +const {ProductController} = require('../controllers/productController.js'); router.get('/', ProductController.showProducts); router.get('/products', ProductController.showProducts); diff --git a/test/productController.test.js b/test/productController.test.js new file mode 100644 index 00000000..abfa87dd --- /dev/null +++ b/test/productController.test.js @@ -0,0 +1,31 @@ +const {ProductController, getProductOneCard, getProductCards} = require('../src/controllers/productController'); + + + +describe('printing products', () =>{ + it('lanza error si el producto es nulo o vacio', () =>{ + expect(() => getProductCards('')).toThrow('El producto esta vacio o nulo') + }); + it('lanza error si el producto es nulo o vacio', () =>{ + expect(() => getProductOneCard('')).toThrow('El producto esta vacio o nulo') + }); + const product = { + name:'zapato', + description: 'zapato negro', + image:'http://imagen.com', + category: 'zapatos', + size: 'm', + price: '25' + } + it('controlar que pinta', () =>{ + expect(getProductOneCard(product)).toEqual(`
+
+

zapato

+ \"zapato\" +

zapato negro

+

Precio: 25€

+

Talla: M

+

Categoria: zapatos

+
`) + }) +}) \ No newline at end of file From 75708e64c73dba8095e2825bb474af217c9593fa Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Wed, 28 Feb 2024 19:33:39 +0100 Subject: [PATCH 10/27] updatin testing --- package.json | 2 +- src/config/db.js | 5 +++- src/controllers/productController.js | 9 ++++-- test/productController.test.js | 45 +++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 67bdf521..199f09cc 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,10 @@ "dependencies": { "dotenv": "16.4.5", "express": "4.18.2", - "jest": "29.7.0", "mongoose": "8.2.0" }, "devDependencies": { + "jest": "29.7.0", "nodemon": "3.1.0" } } diff --git a/src/config/db.js b/src/config/db.js index 246f0347..fe6f9a5a 100644 --- a/src/config/db.js +++ b/src/config/db.js @@ -3,7 +3,10 @@ require('dotenv').config(); const dbConnection = async () => { try { - await mongoose.connect(process.env.MONGO_URI) + await mongoose.connect(process.env.MONGO_URI, { + useNewUrlParser:true, //para utilizar el nuevo analizador de URL de mongo + useUnifiedTopology:true, // para utilizar la nueva capa de conexion + useCreateIndex:true}) console.log('Base de datos conectada con éxito') } catch (error) { console.log(error) diff --git a/src/controllers/productController.js b/src/controllers/productController.js index fff0ae4d..ae3cddac 100644 --- a/src/controllers/productController.js +++ b/src/controllers/productController.js @@ -89,9 +89,11 @@ function getProductOneCard(product) { const ProductController = { async showProducts(req, res) { try { - // controlar con dashboard - + // controlar con dashboard const products = await Product.find(); + if(!products){ + throw new Error('error de busqueda de productos') + } const productCards = getProductCards(products, token); const html = htmlHead + getNavBar() + productCards + htmlEnd res.send(html); @@ -184,6 +186,9 @@ const ProductController = { async createProduct(req, res) { const product = await Product.create({ ...req.body }); + if(!product){ + throw new Error('Error al añadir un articulo') + } res.redirect('/dashboard'); }, diff --git a/test/productController.test.js b/test/productController.test.js index abfa87dd..82e86fd7 100644 --- a/test/productController.test.js +++ b/test/productController.test.js @@ -1,6 +1,49 @@ const {ProductController, getProductOneCard, getProductCards} = require('../src/controllers/productController'); +const Product = require('../src/models/Product') +jest.setTimeout(30000) +describe('ProductController', () => { + const req ={}; + const res ={ + status: jest.fn(()=> res), + send: jest.fn(), + redirect: jest.fn() // jest.fn() para simular el comportamiento de una funcion + } + const product = { + name:'zapato', + description: 'zapato negro', + image:'http://imagen.com', + category: 'zapatos', + size: 'm', + price: '25' + } + + describe('showProducts', () =>{ + it('should retun all products', async()=>{ + await ProductController.showProducts(req, res); + expect(res.send).toHaveBeenCalled(); + }); + /* it('should handle errors', async()=>{ + const errorMessage = 'error de busqueda de productos'; + jest.spyOn(Product, 'find').mockRejectedValue(new Error(errorMessage)); + await ProductController.showProducts(req, res); + //expect(res.status).toHaveBeenCalled(500); + expect(res.send).toEqual(errorMessage); + })*/ + }) + + + /* + describe('createProduct', () =>{ + it('should create a new product', async () =>{ + req.body = product; + await ProductController.createProduct(req, res); + expect(Product.create).toEqual(product); + expect(res.redirect).toEqual('/dashboard') + }) + })*/ +}); describe('printing products', () =>{ it('lanza error si el producto es nulo o vacio', () =>{ @@ -17,7 +60,7 @@ describe('printing products', () =>{ size: 'm', price: '25' } - it('controlar que pinta', () =>{ + it('should print a product', () =>{ expect(getProductOneCard(product)).toEqual(`

zapato

From 65e00b4a4ca619ed877a362780c0e8548910ab6c Mon Sep 17 00:00:00 2001 From: JAVI Date: Thu, 29 Feb 2024 11:47:32 +0100 Subject: [PATCH 11/27] Working --- README2.md | 103 ++++++++++++++++++++++++++++++++++++++++++++++ public/styles.css | 55 ++++++++++++++++--------- 2 files changed, 138 insertions(+), 20 deletions(-) create mode 100644 README2.md diff --git a/README2.md b/README2.md new file mode 100644 index 00000000..35b9c028 --- /dev/null +++ b/README2.md @@ -0,0 +1,103 @@ +# Tienda de ropa + +En esta documentación vamos a explicar el funcionamiento de la tienda de ropa, las tecnologías usadas, endpoints, etc. + +## Índice + +-[Url donce está ubicada nuestra tienda](#URL-Tienda-de-ropa) +-[Funcionamiento de la tienda de ropa](#Funcionamiento-de-la-tienda-de-ropa) +-[Tecnologías usadas para crear esta tienda de ropa](#Tecnologias-usadas) +-[Endpoints utilizados para HTML](#Endpoints-html) +-[Endpoints utilizados para la API](#Endpoints-Api) + +## URL Tienda de ropa +Esta sería la URL donde está alojada la tienda: URL:http******** + +## Funcionamiento de la tienda de ropa + +Una vez que se accede a la url de la web, lo primero que nos vamos ha econtrar es una web con una barra de navegación, la cual consta de las siguientes categorías: + +-[Productos](#Categoría-Productos) +-[Camisetas](#Categoría-Camisetas) +-[Pantalones](#Categoría-Pantalones) +-[Zapatos](#Categoría-Zapatos) +-[Accesorios](#Categoría-Accesorios) +-[login](#Login) +-[La web Logeado](#La-web-Logeado) +-[Logeado Productos](#Logeado-Productos) +-[Botón Actualizar](#Botón-Actualizar) +-[Botón Eliminar](#Botón-Eliminar) +-[Opcion de crear nuevo producto](#Opción-de-crear-nuevo-producto) +-[Opción Logout](#Opción-Logout) + +### Categoría Productos + +En este apartado de la web, nos muestra todos los productos que existen en la web, cada producto tiene un botón para porde ver una vista detalle del producto en cuestión. + +### Categoría Camisetas + +En este apartado de la web, nos muestra solo los productos por camisetas que existan en nuestra web, también con su botón para acceder a su vista detalle. + +### Categoría Pantalones + +En este apartado de la web, nos muestra solo los productos por pantalones que existan en nuestra web, también su botón para acceder a su vista detalle. + +### Categoría Zapatos + +En este apartado de la web, nos muestra solo los productos por zapatos que existan en nuestra web, también su botón para acceder a su vista detalle. + +### Categoría Accesorios + +En este apartado de la web, nos muestra solo los productos por accesorios que existan en nuestra web, también su botón para acceder a su vista detalle. + +#### Login + +En este apartado tienes la opción de logearte en la web para poder acceder a ella con las funciones de administrador y así poder utilizar todas las opciones de Crear, buscar, modificar y borrar los artículos de la tienda. + +#### La web Logeado + +Cuando cliques en la opción de login, te saldrá una pantalla donde deberas introducir tu Usuário y contraseña de administrador de la web, esa pantalla comprueba que la información sea correcta, para poder entrar como administrador. +Una vez logeado te aparece una web con una barra de navegación arriba con; Productos, Camisetas, Pantalones, Zapatos, Accesorios, Nuevo Producto y Logout. + +#### Logeado Productos +A simple vista lo que se muestra es lo mismo que en la opción de inicio de productos pero una vez que presionas el botón Ver detalle, nos muestra una vista detalle del producto con dos botones más, botón Actualizar y Botón Eliminar. + +#### Botón Actualizar + +Una vez presionado este botón, nos muestra una web con la misma barra de navegación que cuando estás logeado y como cuerpo principal de la web un formulario de actualización del producto en cuestión con la información de ese producto y un botón de actualizar, uan vez hechos los cambios pertinentes en dicho producto al pinchar en el botón actualizar no vuelve a mostrar el producto en cuestión con su modificación ya realizada. +Esto es aplicable a todas las categorías de la web pantalones, camisetas, zapatos, accesorios. + + +#### Botón Eliminar + +Una vez pulsado el botón de eleminar, nos mostrará un mensaje el cual no dice que el producto se ha eliminado correctamente. Esto es aplicable a todas las categorías de la web pantalones, camisetas, zapatos, accesorios. + +#### Opción de crear nuevo producto + +Una vez de clicar en la opción de la barra de menus, Nuevo Producto, nos aparece una web cd crear producto con todos los campos para crear dicho producto y un botón de enviar, una vez que se han rellenado todos los campos del nuevo producto, al presionar el botón de enviar, nos redirecciona a la web principal donde nos muestra todos los productos incluido el nuevo producto. + +#### Opción Logout + +Una clicado esta opción, simplemente cerrará la sesón del usuario que estemos usando y nos llevará a la pagina principal de la web que es solo de consulta. + +## Tecnologias usadas + +Estas son las tecnologías o recursos utilizados para nuestra web. + +- [Express](https://expressjs.com/)(#Express) +- [Mongoose](https://mongoosejs.com/) +- [Atlas](https://www.mongodb.com/cloud/atlas) +- [Fl0](https://fl0.io/) +- [dotenv](https://www.npmjs.com/package/dotenv) +- [express-session](https://www.npmjs.com/package/express-session) +- [express.urlencoded](https://expressjs.com/en/api.html#express.urlencoded) +- [express.static](https://expressjs.com/en/api.html#express.static) +- [Template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) +- [Pug](https://pugjs.org/api/getting-started.html) +- [Firebase](https://firebase.google.com/) + - [Firebase Auth](https://firebase.google.com/docs/auth) + - [Get Started with Firebase Authentication on Websites](https://firebase.google.com/docs/auth/web/start) + + +## Endpoints html + diff --git a/public/styles.css b/public/styles.css index 9f9ca9c7..67df9f6b 100644 --- a/public/styles.css +++ b/public/styles.css @@ -130,6 +130,11 @@ table { } /*---------*/ +body { + font-family: "Poppins", sans-serif; + font-weight: 400; + font-style: normal; +} a { text-decoration: none; @@ -140,11 +145,9 @@ img { height: 300px; } -h2{ +h2 { font-size: 16px; - font-family:Verdana, Geneva, Tahoma, sans-serif; font-weight: bold; - text-align: center; } @@ -152,8 +155,8 @@ h2{ display: flex; justify-content: center; padding: 15px; - background-color: #000; - gap: 10px; + background-color: #062ACD; + gap: 15px; margin-bottom: 15px; } @@ -171,45 +174,57 @@ h2{ .productCard { display: flex; flex-direction: column; - border: 1px solid rgb(132, 131, 131); + border: 1px solid rgb(178, 176, 176); border-radius: 10px; width: 300px; padding: 10px; gap: 5px; + -webkit-box-shadow: 6px 6px 5px 0px rgba(128, 126, 128, 1); + -moz-box-shadow: 6px 6px 5px 0px rgba(128, 126, 128, 1); + box-shadow: 6px 6px 5px 0px rgba(128, 126, 128, 1); } -.boton{ - padding: 10px; - background-color:#1239ff; - color: #fff; - border-radius: 10px; - align-self: center; - border: none; -} -.formContainer{ +.formContainer { display: flex; justify-content: center; } -.formulario{ +.formulario { display: flex; flex-direction: column; - gap:5px; + gap: 5px; width: 300px; margin-top: 10px; } -.formcategory{ +.formcategory { display: flex; flex-direction: column; font-size: 12px; } -input{ + +input { border-radius: 10px; padding: 5px; } -select{ +select { border-radius: 10px; padding: 5px; +} + +.containerBoton { + display: flex; + justify-content: center; + gap: 10px; +} + +.boton { + padding: 8px; + background-color: #1239ff; + color: #fff; + border-radius: 10px; + text-align: center; + border: none; + width: 100px; } \ No newline at end of file From e970ff56623cf940fb5ec72ff3f04f24f95eb554 Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Thu, 29 Feb 2024 12:00:06 +0100 Subject: [PATCH 12/27] updating test --- src/controllers/productController.js | 4 +-- test/productController.test.js | 45 ++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/controllers/productController.js b/src/controllers/productController.js index ae3cddac..b32a8812 100644 --- a/src/controllers/productController.js +++ b/src/controllers/productController.js @@ -108,9 +108,7 @@ const ProductController = { const idProduct = req.params.productId; const product = await Product.findById(idProduct); - if(!product){ - throw new Error('El producto no exite') - } + const productCards = getProductOneCard(product, token) const html = htmlHead + getNavBar() + productCards + htmlEnd diff --git a/test/productController.test.js b/test/productController.test.js index 82e86fd7..be70efc1 100644 --- a/test/productController.test.js +++ b/test/productController.test.js @@ -1,3 +1,4 @@ +const { it } = require('node:test'); const {ProductController, getProductOneCard, getProductCards} = require('../src/controllers/productController'); const Product = require('../src/models/Product') @@ -19,18 +20,38 @@ describe('ProductController', () => { } describe('showProducts', () =>{ - it('should retun all products', async()=>{ + it('should return all products', async()=>{ await ProductController.showProducts(req, res); expect(res.send).toHaveBeenCalled(); }); - /* it('should handle errors', async()=>{ + it('should handle errors', async()=>{ const errorMessage = 'error de busqueda de productos'; jest.spyOn(Product, 'find').mockRejectedValue(new Error(errorMessage)); await ProductController.showProducts(req, res); - //expect(res.status).toHaveBeenCalled(500); - expect(res.send).toEqual(errorMessage); - })*/ + expect(res.status).toHaveBeenCalledWith(500); + expect(res.send).toHaveBeenCalledWith(errorMessage); + }) }) +/* + describe('showProductById', () =>{ + it('should return a product by id', async()=>{ + req.params = {productId: '65645121566'} + await ProductController.showProductById(req, res); + expect(res.send).toHaveBeenCalled(); + }); + it('should handle errors', async ()=>{ + req.params = {productId: ''}; + + const errorMessage = 'error de busqueda de producto por ID'; + jest.spyOn(Product, 'findById').mockRejectedValue(new Error(errorMessage)); + + await ProductController.showProductById(req, res); + expect(res.status).toHaveBeenCalledWith(500); + expect(res.send).toHaveBeenCalledWith(errorMessage); + }) + })*/ + + /* @@ -43,8 +64,22 @@ describe('ProductController', () => { }) })*/ + describe('updateProduct', () =>{ + it('should update a product', async() =>{ + req.params = {productId: '64643212154'}; + req.body = product; + + await ProductController.updateProduct(req, res); + expect(Product.findByIdAndUpdate).toHaveBeenCalledWith(req.params.productId, product,{ new: true } ) + expect(res.redirect).toHaveBeenCalledWith('64643212154') + + }) + }) + }); + + describe('printing products', () =>{ it('lanza error si el producto es nulo o vacio', () =>{ expect(() => getProductCards('')).toThrow('El producto esta vacio o nulo') From ebcb82bad135a378e55622b6bafe05a85e40b37c Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Thu, 29 Feb 2024 12:24:46 +0100 Subject: [PATCH 13/27] merging files --- public/styles.css | 41 ---------------------------------- test/productController.test.js | 7 ++---- 2 files changed, 2 insertions(+), 46 deletions(-) diff --git a/public/styles.css b/public/styles.css index b59fe35b..67df9f6b 100644 --- a/public/styles.css +++ b/public/styles.css @@ -130,20 +130,12 @@ table { } /*---------*/ -<<<<<<< HEAD body { font-family: "Poppins", sans-serif; font-weight: 400; font-style: normal; } -======= -body{ - font-family: "Poppins", sans-serif; - font-weight: 400; - font-style: normal; -} ->>>>>>> testing a { text-decoration: none; } @@ -153,13 +145,8 @@ img { height: 300px; } -<<<<<<< HEAD h2 { font-size: 16px; -======= -h2{ - font-size: 16px; ->>>>>>> testing font-weight: bold; text-align: center; } @@ -168,11 +155,7 @@ h2{ display: flex; justify-content: center; padding: 15px; -<<<<<<< HEAD background-color: #062ACD; -======= - background-color: #062acd; ->>>>>>> testing gap: 15px; margin-bottom: 15px; } @@ -196,22 +179,12 @@ h2{ width: 300px; padding: 10px; gap: 5px; -<<<<<<< HEAD -webkit-box-shadow: 6px 6px 5px 0px rgba(128, 126, 128, 1); -moz-box-shadow: 6px 6px 5px 0px rgba(128, 126, 128, 1); box-shadow: 6px 6px 5px 0px rgba(128, 126, 128, 1); } .formContainer { -======= - -webkit-box-shadow: 6px 6px 5px 0px rgba(128,126,128,1); - -moz-box-shadow: 6px 6px 5px 0px rgba(128,126,128,1); - box-shadow: 6px 6px 5px 0px rgba(128,126,128,1); -} - - -.formContainer{ ->>>>>>> testing display: flex; justify-content: center; } @@ -239,33 +212,19 @@ select { border-radius: 10px; padding: 5px; } -<<<<<<< HEAD .containerBoton { -======= -.containerBoton{ ->>>>>>> testing display: flex; justify-content: center; gap: 10px; } -<<<<<<< HEAD .boton { padding: 8px; background-color: #1239ff; -======= -.boton{ - padding: 8px; - background-color:#1239ff; ->>>>>>> testing color: #fff; border-radius: 10px; text-align: center; border: none; width: 100px; -<<<<<<< HEAD -======= - ->>>>>>> testing } \ No newline at end of file diff --git a/test/productController.test.js b/test/productController.test.js index be70efc1..4f0efd60 100644 --- a/test/productController.test.js +++ b/test/productController.test.js @@ -18,7 +18,7 @@ describe('ProductController', () => { size: 'm', price: '25' } - +/* describe('showProducts', () =>{ it('should return all products', async()=>{ await ProductController.showProducts(req, res); @@ -32,7 +32,7 @@ describe('ProductController', () => { expect(res.send).toHaveBeenCalledWith(errorMessage); }) }) -/* + describe('showProductById', () =>{ it('should return a product by id', async()=>{ req.params = {productId: '65645121566'} @@ -51,9 +51,6 @@ describe('ProductController', () => { }) })*/ - - - /* describe('createProduct', () =>{ it('should create a new product', async () =>{ From 65b519021572d7de1cc0e8de4ca5f8e6d7565635 Mon Sep 17 00:00:00 2001 From: JAVI Date: Thu, 29 Feb 2024 12:42:11 +0100 Subject: [PATCH 14/27] Working2 --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index 199f09cc..8d75f302 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "author": "", "license": "ISC", "dependencies": { + "buil": "^0.0.0", + "buildpack": "^0.0.1", "dotenv": "16.4.5", "express": "4.18.2", "mongoose": "8.2.0" From 9b6188b723ad60915ce754d379fb9e2c8595dfce Mon Sep 17 00:00:00 2001 From: JAVI Date: Thu, 29 Feb 2024 12:43:28 +0100 Subject: [PATCH 15/27] Working3 --- test/productController.test.js | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/test/productController.test.js b/test/productController.test.js index 4f0efd60..9b410d4e 100644 --- a/test/productController.test.js +++ b/test/productController.test.js @@ -1,7 +1,7 @@ const { it } = require('node:test'); -const {ProductController, getProductOneCard, getProductCards} = require('../src/controllers/productController'); +const { ProductController, getProductOneCard, getProductCards } = require('../src/controllers/productController'); const Product = require('../src/models/Product') - +/* jest.setTimeout(30000) describe('ProductController', () => { const req ={}; @@ -17,7 +17,7 @@ describe('ProductController', () => { category: 'zapatos', size: 'm', price: '25' - } + }*/ /* describe('showProducts', () =>{ it('should return all products', async()=>{ @@ -51,16 +51,16 @@ describe('ProductController', () => { }) })*/ - /* - describe('createProduct', () =>{ - it('should create a new product', async () =>{ - req.body = product; - await ProductController.createProduct(req, res); - expect(Product.create).toEqual(product); - expect(res.redirect).toEqual('/dashboard') - }) - })*/ - +/* +describe('createProduct', () =>{ + it('should create a new product', async () =>{ + req.body = product; + await ProductController.createProduct(req, res); + expect(Product.create).toEqual(product); + expect(res.redirect).toEqual('/dashboard') + }) +})*/ +/* describe('updateProduct', () =>{ it('should update a product', async() =>{ req.params = {productId: '64643212154'}; @@ -74,25 +74,25 @@ describe('ProductController', () => { }) }); +*/ - -describe('printing products', () =>{ - it('lanza error si el producto es nulo o vacio', () =>{ +describe('printing products', () => { + it('lanza error si el producto es nulo o vacio', () => { expect(() => getProductCards('')).toThrow('El producto esta vacio o nulo') }); - it('lanza error si el producto es nulo o vacio', () =>{ + it('lanza error si el producto es nulo o vacio', () => { expect(() => getProductOneCard('')).toThrow('El producto esta vacio o nulo') }); const product = { - name:'zapato', + name: 'zapato', description: 'zapato negro', - image:'http://imagen.com', + image: 'http://imagen.com', category: 'zapatos', size: 'm', price: '25' } - it('should print a product', () =>{ + it('should print a product', () => { expect(getProductOneCard(product)).toEqual(`

zapato

From 67eb4c282a4ec8cfa0b94abba8f99f93e71317b3 Mon Sep 17 00:00:00 2001 From: JAVI Date: Thu, 29 Feb 2024 12:56:05 +0100 Subject: [PATCH 16/27] Working4 --- src/controllers/productController.js | 52 ++++++++++++++-------------- src/index.js | 23 ------------ 2 files changed, 26 insertions(+), 49 deletions(-) delete mode 100644 src/index.js diff --git a/src/controllers/productController.js b/src/controllers/productController.js index b32a8812..870a74dc 100644 --- a/src/controllers/productController.js +++ b/src/controllers/productController.js @@ -41,12 +41,12 @@ function getNavBar() { } function getProductCards(products) { - if (!products){ - throw new Error ('El producto esta vacio o nulo') + if (!products) { + throw new Error('El producto esta vacio o nulo') } let option; let html = `
`; - if (token){option = 'dashboard'}else{option = 'products'} + if (token) { option = 'dashboard' } else { option = 'products' } for (let product of products) { html += `
@@ -62,8 +62,8 @@ function getProductCards(products) { } function getProductOneCard(product) { - if(!product){ - throw new Error ('El producto esta vacio o nulo') + if (!product) { + throw new Error('El producto esta vacio o nulo') } let html = `
@@ -74,7 +74,7 @@ function getProductOneCard(product) {

Talla: ${product.size.toString().toUpperCase()}

Categoria: ${product.category}

` - if (token){ + if (token) { html += `
actualizar @@ -82,7 +82,7 @@ function getProductOneCard(product) {
` } - + return html + '
'; } @@ -91,7 +91,7 @@ const ProductController = { try { // controlar con dashboard const products = await Product.find(); - if(!products){ + if (!products) { throw new Error('error de busqueda de productos') } const productCards = getProductCards(products, token); @@ -106,9 +106,9 @@ const ProductController = { try { // controlar con dashboard const idProduct = req.params.productId; - + const product = await Product.findById(idProduct); - + const productCards = getProductOneCard(product, token) const html = htmlHead + getNavBar() + productCards + htmlEnd @@ -168,23 +168,23 @@ const ProductController = { }, async showProductCategory(req, res) { try { - const tipo = req.params; + const tipo = req.params; const productCategory = await Product.find({ category: tipo.category }); const productCards = getProductCards(productCategory); const html = htmlHead + getNavBar() + productCards + htmlEnd res.send(html); - + } catch (error) { console.error(error) res.status(500).send('error de articulo nuevo') } - + }, async createProduct(req, res) { const product = await Product.create({ ...req.body }); - if(!product){ + if (!product) { throw new Error('Error al añadir un articulo') } res.redirect('/dashboard'); @@ -266,17 +266,17 @@ const ProductController = { const pBody = req.body const updateProduct = await Product.findByIdAndUpdate( idProduct, { - name: pBody.name, - description: pBody.description, - category: pBody.category, - price: pBody.price, - image: pBody.image, - size: pBody.size - }, { new: true }) + name: pBody.name, + description: pBody.description, + category: pBody.category, + price: pBody.price, + image: pBody.image, + size: pBody.size + }, { new: true }) if (!updateProduct) { return res.status(404).json({ mensaje: 'Product id not found' }) } - + res.redirect(`${idProduct}`) @@ -291,7 +291,7 @@ const ProductController = { const idProduct = req.params.productId; const deletedProduct = await Product.findByIdAndDelete(idProduct) if (!deletedProduct) { - throw new Error('Producto no encontrado') + throw new Error('Producto no encontrado') } let message = `

Producto eliminado correctamente

` html = htmlHead + getNavBar() + message + htmlEnd @@ -302,13 +302,13 @@ const ProductController = { res.status(500).send('error de eliminacion articulo') } }, - async login(req, res){ + async login(req, res) { token = true; res.redirect('/dashboard') }, - async logout(req, res){ - token=false; + async logout(req, res) { + token = false; res.redirect('/products') } } diff --git a/src/index.js b/src/index.js deleted file mode 100644 index f1ffca06..00000000 --- a/src/index.js +++ /dev/null @@ -1,23 +0,0 @@ -const express = require('express'); -const dbConnection = require('./config/db'); -const app = express(); -const path = require('node:path'); - -require('dotenv').config(); - -const PORT = process.env.PORT || 3000 -const router = require('./routes/productRoutes.js'); - -app.use(express.json()); -app.use(express.urlencoded({ extended: true })) - -app.use('/', router); - -const publicPath = path.resolve(__dirname, '..', 'public') -app.use(express.static(publicPath)); - -dbConnection() - -app.listen(PORT, () => { - console.log(`Express está escuchando en el puerto http://localhost:${PORT}`) -}) \ No newline at end of file From cf8137ab733534e5c6be20f7319aa64c45b97cad Mon Sep 17 00:00:00 2001 From: JAVI Date: Thu, 29 Feb 2024 13:13:00 +0100 Subject: [PATCH 17/27] findindex --- index.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 index.js diff --git a/index.js b/index.js new file mode 100644 index 00000000..c2884362 --- /dev/null +++ b/index.js @@ -0,0 +1,23 @@ +const express = require('express'); +const dbConnection = require('./src/config/db.js'); +const app = express(); +const path = require('node:path'); + +require('dotenv').config(); + +const PORT = process.env.PORT || 3000 +const router = require('./src/routes/productRoutes.js'); + +app.use(express.json()); +app.use(express.urlencoded({ extended: true })) + +app.use('/', router); + +const publicPath = path.resolve(__dirname, '..', 'public') +app.use(express.static(publicPath)); + +dbConnection() + +app.listen(PORT, () => { + console.log(`Express está escuchando en el puerto http://localhost:${PORT}`) +}) \ No newline at end of file From 9da0243631297150ae547d22e93ea634decfd479 Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Thu, 29 Feb 2024 18:14:38 +0100 Subject: [PATCH 18/27] updating testing --- test/productController.test.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/productController.test.js b/test/productController.test.js index be70efc1..46a071ff 100644 --- a/test/productController.test.js +++ b/test/productController.test.js @@ -3,6 +3,7 @@ const {ProductController, getProductOneCard, getProductCards} = require('../src/ const Product = require('../src/models/Product') jest.setTimeout(30000) +/* describe('ProductController', () => { const req ={}; const res ={ @@ -49,12 +50,12 @@ describe('ProductController', () => { expect(res.status).toHaveBeenCalledWith(500); expect(res.send).toHaveBeenCalledWith(errorMessage); }) - })*/ + }) - /* + describe('createProduct', () =>{ it('should create a new product', async () =>{ req.body = product; @@ -62,7 +63,7 @@ describe('ProductController', () => { expect(Product.create).toEqual(product); expect(res.redirect).toEqual('/dashboard') }) - })*/ + }) describe('updateProduct', () =>{ it('should update a product', async() =>{ @@ -70,13 +71,15 @@ describe('ProductController', () => { req.body = product; await ProductController.updateProduct(req, res); - expect(Product.findByIdAndUpdate).toHaveBeenCalledWith(req.params.productId, product,{ new: true } ) + jest.spyOn(product, 'findByIdAndUpdate').mockResolvedValue(req.params.productId, product,{ new: true }) + //expect(Product.findByIdAndUpdate).toHaveBeenCalledWith(req.params.productId, product,{ new: true } ) expect(res.redirect).toHaveBeenCalledWith('64643212154') }) }) + -}); +}); */ From f1058ccdb909f44899057f48c0f947e707884824 Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Thu, 29 Feb 2024 18:26:02 +0100 Subject: [PATCH 19/27] updating testing --- package.json | 2 +- test/productController.test.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 8d75f302..baa77e44 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "scripts": { "test": "jest", - "dev": "nodemon src/index.js" + "dev": "nodemon index.js" }, "keywords": [], "author": "", diff --git a/test/productController.test.js b/test/productController.test.js index eb17973e..f8488734 100644 --- a/test/productController.test.js +++ b/test/productController.test.js @@ -1,7 +1,7 @@ -const { it } = require('node:test'); + const { ProductController, getProductOneCard, getProductCards } = require('../src/controllers/productController'); const Product = require('../src/models/Product') -/* + jest.setTimeout(30000) /* describe('ProductController', () => { From 4c0deb889220aaf4d35dde407594a6d64631062a Mon Sep 17 00:00:00 2001 From: JAVI Date: Thu, 29 Feb 2024 18:31:16 +0100 Subject: [PATCH 20/27] working4 --- src/controllers/productController.js | 2 +- src/routes/productRoutes.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/controllers/productController.js b/src/controllers/productController.js index 870a74dc..a7274824 100644 --- a/src/controllers/productController.js +++ b/src/controllers/productController.js @@ -1,4 +1,4 @@ -const Product = require('../models/Product') +const Product = require('./models/Product') let token; const htmlHead = ` diff --git a/src/routes/productRoutes.js b/src/routes/productRoutes.js index 25525a50..32d4b40c 100644 --- a/src/routes/productRoutes.js +++ b/src/routes/productRoutes.js @@ -1,6 +1,6 @@ const express = require('express'); const router = express.Router(); -const {ProductController} = require('../controllers/productController.js'); +const { ProductController } = require('./controllers/productController.js'); router.get('/', ProductController.showProducts); router.get('/products', ProductController.showProducts); @@ -10,16 +10,16 @@ router.get('/products/category/:category', ProductController.showProductCategory // dashboard router.get('/login', ProductController.login) -router.get('/dashboard', ProductController.showProducts); +router.get('/dashboard', ProductController.showProducts); router.get('/dashboard/new', ProductController.showNewProduct); router.post('/dashboard', ProductController.createProduct); -router.get('/dashboard/:productId', ProductController.showProductById); +router.get('/dashboard/:productId', ProductController.showProductById); -router.get('/dashboard/:productId/edit', ProductController.showEditProduct); +router.get('/dashboard/:productId/edit', ProductController.showEditProduct); router.post('/dashboard/:productId', ProductController.updateProduct); -router.get('/dashboard/:productId/delete', ProductController.deleteProduct); +router.get('/dashboard/:productId/delete', ProductController.deleteProduct); router.get('/logout', ProductController.logout) From 1dcf49b85ec43b142f44a1516eed8c82978e0484 Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Thu, 29 Feb 2024 18:33:03 +0100 Subject: [PATCH 21/27] updating index & DB --- index.js | 2 +- src/config/db.js | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index c2884362..712b8ea4 100644 --- a/index.js +++ b/index.js @@ -13,7 +13,7 @@ app.use(express.urlencoded({ extended: true })) app.use('/', router); -const publicPath = path.resolve(__dirname, '..', 'public') +const publicPath = path.resolve(__dirname, 'public') app.use(express.static(publicPath)); dbConnection() diff --git a/src/config/db.js b/src/config/db.js index fe6f9a5a..597c513d 100644 --- a/src/config/db.js +++ b/src/config/db.js @@ -3,10 +3,7 @@ require('dotenv').config(); const dbConnection = async () => { try { - await mongoose.connect(process.env.MONGO_URI, { - useNewUrlParser:true, //para utilizar el nuevo analizador de URL de mongo - useUnifiedTopology:true, // para utilizar la nueva capa de conexion - useCreateIndex:true}) + await mongoose.connect(process.env.MONGO_URI) console.log('Base de datos conectada con éxito') } catch (error) { console.log(error) From bd20beb7adf408b49727e6d781c1a93b0d365f94 Mon Sep 17 00:00:00 2001 From: JAVI Date: Thu, 29 Feb 2024 18:36:19 +0100 Subject: [PATCH 22/27] working4 --- src/routes/productRoutes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/productRoutes.js b/src/routes/productRoutes.js index 32d4b40c..fa994d50 100644 --- a/src/routes/productRoutes.js +++ b/src/routes/productRoutes.js @@ -1,6 +1,6 @@ const express = require('express'); const router = express.Router(); -const { ProductController } = require('./controllers/productController.js'); +const { ProductController } = require('../controllers/productController'); router.get('/', ProductController.showProducts); router.get('/products', ProductController.showProducts); From 217b651e03b47a00cd30cf7af2c2cbc3810575e0 Mon Sep 17 00:00:00 2001 From: JAVI Date: Thu, 29 Feb 2024 18:40:45 +0100 Subject: [PATCH 23/27] working5 --- index.js | 4 ++-- src/controllers/productController.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index c2884362..9c986463 100644 --- a/index.js +++ b/index.js @@ -1,12 +1,12 @@ const express = require('express'); -const dbConnection = require('./src/config/db.js'); +const dbConnection = require('../src/config/db.js'); const app = express(); const path = require('node:path'); require('dotenv').config(); const PORT = process.env.PORT || 3000 -const router = require('./src/routes/productRoutes.js'); +const router = require('../src/routes/productRoutes.js'); app.use(express.json()); app.use(express.urlencoded({ extended: true })) diff --git a/src/controllers/productController.js b/src/controllers/productController.js index a7274824..870a74dc 100644 --- a/src/controllers/productController.js +++ b/src/controllers/productController.js @@ -1,4 +1,4 @@ -const Product = require('./models/Product') +const Product = require('../models/Product') let token; const htmlHead = ` From 658c5b2ea429a9d75dfae92dc7002cd6153b4707 Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Thu, 29 Feb 2024 18:48:48 +0100 Subject: [PATCH 24/27] handle errors --- src/controllers/productController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/productController.js b/src/controllers/productController.js index a7274824..870a74dc 100644 --- a/src/controllers/productController.js +++ b/src/controllers/productController.js @@ -1,4 +1,4 @@ -const Product = require('./models/Product') +const Product = require('../models/Product') let token; const htmlHead = ` From 4e0ecc13921155e3924fcd6a4d48f023b8f043db Mon Sep 17 00:00:00 2001 From: JAVI Date: Thu, 29 Feb 2024 19:32:57 +0100 Subject: [PATCH 25/27] Working6 --- README2.md | 3 +++ index.js | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README2.md b/README2.md index 35b9c028..e8f8460a 100644 --- a/README2.md +++ b/README2.md @@ -84,6 +84,9 @@ Una clicado esta opción, simplemente cerrará la sesón del usuario que estemos Estas son las tecnologías o recursos utilizados para nuestra web. +-[Express](#Epress) + + - [Express](https://expressjs.com/)(#Express) - [Mongoose](https://mongoosejs.com/) - [Atlas](https://www.mongodb.com/cloud/atlas) diff --git a/index.js b/index.js index bbbd2d5e..712b8ea4 100644 --- a/index.js +++ b/index.js @@ -1,12 +1,12 @@ const express = require('express'); -const dbConnection = require('../src/config/db.js'); +const dbConnection = require('./src/config/db.js'); const app = express(); const path = require('node:path'); require('dotenv').config(); const PORT = process.env.PORT || 3000 -const router = require('../src/routes/productRoutes.js'); +const router = require('./src/routes/productRoutes.js'); app.use(express.json()); app.use(express.urlencoded({ extended: true })) From cfcc9cd8e97f2ebe881dd2474c23a2a80db495a9 Mon Sep 17 00:00:00 2001 From: naiara-ada Date: Wed, 6 Mar 2024 10:34:10 +0100 Subject: [PATCH 26/27] session working --- README2.md | 2 +- index.js | 17 ++- package.json | 10 +- public/styles.css | 1 + src/controllers/productController.js | 151 ++++++++++++++++++++++----- src/middlewares/authControl.js | 11 -- src/routes/productRoutes.js | 20 ++-- test/productController.test.js | 43 +------- 8 files changed, 164 insertions(+), 91 deletions(-) delete mode 100644 src/middlewares/authControl.js diff --git a/README2.md b/README2.md index e8f8460a..b45850bd 100644 --- a/README2.md +++ b/README2.md @@ -15,7 +15,7 @@ Esta sería la URL donde está alojada la tienda: URL:http******** ## Funcionamiento de la tienda de ropa -Una vez que se accede a la url de la web, lo primero que nos vamos ha econtrar es una web con una barra de navegación, la cual consta de las siguientes categorías: +Una vez que se accede a la url de la web, lo primero que nos vamos ha encontrar es una web con una barra de navegación, la cual consta de las siguientes categorías: -[Productos](#Categoría-Productos) -[Camisetas](#Categoría-Camisetas) diff --git a/index.js b/index.js index 712b8ea4..97d76050 100644 --- a/index.js +++ b/index.js @@ -2,17 +2,30 @@ const express = require('express'); const dbConnection = require('./src/config/db.js'); const app = express(); const path = require('node:path'); - +const session = require('express-session'); +const cors = require('cors'); require('dotenv').config(); +const {hashedSecret} = require('./src/config/configcryp.js') const PORT = process.env.PORT || 3000 const router = require('./src/routes/productRoutes.js'); + +app.use(cors()); app.use(express.json()); -app.use(express.urlencoded({ extended: true })) +app.use(express.urlencoded({ extended: true })); + +app.use(session({ + secret: hashedSecret, + resave: false, + saveUninitialized: true, + cookie:{secure:false}, +})) + app.use('/', router); + const publicPath = path.resolve(__dirname, 'public') app.use(express.static(publicPath)); diff --git a/package.json b/package.json index baa77e44..a32c5f69 100644 --- a/package.json +++ b/package.json @@ -14,10 +14,16 @@ "author": "", "license": "ISC", "dependencies": { - "buil": "^0.0.0", - "buildpack": "^0.0.1", + "bcrypt": "5.1.1", + "buildpack": "0.0.1", + "cors": "2.8.5", "dotenv": "16.4.5", "express": "4.18.2", + "express-session": "1.18.0", + "firebase": "10.8.1", + "firebase-admin": "^12.0.0", + "firebaseui": "6.1.0", + "jsonwebtoken": "9.0.2", "mongoose": "8.2.0" }, "devDependencies": { diff --git a/public/styles.css b/public/styles.css index 67df9f6b..923e5fea 100644 --- a/public/styles.css +++ b/public/styles.css @@ -154,6 +154,7 @@ h2 { .nav { display: flex; justify-content: center; + flex-wrap: wrap; padding: 15px; background-color: #062ACD; gap: 15px; diff --git a/src/controllers/productController.js b/src/controllers/productController.js index 870a74dc..856a7a18 100644 --- a/src/controllers/productController.js +++ b/src/controllers/productController.js @@ -1,5 +1,8 @@ const Product = require('../models/Product') -let token; +const {signIn, singUp} = require('../controllers/authController'); +const {getAuth } = require("firebase/auth"); +const fireBaseApp = require('../config/firebase'); +const {generateToken} = require('../middlewares/authMiddleware'); const htmlHead = ` @@ -7,6 +10,8 @@ const htmlHead = ` + + @@ -16,7 +21,7 @@ const htmlHead = ` const htmlEnd = `` -function getNavBar() { +function getNavBar(token) { let html = `