<file_sep>import User from '../models/Usuarios'
import Role from '../models/Rol'
import jwt from 'jsonwebtoken'
import config from '../config'

export const signup = async (req, res) => {

     //obteniendo req body
     const {username, email,password,nombre,apellido,numero,poblacion,address,codigo,roles} = req.body
     
     //Creando nuevo usuario 
    const nuevousuario = new User ({
          username,
          email,
          password: await User.encryptPassword(password),
          nombre,
          apellido,
          numero,
          poblacion,address,
          codigo
     })

     //Comprobando si tiene roles si no asigna usuario
     if(roles){
          const foundRoles = await Role.find({name: {$in : roles}})
          nuevousuario.roles = foundRoles.map((role) => role._id)
     }else{
          const role = await Role.findOne({name : "user"});
          nuevousuario.roles = [role._id];
     }
     
     //Guardamos usuario en mongo
     const saveUser = await nuevousuario.save();
     console.log(saveUser)
     
     //Creamos token
     const token = jwt.sign({id:saveUser._id}, config.SECRET,{
          expiresIn: 1800 // 30 min
     })
   
     return res.json(token)
}

export const signin = async (req, res) => {
     
     const userFound = await User.findOne({email: req.body.email}).populate("roles")
     if(!userFound) return res.status(400).json({message: "Usuario no encontrado"})

    const matchpass =  await User.compararPassword(req.body.password , userFound.password)
     if (!matchpass) return res.status(401).json({token: null , message : "Contraseña fallida "})
     
    const token = jwt.sign({id: userFound._id}, config.SECRET,{
          expiresIn : 1800
     })
   
     res.json(token)

}

export const dataProfile = async (req,res) => {
     const userFound = await User.findOne({email: req.body.email}).populate("roles")
     if(!userFound) return res.status(400).json({message: "Usuario no encontrado"})

     const datos = {
          "username" : userFound.username,
          "email" : userFound.email,
          "nombre" : userFound.nombre,
          "apellido" : userFound.apellido,
          "numero" : userFound.numero,
          "poblacion" : userFound.poblacion,
          "address" : userFound.address,
          "codigo" : userFound.codigo
     }
     res.json(datos)
}<file_sep>const state = {
  topRated: [
    {
      id: 1,
      name: "Tele",
      price: 500,
      url: "https://m.media-amazon.com/images/I/81tn5ZRtx7L._AC_SX425_.jpg",
      desc: "Buena tele",
      rate: 4.3,
      quantity: 1,
    },
    {
      id: 2,
      name: "Cascos",
      price: 50,
      url: "aqui va el enlace a la foto",
      desc: "Buen casco",
      rate: 4.0,
    },
    {
      id: 3,
      name: "PC",
      price: 900,
      url: "aqui va el enlace a la foto",
      desc: "Buena pc",
      rate: 3.9,
    },
  ],

  contador_productos: 0,
  products: [],
};

const mutations = {
  addToCart(state, payload) {
    let item = payload;
    item = { ...item, quantity: 1 };

    if (state.products.length > 0) {
      var z = 0;
      for (var j = 0; j < state.products.length; j++) {
        let bool = state.products[j]._id === item._id;
        if (bool) {
          let itemIndex = state.products.findIndex((el) => el._id === item._id);
          state.products[itemIndex]["quantity"] += 1;
          z = 1;
        }
      }
      if (z == 0) {
        state.products.push(item);
      }
    } else {
      //        state.products.push(state.topRated[0])
      state.products.push(item);
    }

    state.contador_productos++;
    //console.log(state.products)
  },

  removeItem(state, payload) {
    if (state.products.length > 0) {
      for (var j = 0; j < state.products.length; j++) {
        let bool = state.products[j]._id === payload._id;
        if (bool) {
          let index = state.products.findIndex((el) => el._id === payload._id);
          if (state.products[index]["quantity"] !== 0) {
            state.products[index]["quantity"] -= 1;
            state.contador_productos--;
          }
          if (state.products[index]["quantity"] === 0) {
            state.products.splice(index, 1);
          }
        }
      }
    }
  },

  /*
    addToCart(state, payload){
    let item = payload;
    item = { ...item, quantity: 1 }
    if(state.products > 0){
        let bool = state.products.some(i => i._id === item._id)
        if (bool){
            let itemIndex = state.products.findIndex(el => el._id === item._id)
            state.products[itemIndex]["quantity"] +=1;
        } else {
            state.products.push(item)
        }
    } else{
        state.products.push(item)
    }
    state.contador_productos++
    console.log(state.contador_productos)
},

    removeItem(state, payload){
        if(state.products.length > 0){
            let bool = state.products.some (i => i._id === payload._id)
            
            if (bool) {
                let index = state.products.findIndex(el => el._id === payload._id)
                if (state.products[index]["quantity"] !== 0){
                    state.products[index]["quantity"] -= 1
                    state.contador_productos--
                }
                if (state.products[index]["quantity"] === 0){
                    state.products.splice(index, 1)
                }
            }
        }
    }
*/
};

