# README Entrega 2
### Proyecto-12
| Identificación |
| -------- |
| Fundamentos de Ingeniería de Software |
| M4B - Docente: Alejandro Adorjan |
| Participantes: Fiorella Alvira, Martín Gulla, Agustina Serrón|
| Fecha de entrega: 29-nov-2021|
| https://github.com/ORT-FIS-202108/proyecto-12.git |
# Construcción
## Implementación de funciones principales (sin la necesidad de persistencia de datos)
Debido al factor tiempo, decidimos implementar las funciones principales de la aplicación para obtener un mínimo producto viable, dejando de lado otras funcionalidades. Es por esto que decidimos llevar a cabo las funcionalidades de agregar un gasto, eliminar un gasto, agregar una categoría y por último ver un resumen de los gastos mensualemnte.
Decidimos dejar por fuera las siguientes funcionalidades: ingresar método de pago, editar gasto, agregar nota, compartir gastos con otro usuario de la aplicación, agregar un ingreso.
### Configuración de plataforma tecnológica para desarrollo y producción
Decidimos como equipo empezar a desarrollar a partir de un nuevo proyecto utilizando como guía el proyecto de ejemplo brindado por el docente.
Creamos un commit inicial en la rama develop donde cargamos el proyecto de ejemplo previamente clonado. Luego cada integrante ejecutó el comando npm install para instalar los node_modules y demás archivos no incluidos en git para ahorrar espacio en el repositorio(.gitignore).
Por último desde la terminal ejecutamos el comando npm start para ejecutar el programa en un servidor local y a partir de allí comenzamos a trabajar en nuestra app.
### Documentación del uso de librerías externas (package.json)
```
{
"name": "Interfaz",
"version": "1.0.0",
"description": "Interfaz para la web app MisGastos",
"main": "index.js",
"scripts": {
"start": "webpack serve",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Fiorella Alvira, Martin Gulla, Agustina Serron",
"license": "",
"dependencies": {
"@material/dialog": "^11.0.0",
"@material/snackbar": "^11.0.0",
"@material/textfield": "^11.0.0",
"material-components-web": "^11.0.0"
},
"devDependencies": {
"@babel/core": "^7.13.16",
"@babel/preset-env": "^7.13.15",
"autoprefixer": "^10.2.5",
"babel-loader": "^8.2.2",
"css-loader": "^5.2.4",
"eslint": "^7.28.0",
"extract-loader": "^5.1.0",
"file-loader": "^6.2.0",
"postcss-loader": "^5.2.0",
"sass": "^1.32.11",
"sass-loader": "^11.0.1",
"webpack": "^5.36.0",
"webpack-cli": "^4.6.0",
"webpack-dev-server": "^3.11.2"
}
}
```
# Interfaz de usuario
### Interfaz de usuario web / mobile (responsive)
Para esto agregamos la siguiente línea en el HTML, cuyo propósito es dar instrucciones al navegador de cómo controlar las dimensiones y la escala:
```htmlmixed=
<meta name="viewport" content="width=device-width, initial-scale=1.0">
```
### Página única con navegación entre secciones
Implementamos una única página index.html. En la misma colocamos etiquetas de *section* para cada una de las pantallas de la aplicación. Al navegar por la aplicación agregamos o quitamos una clase con *display:hidden* para ocultar o mostrar las diferentes secciones. Es por esto que cuando se clickea un botón, se llama a una función que, en base al botón clickeado, cambia a la pantalla correspondiente.
### Implementación: Material Design Web Components
Utilizamos el sitio web oficial "https://material.io/" para buscar las implementaciones de cada componente que necesitamos para completar nuestra aplicación
Utilizamos: `npm install material-components-web` para instalar las dependencias necesarias en el package.json
### Aplicar un sistema de diseño y principios de usabilidad
En este pryecto utilizamos Material Design como sistema de diseño del mismo. Para esto intentamos llevar a cabo las heurísticas de Nielsen.
#### Heurísticas:
#### 1. Visibilidad del estado del sistema
En esta aplicación el usuario siempre recibe feedback con cada acción que toma, ya sea con una animación o cambiando de pantalla, siempre una acción tiene una reacción de parte del sistema.
#### 2. Coincidencia entre el sistema y el mundo real
Los íconos de cada categoría de gastos hacen referencia a un elemento de la realidad que asociamos con esos tipos de gastos. Por ejemplo los gastos de la casa estan implementados con un ícono de una casa. Esto le permite al usuario comprender de forma más sencilla y rápida cómo organizar sus gastos.
#### 3. Dale al usuario el control y la libertad
En esta aplicación le brindamos al usuario la opción de eliminar un gasto de cualquier categoría. Esto le da la libertad al usuario de "volver hacia atrás" en caso de cometer un error o cambiar de opinión.
#### 4. Consistencia y estándares
En la aplicación todos los botones de acción indican con un texto cuál es la función que realizan, de esta forma el usuario jamás va a estar preguntándose si tal botón hace tal cosa.
En relación a los íconos tratamos de seguir los estándares, como por ejemplo, usar el íconos representativos para hacer referencia a cada categoría de gasto, una basura para eliminar gastos y un signo de '+' para agregar más productos. Además utilizamos íconos rellenos en color negro.
#### 5. Prevención de errores
Prevenimos que el usuario accidentalmente genere una categoría repetida , ya que cuando lo hace aparece un cartel con el siguiente mensaje: "categoría ya ingresada, elija otro nombre", además bloqueamos que pueda crear esa cateogoría.
#### 6. Reconocer en lugar de recordar
No fue necesario minimizar la carga de memoria del usuario haciendo visibles los objetos, ya que eran pocos botones que generaban acciones. Por lo tanto no tuvimos que realizar métodos para cumplir con la heurística 8. Esto hace que el usuario no tenga que estar recordando cómo hacer las cosas, con usar el sentido común basta.
#### 7. Flexibilidad y eficiencia de uso
La heurística 7 hace referencia a los siguiente: "La interfaz debe estar optimizada para minimizar el esfuerzo que requiere al usuario alcanzar sus objetivos. No solicitar jamás información innecesaria, acortar al mínimo los formularios y procesos".
Debido a la simpleza de nuestra aplicación, esta heurística no es aplicable. Consideramos que no hay forma de cambiar la aplicación para brindar un mejor manejo o funcionalidades específicas.
#### 8. Estética y diseño minimalista
El diseño de esta aplicación se realizó de forma tal que lo que se visualiza en la pantalla es toda la información que el usuario necesita para llevar a cabo las funciones brindadas por la aplicación. Solo mostramos la información relevante para el usuario.
#### 9. Ayuda al usuario a reconocer, diagnosticar y recuperarse de los errores
La heurística 9 hace referencia a lo siguiente: "Los mensajes de error deben expresarse en lenguaje habitual (no códigos o jerga), indicar con precisión el problema y sugerir constructivamente una solución."
En relación a los posibles errores solo contemplamos el error de que el usuario ingrese una categoría repetida. Para esto mostramos un mensaje de error: "categoría ya ingresada, elija otro nombre", lo que creemos que es de fácil entendimiento para el usuario. Permitiéndole fácilmente solucionar el problema.
La verificación de correctitud de otros elementos ingresados en el formulario es una funcionalidad que nos queda pendiente para un futuro.
#### 10. Ayuda y documentación
Consideramos que no es necesario tener un manual para explicar la aplicación, ya que la misma es simple y lineal. Igualmente en el futuro implementaremos un botón de ayuda, en donde se explicarán todas las funcionalidades agregadas detallando la forma de uso.
### Cumplimiento de estándar de accesibilidad WCAG
Utilizamos dos plugins de VSC para asegurar la accesibilidad:
* W3C validation
* Web Accessibility
Algunos problemas que se encontraron:



Consideramos que es fácil acceder al contenido de la aplicación ya que no es necesario crearse una cuenta (hacer log in).
Actualmente no es posible navegar por toda la aplicación utilizando solamente el teclado.
El texto de la aplicación tiene un tamaño apropiado para que sea sencillo de leer y ademas brindamos funciones para ayudar al usuario a corregir errores que pueda cometer.
### Seguir especificación de estilo
Seguimos la especificación de estilo que teniamos como requerimiento no funcional.
```
@use "@material/theme" with ($primary: #512DA8,
$secondary: #00796b, $background: #c7c7c7);
body {
font-family: Roboto, "Open Sans", "Helvetica Neue", sans-serif;
margin: 0px auto;
}
```
# Codificación
### IDE Visual Studio Code: configuración común del equipo
No utilizamos una configuración común del equipo en Visual Studio Code, ya que todos los integrantes ya contábamos con algunas extensiones de visual studio code instaladas.
### Estándares de codificación Google (HTML, CSS, JavaScript)
Para cumplir con estos estándares nos basamos en la guía de Google: https://google.github.io/styleguide/htmlcssguide.html
Utilizamos esLint para corregir la mayor parte de los errores en el código. Para esto descargamos la extensión ESlint de Visual Studio Code. Como podemos ver en la imagen tuvimos varios problemas en cuanto a la identación del código. Para corregirlos entramos a la guía de ayuda de ESlint : https://eslint.org/docs/rules/indent

