From 08351b524cc8e1b0e5401654e637520a565dd023 Mon Sep 17 00:00:00 2001 From: Senesero Date: Thu, 2 Apr 2020 20:43:59 +0200 Subject: [PATCH 1/9] Add files via upload --- Prueba.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 Prueba.txt diff --git a/Prueba.txt b/Prueba.txt new file mode 100644 index 0000000..d672d08 --- /dev/null +++ b/Prueba.txt @@ -0,0 +1 @@ +Prueba commit inicial \ No newline at end of file From d8f9e92e9b34ea7e2a0a45b187112cd538d0ce1b Mon Sep 17 00:00:00 2001 From: Senesero Date: Thu, 2 Apr 2020 20:46:03 +0200 Subject: [PATCH 2/9] Delete Prueba.txt --- Prueba.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Prueba.txt diff --git a/Prueba.txt b/Prueba.txt deleted file mode 100644 index d672d08..0000000 --- a/Prueba.txt +++ /dev/null @@ -1 +0,0 @@ -Prueba commit inicial \ No newline at end of file From d5bd63ea4db29c82e805befdcd5eb3ef098e60c9 Mon Sep 17 00:00:00 2001 From: Senesero Date: Fri, 3 Apr 2020 13:46:55 +0200 Subject: [PATCH 3/9] Test realizados --- 03 Test Redux PabloRC/.babelrc | 10 +++ .../config/test/polyfills.js | 2 + .../config/test/setupTest.js | 5 ++ 03 Test Redux PabloRC/package.json | 76 +++++++++++++++++++ 03 Test Redux PabloRC/readme.md | 1 + 03 Test Redux PabloRC/readme_es.md | 1 + .../src/actions/todoRequest.spec.ts | 55 ++++++++++++++ .../src/actions/todoRequest.ts | 20 +++++ 03 Test Redux PabloRC/src/api/todo.spec.ts | 31 ++++++++ 03 Test Redux PabloRC/src/api/todo.ts | 15 ++++ 03 Test Redux PabloRC/src/app.tsx | 12 +++ .../src/common/actionsEnums.ts | 3 + 03 Test Redux PabloRC/src/components/index.ts | 1 + .../__snapshots__/todoArea.spec.tsx.snap | 22 ++++++ .../todoAreaContainer.spec.tsx.snap | 50 ++++++++++++ .../__snapshots__/todoRow.spec.tsx.snap | 26 +++++++ .../__snapshots__/todoTable.spec.tsx.snap | 52 +++++++++++++ .../todoList/components/todoRow.spec.tsx | 21 +++++ .../todoList/components/todoRow.tsx | 26 +++++++ .../todoList/components/todoTable.spec.tsx | 29 +++++++ .../todoList/components/todoTable.tsx | 39 ++++++++++ .../src/components/todoList/todoArea.spec.tsx | 31 ++++++++ .../src/components/todoList/todoArea.tsx | 27 +++++++ .../todoList/todoAreaContainer.spec.tsx | 43 +++++++++++ .../components/todoList/todoAreaContainer.tsx | 21 +++++ 03 Test Redux PabloRC/src/content/styles.css | 24 ++++++ 03 Test Redux PabloRC/src/index.html | 13 ++++ 03 Test Redux PabloRC/src/main.tsx | 19 +++++ 03 Test Redux PabloRC/src/model/todo.ts | 13 ++++ 03 Test Redux PabloRC/src/reducers/index.ts | 10 +++ .../src/reducers/todoReducer.spec.ts | 48 ++++++++++++ .../src/reducers/todoReducer.ts | 17 +++++ 03 Test Redux PabloRC/tsconfig.json | 17 +++++ 03 Test Redux PabloRC/webpack.config.js | 65 ++++++++++++++++ Prueba.txt | 1 - 35 files changed, 845 insertions(+), 1 deletion(-) create mode 100644 03 Test Redux PabloRC/.babelrc create mode 100644 03 Test Redux PabloRC/config/test/polyfills.js create mode 100644 03 Test Redux PabloRC/config/test/setupTest.js create mode 100644 03 Test Redux PabloRC/package.json create mode 100644 03 Test Redux PabloRC/readme.md create mode 100644 03 Test Redux PabloRC/readme_es.md create mode 100644 03 Test Redux PabloRC/src/actions/todoRequest.spec.ts create mode 100644 03 Test Redux PabloRC/src/actions/todoRequest.ts create mode 100644 03 Test Redux PabloRC/src/api/todo.spec.ts create mode 100644 03 Test Redux PabloRC/src/api/todo.ts create mode 100644 03 Test Redux PabloRC/src/app.tsx create mode 100644 03 Test Redux PabloRC/src/common/actionsEnums.ts create mode 100644 03 Test Redux PabloRC/src/components/index.ts create mode 100644 03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoArea.spec.tsx.snap create mode 100644 03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoAreaContainer.spec.tsx.snap create mode 100644 03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoRow.spec.tsx.snap create mode 100644 03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoTable.spec.tsx.snap create mode 100644 03 Test Redux PabloRC/src/components/todoList/components/todoRow.spec.tsx create mode 100644 03 Test Redux PabloRC/src/components/todoList/components/todoRow.tsx create mode 100644 03 Test Redux PabloRC/src/components/todoList/components/todoTable.spec.tsx create mode 100644 03 Test Redux PabloRC/src/components/todoList/components/todoTable.tsx create mode 100644 03 Test Redux PabloRC/src/components/todoList/todoArea.spec.tsx create mode 100644 03 Test Redux PabloRC/src/components/todoList/todoArea.tsx create mode 100644 03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.spec.tsx create mode 100644 03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.tsx create mode 100644 03 Test Redux PabloRC/src/content/styles.css create mode 100644 03 Test Redux PabloRC/src/index.html create mode 100644 03 Test Redux PabloRC/src/main.tsx create mode 100644 03 Test Redux PabloRC/src/model/todo.ts create mode 100644 03 Test Redux PabloRC/src/reducers/index.ts create mode 100644 03 Test Redux PabloRC/src/reducers/todoReducer.spec.ts create mode 100644 03 Test Redux PabloRC/src/reducers/todoReducer.ts create mode 100644 03 Test Redux PabloRC/tsconfig.json create mode 100644 03 Test Redux PabloRC/webpack.config.js delete mode 100644 Prueba.txt diff --git a/03 Test Redux PabloRC/.babelrc b/03 Test Redux PabloRC/.babelrc new file mode 100644 index 0000000..957cae3 --- /dev/null +++ b/03 Test Redux PabloRC/.babelrc @@ -0,0 +1,10 @@ +{ + "presets": [ + [ + "@babel/preset-env", + { + "useBuiltIns": "entry" + } + ] + ] +} diff --git a/03 Test Redux PabloRC/config/test/polyfills.js b/03 Test Redux PabloRC/config/test/polyfills.js new file mode 100644 index 0000000..0d9f7ef --- /dev/null +++ b/03 Test Redux PabloRC/config/test/polyfills.js @@ -0,0 +1,2 @@ +// Polyfill requestAnimationFrame required by React >=16.0.0 +require('raf/polyfill'); diff --git a/03 Test Redux PabloRC/config/test/setupTest.js b/03 Test Redux PabloRC/config/test/setupTest.js new file mode 100644 index 0000000..a0373fb --- /dev/null +++ b/03 Test Redux PabloRC/config/test/setupTest.js @@ -0,0 +1,5 @@ +const enzyme = require('enzyme'); +const Adapter = require('enzyme-adapter-react-16'); + +// Setup enzyme's react adapter +enzyme.configure({ adapter: new Adapter() }); diff --git a/03 Test Redux PabloRC/package.json b/03 Test Redux PabloRC/package.json new file mode 100644 index 0000000..227d17b --- /dev/null +++ b/03 Test Redux PabloRC/package.json @@ -0,0 +1,76 @@ +{ + "name": "reactbysample", + "version": "1.0.0", + "description": "In this sample we setup the basic plumbing to \"build\" our project and launch it in a dev server.", + "main": "index.js", + "scripts": { + "start": "webpack-dev-server --mode development --inline --hot --open", + "build": "webpack --mode development", + "test": "jest --verbose", + "test:watch": "jest --watchAll --verbose -i", + "test:coverage": "jest --verbose --coverage" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "@babel/cli": "^7.1.2", + "@babel/core": "^7.1.2", + "@babel/polyfill": "^7.0.0", + "@babel/preset-env": "^7.1.0", + "@types/deep-freeze": "^0.1.2", + "@types/enzyme": "^3.10.5", + "@types/jest": "^25.1.4", + "@types/react": "^16.9.31", + "@types/react-dom": "^16.9.6", + "@types/react-redux": "^7.1.7", + "@types/redux-mock-store": "^1.0.2", + "awesome-typescript-loader": "^5.2.1", + "babel-loader": "^8.0.4", + "css-loader": "^1.0.0", + "deep-freeze": "0.0.1", + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.2", + "enzyme-to-json": "^3.4.4", + "file-loader": "^2.0.0", + "html-webpack-plugin": "^3.2.0", + "jest": "^25.2.6", + "mini-css-extract-plugin": "^0.4.3", + "raf": "^3.4.1", + "style-loader": "^0.23.1", + "ts-jest": "^25.3.0", + "typescript": "^3.1.1", + "url-loader": "^1.1.1", + "webpack": "^4.20.2", + "webpack-cli": "^3.1.2", + "webpack-dev-server": "^3.1.9" + }, + "dependencies": { + "axios": "^0.19.2", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "react-redux": "^7.2.0", + "redux": "^4.0.5", + "redux-mock-store": "^1.5.4", + "redux-thunk": "^2.3.0" + }, + "jest": { + "testRegex": "\\.spec\\.tsx?$", + "moduleFileExtensions": [ + "js", + "jsx", + "json", + "ts", + "tsx" + ], + "setupFiles": [ + "/config/test/polyfills.js", + "/config/test/setupTest.js" + ], + "transform": { + ".tsx?": "/node_modules/ts-jest/preprocessor.js" + }, + "snapshotSerializers": [ + "enzyme-to-json/serializer" + ] + } +} diff --git a/03 Test Redux PabloRC/readme.md b/03 Test Redux PabloRC/readme.md new file mode 100644 index 0000000..2bc0324 --- /dev/null +++ b/03 Test Redux PabloRC/readme.md @@ -0,0 +1 @@ +# 00 Boilerplate --> Lemoncode \ No newline at end of file diff --git a/03 Test Redux PabloRC/readme_es.md b/03 Test Redux PabloRC/readme_es.md new file mode 100644 index 0000000..2bc0324 --- /dev/null +++ b/03 Test Redux PabloRC/readme_es.md @@ -0,0 +1 @@ +# 00 Boilerplate --> Lemoncode \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/actions/todoRequest.spec.ts b/03 Test Redux PabloRC/src/actions/todoRequest.spec.ts new file mode 100644 index 0000000..ef6daf3 --- /dev/null +++ b/03 Test Redux PabloRC/src/actions/todoRequest.spec.ts @@ -0,0 +1,55 @@ +import configureStore from 'redux-mock-store'; +import ReduxThunk from 'redux-thunk'; +const middlewares = [ReduxThunk]; +const mockStore = configureStore(middlewares); + +import { TodoEntity } from "../model/todo"; +import { todoRequestCompletedAction } from "./todoRequest"; +import { actionsEnums } from "../common/actionsEnums"; + +describe('todoRequestCompletedAction', () => { + it('debe devolver acción cuando el tipo sea TODO_REQUEST_COMPLETED', () => { + const todoResponse: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false + } + ] + + const result = todoRequestCompletedAction(todoResponse); + + expect(result.type).toBe(actionsEnums.TODO_REQUEST_COMPLETED); + expect(result.payload).toBe(todoResponse); + }); + + it('se realiza la llamada para obtener los todos', () => { + const todoResponse: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false + } + ] + + const store = mockStore(); + store.dispatch(todoRequestCompletedAction(todoResponse)) + + expect(store.getActions()[0].type).toBe(actionsEnums.TODO_REQUEST_COMPLETED); + expect(store.getActions()[0].payload).toBe(todoResponse); + }); +}); \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/actions/todoRequest.ts b/03 Test Redux PabloRC/src/actions/todoRequest.ts new file mode 100644 index 0000000..eb1d34f --- /dev/null +++ b/03 Test Redux PabloRC/src/actions/todoRequest.ts @@ -0,0 +1,20 @@ +import {actionsEnums} from '../common/actionsEnums'; +import {TodoEntity} from '../model/todo'; +import {todoAPI} from '../api/todo'; + +export const todoRequestCompletedAction = (todos: TodoEntity[]) => { + return { + type: actionsEnums.TODO_REQUEST_COMPLETED, + payload: todos + } +} + +export const todoRequest = () => (dispatcher) =>{ + const promise = todoAPI.getAllTodos(); + + promise.then( + (data) => dispatcher(todoRequestCompletedAction(data)) + ) + + return promise; +} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/api/todo.spec.ts b/03 Test Redux PabloRC/src/api/todo.spec.ts new file mode 100644 index 0000000..335ed36 --- /dev/null +++ b/03 Test Redux PabloRC/src/api/todo.spec.ts @@ -0,0 +1,31 @@ +import configureStore from 'redux-mock-store'; +import ReduxThunk from 'redux-thunk'; +const middlewares = [ReduxThunk]; +const mockStore = configureStore(middlewares); + +import { todoAPI } from './todo'; + +describe('todo API', () => { + it('se realiza la llamada', async () => { + const todos = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false, + } + ] + const spyedTodos = jest.spyOn(todoAPI, 'getAllTodos').mockResolvedValue(todos) + + const response = await todoAPI.getAllTodos() + + expect(spyedTodos).toHaveBeenCalled() + expect(response).toEqual(todos) + }); +}); diff --git a/03 Test Redux PabloRC/src/api/todo.ts b/03 Test Redux PabloRC/src/api/todo.ts new file mode 100644 index 0000000..24932ee --- /dev/null +++ b/03 Test Redux PabloRC/src/api/todo.ts @@ -0,0 +1,15 @@ +import {TodoEntity } from '../model/todo'; +const axios = require('axios').default; + +class TodoAPI { + + getAllTodos() : Promise { + const todosUrl : string = 'https://jsonplaceholder.typicode.com/todos'; + + return axios.get(todosUrl) + .then((response) => response.data) + } + +} + +export const todoAPI = new TodoAPI(); \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/app.tsx b/03 Test Redux PabloRC/src/app.tsx new file mode 100644 index 0000000..3358597 --- /dev/null +++ b/03 Test Redux PabloRC/src/app.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; +import { + TodosAreaContainer +} from './components'; + +export const App = () => { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/common/actionsEnums.ts b/03 Test Redux PabloRC/src/common/actionsEnums.ts new file mode 100644 index 0000000..65a6d3a --- /dev/null +++ b/03 Test Redux PabloRC/src/common/actionsEnums.ts @@ -0,0 +1,3 @@ +export const actionsEnums = { + TODO_REQUEST_COMPLETED: 'TODO_REQUEST_COMPLETED', + } \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/components/index.ts b/03 Test Redux PabloRC/src/components/index.ts new file mode 100644 index 0000000..89f553d --- /dev/null +++ b/03 Test Redux PabloRC/src/components/index.ts @@ -0,0 +1 @@ +export * from './todoList/todoAreaContainer'; \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoArea.spec.tsx.snap b/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoArea.spec.tsx.snap new file mode 100644 index 0000000..df9ce64 --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoArea.spec.tsx.snap @@ -0,0 +1,22 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TodoAreaComponent should render as expected 1`] = ` + +`; diff --git a/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoAreaContainer.spec.tsx.snap b/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoAreaContainer.spec.tsx.snap new file mode 100644 index 0000000..af86e9b --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoAreaContainer.spec.tsx.snap @@ -0,0 +1,50 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TodosAreaContainer debe pintar TodoAreaComponent cuando tenemos todos 1`] = ` + + + + +
+ + + + + + + + + + +
+ UserId + + Id + + Title + + Completed +
+
+
+
+
+
+`; diff --git a/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoRow.spec.tsx.snap b/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoRow.spec.tsx.snap new file mode 100644 index 0000000..525bc3f --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoRow.spec.tsx.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TodoRowComponent should render as expected 1`] = ` + + + + 1 + + + + + 1 + + + + + Hacer la compra + + + + + Completada + + + +`; diff --git a/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoTable.spec.tsx.snap b/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoTable.spec.tsx.snap new file mode 100644 index 0000000..ddf170a --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoTable.spec.tsx.snap @@ -0,0 +1,52 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TodoTableComponent should render as expected 1`] = ` +
+ + + + + + + + + + + + + +
+ UserId + + Id + + Title + + Completed +
+
+`; diff --git a/03 Test Redux PabloRC/src/components/todoList/components/todoRow.spec.tsx b/03 Test Redux PabloRC/src/components/todoList/components/todoRow.spec.tsx new file mode 100644 index 0000000..56eb74a --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/components/todoRow.spec.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import { TodoRowComponent } from './todoRow'; +import { TodoEntity } from '../../../model/todo'; + +describe('TodoRowComponent', () => { + it('should render as expected', () => { + const todo: TodoEntity = { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + } + + const component = shallow( + , + ); + + expect(component).toMatchSnapshot(); + }); +}); diff --git a/03 Test Redux PabloRC/src/components/todoList/components/todoRow.tsx b/03 Test Redux PabloRC/src/components/todoList/components/todoRow.tsx new file mode 100644 index 0000000..96d85df --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/components/todoRow.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import {TodoEntity} from '../../../model/todo'; + +interface Props { + todo : TodoEntity; +} + +export const TodoRowComponent = (props: Props) => { + const { userId, id, title, completed } = props.todo + return ( + + + {userId} + + + {id} + + + {title} + + + {completed && 'Completada'} + + + ); +} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/components/todoList/components/todoTable.spec.tsx b/03 Test Redux PabloRC/src/components/todoList/components/todoTable.spec.tsx new file mode 100644 index 0000000..c6252cf --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/components/todoTable.spec.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import { TodoEntity } from '../../../model/todo'; +import { TodoTableComponent } from './todoTable'; + +describe('TodoTableComponent', () => { + it('should render as expected', () => { + const todos: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false, + } + ] + + const component = shallow( + , + ); + + expect(component).toMatchSnapshot(); + }); +}); diff --git a/03 Test Redux PabloRC/src/components/todoList/components/todoTable.tsx b/03 Test Redux PabloRC/src/components/todoList/components/todoTable.tsx new file mode 100644 index 0000000..8379262 --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/components/todoTable.tsx @@ -0,0 +1,39 @@ +import * as React from 'react'; +import {TodoEntity} from '../../../model/todo'; +import {TodoRowComponent} from './todoRow'; + +interface Props { + todos: TodoEntity[]; +} + +export const TodoTableComponent = (props: Props) => { + return ( +
+ + + + + + + + + + + { + props.todos && props.todos.map((todo: TodoEntity) => + + ) + } + +
+ UserId + + Id + + Title + + Completed +
+
+ ); +} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/components/todoList/todoArea.spec.tsx b/03 Test Redux PabloRC/src/components/todoList/todoArea.spec.tsx new file mode 100644 index 0000000..b88abaa --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/todoArea.spec.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import { TodoAreaComponent } from './todoArea'; +import { TodoEntity } from '../../model/todo'; + +describe('TodoAreaComponent', () => { + it('should render as expected', () => { + const todos: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false, + } + ] + + const loadTodos = () => { }; + + const component = shallow( + , + ); + + expect(component).toMatchSnapshot(); + }); +}); diff --git a/03 Test Redux PabloRC/src/components/todoList/todoArea.tsx b/03 Test Redux PabloRC/src/components/todoList/todoArea.tsx new file mode 100644 index 0000000..5de471a --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/todoArea.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; +import {TodoTableComponent} from './components/todoTable'; +import {TodoEntity} from '../../model/todo' + +interface Props { + todos: Array; + loadTodos: () => any; +} + +export class TodoAreaComponent extends React.Component { + + componentDidMount() { + this.props.loadTodos() + } + + render() { + const { todos } = this.props + + if(todos && todos.length === 0) { + return

Cargando datos...

+ } + + return ( + + ) + } +} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.spec.tsx b/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.spec.tsx new file mode 100644 index 0000000..260cf2b --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.spec.tsx @@ -0,0 +1,43 @@ +import * as React from 'react'; +import { mount } from 'enzyme'; +import { Provider } from 'react-redux'; +import configureStore from 'redux-mock-store'; +import ReduxThunk from 'redux-thunk'; +const middlewares = [ReduxThunk]; +const mockStore = configureStore(middlewares); + +import { TodoEntity } from "../../model/todo"; +import { TodosAreaContainer } from '..'; + +describe('TodosAreaContainer', () => { + it('debe pintar TodoAreaComponent cuando tenemos todos', () => { + const todos: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false + } + ] + + const store = mockStore({ + sessionReducer: { + todos, + }, + }); + + const component = mount( + + + , + ); + + expect(component).toMatchSnapshot(); + }); +}); diff --git a/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.tsx b/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.tsx new file mode 100644 index 0000000..5686ccb --- /dev/null +++ b/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.tsx @@ -0,0 +1,21 @@ +import { connect } from 'react-redux'; +import { todoRequest } from '../../actions/todoRequest'; +import { TodoAreaComponent } from './todoArea'; +import { State } from '../../reducers'; + +const mapStateToProps = (state :State) => { + return{ + todos: state.todoReducer + }; +} + +const mapDispatchToProps = dispatch => { + return { + loadTodos: () => {return dispatch(todoRequest())} + }; +} + +export const TodosAreaContainer = connect( + mapStateToProps, + mapDispatchToProps +)(TodoAreaComponent); \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/content/styles.css b/03 Test Redux PabloRC/src/content/styles.css new file mode 100644 index 0000000..70c3cd1 --- /dev/null +++ b/03 Test Redux PabloRC/src/content/styles.css @@ -0,0 +1,24 @@ +/* Default Table Style */ +table { + color: #333; + background: white; + border: 1px solid grey; + font-size: 12pt; + border-collapse: collapse; +} + +table thead th, +table tfoot th { + color: #777; + background: rgba(0,0,0,.1); +} + +table caption { + padding:.5em; +} + +table th, +table td { + padding: .5em; + border: 1px solid lightgrey; +} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/index.html b/03 Test Redux PabloRC/src/index.html new file mode 100644 index 0000000..da1c0ad --- /dev/null +++ b/03 Test Redux PabloRC/src/index.html @@ -0,0 +1,13 @@ + + + + + + + +
+

Todo List

+
+
+ + diff --git a/03 Test Redux PabloRC/src/main.tsx b/03 Test Redux PabloRC/src/main.tsx new file mode 100644 index 0000000..cad9175 --- /dev/null +++ b/03 Test Redux PabloRC/src/main.tsx @@ -0,0 +1,19 @@ +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { createStore, applyMiddleware, compose } from 'redux'; +import reduxThunk from 'redux-thunk'; +import { Provider } from 'react-redux'; +import {reducers } from './reducers'; +import { App } from './app'; + +const composeEnhancers = window['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__'] || compose; + +const store = createStore(reducers, /* preloadedState, */ composeEnhancers( + applyMiddleware(reduxThunk) + )); + +ReactDOM.render( + + + , + document.getElementById('root')); \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/model/todo.ts b/03 Test Redux PabloRC/src/model/todo.ts new file mode 100644 index 0000000..e3b36a0 --- /dev/null +++ b/03 Test Redux PabloRC/src/model/todo.ts @@ -0,0 +1,13 @@ +export interface TodoEntity { + userId: number + id: number; + title: string; + completed: boolean; +} + +export const createDefaultTodoEntity = () => ({ + userId: -1, + id: -1, + title: '', + completed: false, +}) \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/reducers/index.ts b/03 Test Redux PabloRC/src/reducers/index.ts new file mode 100644 index 0000000..1049f3b --- /dev/null +++ b/03 Test Redux PabloRC/src/reducers/index.ts @@ -0,0 +1,10 @@ +import { combineReducers} from 'redux'; +import { todoReducer, todoState } from './todoReducer'; + +export interface State { + todoReducer : todoState; +}; + +export const reducers = combineReducers({ + todoReducer, +}); \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/reducers/todoReducer.spec.ts b/03 Test Redux PabloRC/src/reducers/todoReducer.spec.ts new file mode 100644 index 0000000..be52a4f --- /dev/null +++ b/03 Test Redux PabloRC/src/reducers/todoReducer.spec.ts @@ -0,0 +1,48 @@ +import * as deepFreeze from 'deep-freeze'; +import { todoReducer, todoState } from './todoReducer'; +import { actionsEnums } from '../common/actionsEnums'; + +describe('todoReducer', () => { + it('debe devolver el mismo estado al mandarle un tipo erróneo', () => { + const initialState = [] as todoState; + + const action = { + type: 'Wrong', + }; + + deepFreeze(initialState); + + const result = todoReducer(initialState, action); + + expect(result).toBe(initialState); + expect(initialState).not.toBe(undefined); + }); + + describe('handleTodoRequestCompletedAction', () => { + it('se actualizan los valores cuando le pasamos un type correcto', () => { + const initialState = [] as todoState; + + const action = { + type: actionsEnums.TODO_REQUEST_COMPLETED, + payload: [{ + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false + }] as todoState, + }; + + deepFreeze(initialState); + + const result = todoReducer(initialState, action); + + expect(result).toBe(action.payload); + }); + }); +}); diff --git a/03 Test Redux PabloRC/src/reducers/todoReducer.ts b/03 Test Redux PabloRC/src/reducers/todoReducer.ts new file mode 100644 index 0000000..52d8ee9 --- /dev/null +++ b/03 Test Redux PabloRC/src/reducers/todoReducer.ts @@ -0,0 +1,17 @@ +import {actionsEnums} from '../common/actionsEnums'; +import {TodoEntity} from '../model/todo'; + +export type todoState = TodoEntity[]; + +export const todoReducer = (state : todoState = [], action) => { + switch (action.type) { + case actionsEnums.TODO_REQUEST_COMPLETED: + return handleTodoRequestCompletedAction(state, action.payload); + } + + return state; +}; + +const handleTodoRequestCompletedAction = (state : todoState, todos) => { + return todos; +} \ No newline at end of file diff --git a/03 Test Redux PabloRC/tsconfig.json b/03 Test Redux PabloRC/tsconfig.json new file mode 100644 index 0000000..885d474 --- /dev/null +++ b/03 Test Redux PabloRC/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "es6", + "moduleResolution": "node", + "declaration": false, + "noImplicitAny": false, + "jsx": "react", + "sourceMap": true, + "noLib": false, + "suppressImplicitAnyIndexErrors": true + }, + "compileOnSave": false, + "exclude": [ + "node_modules" + ] +} diff --git a/03 Test Redux PabloRC/webpack.config.js b/03 Test Redux PabloRC/webpack.config.js new file mode 100644 index 0000000..3e1f971 --- /dev/null +++ b/03 Test Redux PabloRC/webpack.config.js @@ -0,0 +1,65 @@ +var HtmlWebpackPlugin = require('html-webpack-plugin'); +var MiniCssExtractPlugin = require('mini-css-extract-plugin'); +var webpack = require('webpack'); +var path = require('path'); + +var basePath = __dirname; + +module.exports = { + context: path.join(basePath, "src"), + resolve: { + extensions: ['.js', '.ts', '.tsx'] + }, + entry: ['@babel/polyfill', + './content/styles.css' , + './main.tsx' + ], + output: { + path: path.join(basePath, 'dist'), + filename: 'bundle.js' + }, + devtool: 'source-map', + devServer: { + contentBase: './dist', // Content base + inline: true, // Enable watch and live reload + host: 'localhost', + port: 8080, + stats: 'errors-only' + }, + module: { + rules: [ + { + test: /\.(ts|tsx)$/, + exclude: /node_modules/, + loader: 'awesome-typescript-loader', + options: { + useBabel: true, + "babelCore": "@babel/core", // needed for Babel v7 + }, + }, + { + test: /\.css$/, + use: [MiniCssExtractPlugin.loader, "css-loader"] + }, + { + test: /\.(png|jpg|gif|svg)$/, + loader: 'file-loader', + options: { + name: 'assets/img/[name].[ext]?[hash]' + } + }, + ], + }, + plugins: [ + //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', //Name of file in ./dist/ + template: 'index.html', //Name of template in ./src + hash: true, + }), + new MiniCssExtractPlugin({ + filename: "[name].css", + chunkFilename: "[id].css" + }), + ], +}; diff --git a/Prueba.txt b/Prueba.txt deleted file mode 100644 index d672d08..0000000 --- a/Prueba.txt +++ /dev/null @@ -1 +0,0 @@ -Prueba commit inicial \ No newline at end of file From e207c9536b9f03d25b9f0d43c67b5c4fcf44b382 Mon Sep 17 00:00:00 2001 From: Senesero Date: Sun, 5 Apr 2020 14:51:06 +0200 Subject: [PATCH 4/9] CRUD hook completado --- 04 Test Hooks PablorRC/.babelrc | 10 ++ 04 Test Hooks PablorRC/.editorconfig | 9 ++ 04 Test Hooks PablorRC/.prettierrc | 4 + 04 Test Hooks PablorRC/README.md | 8 ++ 04 Test Hooks PablorRC/config/test/jest.json | 6 + 04 Test Hooks PablorRC/config/webpack/base.js | 59 ++++++++++ 04 Test Hooks PablorRC/config/webpack/dev.js | 19 ++++ .../config/webpack/helpers.js | 5 + 04 Test Hooks PablorRC/config/webpack/prod.js | 11 ++ 04 Test Hooks PablorRC/package.json | 47 ++++++++ 04 Test Hooks PablorRC/src/app.spec.tsx | 45 ++++++++ 04 Test Hooks PablorRC/src/app.tsx | 25 ++++ .../src/components/TodoRow.spec.tsx | 67 +++++++++++ .../src/components/TodoRow.tsx | 63 +++++++++++ .../src/components/TodosTable.spec.tsx | 52 +++++++++ .../src/components/TodosTable.tsx | 55 +++++++++ .../src/components/index.ts | 2 + .../src/components/useTodos.spec.tsx | 107 ++++++++++++++++++ .../src/components/useTodos.tsx | 36 ++++++ 04 Test Hooks PablorRC/src/content/styles.css | 23 ++++ 04 Test Hooks PablorRC/src/index.html | 14 +++ 04 Test Hooks PablorRC/src/index.tsx | 5 + 04 Test Hooks PablorRC/tsconfig.json | 20 ++++ 23 files changed, 692 insertions(+) create mode 100644 04 Test Hooks PablorRC/.babelrc create mode 100644 04 Test Hooks PablorRC/.editorconfig create mode 100644 04 Test Hooks PablorRC/.prettierrc create mode 100644 04 Test Hooks PablorRC/README.md create mode 100644 04 Test Hooks PablorRC/config/test/jest.json create mode 100644 04 Test Hooks PablorRC/config/webpack/base.js create mode 100644 04 Test Hooks PablorRC/config/webpack/dev.js create mode 100644 04 Test Hooks PablorRC/config/webpack/helpers.js create mode 100644 04 Test Hooks PablorRC/config/webpack/prod.js create mode 100644 04 Test Hooks PablorRC/package.json create mode 100644 04 Test Hooks PablorRC/src/app.spec.tsx create mode 100644 04 Test Hooks PablorRC/src/app.tsx create mode 100644 04 Test Hooks PablorRC/src/components/TodoRow.spec.tsx create mode 100644 04 Test Hooks PablorRC/src/components/TodoRow.tsx create mode 100644 04 Test Hooks PablorRC/src/components/TodosTable.spec.tsx create mode 100644 04 Test Hooks PablorRC/src/components/TodosTable.tsx create mode 100644 04 Test Hooks PablorRC/src/components/index.ts create mode 100644 04 Test Hooks PablorRC/src/components/useTodos.spec.tsx create mode 100644 04 Test Hooks PablorRC/src/components/useTodos.tsx create mode 100644 04 Test Hooks PablorRC/src/content/styles.css create mode 100644 04 Test Hooks PablorRC/src/index.html create mode 100644 04 Test Hooks PablorRC/src/index.tsx create mode 100644 04 Test Hooks PablorRC/tsconfig.json diff --git a/04 Test Hooks PablorRC/.babelrc b/04 Test Hooks PablorRC/.babelrc new file mode 100644 index 0000000..957cae3 --- /dev/null +++ b/04 Test Hooks PablorRC/.babelrc @@ -0,0 +1,10 @@ +{ + "presets": [ + [ + "@babel/preset-env", + { + "useBuiltIns": "entry" + } + ] + ] +} diff --git a/04 Test Hooks PablorRC/.editorconfig b/04 Test Hooks PablorRC/.editorconfig new file mode 100644 index 0000000..c6c8b36 --- /dev/null +++ b/04 Test Hooks PablorRC/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/04 Test Hooks PablorRC/.prettierrc b/04 Test Hooks PablorRC/.prettierrc new file mode 100644 index 0000000..c1a6f66 --- /dev/null +++ b/04 Test Hooks PablorRC/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "es5" +} diff --git a/04 Test Hooks PablorRC/README.md b/04 Test Hooks PablorRC/README.md new file mode 100644 index 0000000..aa1b941 --- /dev/null +++ b/04 Test Hooks PablorRC/README.md @@ -0,0 +1,8 @@ +# Base project for the training + +React Testing Library is a library built on DOM Testing Library to provide support for React component testing. DOM Testing Library is a light-weight solution to write maintainable tests for UI applications. The main idea behind this library is to focus on the actual functionality behind a given application, so that the tests are more concerned with that the application does and what the user sees rather than implementation details and the abstractions behind them. This approach also favors maintainability in the long term, as the tests themselves should not break when refactoring or performing implementation changes as long as the same outwards functionality is kept. + +This repository covers some guided examples to introduce briefly React Testing Library and React Hooks Testing Library to write tests using Jest. For further examples, you may check some of the resources below +- https://react-hooks-testing-library.com/ +- https://testing-library.com/docs/intro +- https://github.com/Lemoncode/react-testing-by-example diff --git a/04 Test Hooks PablorRC/config/test/jest.json b/04 Test Hooks PablorRC/config/test/jest.json new file mode 100644 index 0000000..7cef52d --- /dev/null +++ b/04 Test Hooks PablorRC/config/test/jest.json @@ -0,0 +1,6 @@ +{ + "rootDir": "../../", + "preset": "ts-jest", + "restoreMocks": true, + "setupFilesAfterEnv": ["@testing-library/react/cleanup-after-each"] +} diff --git a/04 Test Hooks PablorRC/config/webpack/base.js b/04 Test Hooks PablorRC/config/webpack/base.js new file mode 100644 index 0000000..5922317 --- /dev/null +++ b/04 Test Hooks PablorRC/config/webpack/base.js @@ -0,0 +1,59 @@ +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const { CheckerPlugin } = require('awesome-typescript-loader'); +const merge = require('webpack-merge'); +const helpers = require('./helpers'); +var MiniCssExtractPlugin = require('mini-css-extract-plugin'); + +module.exports = merge( + {}, + { + context: helpers.resolveFromRootPath('src'), + resolve: { + extensions: ['.js', '.ts', '.tsx'], + }, + entry: { + app: ['./index.tsx', './content/styles.css'], + }, + module: { + rules: [ + { + test: /\.tsx?$/, + exclude: /node_modules/, + loader: 'awesome-typescript-loader', + options: { + useBabel: true, + useCache: true, + babelCore: '@babel/core', + }, + }, + { + test: /\.css$/, + use: [MiniCssExtractPlugin.loader, "css-loader"] + }, + ], + }, + optimization: { + splitChunks: { + cacheGroups: { + vendor: { + chunks: 'all', + name: 'vendor', + test: /[\\/]node_modules[\\/]/, + enforce: true, + }, + }, + }, + }, + plugins: [ + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + }), + new CheckerPlugin(), + new MiniCssExtractPlugin({ + filename: "[name].css", + chunkFilename: "[id].css" + }), + ], + } +); diff --git a/04 Test Hooks PablorRC/config/webpack/dev.js b/04 Test Hooks PablorRC/config/webpack/dev.js new file mode 100644 index 0000000..99acebc --- /dev/null +++ b/04 Test Hooks PablorRC/config/webpack/dev.js @@ -0,0 +1,19 @@ +const merge = require('webpack-merge'); +const base = require('./base'); +const helpers = require('./helpers'); + +module.exports = merge(base, { + mode: 'development', + devtool: 'inline-source-map', + output: { + path: helpers.resolveFromRootPath('dist'), + filename: '[name].js', + }, + devServer: { + inline: true, + host: 'localhost', + port: 8080, + stats: 'minimal', + hot: true, + }, +}); diff --git a/04 Test Hooks PablorRC/config/webpack/helpers.js b/04 Test Hooks PablorRC/config/webpack/helpers.js new file mode 100644 index 0000000..3a187bd --- /dev/null +++ b/04 Test Hooks PablorRC/config/webpack/helpers.js @@ -0,0 +1,5 @@ +const path = require('path'); + +const rootPath = path.resolve(__dirname, '../../'); + +exports.resolveFromRootPath = (...args) => path.join(rootPath, ...args); diff --git a/04 Test Hooks PablorRC/config/webpack/prod.js b/04 Test Hooks PablorRC/config/webpack/prod.js new file mode 100644 index 0000000..7435bd3 --- /dev/null +++ b/04 Test Hooks PablorRC/config/webpack/prod.js @@ -0,0 +1,11 @@ +const merge = require('webpack-merge'); +const base = require('./base'); +const helpers = require('./helpers'); + +module.exports = merge(base, { + mode: 'production', + output: { + path: helpers.resolveFromRootPath('dist'), + filename: './js/[name].[chunkhash].js', + }, +}); diff --git a/04 Test Hooks PablorRC/package.json b/04 Test Hooks PablorRC/package.json new file mode 100644 index 0000000..cd98a4a --- /dev/null +++ b/04 Test Hooks PablorRC/package.json @@ -0,0 +1,47 @@ +{ + "name": "react-testing-by-example", + "version": "1.0.0", + "description": "Learn testing by sample using jest + react-testing-library, each of the samples contains a readme.md file that indicates the purpose of the sample plus an step by step guide to reproduce it.", + "main": "index.js", + "scripts": { + "start": "webpack-dev-server --config ./config/webpack/dev.js", + "clean": "rimraf dist", + "build": "npm run clean && webpack --config ./config/webpack/prod.js", + "test": "jest -c ./config/test/jest.json --verbose", + "test:watch": "jest -c ./config/test/jest.json --verbose --watchAll -i --no-cache", + "test:coverage": "jest -c ./config/test/jest.json --verbose --coverage" + }, + "author": "arp82", + "license": "MIT", + "dependencies": { + "@material-ui/core": "^4.1.3", + "axios": "^0.19.2", + "css-loader": "^3.4.2", + "mini-css-extract-plugin": "^0.9.0", + "react": "^16.8.6", + "react-dom": "^16.8.6", + "react-router-dom": "^5.0.1" + }, + "devDependencies": { + "@babel/cli": "^7.4.4", + "@babel/core": "^7.4.5", + "@babel/preset-env": "^7.4.5", + "@testing-library/react": "^8.0.7", + "@testing-library/react-hooks": "^3.2.1", + "@types/jest": "^24.0.13", + "@types/react": "^16.8.19", + "@types/react-dom": "^16.8.4", + "@types/react-router-dom": "^4.3.4", + "awesome-typescript-loader": "^5.2.1", + "html-webpack-plugin": "^3.2.0", + "jest": "^24.8.0", + "react-test-renderer": "^16.13.1", + "rimraf": "^2.6.3", + "ts-jest": "^24.0.2", + "typescript": "^3.5.2", + "webpack": "^4.32.2", + "webpack-cli": "^3.3.2", + "webpack-dev-server": "^3.5.0", + "webpack-merge": "^4.2.1" + } +} diff --git a/04 Test Hooks PablorRC/src/app.spec.tsx b/04 Test Hooks PablorRC/src/app.spec.tsx new file mode 100644 index 0000000..557f0ed --- /dev/null +++ b/04 Test Hooks PablorRC/src/app.spec.tsx @@ -0,0 +1,45 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { App } from './app'; + +describe('App', () => { + + it('debe cargar el título', () => { + const { getByText } = render(); + + const element = getByText('Tareas'); + expect(element).not.toBeNull(); + expect(element.tagName).toEqual('H1'); + }); + + it('debe cargar la tabla', () => { + const { getByText, getByTestId } = render(); + + const headerId = getByText('Id'); + expect(headerId).not.toBeNull(); + expect(headerId.tagName).toEqual('TH'); + + const headerTitle = getByText('Título'); + expect(headerTitle).not.toBeNull(); + expect(headerTitle.tagName).toEqual('TH'); + + const headerCompleted = getByText('Completada'); + expect(headerCompleted).not.toBeNull(); + expect(headerCompleted.tagName).toEqual('TH'); + + const headerActions = getByText('Acciones'); + expect(headerActions).not.toBeNull(); + expect(headerActions.tagName).toEqual('TH'); + + const newTodo = getByText('Nueva tarea:'); + expect(newTodo).not.toBeNull(); + expect(newTodo.tagName).toEqual('TD'); + + const inputElement = getByTestId('todo-input') as HTMLInputElement; + expect(inputElement.value).toEqual('') + + const newTodoButton = getByText('Agregar tarea'); + expect(newTodoButton).not.toBeNull(); + expect(newTodoButton.tagName).toEqual('BUTTON'); + }); +}); \ No newline at end of file diff --git a/04 Test Hooks PablorRC/src/app.tsx b/04 Test Hooks PablorRC/src/app.tsx new file mode 100644 index 0000000..5d068a6 --- /dev/null +++ b/04 Test Hooks PablorRC/src/app.tsx @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { TodosTable } from './components'; +import { useTodos } from './components/useTodos'; + +export const App = () => { + // // Data *-*-*- ELIMINAR + // const todosData = [ + // { userId: 1, id: 1, title: 'Comprar', completed: true }, + // { userId: 1, id: 2, title: 'Tirar la basura', completed: false }, + // { userId: 1, id: 3, title: 'Ir al gimnasio', completed: false }, + // ] + + // const todosData = [ + // { userId: 1, id: 1, title: 'Comprar', completed: true }, + // ] + + const {todos, deleteTodo, addTodo, updateTodo} = useTodos() + + return ( +
+

Tareas

+ +
+ ) +} \ No newline at end of file diff --git a/04 Test Hooks PablorRC/src/components/TodoRow.spec.tsx b/04 Test Hooks PablorRC/src/components/TodoRow.spec.tsx new file mode 100644 index 0000000..f9b384f --- /dev/null +++ b/04 Test Hooks PablorRC/src/components/TodoRow.spec.tsx @@ -0,0 +1,67 @@ +import * as React from 'react'; +import { render, fireEvent, waitForElement } from '@testing-library/react'; +import { TodoRow } from '.'; + +describe('TodoRow', () => { + + it('si se le pasa una tarea completada, se debe de pintar Completada', () => { + const todo = { userId: 1, id: 1, title: 'Comprar', completed: true }; + + const { getByText } = render(); + + const textCompleted = getByText('Completada'); + expect(textCompleted).not.toBeNull(); + expect(textCompleted.tagName).toEqual('TD'); + }); + + it('si se le pasa una tarea no completada, se debe de pintar Pendiente', () => { + const todo = { userId: 1, id: 1, title: 'Comprar', completed: false }; + + const { getByText } = render(); + + const textCompleted = getByText('Pendiente'); + expect(textCompleted).not.toBeNull(); + expect(textCompleted.tagName).toEqual('TD'); + }); + + it('si no se está editando, la tarea tiene que mostrarse como texto', () => { + const todo = { userId: 1, id: 1, title: 'Comprar', completed: false }; + + const { getByText } = render(); + + const textCompleted = getByText('Pendiente'); + expect(textCompleted).not.toBeNull(); + expect(textCompleted.tagName).toEqual('TD'); + + const textTitle = getByText('Comprar'); + expect(textTitle).not.toBeNull(); + expect(textTitle.tagName).toEqual('TD'); + }); + + it('la función deleteTodo es llamada correctamente', async () => { + const deleteTodo = jest.fn(); + const todo = { userId: 1, id: 1, title: 'Comprar', completed: true }; + + const { getByTestId } = render(); + + const deleteTodoButton = await waitForElement(() => getByTestId('deleteTodo-button')) as HTMLButtonElement; + + fireEvent.click(deleteTodoButton) + + expect(deleteTodo).toHaveBeenCalledTimes(1) + }); + + // it('la función updateTodo es llamada correctamente', async () => { + // const updateTodo = jest.fn(); + // const todo = { userId: 1, id: 1, title: 'Comprar', completed: true }; + + // const { getByTestId } = render(); + + // const updateTodoButton = await waitForElement(() => getByTestId('updateTodo-button')) as HTMLButtonElement; + + // fireEvent.click(updateTodoButton) + + // expect(updateTodo).toHaveBeenCalledTimes(1) + // }); + +}); \ No newline at end of file diff --git a/04 Test Hooks PablorRC/src/components/TodoRow.tsx b/04 Test Hooks PablorRC/src/components/TodoRow.tsx new file mode 100644 index 0000000..c1545fb --- /dev/null +++ b/04 Test Hooks PablorRC/src/components/TodoRow.tsx @@ -0,0 +1,63 @@ +import React, { useState } from 'react' + +export const TodoRow = props => { + const [ editing, setEditing ] = useState(false) + const [ currentTodo, setCurrentTodo ] = useState(props.todo) + + const onChangeInput = event => { + const { value } = event.target + + setCurrentTodo({ ...currentTodo, title: value}) + } + + const onCancel = () => { + setEditing(false) + setCurrentTodo({ ...currentTodo, title: props.todo.title}) + } + + const onAcept = () => { + setEditing(false) + props.updateTodo(id, currentTodo) + } + + const { id, title, completed } = props.todo + + return ( + + {id} + {editing ? ( + + ) : title} + {completed ? 'Completada' : 'Pendiente'} + {editing ? ( + + + + + ) : ( + + + + + )} + + ) +} diff --git a/04 Test Hooks PablorRC/src/components/TodosTable.spec.tsx b/04 Test Hooks PablorRC/src/components/TodosTable.spec.tsx new file mode 100644 index 0000000..e4d8914 --- /dev/null +++ b/04 Test Hooks PablorRC/src/components/TodosTable.spec.tsx @@ -0,0 +1,52 @@ +import * as React from 'react'; +import { render, fireEvent, waitForElement } from '@testing-library/react'; +import { TodosTable } from './TodosTable'; + +describe('TodosTable', () => { + + it('si no tenemos tareas, debe de mostrar el texto indicándolo', () => { + const todos = []; + + const { getByText } = render(); + + const element = getByText('No existen tareas'); + expect(element).not.toBeNull(); + expect(element.tagName).toEqual('TD'); + }); + + it('si se le pasa una tarea, se debe de pintar en la tabla correctamente', () => { + const todos = [{ userId: 1, id: 1, title: 'Comprar', completed: true }]; + + const { getByText } = render(); + + const elementTitle = getByText('Comprar'); + expect(elementTitle).not.toBeNull(); + expect(elementTitle.tagName).toEqual('TD'); + + const editButton = getByText('Editar'); + expect(editButton).not.toBeNull(); + expect(editButton.tagName).toEqual('BUTTON'); + + const deleteButton = getByText('Borrar'); + expect(deleteButton).not.toBeNull(); + expect(deleteButton.tagName).toEqual('BUTTON'); + }); + + it('al agregar una nueva tarea la función addTodo es llamada correctamente y se limpia el input', async () => { + const addTodo = jest.fn(); + const todos = [{ userId: 1, id: 1, title: 'Comprar', completed: true }]; + + const { getByTestId } = render(); + + const inputElement = getByTestId('todo-input') as HTMLInputElement; + const newTodoButton = await waitForElement(() => getByTestId('addTodo-button')) as HTMLButtonElement; + + fireEvent.change(inputElement, { target: { value: 'Tirar la basura' }}) + expect(inputElement.value).toEqual('Tirar la basura') + + fireEvent.click(newTodoButton) + + expect(addTodo).toHaveBeenCalledTimes(1) + expect(inputElement.value).toEqual('') + }); +}); \ No newline at end of file diff --git a/04 Test Hooks PablorRC/src/components/TodosTable.tsx b/04 Test Hooks PablorRC/src/components/TodosTable.tsx new file mode 100644 index 0000000..f0a59f8 --- /dev/null +++ b/04 Test Hooks PablorRC/src/components/TodosTable.tsx @@ -0,0 +1,55 @@ +import React, { useState } from 'react' +import { TodoRow } from '.' + +export const TodosTable = props => { + const initialFormState = { userId: 1, id: null, title: '', completed: false } + + const [ todo, setTodo ] = useState(initialFormState) + + const handleInputChange = event => { + const { name, value } = event.target + + setTodo({ ...todo, [name]: value }) + } + + const onAddSubmit = () => { + if (!todo.title) { + alert('Rellene la tarea para poder agregarla') + return + } + + props.addTodo(todo) + setTodo(initialFormState) + } + + return ( + + + + + + + + + + + {props.todos.length > 0 ? ( + props.todos.map(todo => ) + ) : ( + + + + )} + + + + + +
IdTítuloCompletadaAcciones
No existen tareas
+ Nueva tarea: + + + +
+ ) +} \ No newline at end of file diff --git a/04 Test Hooks PablorRC/src/components/index.ts b/04 Test Hooks PablorRC/src/components/index.ts new file mode 100644 index 0000000..89b242c --- /dev/null +++ b/04 Test Hooks PablorRC/src/components/index.ts @@ -0,0 +1,2 @@ +export { TodosTable } from './TodosTable'; +export { TodoRow } from './TodoRow'; \ No newline at end of file diff --git a/04 Test Hooks PablorRC/src/components/useTodos.spec.tsx b/04 Test Hooks PablorRC/src/components/useTodos.spec.tsx new file mode 100644 index 0000000..d0efe3c --- /dev/null +++ b/04 Test Hooks PablorRC/src/components/useTodos.spec.tsx @@ -0,0 +1,107 @@ +import { renderHook, act } from '@testing-library/react-hooks'; +import { useTodos, getTodos } from './useTodos' +import Axios from 'axios' + +describe('useTodos', () => { + it('al inicializar, las tareas están vacías y add, delete y update son funciones', () => { + const { result } = renderHook(() => useTodos()) + + expect(result.current.todos).toEqual([]) + expect(result.current.addTodo).toEqual(expect.any(Function)) + expect(result.current.deleteTodo).toEqual(expect.any(Function)) + expect(result.current.updateTodo).toEqual(expect.any(Function)) + }) + + // it('Se realiza la llamada correctamente a la api', async () => { + // const setTodos = jest.fn() + // const todosData = [ + // { userId: 1, id: 1, title: 'Comprar', completed: true }, + // { userId: 1, id: 2, title: 'Tirar la basura', completed: false }, + // { userId: 1, id: 3, title: 'Ir al gimnasio', completed: false }, + // ] + + // const getTodosData = jest.spyOn(Axios, 'get').mockResolvedValue({ + // data: todosData, + // }) + + // await getTodos(setTodos) + + // expect(getTodosData).toHaveBeenCalledWith('https://jsonplaceholder.typicode.com/todos?userId=1') + // expect(setTodos).toHaveBeenCalled() + // }) + + it('debe actualizarse cuando llamamos a setTodos', () => { + const todosData = [ + { userId: 1, id: 1, title: 'Comprar', completed: true }, + { userId: 1, id: 2, title: 'Tirar la basura', completed: false }, + { userId: 1, id: 3, title: 'Ir al gimnasio', completed: false }, + ] + + const { result } = renderHook(() => useTodos()) + + act(() => { + result.current.setTodos(todosData) + }) + + expect(result.current.todos).toEqual(todosData) + }) + + it('debe agregarse correctamente el nuevo elemento cuando llamamos a addTodo', () => { + const todosData = [ + { userId: 1, id: 1, title: 'Comprar', completed: true }, + ] + const newTodo = { userId: 1, id: null, title: 'Tirar la basura', completed: false } + const newTodosData = [ + { userId: 1, id: 1, title: 'Comprar', completed: true }, + { userId: 1, id: 2, title: 'Tirar la basura', completed: false } + ] + + const { result } = renderHook(() => useTodos(todosData)) + + act(() => { + result.current.addTodo(newTodo) + }) + + expect(result.current.todos).toEqual(newTodosData) + }) + + it('debe eliminarse correctamente el elemento indicado cuando llamamos a deleteTodo', () => { + const todosData = [ + { userId: 1, id: 1, title: 'Comprar', completed: true }, + { userId: 1, id: 2, title: 'Tirar la basura', completed: false } + ] + const idToDelete = 1 + const newTodosData = [ + { userId: 1, id: 2, title: 'Tirar la basura', completed: false } + ] + + const { result } = renderHook(() => useTodos(todosData)) + + act(() => { + result.current.deleteTodo(idToDelete) + }) + + expect(result.current.todos).toEqual(newTodosData) + }) + + it('debe actualizarse correctamente el elemento indicado cuando llamamos a updateTodo', () => { + const todosData = [ + { userId: 1, id: 1, title: 'Comprar', completed: true }, + { userId: 1, id: 2, title: 'Tirar la basura', completed: false } + ] + const idToUpdate = 2 + const newTodo = { userId: 1, id: 2, title: 'Tirar la basura a las 20.00', completed: false } + const newTodosData = [ + { userId: 1, id: 1, title: 'Comprar', completed: true }, + { userId: 1, id: 2, title: 'Tirar la basura a las 20.00', completed: false } + ] + + const { result } = renderHook(() => useTodos(todosData)) + + act(() => { + result.current.updateTodo(idToUpdate, newTodo) + }) + + expect(result.current.todos).toEqual(newTodosData) + }) +}) \ No newline at end of file diff --git a/04 Test Hooks PablorRC/src/components/useTodos.tsx b/04 Test Hooks PablorRC/src/components/useTodos.tsx new file mode 100644 index 0000000..05ca01e --- /dev/null +++ b/04 Test Hooks PablorRC/src/components/useTodos.tsx @@ -0,0 +1,36 @@ +import * as React from 'react'; +import Axios from 'axios' + +export const getTodos = (setTodos) => + React.useEffect(() => { + Axios.get('https://jsonplaceholder.typicode.com/todos?userId=1') + .then(response => setTodos(response.data)); + }, []); + +export const useTodos = (todosData = []) => { + const [ todos, setTodos] = React.useState(todosData); + + getTodos(setTodos) + + const addTodo = (todo) => { + todo.id = todos[todos.length - 1].id + 1 + setTodos([ ...todos, todo ]) + } + + const deleteTodo = id => { + setTodos(todos.filter(todo => todo.id !== id)) + } + + const updateTodo = (id, updatedTodo) => { + setTodos(todos.map(todo => (todo.id === id ? updatedTodo : todo))) + } + + return { + todos, + setTodos, + getTodos, + addTodo, + deleteTodo, + updateTodo, + } +} \ No newline at end of file diff --git a/04 Test Hooks PablorRC/src/content/styles.css b/04 Test Hooks PablorRC/src/content/styles.css new file mode 100644 index 0000000..630e085 --- /dev/null +++ b/04 Test Hooks PablorRC/src/content/styles.css @@ -0,0 +1,23 @@ +table { + color: #333; + background: white; + border: 1px solid grey; + font-size: 12pt; + border-collapse: collapse; +} + +table thead th, +table tfoot th { + color: #777; + background: rgba(0,0,0,.1); +} + +table caption { + padding:.5em; +} + +table th, +table td { + padding: .5em; + border: 1px solid lightgrey; +} \ No newline at end of file diff --git a/04 Test Hooks PablorRC/src/index.html b/04 Test Hooks PablorRC/src/index.html new file mode 100644 index 0000000..64a436c --- /dev/null +++ b/04 Test Hooks PablorRC/src/index.html @@ -0,0 +1,14 @@ + + + + + + Tareas + + +
+ + diff --git a/04 Test Hooks PablorRC/src/index.tsx b/04 Test Hooks PablorRC/src/index.tsx new file mode 100644 index 0000000..ded7936 --- /dev/null +++ b/04 Test Hooks PablorRC/src/index.tsx @@ -0,0 +1,5 @@ +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from './app'; + +ReactDOM.render(, document.getElementById('root')); diff --git a/04 Test Hooks PablorRC/tsconfig.json b/04 Test Hooks PablorRC/tsconfig.json new file mode 100644 index 0000000..86c8569 --- /dev/null +++ b/04 Test Hooks PablorRC/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "es6", + "moduleResolution": "node", + "declaration": false, + "noImplicitAny": false, + "sourceMap": true, + "jsx": "react", + "noLib": false, + "allowJs": true, + "suppressImplicitAnyIndexErrors": true, + "skipLibCheck": true, + "esModuleInterop": true + }, + "include": ["./src/**/*"], + "exclude": [ + "node_modules", + ] +} From c3490fae2b02cc7cbf84d009b41e3775e51a1f8c Mon Sep 17 00:00:00 2001 From: Senesero Date: Thu, 9 Apr 2020 18:52:27 +0200 Subject: [PATCH 5/9] Eliminar proyecto redux --- .../.babelrc | 0 .../.editorconfig | 0 .../.prettierrc | 0 .../README.md | 0 .../config/test/jest.json | 0 .../config/webpack/base.js | 0 .../config/webpack/dev.js | 0 .../config/webpack/helpers.js | 0 .../config/webpack/prod.js | 0 .../package.json | 0 .../src/app.spec.tsx | 0 .../src/app.tsx | 0 .../src/components/TodoRow.spec.tsx | 0 .../src/components/TodoRow.tsx | 0 .../src/components/TodosTable.spec.tsx | 0 .../src/components/TodosTable.tsx | 0 .../src/components/index.ts | 0 .../src/components/useTodos.spec.tsx | 0 .../src/components/useTodos.tsx | 0 .../src/content/styles.css | 0 .../src/index.html | 0 .../src/index.tsx | 0 .../tsconfig.json | 0 .../config/test/polyfills.js | 2 - .../config/test/setupTest.js | 5 -- 03 Test Redux PabloRC/package.json | 76 ------------------- 03 Test Redux PabloRC/readme.md | 1 - 03 Test Redux PabloRC/readme_es.md | 1 - .../src/actions/todoRequest.spec.ts | 55 -------------- .../src/actions/todoRequest.ts | 20 ----- 03 Test Redux PabloRC/src/api/todo.spec.ts | 31 -------- 03 Test Redux PabloRC/src/api/todo.ts | 15 ---- 03 Test Redux PabloRC/src/app.tsx | 12 --- .../src/common/actionsEnums.ts | 3 - 03 Test Redux PabloRC/src/components/index.ts | 1 - .../__snapshots__/todoArea.spec.tsx.snap | 22 ------ .../todoAreaContainer.spec.tsx.snap | 50 ------------ .../__snapshots__/todoRow.spec.tsx.snap | 26 ------- .../__snapshots__/todoTable.spec.tsx.snap | 52 ------------- .../todoList/components/todoRow.spec.tsx | 21 ----- .../todoList/components/todoRow.tsx | 26 ------- .../todoList/components/todoTable.spec.tsx | 29 ------- .../todoList/components/todoTable.tsx | 39 ---------- .../src/components/todoList/todoArea.spec.tsx | 31 -------- .../src/components/todoList/todoArea.tsx | 27 ------- .../todoList/todoAreaContainer.spec.tsx | 43 ----------- .../components/todoList/todoAreaContainer.tsx | 21 ----- 03 Test Redux PabloRC/src/content/styles.css | 24 ------ 03 Test Redux PabloRC/src/index.html | 13 ---- 03 Test Redux PabloRC/src/main.tsx | 19 ----- 03 Test Redux PabloRC/src/model/todo.ts | 13 ---- 03 Test Redux PabloRC/src/reducers/index.ts | 10 --- .../src/reducers/todoReducer.spec.ts | 48 ------------ .../src/reducers/todoReducer.ts | 17 ----- 03 Test Redux PabloRC/tsconfig.json | 17 ----- 03 Test Redux PabloRC/webpack.config.js | 65 ---------------- 04 Test Hooks PablorRC/.babelrc | 10 --- 57 files changed, 845 deletions(-) rename {03 Test Redux PabloRC => 03 Test Hooks PablorRC}/.babelrc (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/.editorconfig (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/.prettierrc (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/README.md (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/config/test/jest.json (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/config/webpack/base.js (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/config/webpack/dev.js (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/config/webpack/helpers.js (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/config/webpack/prod.js (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/package.json (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/app.spec.tsx (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/app.tsx (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/components/TodoRow.spec.tsx (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/components/TodoRow.tsx (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/components/TodosTable.spec.tsx (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/components/TodosTable.tsx (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/components/index.ts (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/components/useTodos.spec.tsx (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/components/useTodos.tsx (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/content/styles.css (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/index.html (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/src/index.tsx (100%) rename {04 Test Hooks PablorRC => 03 Test Hooks PablorRC}/tsconfig.json (100%) delete mode 100644 03 Test Redux PabloRC/config/test/polyfills.js delete mode 100644 03 Test Redux PabloRC/config/test/setupTest.js delete mode 100644 03 Test Redux PabloRC/package.json delete mode 100644 03 Test Redux PabloRC/readme.md delete mode 100644 03 Test Redux PabloRC/readme_es.md delete mode 100644 03 Test Redux PabloRC/src/actions/todoRequest.spec.ts delete mode 100644 03 Test Redux PabloRC/src/actions/todoRequest.ts delete mode 100644 03 Test Redux PabloRC/src/api/todo.spec.ts delete mode 100644 03 Test Redux PabloRC/src/api/todo.ts delete mode 100644 03 Test Redux PabloRC/src/app.tsx delete mode 100644 03 Test Redux PabloRC/src/common/actionsEnums.ts delete mode 100644 03 Test Redux PabloRC/src/components/index.ts delete mode 100644 03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoArea.spec.tsx.snap delete mode 100644 03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoAreaContainer.spec.tsx.snap delete mode 100644 03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoRow.spec.tsx.snap delete mode 100644 03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoTable.spec.tsx.snap delete mode 100644 03 Test Redux PabloRC/src/components/todoList/components/todoRow.spec.tsx delete mode 100644 03 Test Redux PabloRC/src/components/todoList/components/todoRow.tsx delete mode 100644 03 Test Redux PabloRC/src/components/todoList/components/todoTable.spec.tsx delete mode 100644 03 Test Redux PabloRC/src/components/todoList/components/todoTable.tsx delete mode 100644 03 Test Redux PabloRC/src/components/todoList/todoArea.spec.tsx delete mode 100644 03 Test Redux PabloRC/src/components/todoList/todoArea.tsx delete mode 100644 03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.spec.tsx delete mode 100644 03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.tsx delete mode 100644 03 Test Redux PabloRC/src/content/styles.css delete mode 100644 03 Test Redux PabloRC/src/index.html delete mode 100644 03 Test Redux PabloRC/src/main.tsx delete mode 100644 03 Test Redux PabloRC/src/model/todo.ts delete mode 100644 03 Test Redux PabloRC/src/reducers/index.ts delete mode 100644 03 Test Redux PabloRC/src/reducers/todoReducer.spec.ts delete mode 100644 03 Test Redux PabloRC/src/reducers/todoReducer.ts delete mode 100644 03 Test Redux PabloRC/tsconfig.json delete mode 100644 03 Test Redux PabloRC/webpack.config.js delete mode 100644 04 Test Hooks PablorRC/.babelrc diff --git a/03 Test Redux PabloRC/.babelrc b/03 Test Hooks PablorRC/.babelrc similarity index 100% rename from 03 Test Redux PabloRC/.babelrc rename to 03 Test Hooks PablorRC/.babelrc diff --git a/04 Test Hooks PablorRC/.editorconfig b/03 Test Hooks PablorRC/.editorconfig similarity index 100% rename from 04 Test Hooks PablorRC/.editorconfig rename to 03 Test Hooks PablorRC/.editorconfig diff --git a/04 Test Hooks PablorRC/.prettierrc b/03 Test Hooks PablorRC/.prettierrc similarity index 100% rename from 04 Test Hooks PablorRC/.prettierrc rename to 03 Test Hooks PablorRC/.prettierrc diff --git a/04 Test Hooks PablorRC/README.md b/03 Test Hooks PablorRC/README.md similarity index 100% rename from 04 Test Hooks PablorRC/README.md rename to 03 Test Hooks PablorRC/README.md diff --git a/04 Test Hooks PablorRC/config/test/jest.json b/03 Test Hooks PablorRC/config/test/jest.json similarity index 100% rename from 04 Test Hooks PablorRC/config/test/jest.json rename to 03 Test Hooks PablorRC/config/test/jest.json diff --git a/04 Test Hooks PablorRC/config/webpack/base.js b/03 Test Hooks PablorRC/config/webpack/base.js similarity index 100% rename from 04 Test Hooks PablorRC/config/webpack/base.js rename to 03 Test Hooks PablorRC/config/webpack/base.js diff --git a/04 Test Hooks PablorRC/config/webpack/dev.js b/03 Test Hooks PablorRC/config/webpack/dev.js similarity index 100% rename from 04 Test Hooks PablorRC/config/webpack/dev.js rename to 03 Test Hooks PablorRC/config/webpack/dev.js diff --git a/04 Test Hooks PablorRC/config/webpack/helpers.js b/03 Test Hooks PablorRC/config/webpack/helpers.js similarity index 100% rename from 04 Test Hooks PablorRC/config/webpack/helpers.js rename to 03 Test Hooks PablorRC/config/webpack/helpers.js diff --git a/04 Test Hooks PablorRC/config/webpack/prod.js b/03 Test Hooks PablorRC/config/webpack/prod.js similarity index 100% rename from 04 Test Hooks PablorRC/config/webpack/prod.js rename to 03 Test Hooks PablorRC/config/webpack/prod.js diff --git a/04 Test Hooks PablorRC/package.json b/03 Test Hooks PablorRC/package.json similarity index 100% rename from 04 Test Hooks PablorRC/package.json rename to 03 Test Hooks PablorRC/package.json diff --git a/04 Test Hooks PablorRC/src/app.spec.tsx b/03 Test Hooks PablorRC/src/app.spec.tsx similarity index 100% rename from 04 Test Hooks PablorRC/src/app.spec.tsx rename to 03 Test Hooks PablorRC/src/app.spec.tsx diff --git a/04 Test Hooks PablorRC/src/app.tsx b/03 Test Hooks PablorRC/src/app.tsx similarity index 100% rename from 04 Test Hooks PablorRC/src/app.tsx rename to 03 Test Hooks PablorRC/src/app.tsx diff --git a/04 Test Hooks PablorRC/src/components/TodoRow.spec.tsx b/03 Test Hooks PablorRC/src/components/TodoRow.spec.tsx similarity index 100% rename from 04 Test Hooks PablorRC/src/components/TodoRow.spec.tsx rename to 03 Test Hooks PablorRC/src/components/TodoRow.spec.tsx diff --git a/04 Test Hooks PablorRC/src/components/TodoRow.tsx b/03 Test Hooks PablorRC/src/components/TodoRow.tsx similarity index 100% rename from 04 Test Hooks PablorRC/src/components/TodoRow.tsx rename to 03 Test Hooks PablorRC/src/components/TodoRow.tsx diff --git a/04 Test Hooks PablorRC/src/components/TodosTable.spec.tsx b/03 Test Hooks PablorRC/src/components/TodosTable.spec.tsx similarity index 100% rename from 04 Test Hooks PablorRC/src/components/TodosTable.spec.tsx rename to 03 Test Hooks PablorRC/src/components/TodosTable.spec.tsx diff --git a/04 Test Hooks PablorRC/src/components/TodosTable.tsx b/03 Test Hooks PablorRC/src/components/TodosTable.tsx similarity index 100% rename from 04 Test Hooks PablorRC/src/components/TodosTable.tsx rename to 03 Test Hooks PablorRC/src/components/TodosTable.tsx diff --git a/04 Test Hooks PablorRC/src/components/index.ts b/03 Test Hooks PablorRC/src/components/index.ts similarity index 100% rename from 04 Test Hooks PablorRC/src/components/index.ts rename to 03 Test Hooks PablorRC/src/components/index.ts diff --git a/04 Test Hooks PablorRC/src/components/useTodos.spec.tsx b/03 Test Hooks PablorRC/src/components/useTodos.spec.tsx similarity index 100% rename from 04 Test Hooks PablorRC/src/components/useTodos.spec.tsx rename to 03 Test Hooks PablorRC/src/components/useTodos.spec.tsx diff --git a/04 Test Hooks PablorRC/src/components/useTodos.tsx b/03 Test Hooks PablorRC/src/components/useTodos.tsx similarity index 100% rename from 04 Test Hooks PablorRC/src/components/useTodos.tsx rename to 03 Test Hooks PablorRC/src/components/useTodos.tsx diff --git a/04 Test Hooks PablorRC/src/content/styles.css b/03 Test Hooks PablorRC/src/content/styles.css similarity index 100% rename from 04 Test Hooks PablorRC/src/content/styles.css rename to 03 Test Hooks PablorRC/src/content/styles.css diff --git a/04 Test Hooks PablorRC/src/index.html b/03 Test Hooks PablorRC/src/index.html similarity index 100% rename from 04 Test Hooks PablorRC/src/index.html rename to 03 Test Hooks PablorRC/src/index.html diff --git a/04 Test Hooks PablorRC/src/index.tsx b/03 Test Hooks PablorRC/src/index.tsx similarity index 100% rename from 04 Test Hooks PablorRC/src/index.tsx rename to 03 Test Hooks PablorRC/src/index.tsx diff --git a/04 Test Hooks PablorRC/tsconfig.json b/03 Test Hooks PablorRC/tsconfig.json similarity index 100% rename from 04 Test Hooks PablorRC/tsconfig.json rename to 03 Test Hooks PablorRC/tsconfig.json diff --git a/03 Test Redux PabloRC/config/test/polyfills.js b/03 Test Redux PabloRC/config/test/polyfills.js deleted file mode 100644 index 0d9f7ef..0000000 --- a/03 Test Redux PabloRC/config/test/polyfills.js +++ /dev/null @@ -1,2 +0,0 @@ -// Polyfill requestAnimationFrame required by React >=16.0.0 -require('raf/polyfill'); diff --git a/03 Test Redux PabloRC/config/test/setupTest.js b/03 Test Redux PabloRC/config/test/setupTest.js deleted file mode 100644 index a0373fb..0000000 --- a/03 Test Redux PabloRC/config/test/setupTest.js +++ /dev/null @@ -1,5 +0,0 @@ -const enzyme = require('enzyme'); -const Adapter = require('enzyme-adapter-react-16'); - -// Setup enzyme's react adapter -enzyme.configure({ adapter: new Adapter() }); diff --git a/03 Test Redux PabloRC/package.json b/03 Test Redux PabloRC/package.json deleted file mode 100644 index 227d17b..0000000 --- a/03 Test Redux PabloRC/package.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "name": "reactbysample", - "version": "1.0.0", - "description": "In this sample we setup the basic plumbing to \"build\" our project and launch it in a dev server.", - "main": "index.js", - "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", - "build": "webpack --mode development", - "test": "jest --verbose", - "test:watch": "jest --watchAll --verbose -i", - "test:coverage": "jest --verbose --coverage" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "@babel/cli": "^7.1.2", - "@babel/core": "^7.1.2", - "@babel/polyfill": "^7.0.0", - "@babel/preset-env": "^7.1.0", - "@types/deep-freeze": "^0.1.2", - "@types/enzyme": "^3.10.5", - "@types/jest": "^25.1.4", - "@types/react": "^16.9.31", - "@types/react-dom": "^16.9.6", - "@types/react-redux": "^7.1.7", - "@types/redux-mock-store": "^1.0.2", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.4", - "css-loader": "^1.0.0", - "deep-freeze": "0.0.1", - "enzyme": "^3.11.0", - "enzyme-adapter-react-16": "^1.15.2", - "enzyme-to-json": "^3.4.4", - "file-loader": "^2.0.0", - "html-webpack-plugin": "^3.2.0", - "jest": "^25.2.6", - "mini-css-extract-plugin": "^0.4.3", - "raf": "^3.4.1", - "style-loader": "^0.23.1", - "ts-jest": "^25.3.0", - "typescript": "^3.1.1", - "url-loader": "^1.1.1", - "webpack": "^4.20.2", - "webpack-cli": "^3.1.2", - "webpack-dev-server": "^3.1.9" - }, - "dependencies": { - "axios": "^0.19.2", - "react": "^16.13.1", - "react-dom": "^16.13.1", - "react-redux": "^7.2.0", - "redux": "^4.0.5", - "redux-mock-store": "^1.5.4", - "redux-thunk": "^2.3.0" - }, - "jest": { - "testRegex": "\\.spec\\.tsx?$", - "moduleFileExtensions": [ - "js", - "jsx", - "json", - "ts", - "tsx" - ], - "setupFiles": [ - "/config/test/polyfills.js", - "/config/test/setupTest.js" - ], - "transform": { - ".tsx?": "/node_modules/ts-jest/preprocessor.js" - }, - "snapshotSerializers": [ - "enzyme-to-json/serializer" - ] - } -} diff --git a/03 Test Redux PabloRC/readme.md b/03 Test Redux PabloRC/readme.md deleted file mode 100644 index 2bc0324..0000000 --- a/03 Test Redux PabloRC/readme.md +++ /dev/null @@ -1 +0,0 @@ -# 00 Boilerplate --> Lemoncode \ No newline at end of file diff --git a/03 Test Redux PabloRC/readme_es.md b/03 Test Redux PabloRC/readme_es.md deleted file mode 100644 index 2bc0324..0000000 --- a/03 Test Redux PabloRC/readme_es.md +++ /dev/null @@ -1 +0,0 @@ -# 00 Boilerplate --> Lemoncode \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/actions/todoRequest.spec.ts b/03 Test Redux PabloRC/src/actions/todoRequest.spec.ts deleted file mode 100644 index ef6daf3..0000000 --- a/03 Test Redux PabloRC/src/actions/todoRequest.spec.ts +++ /dev/null @@ -1,55 +0,0 @@ -import configureStore from 'redux-mock-store'; -import ReduxThunk from 'redux-thunk'; -const middlewares = [ReduxThunk]; -const mockStore = configureStore(middlewares); - -import { TodoEntity } from "../model/todo"; -import { todoRequestCompletedAction } from "./todoRequest"; -import { actionsEnums } from "../common/actionsEnums"; - -describe('todoRequestCompletedAction', () => { - it('debe devolver acción cuando el tipo sea TODO_REQUEST_COMPLETED', () => { - const todoResponse: TodoEntity[] = [ - { - userId: 1, - id: 1, - title: 'Hacer la compra', - completed: true, - }, - { - userId: 1, - id: 2, - title: 'Ir al gimnasio', - completed: false - } - ] - - const result = todoRequestCompletedAction(todoResponse); - - expect(result.type).toBe(actionsEnums.TODO_REQUEST_COMPLETED); - expect(result.payload).toBe(todoResponse); - }); - - it('se realiza la llamada para obtener los todos', () => { - const todoResponse: TodoEntity[] = [ - { - userId: 1, - id: 1, - title: 'Hacer la compra', - completed: true, - }, - { - userId: 1, - id: 2, - title: 'Ir al gimnasio', - completed: false - } - ] - - const store = mockStore(); - store.dispatch(todoRequestCompletedAction(todoResponse)) - - expect(store.getActions()[0].type).toBe(actionsEnums.TODO_REQUEST_COMPLETED); - expect(store.getActions()[0].payload).toBe(todoResponse); - }); -}); \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/actions/todoRequest.ts b/03 Test Redux PabloRC/src/actions/todoRequest.ts deleted file mode 100644 index eb1d34f..0000000 --- a/03 Test Redux PabloRC/src/actions/todoRequest.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {actionsEnums} from '../common/actionsEnums'; -import {TodoEntity} from '../model/todo'; -import {todoAPI} from '../api/todo'; - -export const todoRequestCompletedAction = (todos: TodoEntity[]) => { - return { - type: actionsEnums.TODO_REQUEST_COMPLETED, - payload: todos - } -} - -export const todoRequest = () => (dispatcher) =>{ - const promise = todoAPI.getAllTodos(); - - promise.then( - (data) => dispatcher(todoRequestCompletedAction(data)) - ) - - return promise; -} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/api/todo.spec.ts b/03 Test Redux PabloRC/src/api/todo.spec.ts deleted file mode 100644 index 335ed36..0000000 --- a/03 Test Redux PabloRC/src/api/todo.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import configureStore from 'redux-mock-store'; -import ReduxThunk from 'redux-thunk'; -const middlewares = [ReduxThunk]; -const mockStore = configureStore(middlewares); - -import { todoAPI } from './todo'; - -describe('todo API', () => { - it('se realiza la llamada', async () => { - const todos = [ - { - userId: 1, - id: 1, - title: 'Hacer la compra', - completed: true, - }, - { - userId: 1, - id: 2, - title: 'Ir al gimnasio', - completed: false, - } - ] - const spyedTodos = jest.spyOn(todoAPI, 'getAllTodos').mockResolvedValue(todos) - - const response = await todoAPI.getAllTodos() - - expect(spyedTodos).toHaveBeenCalled() - expect(response).toEqual(todos) - }); -}); diff --git a/03 Test Redux PabloRC/src/api/todo.ts b/03 Test Redux PabloRC/src/api/todo.ts deleted file mode 100644 index 24932ee..0000000 --- a/03 Test Redux PabloRC/src/api/todo.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {TodoEntity } from '../model/todo'; -const axios = require('axios').default; - -class TodoAPI { - - getAllTodos() : Promise { - const todosUrl : string = 'https://jsonplaceholder.typicode.com/todos'; - - return axios.get(todosUrl) - .then((response) => response.data) - } - -} - -export const todoAPI = new TodoAPI(); \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/app.tsx b/03 Test Redux PabloRC/src/app.tsx deleted file mode 100644 index 3358597..0000000 --- a/03 Test Redux PabloRC/src/app.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import * as React from 'react'; -import { - TodosAreaContainer -} from './components'; - -export const App = () => { - return ( -
- -
- ); -} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/common/actionsEnums.ts b/03 Test Redux PabloRC/src/common/actionsEnums.ts deleted file mode 100644 index 65a6d3a..0000000 --- a/03 Test Redux PabloRC/src/common/actionsEnums.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const actionsEnums = { - TODO_REQUEST_COMPLETED: 'TODO_REQUEST_COMPLETED', - } \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/components/index.ts b/03 Test Redux PabloRC/src/components/index.ts deleted file mode 100644 index 89f553d..0000000 --- a/03 Test Redux PabloRC/src/components/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './todoList/todoAreaContainer'; \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoArea.spec.tsx.snap b/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoArea.spec.tsx.snap deleted file mode 100644 index df9ce64..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoArea.spec.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TodoAreaComponent should render as expected 1`] = ` - -`; diff --git a/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoAreaContainer.spec.tsx.snap b/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoAreaContainer.spec.tsx.snap deleted file mode 100644 index af86e9b..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/__snapshots__/todoAreaContainer.spec.tsx.snap +++ /dev/null @@ -1,50 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TodosAreaContainer debe pintar TodoAreaComponent cuando tenemos todos 1`] = ` - - - - -
- - - - - - - - - - -
- UserId - - Id - - Title - - Completed -
-
-
-
-
-
-`; diff --git a/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoRow.spec.tsx.snap b/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoRow.spec.tsx.snap deleted file mode 100644 index 525bc3f..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoRow.spec.tsx.snap +++ /dev/null @@ -1,26 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TodoRowComponent should render as expected 1`] = ` - - - - 1 - - - - - 1 - - - - - Hacer la compra - - - - - Completada - - - -`; diff --git a/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoTable.spec.tsx.snap b/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoTable.spec.tsx.snap deleted file mode 100644 index ddf170a..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/components/__snapshots__/todoTable.spec.tsx.snap +++ /dev/null @@ -1,52 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TodoTableComponent should render as expected 1`] = ` -
- - - - - - - - - - - - - -
- UserId - - Id - - Title - - Completed -
-
-`; diff --git a/03 Test Redux PabloRC/src/components/todoList/components/todoRow.spec.tsx b/03 Test Redux PabloRC/src/components/todoList/components/todoRow.spec.tsx deleted file mode 100644 index 56eb74a..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/components/todoRow.spec.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react'; -import { shallow } from 'enzyme'; -import { TodoRowComponent } from './todoRow'; -import { TodoEntity } from '../../../model/todo'; - -describe('TodoRowComponent', () => { - it('should render as expected', () => { - const todo: TodoEntity = { - userId: 1, - id: 1, - title: 'Hacer la compra', - completed: true, - } - - const component = shallow( - , - ); - - expect(component).toMatchSnapshot(); - }); -}); diff --git a/03 Test Redux PabloRC/src/components/todoList/components/todoRow.tsx b/03 Test Redux PabloRC/src/components/todoList/components/todoRow.tsx deleted file mode 100644 index 96d85df..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/components/todoRow.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import * as React from 'react'; -import {TodoEntity} from '../../../model/todo'; - -interface Props { - todo : TodoEntity; -} - -export const TodoRowComponent = (props: Props) => { - const { userId, id, title, completed } = props.todo - return ( - - - {userId} - - - {id} - - - {title} - - - {completed && 'Completada'} - - - ); -} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/components/todoList/components/todoTable.spec.tsx b/03 Test Redux PabloRC/src/components/todoList/components/todoTable.spec.tsx deleted file mode 100644 index c6252cf..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/components/todoTable.spec.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react'; -import { shallow } from 'enzyme'; -import { TodoEntity } from '../../../model/todo'; -import { TodoTableComponent } from './todoTable'; - -describe('TodoTableComponent', () => { - it('should render as expected', () => { - const todos: TodoEntity[] = [ - { - userId: 1, - id: 1, - title: 'Hacer la compra', - completed: true, - }, - { - userId: 1, - id: 2, - title: 'Ir al gimnasio', - completed: false, - } - ] - - const component = shallow( - , - ); - - expect(component).toMatchSnapshot(); - }); -}); diff --git a/03 Test Redux PabloRC/src/components/todoList/components/todoTable.tsx b/03 Test Redux PabloRC/src/components/todoList/components/todoTable.tsx deleted file mode 100644 index 8379262..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/components/todoTable.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import * as React from 'react'; -import {TodoEntity} from '../../../model/todo'; -import {TodoRowComponent} from './todoRow'; - -interface Props { - todos: TodoEntity[]; -} - -export const TodoTableComponent = (props: Props) => { - return ( -
- - - - - - - - - - - { - props.todos && props.todos.map((todo: TodoEntity) => - - ) - } - -
- UserId - - Id - - Title - - Completed -
-
- ); -} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/components/todoList/todoArea.spec.tsx b/03 Test Redux PabloRC/src/components/todoList/todoArea.spec.tsx deleted file mode 100644 index b88abaa..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/todoArea.spec.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { shallow } from 'enzyme'; -import { TodoAreaComponent } from './todoArea'; -import { TodoEntity } from '../../model/todo'; - -describe('TodoAreaComponent', () => { - it('should render as expected', () => { - const todos: TodoEntity[] = [ - { - userId: 1, - id: 1, - title: 'Hacer la compra', - completed: true, - }, - { - userId: 1, - id: 2, - title: 'Ir al gimnasio', - completed: false, - } - ] - - const loadTodos = () => { }; - - const component = shallow( - , - ); - - expect(component).toMatchSnapshot(); - }); -}); diff --git a/03 Test Redux PabloRC/src/components/todoList/todoArea.tsx b/03 Test Redux PabloRC/src/components/todoList/todoArea.tsx deleted file mode 100644 index 5de471a..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/todoArea.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from 'react'; -import {TodoTableComponent} from './components/todoTable'; -import {TodoEntity} from '../../model/todo' - -interface Props { - todos: Array; - loadTodos: () => any; -} - -export class TodoAreaComponent extends React.Component { - - componentDidMount() { - this.props.loadTodos() - } - - render() { - const { todos } = this.props - - if(todos && todos.length === 0) { - return

Cargando datos...

- } - - return ( - - ) - } -} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.spec.tsx b/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.spec.tsx deleted file mode 100644 index 260cf2b..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.spec.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import * as React from 'react'; -import { mount } from 'enzyme'; -import { Provider } from 'react-redux'; -import configureStore from 'redux-mock-store'; -import ReduxThunk from 'redux-thunk'; -const middlewares = [ReduxThunk]; -const mockStore = configureStore(middlewares); - -import { TodoEntity } from "../../model/todo"; -import { TodosAreaContainer } from '..'; - -describe('TodosAreaContainer', () => { - it('debe pintar TodoAreaComponent cuando tenemos todos', () => { - const todos: TodoEntity[] = [ - { - userId: 1, - id: 1, - title: 'Hacer la compra', - completed: true, - }, - { - userId: 1, - id: 2, - title: 'Ir al gimnasio', - completed: false - } - ] - - const store = mockStore({ - sessionReducer: { - todos, - }, - }); - - const component = mount( - - - , - ); - - expect(component).toMatchSnapshot(); - }); -}); diff --git a/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.tsx b/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.tsx deleted file mode 100644 index 5686ccb..0000000 --- a/03 Test Redux PabloRC/src/components/todoList/todoAreaContainer.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { connect } from 'react-redux'; -import { todoRequest } from '../../actions/todoRequest'; -import { TodoAreaComponent } from './todoArea'; -import { State } from '../../reducers'; - -const mapStateToProps = (state :State) => { - return{ - todos: state.todoReducer - }; -} - -const mapDispatchToProps = dispatch => { - return { - loadTodos: () => {return dispatch(todoRequest())} - }; -} - -export const TodosAreaContainer = connect( - mapStateToProps, - mapDispatchToProps -)(TodoAreaComponent); \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/content/styles.css b/03 Test Redux PabloRC/src/content/styles.css deleted file mode 100644 index 70c3cd1..0000000 --- a/03 Test Redux PabloRC/src/content/styles.css +++ /dev/null @@ -1,24 +0,0 @@ -/* Default Table Style */ -table { - color: #333; - background: white; - border: 1px solid grey; - font-size: 12pt; - border-collapse: collapse; -} - -table thead th, -table tfoot th { - color: #777; - background: rgba(0,0,0,.1); -} - -table caption { - padding:.5em; -} - -table th, -table td { - padding: .5em; - border: 1px solid lightgrey; -} \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/index.html b/03 Test Redux PabloRC/src/index.html deleted file mode 100644 index da1c0ad..0000000 --- a/03 Test Redux PabloRC/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - -
-

Todo List

-
-
- - diff --git a/03 Test Redux PabloRC/src/main.tsx b/03 Test Redux PabloRC/src/main.tsx deleted file mode 100644 index cad9175..0000000 --- a/03 Test Redux PabloRC/src/main.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import { createStore, applyMiddleware, compose } from 'redux'; -import reduxThunk from 'redux-thunk'; -import { Provider } from 'react-redux'; -import {reducers } from './reducers'; -import { App } from './app'; - -const composeEnhancers = window['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__'] || compose; - -const store = createStore(reducers, /* preloadedState, */ composeEnhancers( - applyMiddleware(reduxThunk) - )); - -ReactDOM.render( - - - , - document.getElementById('root')); \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/model/todo.ts b/03 Test Redux PabloRC/src/model/todo.ts deleted file mode 100644 index e3b36a0..0000000 --- a/03 Test Redux PabloRC/src/model/todo.ts +++ /dev/null @@ -1,13 +0,0 @@ -export interface TodoEntity { - userId: number - id: number; - title: string; - completed: boolean; -} - -export const createDefaultTodoEntity = () => ({ - userId: -1, - id: -1, - title: '', - completed: false, -}) \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/reducers/index.ts b/03 Test Redux PabloRC/src/reducers/index.ts deleted file mode 100644 index 1049f3b..0000000 --- a/03 Test Redux PabloRC/src/reducers/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { combineReducers} from 'redux'; -import { todoReducer, todoState } from './todoReducer'; - -export interface State { - todoReducer : todoState; -}; - -export const reducers = combineReducers({ - todoReducer, -}); \ No newline at end of file diff --git a/03 Test Redux PabloRC/src/reducers/todoReducer.spec.ts b/03 Test Redux PabloRC/src/reducers/todoReducer.spec.ts deleted file mode 100644 index be52a4f..0000000 --- a/03 Test Redux PabloRC/src/reducers/todoReducer.spec.ts +++ /dev/null @@ -1,48 +0,0 @@ -import * as deepFreeze from 'deep-freeze'; -import { todoReducer, todoState } from './todoReducer'; -import { actionsEnums } from '../common/actionsEnums'; - -describe('todoReducer', () => { - it('debe devolver el mismo estado al mandarle un tipo erróneo', () => { - const initialState = [] as todoState; - - const action = { - type: 'Wrong', - }; - - deepFreeze(initialState); - - const result = todoReducer(initialState, action); - - expect(result).toBe(initialState); - expect(initialState).not.toBe(undefined); - }); - - describe('handleTodoRequestCompletedAction', () => { - it('se actualizan los valores cuando le pasamos un type correcto', () => { - const initialState = [] as todoState; - - const action = { - type: actionsEnums.TODO_REQUEST_COMPLETED, - payload: [{ - userId: 1, - id: 1, - title: 'Hacer la compra', - completed: true, - }, - { - userId: 1, - id: 2, - title: 'Ir al gimnasio', - completed: false - }] as todoState, - }; - - deepFreeze(initialState); - - const result = todoReducer(initialState, action); - - expect(result).toBe(action.payload); - }); - }); -}); diff --git a/03 Test Redux PabloRC/src/reducers/todoReducer.ts b/03 Test Redux PabloRC/src/reducers/todoReducer.ts deleted file mode 100644 index 52d8ee9..0000000 --- a/03 Test Redux PabloRC/src/reducers/todoReducer.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {actionsEnums} from '../common/actionsEnums'; -import {TodoEntity} from '../model/todo'; - -export type todoState = TodoEntity[]; - -export const todoReducer = (state : todoState = [], action) => { - switch (action.type) { - case actionsEnums.TODO_REQUEST_COMPLETED: - return handleTodoRequestCompletedAction(state, action.payload); - } - - return state; -}; - -const handleTodoRequestCompletedAction = (state : todoState, todos) => { - return todos; -} \ No newline at end of file diff --git a/03 Test Redux PabloRC/tsconfig.json b/03 Test Redux PabloRC/tsconfig.json deleted file mode 100644 index 885d474..0000000 --- a/03 Test Redux PabloRC/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, - "noImplicitAny": false, - "jsx": "react", - "sourceMap": true, - "noLib": false, - "suppressImplicitAnyIndexErrors": true - }, - "compileOnSave": false, - "exclude": [ - "node_modules" - ] -} diff --git a/03 Test Redux PabloRC/webpack.config.js b/03 Test Redux PabloRC/webpack.config.js deleted file mode 100644 index 3e1f971..0000000 --- a/03 Test Redux PabloRC/webpack.config.js +++ /dev/null @@ -1,65 +0,0 @@ -var HtmlWebpackPlugin = require('html-webpack-plugin'); -var MiniCssExtractPlugin = require('mini-css-extract-plugin'); -var webpack = require('webpack'); -var path = require('path'); - -var basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: ['.js', '.ts', '.tsx'] - }, - entry: ['@babel/polyfill', - './content/styles.css' , - './main.tsx' - ], - output: { - path: path.join(basePath, 'dist'), - filename: 'bundle.js' - }, - devtool: 'source-map', - devServer: { - contentBase: './dist', // Content base - inline: true, // Enable watch and live reload - host: 'localhost', - port: 8080, - stats: 'errors-only' - }, - module: { - rules: [ - { - test: /\.(ts|tsx)$/, - exclude: /node_modules/, - loader: 'awesome-typescript-loader', - options: { - useBabel: true, - "babelCore": "@babel/core", // needed for Babel v7 - }, - }, - { - test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] - }, - { - test: /\.(png|jpg|gif|svg)$/, - loader: 'file-loader', - options: { - name: 'assets/img/[name].[ext]?[hash]' - } - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: 'index.html', //Name of file in ./dist/ - template: 'index.html', //Name of template in ./src - hash: true, - }), - new MiniCssExtractPlugin({ - filename: "[name].css", - chunkFilename: "[id].css" - }), - ], -}; diff --git a/04 Test Hooks PablorRC/.babelrc b/04 Test Hooks PablorRC/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/04 Test Hooks PablorRC/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} From 90a787a01127b0b2501321f52e460c14d4e43122 Mon Sep 17 00:00:00 2001 From: Senesero Date: Fri, 10 Apr 2020 19:23:31 +0200 Subject: [PATCH 6/9] Show and add todo correctly --- .gitignore | 2 +- 00 Base/config/webpack/base.js | 13 ++++- 00 Base/package.json | 10 +++- 00 Base/src/app.tsx | 4 +- 00 Base/src/components/index.ts | 1 + .../todoList/components/todoRow.spec.tsx | 21 +++++++ .../todoList/components/todoRow.tsx | 28 ++++++++++ .../todoList/components/todoTable.spec.tsx | 29 ++++++++++ .../todoList/components/todoTable.tsx | 39 +++++++++++++ .../components/todoList/todosArea.spec.tsx | 31 +++++++++++ 00 Base/src/components/todoList/todosArea.tsx | 49 +++++++++++++++++ .../todoList/todosAreaContainer.spec.tsx | 43 +++++++++++++++ .../todoList/todosAreaContainer.tsx | 22 ++++++++ 00 Base/src/content/styles.css | 28 ++++++++++ 00 Base/src/index.html | 2 +- 00 Base/src/index.tsx | 16 +++++- 00 Base/src/model/todo.ts | 13 +++++ 00 Base/src/myApi/index.ts | 2 +- 00 Base/src/myApi/myApi.ts | 17 ++++-- 00 Base/src/myApi/myBackEndApiEndpoint.ts | 35 ++++++++---- 00 Base/src/myComponent/index.ts | 1 - 00 Base/src/myComponent/myComponent.tsx | 15 ----- .../src/redux/actions/todosActions.spec.ts | 55 +++++++++++++++++++ 00 Base/src/redux/actions/todosActions.ts | 37 +++++++++++++ 00 Base/src/redux/common/actionsEnums.ts | 4 ++ 00 Base/src/redux/reducers/index.ts | 10 ++++ .../src/redux/reducers/todoReducer.spec.ts | 48 ++++++++++++++++ 00 Base/src/redux/reducers/todoReducer.ts | 23 ++++++++ 28 files changed, 555 insertions(+), 43 deletions(-) create mode 100644 00 Base/src/components/index.ts create mode 100644 00 Base/src/components/todoList/components/todoRow.spec.tsx create mode 100644 00 Base/src/components/todoList/components/todoRow.tsx create mode 100644 00 Base/src/components/todoList/components/todoTable.spec.tsx create mode 100644 00 Base/src/components/todoList/components/todoTable.tsx create mode 100644 00 Base/src/components/todoList/todosArea.spec.tsx create mode 100644 00 Base/src/components/todoList/todosArea.tsx create mode 100644 00 Base/src/components/todoList/todosAreaContainer.spec.tsx create mode 100644 00 Base/src/components/todoList/todosAreaContainer.tsx create mode 100644 00 Base/src/content/styles.css create mode 100644 00 Base/src/model/todo.ts delete mode 100644 00 Base/src/myComponent/index.ts delete mode 100644 00 Base/src/myComponent/myComponent.tsx create mode 100644 00 Base/src/redux/actions/todosActions.spec.ts create mode 100644 00 Base/src/redux/actions/todosActions.ts create mode 100644 00 Base/src/redux/common/actionsEnums.ts create mode 100644 00 Base/src/redux/reducers/index.ts create mode 100644 00 Base/src/redux/reducers/todoReducer.spec.ts create mode 100644 00 Base/src/redux/reducers/todoReducer.ts diff --git a/.gitignore b/.gitignore index 7d48688..41f5179 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,5 @@ src/api/apiUtils.ts *.iml junit.xml /reports/ -/.awcache +.awcache /.vscode diff --git a/00 Base/config/webpack/base.js b/00 Base/config/webpack/base.js index 116fcaf..3726108 100644 --- a/00 Base/config/webpack/base.js +++ b/00 Base/config/webpack/base.js @@ -2,6 +2,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CheckerPlugin } = require('awesome-typescript-loader'); const merge = require('webpack-merge'); const helpers = require('./helpers'); +var MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = merge( {}, @@ -11,7 +12,9 @@ module.exports = merge( extensions: ['.js', '.ts', '.tsx'], }, entry: { - app: ['./index.tsx'], + app: ['./index.tsx', + './content/styles.css', + ], }, module: { rules: [ @@ -25,6 +28,10 @@ module.exports = merge( babelCore: '@babel/core', }, }, + { + test: /\.css$/, + use: [MiniCssExtractPlugin.loader, "css-loader"] + }, ], }, optimization: { @@ -45,6 +52,10 @@ module.exports = merge( template: 'index.html', }), new CheckerPlugin(), + new MiniCssExtractPlugin({ + filename: "[name].css", + chunkFilename: "[id].css" + }), ], } ); diff --git a/00 Base/package.json b/00 Base/package.json index c70f345..f1befee 100644 --- a/00 Base/package.json +++ b/00 Base/package.json @@ -17,7 +17,11 @@ "axios": "^0.19.0", "react": "^16.8.6", "react-dom": "^16.8.6", - "react-router-dom": "^5.0.1" + "react-redux": "^7.2.0", + "react-router-dom": "^5.0.1", + "redux": "^4.0.5", + "redux-mock-store": "^1.5.4", + "redux-thunk": "^2.3.0" }, "devDependencies": { "@babel/cli": "^7.4.4", @@ -37,6 +41,8 @@ "webpack": "^4.32.2", "webpack-cli": "^3.3.2", "webpack-dev-server": "^3.5.0", - "webpack-merge": "^4.2.1" + "webpack-merge": "^4.2.1", + "css-loader": "^3.5.1", + "mini-css-extract-plugin": "^0.9.0" } } diff --git a/00 Base/src/app.tsx b/00 Base/src/app.tsx index f201da0..4a9edd7 100644 --- a/00 Base/src/app.tsx +++ b/00 Base/src/app.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; -import { MyComponent } from './myComponent'; +import { TodosAreaContainer } from './components'; export const App: React.FunctionComponent = props => (
- +
); diff --git a/00 Base/src/components/index.ts b/00 Base/src/components/index.ts new file mode 100644 index 0000000..a3a603a --- /dev/null +++ b/00 Base/src/components/index.ts @@ -0,0 +1 @@ +export { TodosAreaContainer } from './todoList/TodosAreaContainer'; \ No newline at end of file diff --git a/00 Base/src/components/todoList/components/todoRow.spec.tsx b/00 Base/src/components/todoList/components/todoRow.spec.tsx new file mode 100644 index 0000000..d7e74f5 --- /dev/null +++ b/00 Base/src/components/todoList/components/todoRow.spec.tsx @@ -0,0 +1,21 @@ +// import * as React from 'react'; +// import { shallow } from 'enzyme'; +// import { TodoRowComponent } from './todoRow'; +// import { TodoEntity } from '../../../model/todo'; + +// describe('TodoRowComponent', () => { +// it('should render as expected', () => { +// const todo: TodoEntity = { +// userId: 1, +// id: 1, +// title: 'Hacer la compra', +// completed: true, +// } + +// const component = shallow( +// , +// ); + +// expect(component).toMatchSnapshot(); +// }); +// }); diff --git a/00 Base/src/components/todoList/components/todoRow.tsx b/00 Base/src/components/todoList/components/todoRow.tsx new file mode 100644 index 0000000..9f0c7bf --- /dev/null +++ b/00 Base/src/components/todoList/components/todoRow.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import {TodoEntity} from '../../../model/todo'; + +interface Props { + todo: TodoEntity; +} + +const onDeleteSubmit = () => console.log('Delete todo') + +export const TodoRowComponent = (props: Props) => { + const { id, title, completed } = props.todo + return ( + + + {id} + + + {title} + + + {completed ? 'Completed' : 'Pending'} + + + + + + ); +} \ No newline at end of file diff --git a/00 Base/src/components/todoList/components/todoTable.spec.tsx b/00 Base/src/components/todoList/components/todoTable.spec.tsx new file mode 100644 index 0000000..53e2cbb --- /dev/null +++ b/00 Base/src/components/todoList/components/todoTable.spec.tsx @@ -0,0 +1,29 @@ +// import * as React from 'react'; +// import { shallow } from 'enzyme'; +// import { TodoEntity } from '../../../model/todo'; +// import { TodoTableComponent } from './todoTable'; + +// describe('TodoTableComponent', () => { +// it('should render as expected', () => { +// const todos: TodoEntity[] = [ +// { +// userId: 1, +// id: 1, +// title: 'Hacer la compra', +// completed: true, +// }, +// { +// userId: 1, +// id: 2, +// title: 'Ir al gimnasio', +// completed: false, +// } +// ] + +// const component = shallow( +// , +// ); + +// expect(component).toMatchSnapshot(); +// }); +// }); diff --git a/00 Base/src/components/todoList/components/todoTable.tsx b/00 Base/src/components/todoList/components/todoTable.tsx new file mode 100644 index 0000000..1476a60 --- /dev/null +++ b/00 Base/src/components/todoList/components/todoTable.tsx @@ -0,0 +1,39 @@ +import * as React from 'react'; +import {TodoEntity} from '../../../model/todo'; +import {TodoRowComponent} from './todoRow'; + +interface Props { + todos: TodoEntity[]; +} + +export const TodoTableComponent = (props: Props) => { + return ( +
+ + + + + + + + + + + { + props.todos && props.todos.map((todo: TodoEntity) => + + ) + } + +
+ Id + + Title + + Completed + + Action +
+
+ ); +} \ No newline at end of file diff --git a/00 Base/src/components/todoList/todosArea.spec.tsx b/00 Base/src/components/todoList/todosArea.spec.tsx new file mode 100644 index 0000000..5ab1ee3 --- /dev/null +++ b/00 Base/src/components/todoList/todosArea.spec.tsx @@ -0,0 +1,31 @@ +// import * as React from 'react'; +// import { shallow } from 'enzyme'; +// import { TodoAreaComponent } from './todosArea'; +// import { TodoEntity } from '../../model/todo'; + +// describe('TodoAreaComponent', () => { +// it('should render as expected', () => { +// const todos: TodoEntity[] = [ +// { +// userId: 1, +// id: 1, +// title: 'Hacer la compra', +// completed: true, +// }, +// { +// userId: 1, +// id: 2, +// title: 'Ir al gimnasio', +// completed: false, +// } +// ] + +// const loadTodos = () => { }; + +// const component = shallow( +// , +// ); + +// expect(component).toMatchSnapshot(); +// }); +// }); diff --git a/00 Base/src/components/todoList/todosArea.tsx b/00 Base/src/components/todoList/todosArea.tsx new file mode 100644 index 0000000..f1e0dae --- /dev/null +++ b/00 Base/src/components/todoList/todosArea.tsx @@ -0,0 +1,49 @@ +import * as React from 'react'; +import {TodoTableComponent} from './components/todoTable'; +import { TodoEntity } from '../../model/todo'; + +interface State { + newTodo: string +} + +interface Props { + todos: Array; + loadTodos: () => void; + addTodo: (newTodo: string) => void; +} + +export class TodoAreaComponent extends React.Component { + + state = { + newTodo: "" + } + + componentDidMount() { + this.props.loadTodos() + } + + onAddSubmit = () => { + this.props.addTodo(this.state.newTodo) + this.setState({ newTodo: ''}) + } + + render() { + const { todos } = this.props + const { newTodo } = this.state + + if(todos && todos.length === 0) { + return

Cargando datos...

+ } + + return ( + <> + <> + New todo: + this.setState({ newTodo: event.target.value })} /> + + + + + ) + } +} \ No newline at end of file diff --git a/00 Base/src/components/todoList/todosAreaContainer.spec.tsx b/00 Base/src/components/todoList/todosAreaContainer.spec.tsx new file mode 100644 index 0000000..b43960f --- /dev/null +++ b/00 Base/src/components/todoList/todosAreaContainer.spec.tsx @@ -0,0 +1,43 @@ +// import * as React from 'react'; +// import { mount } from 'enzyme'; +// import { Provider } from 'react-redux'; +// import configureStore from 'redux-mock-store'; +// import ReduxThunk from 'redux-thunk'; +// const middlewares = [ReduxThunk]; +// const mockStore = configureStore(middlewares); + +// import { TodoEntity } from "../../model/todo"; +// import { TodosAreaContainer } from '..'; + +// describe('TodosAreaContainer', () => { +// it('debe pintar TodoAreaComponent cuando tenemos todos', () => { +// const todos: TodoEntity[] = [ +// { +// userId: 1, +// id: 1, +// title: 'Hacer la compra', +// completed: true, +// }, +// { +// userId: 1, +// id: 2, +// title: 'Ir al gimnasio', +// completed: false +// } +// ] + +// const store = mockStore({ +// sessionReducer: { +// todos, +// }, +// }); + +// const component = mount( +// +// +// , +// ); + +// expect(component).toMatchSnapshot(); +// }); +// }); diff --git a/00 Base/src/components/todoList/todosAreaContainer.tsx b/00 Base/src/components/todoList/todosAreaContainer.tsx new file mode 100644 index 0000000..db1c750 --- /dev/null +++ b/00 Base/src/components/todoList/todosAreaContainer.tsx @@ -0,0 +1,22 @@ +import { connect } from 'react-redux'; +import { TodoAreaComponent } from './todosArea'; +import { State } from '../../redux/reducers'; +import { getTodos, addTodo } from '../../redux/actions/todosActions'; + +const mapStateToProps = (state: State) => { + return{ + todos: state.todoReducer + }; +} + +const mapDispatchToProps = dispatch => { + return { + loadTodos: () => {return dispatch(getTodos())}, + addTodo: (newTodo: string) => {return dispatch(addTodo(newTodo))} + }; +} + +export const TodosAreaContainer = connect( + mapStateToProps, + mapDispatchToProps +)(TodoAreaComponent); \ No newline at end of file diff --git a/00 Base/src/content/styles.css b/00 Base/src/content/styles.css new file mode 100644 index 0000000..0a7e94d --- /dev/null +++ b/00 Base/src/content/styles.css @@ -0,0 +1,28 @@ +/* Default Table Style */ +.table { + color: #333; + background: white; + border: 1px solid grey; + font-size: 12pt; + border-collapse: collapse; +} + +table thead th, +table tfoot th { + color: #777; + background: rgba(0,0,0,.1); +} + +table caption { + padding:.5em; +} + +table th, +table td { + padding: .5em; + border: 1px solid lightgrey; +} + +.row { + padding-top: 20px; +} \ No newline at end of file diff --git a/00 Base/src/index.html b/00 Base/src/index.html index 2c5018a..8987da2 100644 --- a/00 Base/src/index.html +++ b/00 Base/src/index.html @@ -6,7 +6,7 @@ name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> - React testing by sample + Fruits List
diff --git a/00 Base/src/index.tsx b/00 Base/src/index.tsx index ded7936..5a18166 100644 --- a/00 Base/src/index.tsx +++ b/00 Base/src/index.tsx @@ -1,5 +1,19 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { App } from './app'; +import { createStore, applyMiddleware, compose } from 'redux'; +import reduxThunk from 'redux-thunk'; +import { Provider } from 'react-redux'; +import { reducers } from './redux/reducers'; -ReactDOM.render(, document.getElementById('root')); +const composeEnhancers = window['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__'] || compose; + +const store = createStore(reducers, /* preloadedState, */ composeEnhancers( + applyMiddleware(reduxThunk) + )); + +ReactDOM.render( + + + + , document.getElementById('root')); diff --git a/00 Base/src/model/todo.ts b/00 Base/src/model/todo.ts new file mode 100644 index 0000000..e3b36a0 --- /dev/null +++ b/00 Base/src/model/todo.ts @@ -0,0 +1,13 @@ +export interface TodoEntity { + userId: number + id: number; + title: string; + completed: boolean; +} + +export const createDefaultTodoEntity = () => ({ + userId: -1, + id: -1, + title: '', + completed: false, +}) \ No newline at end of file diff --git a/00 Base/src/myApi/index.ts b/00 Base/src/myApi/index.ts index 3e74d70..31b8e23 100644 --- a/00 Base/src/myApi/index.ts +++ b/00 Base/src/myApi/index.ts @@ -1 +1 @@ -export { getListOfFruit } from './myApi'; \ No newline at end of file +export { getListOfTodos, insertTodo } from './myApi'; \ No newline at end of file diff --git a/00 Base/src/myApi/myApi.ts b/00 Base/src/myApi/myApi.ts index 988d0c5..a811b0d 100644 --- a/00 Base/src/myApi/myApi.ts +++ b/00 Base/src/myApi/myApi.ts @@ -1,15 +1,20 @@ import * as BEApi from './myBackEndApiEndpoint'; +import { TodoEntity } from '../model/todo'; -export const getListOfFruit = (): Promise => { - return BEApi.getFruits('http://fruityfruit.com') - .then(resolveFruits) +export const getListOfTodos = (): Promise => { + return BEApi.getTodos() + .then(resolveTodos) .catch(handleError); } -const resolveFruits = (fruits: string[]) => { - return fruits; +export const insertTodo = (todo: string): Promise => { + return BEApi.insertTodo(todo) + .then(resolveTodos) + .catch(handleError); } +const resolveTodos = (todos: TodoEntity[]): TodoEntity[] => todos + const handleError = () => { - throw new Error('Where is my fruit???'); + throw new Error('Where is my todos???'); } \ No newline at end of file diff --git a/00 Base/src/myApi/myBackEndApiEndpoint.ts b/00 Base/src/myApi/myBackEndApiEndpoint.ts index 1457042..bcafa96 100644 --- a/00 Base/src/myApi/myBackEndApiEndpoint.ts +++ b/00 Base/src/myApi/myBackEndApiEndpoint.ts @@ -1,12 +1,23 @@ -export const getFruits = (_url: string) => { - return Promise.resolve([ - 'grape', - 'pineapple', - 'watermelon', - 'orange', - 'lemon', - 'strawberry', - 'cherry', - 'peach', - ]); -} \ No newline at end of file +import Axios from 'axios' +import { TodoEntity } from '../model/todo' + +let todos = [] + +export const getTodos = () => + Axios.get('https://jsonplaceholder.typicode.com/todos?userId=1') + .then( response => { + todos = response.data + return Promise.resolve(todos) + } + ) + +export const insertTodo = (todo: string) => { + const newTodo: TodoEntity = { + userId: 1, + id: todos[todos.length - 1].id + 1, + title: todo, + completed: false + } + todos.push(newTodo) + return Promise.resolve(todos) +} diff --git a/00 Base/src/myComponent/index.ts b/00 Base/src/myComponent/index.ts deleted file mode 100644 index bcc7da0..0000000 --- a/00 Base/src/myComponent/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { MyComponent } from './myComponent'; \ No newline at end of file diff --git a/00 Base/src/myComponent/myComponent.tsx b/00 Base/src/myComponent/myComponent.tsx deleted file mode 100644 index ea44068..0000000 --- a/00 Base/src/myComponent/myComponent.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; - -export interface Props { - nameFromProps: string; -} - -export const MyComponent: React.FunctionComponent = props => { - const { nameFromProps } = props; - - return ( - <> -

Hello {nameFromProps}!

- - ); -}; \ No newline at end of file diff --git a/00 Base/src/redux/actions/todosActions.spec.ts b/00 Base/src/redux/actions/todosActions.spec.ts new file mode 100644 index 0000000..6077402 --- /dev/null +++ b/00 Base/src/redux/actions/todosActions.spec.ts @@ -0,0 +1,55 @@ +// import configureStore from 'redux-mock-store'; +// import ReduxThunk from 'redux-thunk'; +// const middlewares = [ReduxThunk]; +// const mockStore = configureStore(middlewares); + +// import { TodoEntity } from '../../model/todo'; +// import { todoActionsCompletedAction } from "./todoActions"; +// import { actionsEnums } from '../common/actionsEnums'; + +// describe('todoActionsCompletedAction', () => { +// it('debe devolver acción cuando el tipo sea TODO_REQUEST_COMPLETED', () => { +// const todoResponse: TodoEntity[] = [ +// { +// userId: 1, +// id: 1, +// title: 'Hacer la compra', +// completed: true, +// }, +// { +// userId: 1, +// id: 2, +// title: 'Ir al gimnasio', +// completed: false +// } +// ] + +// const result = todoActionsCompletedAction(todoResponse); + +// expect(result.type).toBe(actionsEnums.TODO_REQUEST_COMPLETED); +// expect(result.payload).toBe(todoResponse); +// }); + +// it('se realiza la llamada para obtener los todos', () => { +// const todoResponse: TodoEntity[] = [ +// { +// userId: 1, +// id: 1, +// title: 'Hacer la compra', +// completed: true, +// }, +// { +// userId: 1, +// id: 2, +// title: 'Ir al gimnasio', +// completed: false +// } +// ] + +// const store = mockStore(); +// store.dispatch(todoActionsCompletedAction(todoResponse)) + +// expect(store.getActions()[0].type).toBe(actionsEnums.TODO_REQUEST_COMPLETED); +// expect(store.getActions()[0].payload).toBe(todoResponse); +// }); +// }); \ No newline at end of file diff --git a/00 Base/src/redux/actions/todosActions.ts b/00 Base/src/redux/actions/todosActions.ts new file mode 100644 index 0000000..4687dc9 --- /dev/null +++ b/00 Base/src/redux/actions/todosActions.ts @@ -0,0 +1,37 @@ +import { getListOfTodos, insertTodo } from "../../myApi"; +import { TodoEntity } from "../../model/todo"; +import { actionsEnums } from "../common/actionsEnums"; + +export const getTodosCompletedAction = (todos: TodoEntity[]) => { + return { + type: actionsEnums.TODO_REQUEST_COMPLETED, + payload: todos + } +} + +export const getTodos = () => (dispatcher) =>{ + const promise = getListOfTodos(); + + promise.then( + (data) => dispatcher(getTodosCompletedAction(data)) + ) + + return promise; +} + +export const addTodosCompletedAction = (todo: TodoEntity) => { + return { + type: actionsEnums.ADD_REQUEST_COMPLETED, + payload: todo + } +} + +export const addTodo = (todo: string) => (dispatcher) => { + const promise = insertTodo(todo); + + promise.then( + (data) => dispatcher(getTodosCompletedAction(data)) + ) + + return promise; +} \ No newline at end of file diff --git a/00 Base/src/redux/common/actionsEnums.ts b/00 Base/src/redux/common/actionsEnums.ts new file mode 100644 index 0000000..997dbdd --- /dev/null +++ b/00 Base/src/redux/common/actionsEnums.ts @@ -0,0 +1,4 @@ +export const actionsEnums = { + TODO_REQUEST_COMPLETED: 'TODO_REQUEST_COMPLETED', + ADD_REQUEST_COMPLETED: 'ADD_REQUEST_COMPLETED', + } \ No newline at end of file diff --git a/00 Base/src/redux/reducers/index.ts b/00 Base/src/redux/reducers/index.ts new file mode 100644 index 0000000..1049f3b --- /dev/null +++ b/00 Base/src/redux/reducers/index.ts @@ -0,0 +1,10 @@ +import { combineReducers} from 'redux'; +import { todoReducer, todoState } from './todoReducer'; + +export interface State { + todoReducer : todoState; +}; + +export const reducers = combineReducers({ + todoReducer, +}); \ No newline at end of file diff --git a/00 Base/src/redux/reducers/todoReducer.spec.ts b/00 Base/src/redux/reducers/todoReducer.spec.ts new file mode 100644 index 0000000..f981f7c --- /dev/null +++ b/00 Base/src/redux/reducers/todoReducer.spec.ts @@ -0,0 +1,48 @@ +// import * as deepFreeze from 'deep-freeze'; +// import { todoReducer, todoState } from './todoReducer'; +// import { actionsEnums } from '../common/actionsEnums'; + +// describe('todoReducer', () => { +// it('debe devolver el mismo estado al mandarle un tipo erróneo', () => { +// const initialState = [] as todoState; + +// const action = { +// type: 'Wrong', +// }; + +// deepFreeze(initialState); + +// const result = todoReducer(initialState, action); + +// expect(result).toBe(initialState); +// expect(initialState).not.toBe(undefined); +// }); + +// describe('handleGetTodosActionCompleted', () => { +// it('se actualizan los valores cuando le pasamos un type correcto', () => { +// const initialState = [] as todoState; + +// const action = { +// type: actionsEnums.TODO_REQUEST_COMPLETED, +// payload: [{ +// userId: 1, +// id: 1, +// title: 'Hacer la compra', +// completed: true, +// }, +// { +// userId: 1, +// id: 2, +// title: 'Ir al gimnasio', +// completed: false +// }] as todoState, +// }; + +// deepFreeze(initialState); + +// const result = todoReducer(initialState, action); + +// expect(result).toBe(action.payload); +// }); +// }); +// }); diff --git a/00 Base/src/redux/reducers/todoReducer.ts b/00 Base/src/redux/reducers/todoReducer.ts new file mode 100644 index 0000000..cabf9ad --- /dev/null +++ b/00 Base/src/redux/reducers/todoReducer.ts @@ -0,0 +1,23 @@ +import {actionsEnums} from '../common/actionsEnums'; +import {TodoEntity} from '../../model/todo'; + +export type todoState = TodoEntity[]; + +export const todoReducer = (state : todoState = [], action) => { + switch (action.type) { + case actionsEnums.TODO_REQUEST_COMPLETED: + return handleGetTodosActionCompleted(state, action.payload); + case actionsEnums.ADD_REQUEST_COMPLETED: + return handleAddTodoActionCompleted(state, action.payload); + } + + return state; +}; + +const handleGetTodosActionCompleted = (state : todoState, todos) => { + return todos; +} + +const handleAddTodoActionCompleted = (state : todoState, todo) => { + return todo; +} \ No newline at end of file From 3d5639e391431807b58f961484f333f60d367fb1 Mon Sep 17 00:00:00 2001 From: Senesero Date: Fri, 10 Apr 2020 21:40:04 +0200 Subject: [PATCH 7/9] Delete todo --- .../todoList/components/todoRow.tsx | 6 +-- .../components/todoRowContainer.spec.tsx | 43 +++++++++++++++++++ .../todoList/components/todoRowContainer.tsx | 14 ++++++ .../todoList/components/todoTable.tsx | 7 +-- 00 Base/src/components/todoList/todosArea.tsx | 8 ++-- .../todoList/todosAreaContainer.tsx | 2 +- 00 Base/src/myApi/index.ts | 2 +- 00 Base/src/myApi/myApi.ts | 10 ++++- 00 Base/src/myApi/myBackEndApiEndpoint.ts | 14 ++++-- 00 Base/src/redux/actions/todosActions.ts | 27 ++++++------ 00 Base/src/redux/common/actionsEnums.ts | 1 + 00 Base/src/redux/reducers/todoReducer.ts | 10 ++--- 12 files changed, 106 insertions(+), 38 deletions(-) create mode 100644 00 Base/src/components/todoList/components/todoRowContainer.spec.tsx create mode 100644 00 Base/src/components/todoList/components/todoRowContainer.tsx diff --git a/00 Base/src/components/todoList/components/todoRow.tsx b/00 Base/src/components/todoList/components/todoRow.tsx index 9f0c7bf..944f611 100644 --- a/00 Base/src/components/todoList/components/todoRow.tsx +++ b/00 Base/src/components/todoList/components/todoRow.tsx @@ -3,11 +3,11 @@ import {TodoEntity} from '../../../model/todo'; interface Props { todo: TodoEntity; + deleteTodo: (id: number) => void } -const onDeleteSubmit = () => console.log('Delete todo') - export const TodoRowComponent = (props: Props) => { + const { deleteTodo } = props const { id, title, completed } = props.todo return ( @@ -21,7 +21,7 @@ export const TodoRowComponent = (props: Props) => { {completed ? 'Completed' : 'Pending'} - + ); diff --git a/00 Base/src/components/todoList/components/todoRowContainer.spec.tsx b/00 Base/src/components/todoList/components/todoRowContainer.spec.tsx new file mode 100644 index 0000000..b43960f --- /dev/null +++ b/00 Base/src/components/todoList/components/todoRowContainer.spec.tsx @@ -0,0 +1,43 @@ +// import * as React from 'react'; +// import { mount } from 'enzyme'; +// import { Provider } from 'react-redux'; +// import configureStore from 'redux-mock-store'; +// import ReduxThunk from 'redux-thunk'; +// const middlewares = [ReduxThunk]; +// const mockStore = configureStore(middlewares); + +// import { TodoEntity } from "../../model/todo"; +// import { TodosAreaContainer } from '..'; + +// describe('TodosAreaContainer', () => { +// it('debe pintar TodoAreaComponent cuando tenemos todos', () => { +// const todos: TodoEntity[] = [ +// { +// userId: 1, +// id: 1, +// title: 'Hacer la compra', +// completed: true, +// }, +// { +// userId: 1, +// id: 2, +// title: 'Ir al gimnasio', +// completed: false +// } +// ] + +// const store = mockStore({ +// sessionReducer: { +// todos, +// }, +// }); + +// const component = mount( +// +// +// , +// ); + +// expect(component).toMatchSnapshot(); +// }); +// }); diff --git a/00 Base/src/components/todoList/components/todoRowContainer.tsx b/00 Base/src/components/todoList/components/todoRowContainer.tsx new file mode 100644 index 0000000..beb0145 --- /dev/null +++ b/00 Base/src/components/todoList/components/todoRowContainer.tsx @@ -0,0 +1,14 @@ +import { connect } from 'react-redux'; +import { TodoRowComponent } from './todoRow'; +import { deleteTodo } from '../../../redux/actions/todosActions'; + +const mapDispatchToProps = dispatch => { + return { + deleteTodo: (id: number) => {return dispatch(deleteTodo(id))}, + }; +} + +export const TodoRowContainer = connect( + null, + mapDispatchToProps +)(TodoRowComponent); \ No newline at end of file diff --git a/00 Base/src/components/todoList/components/todoTable.tsx b/00 Base/src/components/todoList/components/todoTable.tsx index 1476a60..84e0e75 100644 --- a/00 Base/src/components/todoList/components/todoTable.tsx +++ b/00 Base/src/components/todoList/components/todoTable.tsx @@ -1,12 +1,13 @@ import * as React from 'react'; import {TodoEntity} from '../../../model/todo'; -import {TodoRowComponent} from './todoRow'; +import { TodoRowContainer } from './todoRowContainer'; interface Props { todos: TodoEntity[]; } export const TodoTableComponent = (props: Props) => { + const {todos } = props return (
@@ -28,8 +29,8 @@ export const TodoTableComponent = (props: Props) => { { - props.todos && props.todos.map((todo: TodoEntity) => - + todos && todos.map((todo: TodoEntity) => + ) } diff --git a/00 Base/src/components/todoList/todosArea.tsx b/00 Base/src/components/todoList/todosArea.tsx index f1e0dae..29f5b4d 100644 --- a/00 Base/src/components/todoList/todosArea.tsx +++ b/00 Base/src/components/todoList/todosArea.tsx @@ -31,10 +31,6 @@ export class TodoAreaComponent extends React.Component { const { todos } = this.props const { newTodo } = this.state - if(todos && todos.length === 0) { - return

Cargando datos...

- } - return ( <> <> @@ -42,7 +38,9 @@ export class TodoAreaComponent extends React.Component { this.setState({ newTodo: event.target.value })} /> - + {todos && todos.length > 0 ? + : +

No todos yet

} ) } diff --git a/00 Base/src/components/todoList/todosAreaContainer.tsx b/00 Base/src/components/todoList/todosAreaContainer.tsx index db1c750..db95ba9 100644 --- a/00 Base/src/components/todoList/todosAreaContainer.tsx +++ b/00 Base/src/components/todoList/todosAreaContainer.tsx @@ -12,7 +12,7 @@ const mapStateToProps = (state: State) => { const mapDispatchToProps = dispatch => { return { loadTodos: () => {return dispatch(getTodos())}, - addTodo: (newTodo: string) => {return dispatch(addTodo(newTodo))} + addTodo: (newTodo: string) => {return dispatch(addTodo(newTodo))}, }; } diff --git a/00 Base/src/myApi/index.ts b/00 Base/src/myApi/index.ts index 31b8e23..fdec20b 100644 --- a/00 Base/src/myApi/index.ts +++ b/00 Base/src/myApi/index.ts @@ -1 +1 @@ -export { getListOfTodos, insertTodo } from './myApi'; \ No newline at end of file +export { getListOfTodos, addToTodoList, deleteFromTodoList } from './myApi'; \ No newline at end of file diff --git a/00 Base/src/myApi/myApi.ts b/00 Base/src/myApi/myApi.ts index a811b0d..9bdb338 100644 --- a/00 Base/src/myApi/myApi.ts +++ b/00 Base/src/myApi/myApi.ts @@ -7,8 +7,14 @@ export const getListOfTodos = (): Promise => { .catch(handleError); } -export const insertTodo = (todo: string): Promise => { - return BEApi.insertTodo(todo) +export const addToTodoList = (todo: string): Promise => { + return BEApi.addToTodoList(todo) + .then(resolveTodos) + .catch(handleError); +} + +export const deleteFromTodoList = (id: number): Promise => { + return BEApi.deleteFromTodoList(id) .then(resolveTodos) .catch(handleError); } diff --git a/00 Base/src/myApi/myBackEndApiEndpoint.ts b/00 Base/src/myApi/myBackEndApiEndpoint.ts index bcafa96..f2bc6e9 100644 --- a/00 Base/src/myApi/myBackEndApiEndpoint.ts +++ b/00 Base/src/myApi/myBackEndApiEndpoint.ts @@ -1,7 +1,7 @@ import Axios from 'axios' import { TodoEntity } from '../model/todo' -let todos = [] +let todos: TodoEntity[] = [] export const getTodos = () => Axios.get('https://jsonplaceholder.typicode.com/todos?userId=1') @@ -11,13 +11,19 @@ export const getTodos = () => } ) -export const insertTodo = (todo: string) => { +export const addToTodoList = (title: string) => { + const id = todos.length > 0 ? todos[todos.length - 1].id + 1 : 1 const newTodo: TodoEntity = { userId: 1, - id: todos[todos.length - 1].id + 1, - title: todo, + id, + title, completed: false } todos.push(newTodo) return Promise.resolve(todos) } + +export const deleteFromTodoList = (id: number) => { + todos = todos.filter(todo => todo.id !== id) + return Promise.resolve(todos) +} diff --git a/00 Base/src/redux/actions/todosActions.ts b/00 Base/src/redux/actions/todosActions.ts index 4687dc9..4b3c3c7 100644 --- a/00 Base/src/redux/actions/todosActions.ts +++ b/00 Base/src/redux/actions/todosActions.ts @@ -1,10 +1,10 @@ -import { getListOfTodos, insertTodo } from "../../myApi"; +import { getListOfTodos, addToTodoList, deleteFromTodoList } from "../../myApi"; import { TodoEntity } from "../../model/todo"; import { actionsEnums } from "../common/actionsEnums"; -export const getTodosCompletedAction = (todos: TodoEntity[]) => { +export const completedAction = (todos: TodoEntity[], action) => { return { - type: actionsEnums.TODO_REQUEST_COMPLETED, + type: action, payload: todos } } @@ -13,24 +13,27 @@ export const getTodos = () => (dispatcher) =>{ const promise = getListOfTodos(); promise.then( - (data) => dispatcher(getTodosCompletedAction(data)) + (data) => dispatcher(completedAction(data, actionsEnums.TODO_REQUEST_COMPLETED)) ) return promise; } -export const addTodosCompletedAction = (todo: TodoEntity) => { - return { - type: actionsEnums.ADD_REQUEST_COMPLETED, - payload: todo - } +export const addTodo = (todo: string) => (dispatcher) => { + const promise = addToTodoList(todo); + + promise.then( + (data) => dispatcher(completedAction(data, actionsEnums.ADD_REQUEST_COMPLETED)) + ) + + return promise; } -export const addTodo = (todo: string) => (dispatcher) => { - const promise = insertTodo(todo); +export const deleteTodo = (id: number) => (dispatcher) => { + const promise = deleteFromTodoList(id); promise.then( - (data) => dispatcher(getTodosCompletedAction(data)) + (data) => dispatcher(completedAction(data, actionsEnums.DELETE_REQUEST_COMPLETED)) ) return promise; diff --git a/00 Base/src/redux/common/actionsEnums.ts b/00 Base/src/redux/common/actionsEnums.ts index 997dbdd..53c85ae 100644 --- a/00 Base/src/redux/common/actionsEnums.ts +++ b/00 Base/src/redux/common/actionsEnums.ts @@ -1,4 +1,5 @@ export const actionsEnums = { TODO_REQUEST_COMPLETED: 'TODO_REQUEST_COMPLETED', ADD_REQUEST_COMPLETED: 'ADD_REQUEST_COMPLETED', + DELETE_REQUEST_COMPLETED: 'DELETE_REQUEST_COMPLETED', } \ No newline at end of file diff --git a/00 Base/src/redux/reducers/todoReducer.ts b/00 Base/src/redux/reducers/todoReducer.ts index cabf9ad..ffa5be6 100644 --- a/00 Base/src/redux/reducers/todoReducer.ts +++ b/00 Base/src/redux/reducers/todoReducer.ts @@ -6,18 +6,14 @@ export type todoState = TodoEntity[]; export const todoReducer = (state : todoState = [], action) => { switch (action.type) { case actionsEnums.TODO_REQUEST_COMPLETED: - return handleGetTodosActionCompleted(state, action.payload); case actionsEnums.ADD_REQUEST_COMPLETED: - return handleAddTodoActionCompleted(state, action.payload); + case actionsEnums.DELETE_REQUEST_COMPLETED: + return handleActionCompleted(state, action.payload); } return state; }; -const handleGetTodosActionCompleted = (state : todoState, todos) => { +const handleActionCompleted = (state : todoState, todos) => { return todos; -} - -const handleAddTodoActionCompleted = (state : todoState, todo) => { - return todo; } \ No newline at end of file From c66ca9cd8ba7aac7f1ab96c4858fcb254db43f56 Mon Sep 17 00:00:00 2001 From: Senesero Date: Mon, 13 Apr 2020 16:50:36 +0200 Subject: [PATCH 8/9] Test a medias --- 00 Base/package.json | 12 ++- 00 Base/src/app.tsx | 6 +- 00 Base/src/components/index.ts | 2 +- .../todoList/components/todoRow.spec.tsx | 67 +++++++++---- .../todoList/components/todoRow.tsx | 16 ++- .../components/todoRowContainer.spec.tsx | 43 -------- .../todoList/components/todoRowContainer.tsx | 14 --- .../todoList/components/todoTable.spec.tsx | 76 ++++++++++----- .../todoList/components/todoTable.tsx | 12 +-- .../components/todoList/todosArea.spec.tsx | 31 ------ .../todoList/todosAreaContainer.spec.tsx | 43 -------- .../todoList/todosAreaContainer.tsx | 22 ----- .../todoList/todosContainer.spec.tsx | 93 ++++++++++++++++++ .../{todosArea.tsx => todosContainer.tsx} | 31 +++++- 00 Base/src/index.html | 2 +- 00 Base/src/model/todo.ts | 2 +- 00 Base/src/myApi/myApi.spec.ts | 47 +++++++++ .../src/redux/actions/todosActions.spec.ts | 97 +++++++++---------- 00 Base/src/redux/actions/todosActions.ts | 2 +- 00 Base/src/redux/reducers/index.ts | 4 +- .../src/redux/reducers/todoReducer.spec.ts | 76 ++++++--------- 00 Base/src/redux/reducers/todoReducer.ts | 12 +-- 22 files changed, 381 insertions(+), 329 deletions(-) delete mode 100644 00 Base/src/components/todoList/components/todoRowContainer.spec.tsx delete mode 100644 00 Base/src/components/todoList/components/todoRowContainer.tsx delete mode 100644 00 Base/src/components/todoList/todosArea.spec.tsx delete mode 100644 00 Base/src/components/todoList/todosAreaContainer.spec.tsx delete mode 100644 00 Base/src/components/todoList/todosAreaContainer.tsx create mode 100644 00 Base/src/components/todoList/todosContainer.spec.tsx rename 00 Base/src/components/todoList/{todosArea.tsx => todosContainer.tsx} (54%) create mode 100644 00 Base/src/myApi/myApi.spec.ts diff --git a/00 Base/package.json b/00 Base/package.json index f1befee..88807cf 100644 --- a/00 Base/package.json +++ b/00 Base/package.json @@ -8,13 +8,15 @@ "clean": "rimraf dist", "build": "npm run clean && webpack --config ./config/webpack/prod.js", "test": "jest -c ./config/test/jest.json --verbose", - "test:watch": "jest -c ./config/test/jest.json --verbose --watchAll -i" + "test:watch": "jest -c ./config/test/jest.json --verbose --watchAll -i", + "test:coverage": "jest -c ./config/test/jest.json --verbose --coverage" }, "author": "arp82", "license": "MIT", "dependencies": { "@material-ui/core": "^4.1.3", "axios": "^0.19.0", + "deep-freeze": "0.0.1", "react": "^16.8.6", "react-dom": "^16.8.6", "react-redux": "^7.2.0", @@ -33,16 +35,18 @@ "@types/react-dom": "^16.8.4", "@types/react-router-dom": "^4.3.4", "awesome-typescript-loader": "^5.2.1", + "css-loader": "^3.5.1", + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.2", "html-webpack-plugin": "^3.2.0", "jest": "^24.8.0", + "mini-css-extract-plugin": "^0.9.0", "rimraf": "^2.6.3", "ts-jest": "^24.0.2", "typescript": "^3.5.2", "webpack": "^4.32.2", "webpack-cli": "^3.3.2", "webpack-dev-server": "^3.5.0", - "webpack-merge": "^4.2.1", - "css-loader": "^3.5.1", - "mini-css-extract-plugin": "^0.9.0" + "webpack-merge": "^4.2.1" } } diff --git a/00 Base/src/app.tsx b/00 Base/src/app.tsx index 4a9edd7..bef0ed5 100644 --- a/00 Base/src/app.tsx +++ b/00 Base/src/app.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; -import { TodosAreaContainer } from './components'; +import { TodosContainer } from './components'; -export const App: React.FunctionComponent = props => ( +export const App: React.FunctionComponent = () => (
- +
); diff --git a/00 Base/src/components/index.ts b/00 Base/src/components/index.ts index a3a603a..0ebcc5a 100644 --- a/00 Base/src/components/index.ts +++ b/00 Base/src/components/index.ts @@ -1 +1 @@ -export { TodosAreaContainer } from './todoList/TodosAreaContainer'; \ No newline at end of file +export { TodosContainer } from './todoList/todosContainer'; \ No newline at end of file diff --git a/00 Base/src/components/todoList/components/todoRow.spec.tsx b/00 Base/src/components/todoList/components/todoRow.spec.tsx index d7e74f5..fc52b71 100644 --- a/00 Base/src/components/todoList/components/todoRow.spec.tsx +++ b/00 Base/src/components/todoList/components/todoRow.spec.tsx @@ -1,21 +1,50 @@ -// import * as React from 'react'; -// import { shallow } from 'enzyme'; -// import { TodoRowComponent } from './todoRow'; -// import { TodoEntity } from '../../../model/todo'; - -// describe('TodoRowComponent', () => { -// it('should render as expected', () => { -// const todo: TodoEntity = { -// userId: 1, -// id: 1, -// title: 'Hacer la compra', -// completed: true, -// } +import * as React from 'react'; +import Enzyme, { shallow } from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; +import { TodoEntity } from '../../../model/todo'; +import { TodoRowComponent } from './todoRow'; + +Enzyme.configure({ adapter: new Adapter() }) + +function setup(todo) { + const props = { + key: '1', + todo, + deleteTodo: jest.fn(), + } + + const enzymeWrapper = shallow() + + return { + props, + enzymeWrapper + } +} + +describe('TodoRow', () => { + it('should render self', () => { + const todo: TodoEntity = { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + } -// const component = shallow( -// , -// ); + const { enzymeWrapper } = setup(todo) + + expect(enzymeWrapper.find('tr')).toHaveLength(1) + expect(enzymeWrapper.find('td')).toHaveLength(4) + expect(enzymeWrapper.find('span')).toHaveLength(3) + expect(enzymeWrapper.find('button').text()).toBe('Delete') + }) + + it('should call deleteTodo when the button is clicked', () => { + const event = jest.fn() + const { enzymeWrapper, props } = setup([]) + const deleteTodoButton = enzymeWrapper.find('button') + + deleteTodoButton.simulate('click', event) -// expect(component).toMatchSnapshot(); -// }); -// }); + expect(props.deleteTodo).toHaveBeenCalledTimes(1) + }) +}); \ No newline at end of file diff --git a/00 Base/src/components/todoList/components/todoRow.tsx b/00 Base/src/components/todoList/components/todoRow.tsx index 944f611..5df01ff 100644 --- a/00 Base/src/components/todoList/components/todoRow.tsx +++ b/00 Base/src/components/todoList/components/todoRow.tsx @@ -1,3 +1,6 @@ +import { connect } from 'react-redux'; +import { deleteTodo } from '../../../redux/actions/todosActions'; + import * as React from 'react'; import {TodoEntity} from '../../../model/todo'; @@ -25,4 +28,15 @@ export const TodoRowComponent = (props: Props) => { ); -} \ No newline at end of file +} + +const mapDispatchToProps = dispatch => { + return { + deleteTodo: (id: number) => {return dispatch(deleteTodo(id))}, + }; +} + +export const TodoRow = connect( + null, + mapDispatchToProps +)(TodoRowComponent); \ No newline at end of file diff --git a/00 Base/src/components/todoList/components/todoRowContainer.spec.tsx b/00 Base/src/components/todoList/components/todoRowContainer.spec.tsx deleted file mode 100644 index b43960f..0000000 --- a/00 Base/src/components/todoList/components/todoRowContainer.spec.tsx +++ /dev/null @@ -1,43 +0,0 @@ -// import * as React from 'react'; -// import { mount } from 'enzyme'; -// import { Provider } from 'react-redux'; -// import configureStore from 'redux-mock-store'; -// import ReduxThunk from 'redux-thunk'; -// const middlewares = [ReduxThunk]; -// const mockStore = configureStore(middlewares); - -// import { TodoEntity } from "../../model/todo"; -// import { TodosAreaContainer } from '..'; - -// describe('TodosAreaContainer', () => { -// it('debe pintar TodoAreaComponent cuando tenemos todos', () => { -// const todos: TodoEntity[] = [ -// { -// userId: 1, -// id: 1, -// title: 'Hacer la compra', -// completed: true, -// }, -// { -// userId: 1, -// id: 2, -// title: 'Ir al gimnasio', -// completed: false -// } -// ] - -// const store = mockStore({ -// sessionReducer: { -// todos, -// }, -// }); - -// const component = mount( -// -// -// , -// ); - -// expect(component).toMatchSnapshot(); -// }); -// }); diff --git a/00 Base/src/components/todoList/components/todoRowContainer.tsx b/00 Base/src/components/todoList/components/todoRowContainer.tsx deleted file mode 100644 index beb0145..0000000 --- a/00 Base/src/components/todoList/components/todoRowContainer.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { connect } from 'react-redux'; -import { TodoRowComponent } from './todoRow'; -import { deleteTodo } from '../../../redux/actions/todosActions'; - -const mapDispatchToProps = dispatch => { - return { - deleteTodo: (id: number) => {return dispatch(deleteTodo(id))}, - }; -} - -export const TodoRowContainer = connect( - null, - mapDispatchToProps -)(TodoRowComponent); \ No newline at end of file diff --git a/00 Base/src/components/todoList/components/todoTable.spec.tsx b/00 Base/src/components/todoList/components/todoTable.spec.tsx index 53e2cbb..2447682 100644 --- a/00 Base/src/components/todoList/components/todoTable.spec.tsx +++ b/00 Base/src/components/todoList/components/todoTable.spec.tsx @@ -1,29 +1,53 @@ -// import * as React from 'react'; -// import { shallow } from 'enzyme'; -// import { TodoEntity } from '../../../model/todo'; -// import { TodoTableComponent } from './todoTable'; +import * as React from 'react'; +import Enzyme, { shallow } from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; +import { TodoTableComponent } from './todoTable'; +import { TodoEntity } from '../../../model/todo'; -// describe('TodoTableComponent', () => { -// it('should render as expected', () => { -// const todos: TodoEntity[] = [ -// { -// userId: 1, -// id: 1, -// title: 'Hacer la compra', -// completed: true, -// }, -// { -// userId: 1, -// id: 2, -// title: 'Ir al gimnasio', -// completed: false, -// } -// ] +Enzyme.configure({ adapter: new Adapter() }) + +function setup(todos) { + const props = { + todos, + } + + const enzymeWrapper = shallow() + + return { + props, + enzymeWrapper + } +} + +describe('TodoTable', () => { + it('should render self', () => { + const todos: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false, + } + ] -// const component = shallow( -// , -// ); + const { enzymeWrapper } = setup(todos) -// expect(component).toMatchSnapshot(); -// }); -// }); + expect(enzymeWrapper.find('div').hasClass('row')).toBe(true) + expect(enzymeWrapper.find('table').hasClass('table')) + expect(enzymeWrapper.find('table')).toHaveLength(1) + expect(enzymeWrapper.find('thead')).toHaveLength(1) + expect(enzymeWrapper.find('tr')).toHaveLength(1) + expect(enzymeWrapper.find('th')).toHaveLength(4) + expect(enzymeWrapper.find('Id')).toBeDefined() + expect(enzymeWrapper.find('Title')).toBeDefined() + expect(enzymeWrapper.find('Completed')).toBeDefined() + expect(enzymeWrapper.find('Action')).toBeDefined() + expect(enzymeWrapper.find('tbody')).toHaveLength(1) + }) +}); diff --git a/00 Base/src/components/todoList/components/todoTable.tsx b/00 Base/src/components/todoList/components/todoTable.tsx index 84e0e75..385068b 100644 --- a/00 Base/src/components/todoList/components/todoTable.tsx +++ b/00 Base/src/components/todoList/components/todoTable.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import {TodoEntity} from '../../../model/todo'; -import { TodoRowContainer } from './todoRowContainer'; +import { TodoRow } from './todoRow'; interface Props { todos: TodoEntity[]; @@ -14,23 +14,23 @@ export const TodoTableComponent = (props: Props) => {
{ todos && todos.map((todo: TodoEntity) => - + ) } diff --git a/00 Base/src/components/todoList/todosArea.spec.tsx b/00 Base/src/components/todoList/todosArea.spec.tsx deleted file mode 100644 index 5ab1ee3..0000000 --- a/00 Base/src/components/todoList/todosArea.spec.tsx +++ /dev/null @@ -1,31 +0,0 @@ -// import * as React from 'react'; -// import { shallow } from 'enzyme'; -// import { TodoAreaComponent } from './todosArea'; -// import { TodoEntity } from '../../model/todo'; - -// describe('TodoAreaComponent', () => { -// it('should render as expected', () => { -// const todos: TodoEntity[] = [ -// { -// userId: 1, -// id: 1, -// title: 'Hacer la compra', -// completed: true, -// }, -// { -// userId: 1, -// id: 2, -// title: 'Ir al gimnasio', -// completed: false, -// } -// ] - -// const loadTodos = () => { }; - -// const component = shallow( -// , -// ); - -// expect(component).toMatchSnapshot(); -// }); -// }); diff --git a/00 Base/src/components/todoList/todosAreaContainer.spec.tsx b/00 Base/src/components/todoList/todosAreaContainer.spec.tsx deleted file mode 100644 index b43960f..0000000 --- a/00 Base/src/components/todoList/todosAreaContainer.spec.tsx +++ /dev/null @@ -1,43 +0,0 @@ -// import * as React from 'react'; -// import { mount } from 'enzyme'; -// import { Provider } from 'react-redux'; -// import configureStore from 'redux-mock-store'; -// import ReduxThunk from 'redux-thunk'; -// const middlewares = [ReduxThunk]; -// const mockStore = configureStore(middlewares); - -// import { TodoEntity } from "../../model/todo"; -// import { TodosAreaContainer } from '..'; - -// describe('TodosAreaContainer', () => { -// it('debe pintar TodoAreaComponent cuando tenemos todos', () => { -// const todos: TodoEntity[] = [ -// { -// userId: 1, -// id: 1, -// title: 'Hacer la compra', -// completed: true, -// }, -// { -// userId: 1, -// id: 2, -// title: 'Ir al gimnasio', -// completed: false -// } -// ] - -// const store = mockStore({ -// sessionReducer: { -// todos, -// }, -// }); - -// const component = mount( -// -// -// , -// ); - -// expect(component).toMatchSnapshot(); -// }); -// }); diff --git a/00 Base/src/components/todoList/todosAreaContainer.tsx b/00 Base/src/components/todoList/todosAreaContainer.tsx deleted file mode 100644 index db95ba9..0000000 --- a/00 Base/src/components/todoList/todosAreaContainer.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { connect } from 'react-redux'; -import { TodoAreaComponent } from './todosArea'; -import { State } from '../../redux/reducers'; -import { getTodos, addTodo } from '../../redux/actions/todosActions'; - -const mapStateToProps = (state: State) => { - return{ - todos: state.todoReducer - }; -} - -const mapDispatchToProps = dispatch => { - return { - loadTodos: () => {return dispatch(getTodos())}, - addTodo: (newTodo: string) => {return dispatch(addTodo(newTodo))}, - }; -} - -export const TodosAreaContainer = connect( - mapStateToProps, - mapDispatchToProps -)(TodoAreaComponent); \ No newline at end of file diff --git a/00 Base/src/components/todoList/todosContainer.spec.tsx b/00 Base/src/components/todoList/todosContainer.spec.tsx new file mode 100644 index 0000000..235e42a --- /dev/null +++ b/00 Base/src/components/todoList/todosContainer.spec.tsx @@ -0,0 +1,93 @@ +import * as React from 'react'; +import Enzyme, { shallow } from 'enzyme'; +import { TodoEntity } from '../../model/todo'; +import { TodoAreaComponent } from './todosContainer'; +import Adapter from 'enzyme-adapter-react-16'; + +import { mount } from 'enzyme'; +import { Provider } from 'react-redux'; +import configureStore from 'redux-mock-store'; +import ReduxThunk from 'redux-thunk'; +const middlewares = [ReduxThunk]; +const mockStore = configureStore(middlewares); + +Enzyme.configure({ adapter: new Adapter() }) + +function setup(todos) { + const props = { + todos, + loadTodos: jest.fn(), + addTodo: jest.fn(), + } + + const enzymeWrapper = shallow() + + return { + props, + enzymeWrapper + } +} + +describe('TodoAreaComponent', () => { + it('should render self', () => { + const todos: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false, + } + ] + + const { enzymeWrapper } = setup(todos) + + expect(enzymeWrapper.find('h1').text()).toBe('Todos') + expect(enzymeWrapper.find('div').hasClass('addTodoContainer')).toBe(true) + expect(enzymeWrapper.find('input').hasClass('todoInput')) + expect(enzymeWrapper.find('span').text()).toBe('New todo:') + expect(enzymeWrapper.find('button').text()).toBe('Add todo') + }) + + it('should call loadTodos when componentDidMount', () => { + const todos: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false, + } + ] + + const { props } = setup(todos) + expect(props.loadTodos).toBeCalled() + expect(props.addTodo).not.toBeCalled() + }) + + it('should call addTodo when the button is clicked', () => { + const event = jest.fn() + const { enzymeWrapper, props } = setup([]) + const newTodoButton = enzymeWrapper.find('button') + + newTodoButton.simulate('click', event) + + expect(props.addTodo).toHaveBeenCalledTimes(1) + }) + + it('if we dont have todos, should show de text ', () => { + const { enzymeWrapper } = setup([]) + + expect(enzymeWrapper.find('p').text()).toBe('No todos yet') + }) +}); \ No newline at end of file diff --git a/00 Base/src/components/todoList/todosArea.tsx b/00 Base/src/components/todoList/todosContainer.tsx similarity index 54% rename from 00 Base/src/components/todoList/todosArea.tsx rename to 00 Base/src/components/todoList/todosContainer.tsx index 29f5b4d..77f8421 100644 --- a/00 Base/src/components/todoList/todosArea.tsx +++ b/00 Base/src/components/todoList/todosContainer.tsx @@ -1,3 +1,7 @@ +import { connect } from 'react-redux'; +import { TodoState } from '../../redux/reducers'; +import { getTodos, addTodo } from '../../redux/actions/todosActions'; + import * as React from 'react'; import {TodoTableComponent} from './components/todoTable'; import { TodoEntity } from '../../model/todo'; @@ -33,15 +37,34 @@ export class TodoAreaComponent extends React.Component { return ( <> - <> +

Todos

+
New todo: - this.setState({ newTodo: event.target.value })} /> + this.setState({ newTodo: event.target.value })} /> - +
{todos && todos.length > 0 ? :

No todos yet

} ) } -} \ No newline at end of file +} + +const mapStateToProps = (state: TodoState) => { + return{ + todos: state.todoReducer + }; +} + +const mapDispatchToProps = dispatch => { + return { + loadTodos: () => {return dispatch(getTodos())}, + addTodo: (newTodo: string) => {return dispatch(addTodo(newTodo))}, + }; +} + +export const TodosContainer = connect( + mapStateToProps, + mapDispatchToProps +)(TodoAreaComponent); \ No newline at end of file diff --git a/00 Base/src/index.html b/00 Base/src/index.html index 8987da2..196fd86 100644 --- a/00 Base/src/index.html +++ b/00 Base/src/index.html @@ -6,7 +6,7 @@ name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> - Fruits List + Todos List
diff --git a/00 Base/src/model/todo.ts b/00 Base/src/model/todo.ts index e3b36a0..7d4c836 100644 --- a/00 Base/src/model/todo.ts +++ b/00 Base/src/model/todo.ts @@ -1,5 +1,5 @@ export interface TodoEntity { - userId: number + userId: number; id: number; title: string; completed: boolean; diff --git a/00 Base/src/myApi/myApi.spec.ts b/00 Base/src/myApi/myApi.spec.ts new file mode 100644 index 0000000..9768780 --- /dev/null +++ b/00 Base/src/myApi/myApi.spec.ts @@ -0,0 +1,47 @@ +import * as BEApi from './myBackEndApiEndpoint'; +import { todoState } from '../redux/reducers/todoReducer'; +import { getListOfTodos } from './myApi'; + +describe('myApi', () => { + const todos = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false, + } + ] as todoState; + + it('getListOfTodos should call getTodos and return the todos', async () => { + jest.spyOn(BEApi, "getTodos").mockResolvedValue(todos) + + const result = await getListOfTodos() + + expect(BEApi.getTodos).toBeCalled() + expect(result).toEqual(todos); + }); + + it('addToTodoList should call addToTodoList and return the todos', async () => { + jest.spyOn(BEApi, "addToTodoList").mockResolvedValue(todos) + + const result = await BEApi.addToTodoList('new todo') + + expect(BEApi.addToTodoList).toBeCalled() + expect(result).toEqual(todos); + }); + + it('deleteFromTodoList should call deleteFromTodoList and return the todos', async () => { + jest.spyOn(BEApi, "deleteFromTodoList").mockResolvedValue(todos) + + const result = await BEApi.deleteFromTodoList(2) + + expect(BEApi.deleteFromTodoList).toBeCalled() + expect(result).toEqual(todos); + }); +}); diff --git a/00 Base/src/redux/actions/todosActions.spec.ts b/00 Base/src/redux/actions/todosActions.spec.ts index 6077402..4aa4266 100644 --- a/00 Base/src/redux/actions/todosActions.spec.ts +++ b/00 Base/src/redux/actions/todosActions.spec.ts @@ -1,55 +1,50 @@ -// import configureStore from 'redux-mock-store'; -// import ReduxThunk from 'redux-thunk'; -// const middlewares = [ReduxThunk]; -// const mockStore = configureStore(middlewares); +import { actionsEnums } from "../common/actionsEnums"; +import { completedAction } from "./todosActions"; +import { TodoEntity } from "../../model/todo"; -// import { TodoEntity } from '../../model/todo'; -// import { todoActionsCompletedAction } from "./todoActions"; -// import { actionsEnums } from '../common/actionsEnums'; +describe('todosActions', () => { + it('should create an action to get todos', () => { + const todos: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false, + } + ] + const action = actionsEnums.ADD_REQUEST_COMPLETED + const expectedAction = { + type: action, + payload: todos, + } + expect(completedAction(todos, action)).toEqual(expectedAction) + }) -// describe('todoActionsCompletedAction', () => { -// it('debe devolver acción cuando el tipo sea TODO_REQUEST_COMPLETED', () => { -// const todoResponse: TodoEntity[] = [ -// { -// userId: 1, -// id: 1, -// title: 'Hacer la compra', -// completed: true, -// }, -// { -// userId: 1, -// id: 2, -// title: 'Ir al gimnasio', -// completed: false -// } -// ] + it('should return action when is called', () => { + const todoResponse: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false + } + ] -// const result = todoActionsCompletedAction(todoResponse); + const result = completedAction(todoResponse, actionsEnums.TODO_REQUEST_COMPLETED); -// expect(result.type).toBe(actionsEnums.TODO_REQUEST_COMPLETED); -// expect(result.payload).toBe(todoResponse); -// }); - -// it('se realiza la llamada para obtener los todos', () => { -// const todoResponse: TodoEntity[] = [ -// { -// userId: 1, -// id: 1, -// title: 'Hacer la compra', -// completed: true, -// }, -// { -// userId: 1, -// id: 2, -// title: 'Ir al gimnasio', -// completed: false -// } -// ] - -// const store = mockStore(); -// store.dispatch(todoActionsCompletedAction(todoResponse)) - -// expect(store.getActions()[0].type).toBe(actionsEnums.TODO_REQUEST_COMPLETED); -// expect(store.getActions()[0].payload).toBe(todoResponse); -// }); -// }); \ No newline at end of file + expect(result.type).toBe(actionsEnums.TODO_REQUEST_COMPLETED); + expect(result.payload).toBe(todoResponse); + }); +}); \ No newline at end of file diff --git a/00 Base/src/redux/actions/todosActions.ts b/00 Base/src/redux/actions/todosActions.ts index 4b3c3c7..69e8ea6 100644 --- a/00 Base/src/redux/actions/todosActions.ts +++ b/00 Base/src/redux/actions/todosActions.ts @@ -9,7 +9,7 @@ export const completedAction = (todos: TodoEntity[], action) => { } } -export const getTodos = () => (dispatcher) =>{ +export const getTodos = () => (dispatcher) => { const promise = getListOfTodos(); promise.then( diff --git a/00 Base/src/redux/reducers/index.ts b/00 Base/src/redux/reducers/index.ts index 1049f3b..4a87506 100644 --- a/00 Base/src/redux/reducers/index.ts +++ b/00 Base/src/redux/reducers/index.ts @@ -1,10 +1,10 @@ import { combineReducers} from 'redux'; import { todoReducer, todoState } from './todoReducer'; -export interface State { +export interface TodoState { todoReducer : todoState; }; -export const reducers = combineReducers({ +export const reducers = combineReducers({ todoReducer, }); \ No newline at end of file diff --git a/00 Base/src/redux/reducers/todoReducer.spec.ts b/00 Base/src/redux/reducers/todoReducer.spec.ts index f981f7c..c172e19 100644 --- a/00 Base/src/redux/reducers/todoReducer.spec.ts +++ b/00 Base/src/redux/reducers/todoReducer.spec.ts @@ -1,48 +1,28 @@ -// import * as deepFreeze from 'deep-freeze'; -// import { todoReducer, todoState } from './todoReducer'; -// import { actionsEnums } from '../common/actionsEnums'; - -// describe('todoReducer', () => { -// it('debe devolver el mismo estado al mandarle un tipo erróneo', () => { -// const initialState = [] as todoState; - -// const action = { -// type: 'Wrong', -// }; - -// deepFreeze(initialState); - -// const result = todoReducer(initialState, action); - -// expect(result).toBe(initialState); -// expect(initialState).not.toBe(undefined); -// }); - -// describe('handleGetTodosActionCompleted', () => { -// it('se actualizan los valores cuando le pasamos un type correcto', () => { -// const initialState = [] as todoState; - -// const action = { -// type: actionsEnums.TODO_REQUEST_COMPLETED, -// payload: [{ -// userId: 1, -// id: 1, -// title: 'Hacer la compra', -// completed: true, -// }, -// { -// userId: 1, -// id: 2, -// title: 'Ir al gimnasio', -// completed: false -// }] as todoState, -// }; - -// deepFreeze(initialState); - -// const result = todoReducer(initialState, action); - -// expect(result).toBe(action.payload); -// }); -// }); -// }); +import { todoReducer, todoState } from "./todoReducer"; +import { actionsEnums } from "../common/actionsEnums"; + +describe('todoReducer', () => { + it('should update values when send correct type', () => { + const initialState = [] as todoState; + + const action = { + type: actionsEnums.TODO_REQUEST_COMPLETED, + payload: [{ + userId: 1, + id: 1, + title: 'Hacer la compra', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Ir al gimnasio', + completed: false + }] as todoState, + }; + + const result = todoReducer(initialState, action); + + expect(result).toBe(action.payload); + }); +}); diff --git a/00 Base/src/redux/reducers/todoReducer.ts b/00 Base/src/redux/reducers/todoReducer.ts index ffa5be6..dc2d60f 100644 --- a/00 Base/src/redux/reducers/todoReducer.ts +++ b/00 Base/src/redux/reducers/todoReducer.ts @@ -8,12 +8,8 @@ export const todoReducer = (state : todoState = [], action) => { case actionsEnums.TODO_REQUEST_COMPLETED: case actionsEnums.ADD_REQUEST_COMPLETED: case actionsEnums.DELETE_REQUEST_COMPLETED: - return handleActionCompleted(state, action.payload); + return action.payload; + default: + return state } - - return state; -}; - -const handleActionCompleted = (state : todoState, todos) => { - return todos; -} \ No newline at end of file +}; \ No newline at end of file From 096cb0867c110f252733539f3a114dde8f0b0147 Mon Sep 17 00:00:00 2001 From: Senesero Date: Mon, 13 Apr 2020 17:34:18 +0200 Subject: [PATCH 9/9] Testear api --- .../todoList/components/todoRow.spec.tsx | 2 +- .../todoList/components/todoTable.spec.tsx | 4 +- .../todoList/todosContainer.spec.tsx | 8 +- 00 Base/src/myApi/myApi.spec.ts | 4 +- .../src/myApi/myBackEndApiEndpoint.spec.ts | 84 +++++++++++++++++++ 00 Base/src/myApi/myBackEndApiEndpoint.ts | 6 ++ .../src/redux/actions/todosActions.spec.ts | 8 +- .../src/redux/reducers/todoReducer.spec.ts | 4 +- 8 files changed, 105 insertions(+), 15 deletions(-) create mode 100644 00 Base/src/myApi/myBackEndApiEndpoint.spec.ts diff --git a/00 Base/src/components/todoList/components/todoRow.spec.tsx b/00 Base/src/components/todoList/components/todoRow.spec.tsx index fc52b71..99964dc 100644 --- a/00 Base/src/components/todoList/components/todoRow.spec.tsx +++ b/00 Base/src/components/todoList/components/todoRow.spec.tsx @@ -26,7 +26,7 @@ describe('TodoRow', () => { const todo: TodoEntity = { userId: 1, id: 1, - title: 'Hacer la compra', + title: 'Buy', completed: true, } diff --git a/00 Base/src/components/todoList/components/todoTable.spec.tsx b/00 Base/src/components/todoList/components/todoTable.spec.tsx index 2447682..12442a3 100644 --- a/00 Base/src/components/todoList/components/todoTable.spec.tsx +++ b/00 Base/src/components/todoList/components/todoTable.spec.tsx @@ -25,13 +25,13 @@ describe('TodoTable', () => { { userId: 1, id: 1, - title: 'Hacer la compra', + title: 'Buy', completed: true, }, { userId: 1, id: 2, - title: 'Ir al gimnasio', + title: 'Go to the gym', completed: false, } ] diff --git a/00 Base/src/components/todoList/todosContainer.spec.tsx b/00 Base/src/components/todoList/todosContainer.spec.tsx index 235e42a..fdf3b24 100644 --- a/00 Base/src/components/todoList/todosContainer.spec.tsx +++ b/00 Base/src/components/todoList/todosContainer.spec.tsx @@ -34,13 +34,13 @@ describe('TodoAreaComponent', () => { { userId: 1, id: 1, - title: 'Hacer la compra', + title: 'Buy', completed: true, }, { userId: 1, id: 2, - title: 'Ir al gimnasio', + title: 'Go to the gym', completed: false, } ] @@ -59,13 +59,13 @@ describe('TodoAreaComponent', () => { { userId: 1, id: 1, - title: 'Hacer la compra', + title: 'Buy', completed: true, }, { userId: 1, id: 2, - title: 'Ir al gimnasio', + title: 'Go to the gym', completed: false, } ] diff --git a/00 Base/src/myApi/myApi.spec.ts b/00 Base/src/myApi/myApi.spec.ts index 9768780..c9034b8 100644 --- a/00 Base/src/myApi/myApi.spec.ts +++ b/00 Base/src/myApi/myApi.spec.ts @@ -7,13 +7,13 @@ describe('myApi', () => { { userId: 1, id: 1, - title: 'Hacer la compra', + title: 'Buy', completed: true, }, { userId: 1, id: 2, - title: 'Ir al gimnasio', + title: 'Go to the gym', completed: false, } ] as todoState; diff --git a/00 Base/src/myApi/myBackEndApiEndpoint.spec.ts b/00 Base/src/myApi/myBackEndApiEndpoint.spec.ts new file mode 100644 index 0000000..32124a2 --- /dev/null +++ b/00 Base/src/myApi/myBackEndApiEndpoint.spec.ts @@ -0,0 +1,84 @@ +import * as BEApi from './myBackEndApiEndpoint'; +import Axios from 'axios' +import { TodoEntity } from '../model/todo'; + +describe('myBackEndApiEndpoint', () => { + const todos: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Buy', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Go to the gym', + completed: false, + } + ]; + + it('getTodos should return the todos', async () => { + jest.spyOn(Axios, "get").mockResolvedValue(todos) + + await BEApi.getTodos() + + expect(Axios.get).toBeCalled() + }); + + it('addToTodoList should add todo the todos', async () => { + const newTodo: string = 'Do the test' + const newTodos: TodoEntity[] = [ + { + userId: 1, + id: 1, + title: 'Buy', + completed: true, + }, + { + userId: 1, + id: 2, + title: 'Go to the gym', + completed: false, + }, + { + userId: 1, + id: 3, + title: 'Do the test', + completed: false, + } + ] + + await BEApi.setTodos(todos) + expect(BEApi.getTodosValue()).toEqual(todos) + + const result = await BEApi.addToTodoList(newTodo) + expect(result).toEqual(newTodos) + expect(BEApi.getTodosValue()).toEqual(newTodos) + }); + + it('deleteFromTodoList should delete todo from todos', async () => { + const todoToDelete: number = 1 + const newTodos: TodoEntity[] = [ + { + userId: 1, + id: 2, + title: 'Go to the gym', + completed: false, + }, + { + userId: 1, + id: 3, + title: 'Do the test', + completed: false, + } + ] + + await BEApi.setTodos(todos) + expect(BEApi.getTodosValue()).toEqual(todos) + + const result = await BEApi.deleteFromTodoList(todoToDelete) + expect(result).toEqual(newTodos) + expect(BEApi.getTodosValue()).toEqual(newTodos) + }); +}); diff --git a/00 Base/src/myApi/myBackEndApiEndpoint.ts b/00 Base/src/myApi/myBackEndApiEndpoint.ts index f2bc6e9..5f0e0fe 100644 --- a/00 Base/src/myApi/myBackEndApiEndpoint.ts +++ b/00 Base/src/myApi/myBackEndApiEndpoint.ts @@ -3,6 +3,12 @@ import { TodoEntity } from '../model/todo' let todos: TodoEntity[] = [] +// Funnctions to test the other functions +export const setTodos = (newTodos: TodoEntity[]) => { + todos = newTodos +} +export const getTodosValue = () => todos + export const getTodos = () => Axios.get('https://jsonplaceholder.typicode.com/todos?userId=1') .then( response => { diff --git a/00 Base/src/redux/actions/todosActions.spec.ts b/00 Base/src/redux/actions/todosActions.spec.ts index 4aa4266..3aaaeb1 100644 --- a/00 Base/src/redux/actions/todosActions.spec.ts +++ b/00 Base/src/redux/actions/todosActions.spec.ts @@ -8,13 +8,13 @@ describe('todosActions', () => { { userId: 1, id: 1, - title: 'Hacer la compra', + title: 'Buy', completed: true, }, { userId: 1, id: 2, - title: 'Ir al gimnasio', + title: 'Go to the gym', completed: false, } ] @@ -31,13 +31,13 @@ describe('todosActions', () => { { userId: 1, id: 1, - title: 'Hacer la compra', + title: 'Buy', completed: true, }, { userId: 1, id: 2, - title: 'Ir al gimnasio', + title: 'Go to the gym', completed: false } ] diff --git a/00 Base/src/redux/reducers/todoReducer.spec.ts b/00 Base/src/redux/reducers/todoReducer.spec.ts index c172e19..646583b 100644 --- a/00 Base/src/redux/reducers/todoReducer.spec.ts +++ b/00 Base/src/redux/reducers/todoReducer.spec.ts @@ -10,13 +10,13 @@ describe('todoReducer', () => { payload: [{ userId: 1, id: 1, - title: 'Hacer la compra', + title: 'Buy', completed: true, }, { userId: 1, id: 2, - title: 'Ir al gimnasio', + title: 'Go to the gym', completed: false }] as todoState, };
- Id + Id - Title + Title - Completed + Completed - Action + Action