const actions = {
  addToCart: (context, payload) => {
    context.commit("addToCart", payload);
  },
  removeItem: (context, payload) => {
    context.commit("removeItem", payload);
  },
};

const getters = {
  contador: (state) => state.contador_productos,
  array_productos: (state) => state.products,
};

/* Esto hay que añadirlo al los methods de Detalles productos

addToCart() {
//    this.$store.commit("addToCart")
    this.$store.dispatch("addToCart", this.details);

}

removeItem() {
//    this.$store.commit("removeItem")
    this.$store.dispatch("removeItem", this.details);

}
*/

export default { state, getters, actions, mutations };

/*


    addToCart(state, payload){
    let item = payload;
    item = { ...item, quantity: 1 }
    console.log('tetonsito si soy uy')
    console.log(item)
    console.log('el state products')
    console.log(state.products)
    if(state.products.length > 0){
        var j = 0
        while  (j < state.products.length || state.products[j]._id === item._id){
            let bool = (state.products[j]._id === item._id)
            if (bool){
                console.log('TETONER FUNCIONA')
                let itemIndex = state.products.findIndex(el => el._id === item._id)
                state.products[itemIndex]["quantity"] +=1;
            }
        j++
        }

        if (j == state.products.length){
            state.products.push(item)
            console.log('tetoncito')
        }
    } else{
//        state.products.push(state.topRated[0])
        state.products.push(item)
    }
    
    state.contador_productos++
    //console.log(state.products)
},


*/
<file_sep>import mongoose from 'mongoose'


mongoose.connect("mongodb+srv://grupo08:grupo08@cluster0.2gmcf.mongodb.net/myFirstDatabase?retryWrites=true&w=majority",
{
    useNewUrlParser : true,
    useUnifiedTopology:true,
    useFindAndModify: true,
    useCreateIndex: true
})
    .then(db => console.log("DB is connect"))
    .catch(error => console.log(error))<file_sep>const supertest = require('supertest');
const app = require('../../../front/index');

const api = supertest(app);

test('Pruebas Servidor', async () => {
    await api
        .get('/')
        .expect(200)
        .expect('Content-Type', 'application/json; charset=utf-8')

})

const validaToken = require("../../../front/src/router/validate-tokens");
const admin = require("../../../front/src/router/admin");

test('Pruebas Servidor', async () => {
    await api
        .get('/admin', validaToken, admin)
        .expect(200)
        .expect('Content-Type', 'application/json; charset=utf-8')

})<file_sep>import {Schema, model} from 'mongoose'

const ProducSchema = new Schema({
    name: String,
    categoria: String,
    precio: Number,
    stock : Number,
    descripcion: String,
    imgUrl : String
},
{
        timestamps : true,
        versionKwy : false

})

export default model('Procust',ProducSchema);<file_sep>import axios from "axios";

const url = "https://elective-backend.herokuapp.com/products";

const state = {
  products: [],
  detalles: {},
};

const getters = {
  allProducts: (state) => state.products,
  detallesProductos: (state) => state.detalles,
};

const actions = {
  async obtenerProductos({ commit }) {
    const res = await axios.get(url);
    commit("setProducts", res.data);
  },

  async obtenerDataProducto({ commit }, producto) {
    console.log(producto);
    const res = await axios.get(`${url}/${producto}`);
    console.log(res);
    commit("getProduct", res.data);
  },
};
const mutations = {
  setProducts: (state, products) => (state.products = products),
  getProduct: (state, producto) => (state.detalles = producto),
};

export default { state, getters, actions, mutations };
<file_sep>import { shallowMount, mount } from "@vue/test-utils";
import Login from "@/components/Login_component";
import Register from "@/components/Register_component";