### Buenas prácticas de OOP: separación de lógica e interfaz
Para la realización del proyecto creamos dos carpetas, una llamada dominio, donde guardamos los códigos de funcionalidad de la aplicación y la otra interfaz donde guardamos los componentes del diseño y vista de la aplicación. De esta forma podemos visualizar de forma prolija lo correspondiente a la lógica y a la interfaz gráfica.
A continuación detallamos los componentes de cada una:
Dominio: realizamos 3 clases: Usuario, Gasto y Categoría que contienen las estructuras y algoritmos que nos permiten manejar los datos de la aplicación.
Interfaz: tenemos el index.html, donde programamos la estructura de la página y también index.js, donde se encuentran las funciones que vinculan los elementos del html con las funciones del dominio.
### Análisis estático de código: mostrar reducción de problemas
Utilizamos esLint para corregir la mayor parte de los errores en el código. A lo largo del desarrollo del código fuimos creando issues para resolver los problemas no resueltos automáticamente y logramos solucionamos todos los errores.
# Test unitario
### Test unitarios en Jest
Para realizar las pruebas correspondientes en la aplicación instalamos el framework para testing Jest, con el comando "npm install --save-dev jest".
Utilizamos una función test que prueba todas las líneas de código de una de nuestras clases. Cada test evalúa una única función.
-----
Prueba de usuario1 (usuario1.test.js)
```
import Usuario1 from './usuario1.js';
test('creación de usuario', () => {
const nuevoUsuario = new Usuario1();
expect(nuevoUsuario.listaCategorias).toStrictEqual([]);
expect(nuevoUsuario.listaGastos).toStrictEqual([]);
expect(nuevoUsuario.cantidadCategorias).toBe(0);
expect(nuevoUsuario.cantidadGastos).toBe(0);
});
test('agregar categoria', () => {
const nuevoUsuario = new Usuario1();
nuevoUsuario.agregarCategoria('Descripcion1', 3000, 'Categoria1', '../resources/images/MisGastosAuto.png');
nuevoUsuario.agregarCategoria('Descripcion2', 3000, 'Categoria2', '../resources/images/MisGastosCasa.png');
expect(nuevoUsuario.getListaCategorias()[0].nombre).toStrictEqual('Categoria1');
expect(nuevoUsuario.getListaCategorias()[1].nombre).toStrictEqual('Categoria2');
expect(nuevoUsuario.getCantidadCategorias()).toBe(2);
});
test('agregar/eliminar categoria y gasto', () => {
const nuevoUsuario = new Usuario1();
nuevoUsuario.agregarCategoria('Descripcion1', 3000, 'Categoria1', '../resources/images/MisGastosAuto.png');
nuevoUsuario.agregarCategoria('Descripcion2', 3000, 'Categoria2', '../resources/images/MisGastosCasa.png');
nuevoUsuario.agregarGasto('Categoria2', 0, 'Descripcion1', '01-01-2021', 500);
nuevoUsuario.agregarGasto('Categoria2', 1, 'Descripcion2', '02-01-2021', 50);
nuevoUsuario.eliminarGasto(1);
expect(nuevoUsuario.getListaGastos()[0].monto).toBe(500);
expect(nuevoUsuario.getCantidadGastos()).toBe(1);
expect(nuevoUsuario.getListaCategorias()[0].cantidadGastos).toBe(0);
expect(nuevoUsuario.getListaCategorias()[1].getListaGastos().length).toBe(1);
nuevoUsuario.eliminarGasto(0);
expect(nuevoUsuario.getCantidadGastos()).toBe(0);
});
```
Prueba de categoría (categoria.test.js)
```
import Categoria from './categoria.js';
import Gasto from './gasto.js';
test('creación de categoria', () => {
const categoria = new Categoria('compramos cosas', 100, 'gastos casa', '../interfaz/resources/images/MisGastosCasa.png');
expect(categoria.getListaGastos()).toStrictEqual([]);
expect(categoria.cantidadGastos).toBe(0);
expect(categoria.limite).toBe(100);
expect(categoria.nombre).toStrictEqual('gastos casa');
expect(categoria.descripcion).toStrictEqual('compramos cosas');
});
test('creación de categoria', () => {
const categoria = new Categoria('compramos cosas', 100, 'gastos casa', '../interfaz/resources/images/MisGastosCasa.png');
const gasto = new Gasto(0, 'descripcion gasto', '22/11/2021', 400);
categoria.insertar(gasto);
expect(categoria.cantidadGastos).toBe(1);
expect(categoria.getListaGastos()).toStrictEqual([gasto]);
});
```
Prueba de gasto (gasto.test.js)
```
import Gasto from './gasto';
test('crear gasto', () => {
const gasto=new Gasto(0, 'Descripcion gasto', '22-11-2021', 100);
expect(gasto.identificador).toBe(0);
expect(gasto.descripcion).toStrictEqual('Descripcion gasto');
expect(gasto.fecha).toStrictEqual('22-11-2021');
expect(gasto.monto).toStrictEqual(100);
});
```
### 100% cobertura en clases de dominio
Resultado de las pruebas:

# Test de sistema
### Realizar test de sistema en un entorno separado del desarrollo
Para esto probamos nuestro código en una computadora diferente a las que usamos para desarrollar. Descargamos todas las dependencias necesarias y la aplicación funcionó correctamente.
### Generar casos de prueba aplicando técnica partición equivalente
Para generar los casos de prueba elegimos la clase usuario del dominio. Utilizamos una técnica de caja negra es decir, evaluamos las entradas y salidas del sistema. Para esto elegimos la técnica de partición de equivalencia dividiendo los valores de entrada en clases de equivalencia e identificando para cada entrada los valores válidos y no válidos que podría tomar.




### Detallar sesiones de prueba exploratoria
Testing exploratorio sobre creación de categorías y gastos:
Misión: Validar el correcto funcionamiento de creación de categorías, gastos y el resumen general.
Duración: 30 min.
Fecha: 26 de Noviembre del 2021
Tester: Martin, Agustina, Fiorella
Sitio: http://localhost:8080/
Set up: Instalar los módulos de node y luego ejecutar el comando npm start para acceder a la app. Ingresar a
http://localhost:8080/ Hacer click en el boton de agregar (+)
#### Prueba 1
Selecciono Boton (+)
Resultado: Se abre la ventana de elección entre gasto y categoría
PASA
#### Prueba 2
Selecciono Categoría y Aceptar
Resultado: Se abre la ventana de creación de categoría
PASA
#### Prueba 3
Ingreso los datos "Categoria1", "Descripción1", "1000" y selecciono la opcion "auto", luego doy Aceptar
Resultado: Se crea la categoría con los datos especificados
PASA
#### Prueba 4
Ver en la subpantalla "Resumen" que aparezca la categoría recién creada, y también en la subpantalla "Categorías"
Resultado: Aparece en ambas subpantallas, en "Resumen" sin gastos, y en "Categorías" con todos sus gastos
PASA
#### Prueba 5
Repetir pruebas 1, 2 y 3, creando otra categoría con el mismo nombre.
Resultado: Se crea otra categoría con el mismo nombre
PASA
#### Prueba 6
Repetir paso 1 y 2, pero eligiendo Gasto
Resultado: Se abre la ventana de creación de gasto
PASA
#### Prueba 7
Ingreso los datos "Gasto1", "1000", "01-01-2000", y una de las dos categorías nombradas "Categoría1"
Resultado: Se crea el gasto
PASA
#### Prueba 8
Ver en la subpantalla "Resumen" que aparezca el gasto recién creado en la categoría seleccionada
Resultado: El gasto aparece en ambas categorías con el mismo nombre, no solo en la seleccionada
NO PASA: El correcto funcionamiento seria que solo se agregue a una de las dos categorías con el mismo nombre, esto se puede solucionar impidiendo crear una categoría con un nombre ya utilizado
# Reporte de issues
A lo largo de la implementación de la aplicación, nos fuimos encontrando con errores en el código, ya sea cosas que no funcionaban, o que no tenían el comportamiento deseado.
Para la creación de issues lo hicimos a partir de la web de git, creamos entre todos un template de cosas que deberían estar descriptas para cada uno de los errores. Cuando teníamos reuniones y veíamos que no lográbamos solucionar algún problema creamos un issue para recordarnos que ese error persistía y necesitábamos solucionarlo antes de la entrega. Cuándo lográbamos solucionar el error cerrábamos el issue.
### Dejar issues abiertos para correcciones o mejoras futuras
Durante la realización del proyecto y testeo surgieron varios aspectos a mejorar que pueden verse reflejados en el repositorio como open issues.
### Definir labels para tipos de issue y niveles de severidad
Utilizamos los labels que trae git para cada tipo de issue. Cada uno tiene una descripción de su uso y un nombre nemotécnico. Incluímos también dos niveles de severidad para indicar prioridad alta y baja de resolución del issue.

### Realizar una evaluación global de la calidad
Consideramos que alcanzamos un producto funcional y con una estética coherente. Logramos un correcto funcionamiento de la creación de gastos y categorías, dar "feedback" en los botones, inhabilitar botones para evitar errores por parte del usuario, generar mensajes de error explicativos, fáciles para que el usuario los pueda resolver.
# Reflexión
### Detalle del trabajo individual
#### Martin
Este segundo obligatorio me pareció una experiencia nueva, llevando a código requerimientos planteados en el primer obligatorio. Fue un proceso de aprendizaje el ver como utilizar Node, esLint, Material Design y Jest, lo cual fue lo que mas tiempo nos llevo, una vez que comprendimos bien como funcionaba cada componente, la impementación de la aplicacián fue mucho más rápida y fácil.
#### Agustina
Me pareció una experiencia excelente para poder llevar a cabo lo que es aprender a crear una aplicación desde cero. Creo que los conocimientos adquiridos son la base para entender cómo llevar a cabo estas actividades en el mundo laboral. Considero que aprendí muchas técnicas que me van a servir en mi futuro tanto en lo que queda de la facultad como en un futuro laboral. Todo el tiempo sentí una presión por el tiempo de entrega, lo cual ayudó a no dejar de lado el proyecto y todos los días estar investigando cosas nuevas lo que me pareció muy interactivo y dinámico.
En relación con el trabajo en equipo creo que nos logramos complementar a la hora de la realización del proyecto.
Por último me pareció muy bueno realizar presentaciones orales en clase, ya que creo que es muy importante la comunicación en estas áreas.
#### Fiorella
Personalmente me pareció una experiencia enriquecedora en cuanto a la creación de la aplicación, considero que todo lo aprendido en el curso tanto teórico como práctico va a ser útil en un futuro académico y laboral.
Estoy totalmente conforme y agradecida con mis compañeros que ayudaron a llevar el proyecto adelante y se comprometieron desde el primer momento.
### Técnicas aplicadas y aprendizajes
En cuánto al desarrollo de la aplicación decidimos trabajar conjuntamente en la rama develop ya que no teníamos muy claras algunas partes necesarias para el proyecto como la parte de Material Design, es por esto que realizamos reuniones semanales para trabajar. En la última etapa como nos faltaba tiempo decidimos ir avanzando cada uno por su cuenta y avisando los cambios realizados.
Para utilizar material design nos basamos en la implementación otorgada por el docente. Pero además nos apoyamos con la documentación ofrecida en: [material.io](https://material.io/components?platform=web), adaptando los estilos de los componentes a nuestras necesidades.
Nos enfocamos en la creación de un código claro, separando las funciones correctamente y no generando métodos largos que no se entiendan. Tratando de seguir con las buenas prácticas de codificación.
Entre todos realizamos las pruebas de JEST. Esta herramienta nos fue bastante útil ya que encontramos errores en el código que no ocurrian en el flujo normal de la aplicación, ya que había codigo que no recorriamos.
# Presentaciones individuales sobre temas de clase
### Martin
Presentación fue sobre Creación de casos de prueba.
Link a la presentación: https://fism4b-2021.slack.com/archives/C02N6D26B42/p1637853241000700
¿Qué es un caso de prueba?
“Es un conjunto de condiciones o variables bajo las cuales se determinará si una aplicación, un sistema de software o una característica o comportamiento de estos resulta o no aceptable.”
### Agustina
Testing Exploratorio
Link : https://fism4b-2021.slack.com/files/U02CCCZ717W/F02MKHKUCCC/testing_exploratorio__2_.pdf
El testing exploratorio es un enfoque de pruebas
en el que simultáneamente se aprende sobre la aplicación, se diseñan casos de prueba y se ejecutan esos casos de prueba. Cuando una persona hace testing exploratorio, diseña y ejecuta pruebas con un objetivo en concreto. Con las conclusiones que obtiene va aprendiendo sobre la aplicación, y utiliza esa información para diseñar y ejecutar nuevas pruebas.
### Fiorella
Testing exploratorio
Link: https://fism4b-2021.slack.com/files/U02CCCZ717W/F02MKHKUCCC/testing_exploratorio__2_.pdf
El testing exploratorio como desventaja presenta qué, carece de metodología estándar lo cual dificulta saber como llevar a cabo el proceso ya que no hay un paso a paso a seguir.
La unidad básica del testing exploratorio son las sesiones, las cuales no son consideradas casos de prueba ni tampoco un reporte de defectos. Simplemente es un bloque donde se puede evidenciar todo el trabajo hecho durante la prueba.
Las mismas tienen características como ser ininterrumpidas, es decir se respeta el tiempo acordado para las pruebas y de esta forma no se pierde tiempo valioso documentando. También tienen un balance entre foco y flexibilidad, lo cual nos permite "irnos por las ramas" y no limitarnos a un único objetivo. A su vez se encuentran en mejora continua y el test no es guionado, es decir se lo qué quiero probar pero no se cómo.