describe("Prueba 2", () => {
  let wrapper;
  beforeEach(() => {
    wrapper = shallowMount(Register, {
      methods: { signup: () => {} },
      data() {
        return {
          registro_datos: {
            username: "",
            nombre: "",
            apellido: "",
            email: "",
            password: "",
            address: "",
            numero: null,
            poblacio: "",
            codigo: null,
          },
        };
      },
    });
  });
  it("should create", () => {
    expect(wrapper.exists()).toBe(true);
  });
});

describe("Prueba 3", () => {
  let wrapper;
  beforeEach(() => {
    wrapper = shallowMount(Login, {
      methods: { login: () => {} },
      data() {
        return {
          usuario: {
            email: "<EMAIL>",
            password: "<PASSWORD>",
          },
        };
      },
    });
  });
  it("should create", () => {
    expect(wrapper.exists()).toBe(true);
  });
});
<file_sep>export default{
    SECRET : 'grupo08'
}<file_sep># E08 - Elective

## Autores:

- <NAME>
    - [<EMAIL>](mailto:<EMAIL>)
- <NAME>
    - [<EMAIL>](mailto:<EMAIL>)
- <NAME>
    - [<EMAIL>](mailto:<EMAIL>)
- <NAME>
    - [<EMAIL>](mailto:<EMAIL>)

### Informe

[Documentación](https://drive.google.com/file/d/1iJOJrPNKa5rGqI1puPLPP8PNZfdpmxjm/view?usp=sharing) detallada de la aplicación web

### Aplicación

[Web](https://string-sergio.github.io/La_Web/#/) desplegada

---

## Introducción

Proyecto web de [Vue](https://vuejs.org) basado en una tienda online con registro y login de usuarios, apoyada en una base de datos en [MongoDB](https://www.mongodb.com/es) desplegada con [Heroku](https://www.heroku.com).

## Ejecución de la aplicación en local

### Clonar el repositorio

```bash
mi-workspace> git clone https://github.com/SyTW2020/E08.git
```

### Desplegar la web en local

Hay que ejecutar dos comando, uno en cada carpeta del proyecto *front* y *backend.*

Primero para abrir el servidor:

```bash
mi-workspace/E08/backend> npm run dev
```

Para ejecutar el frontend de la web

```bash
mi-workspace/E08/front> npm run serve
```
<file_sep>"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _mongoose = require("mongoose");

var ProducSchema = new _mongoose.Schema({
  name: String,
  categoria: String,
  precio: Number,
  stock: Number,
  descripcion: String,
  imgUrl: String
}, {
  timestamps: true,
  versionKwy: false
});

var _default = (0, _mongoose.model)('Procust', ProducSchema);

exports["default"] = _default;<file_sep>"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.dataProfile = exports.signin = exports.signup = void 0;

var _Usuarios = _interopRequireDefault(require("../models/Usuarios"));

var _Rol = _interopRequireDefault(require("../models/Rol"));

var _jsonwebtoken = _interopRequireDefault(require("jsonwebtoken"));

var _config = _interopRequireDefault(require("../config"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

var signup = /*#__PURE__*/function () {
  var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(req, res) {
    var _req$body, username, email, password, nombre, apellido, numero, poblacion, address, codigo, roles, nuevousuario, foundRoles, role, saveUser, token;

    return regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            //obteniendo req body
            _req$body = req.body, username = _req$body.username, email = _req$body.email, password = _req$body.password, nombre = _req$body.nombre, apellido = _req$body.apellido, numero = _req$body.numero, poblacion = _req$body.poblacion, address = _req$body.address, codigo = _req$body.codigo, roles = _req$body.roles; //Creando nuevo usuario 

            _context.t0 = _Usuarios["default"];
            _context.t1 = username;
            _context.t2 = email;
            _context.next = 6;
            return _Usuarios["default"].encryptPassword(password);

          case 6:
            _context.t3 = _context.sent;
            _context.t4 = nombre;
            _context.t5 = apellido;
            _context.t6 = numero;
            _context.t7 = poblacion;
            _context.t8 = address;
            _context.t9 = codigo;
            _context.t10 = {
              username: _context.t1,
              email: _context.t2,
              password: <PASSWORD>,
              nombre: _context.t4,
              apellido: _context.t5,
              numero: _context.t6,
              poblacion: _context.t7,
              address: _context.t8,
              codigo: _context.t9
            };
            nuevousuario = new _context.t0(_context.t10);

            if (!roles) {
              _context.next = 22;
              break;
            }

            _context.next = 18;
            return _Rol["default"].find({
              name: {
                $in: roles
              }
            });

          case 18:
            foundRoles = _context.sent;
            nuevousuario.roles = foundRoles.map(function (role) {
              return role._id;
            });
            _context.next = 26;
            break;

          case 22:
            _context.next = 24;
            return _Rol["default"].findOne({
              name: "user"
            });

          case 24:
            role = _context.sent;
            nuevousuario.roles = [role._id];

          case 26:
            _context.next = 28;
            return nuevousuario.save();

          case 28:
            saveUser = _context.sent;
            console.log(saveUser); //Creamos token

            token = _jsonwebtoken["default"].sign({
              id: saveUser._id
            }, _config["default"].SECRET, {
              expiresIn: 1800 // 30 min

            });
            return _context.abrupt("return", res.json(token));

          case 32:
          case "end":
            return _context.stop();
        }
      }
    }, _callee);
  }));

  return function signup(_x, _x2) {
    return _ref.apply(this, arguments);
  };
}();

exports.signup = signup;

var signin = /*#__PURE__*/function () {
  var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(req, res) {
    var userFound, matchpass, token;
    return regeneratorRuntime.wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            _context2.next = 2;
            return _Usuarios["default"].findOne({
              email: req.body.email
            }).populate("roles");

          case 2:
            userFound = _context2.sent;

            if (userFound) {
              _context2.next = 5;
              break;
            }

            return _context2.abrupt("return", res.status(400).json({
              message: "Usuario no encontrado"
            }));

          case 5:
            _context2.next = 7;
            return _Usuarios["default"].compararPassword(req.body.password, userFound.password);

          case 7:
            matchpass = _context2.sent;

            if (matchpass) {
              _context2.next = 10;
              break;
            }

            return _context2.abrupt("return", res.status(401).json({
              token: null,
              message: "Contraseña fallida "
            }));

          case 10:
            token = _jsonwebtoken["default"].sign({
              id: userFound._id
            }, _config["default"].SECRET, {
              expiresIn: 1800
            });
            res.json(token);

          case 12:
          case "end":
            return _context2.stop();
        }
      }
    }, _callee2);
  }));

  return function signin(_x3, _x4) {
    return _ref2.apply(this, arguments);
  };
}();

exports.signin = signin;

var dataProfile = /*#__PURE__*/function () {
  var _ref3 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(req, res) {
    var userFound, datos;
    return regeneratorRuntime.wrap(function _callee3$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            _context3.next = 2;
            return _Usuarios["default"].findOne({
              email: req.body.email
            }).populate("roles");

          case 2:
            userFound = _context3.sent;

            if (userFound) {
              _context3.next = 5;
              break;
            }

            return _context3.abrupt("return", res.status(400).json({
              message: "Usuario no encontrado"
            }));

          case 5:
            datos = {
              "username": userFound.username,
              "email": userFound.email,
              "nombre": userFound.nombre,
              "apellido": userFound.apellido,
              "numero": userFound.numero,
              "poblacion": userFound.poblacion,
              "address": userFound.address,
              "codigo": userFound.codigo
            };
            res.json(datos);

          case 7:
          case "end":
            return _context3.stop();
        }
      }
    }, _callee3);
  }));

  return function dataProfile(_x5, _x6) {
    return _ref3.apply(this, arguments);
  };
}();

exports.dataProfile = dataProfile;<file_sep>import {Router} from 'express'
import * as productcontroller from '../controllers/products.controller'
import {verify} from '../middlewares'
const router = Router()


router.post('/',[verify.verifytoken, verify.isModerador ],productcontroller.createProduct)
router.get('/',productcontroller.getProducts)
router.get('/:productId',productcontroller.getProductById)
router.put('/:productId',verify.verifytoken,productcontroller.updateProductById)
router.delete('/:productId',[verify.verifytoken, verify.isModerador ],productcontroller.deleteProductById)

export default router;

<file_sep>import Login_component from "@/components/Login_component";

describe("Prueba 1", () => {
  it("should create", () => {
    // usuario:{
    //     email: 'test';
    //     password: '<PASSWORD>'
    // }
    expect(Login_component.data()).toStrictEqual({
      usuario: {
        email: "<EMAIL>",
        password: "<PASSWORD>",
      },
    });
  });
});
