Skip to content
This repository has been archived by the owner on May 20, 2024. It is now read-only.

Migrate to Redux Toolkit #156

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cypress/integration/selectors-spec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/// <reference types="cypress" />

import {getVisibleTodos} from '../../src/selectors'
import { getVisibleTodos } from '../../src/slices/visibilityFilter'

describe('getVisibleTodos', () => {
it('throws an error for unknown visibility filter', () => {
expect(() => {
getVisibleTodos({
todos: [],
visibilityFilter: 'unknown-filter'
visibilityFilter: 'unknown-filter',
})
}).to.throw()
})
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,12 @@
"start-server-and-test": "1.12.1"
},
"dependencies": {
"@reduxjs/toolkit": "^1.4.0",
"classnames": "2.2.6",
"prop-types": "15.7.2",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-redux": "6.0.1",
"redux": "4.0.5",
"reselect": "4.0.0",
"todomvc-app-css": "2.3.0"
}
}
45 changes: 0 additions & 45 deletions src/actions/index.cy-spec.js

This file was deleted.

9 changes: 0 additions & 9 deletions src/actions/index.js

This file was deleted.

45 changes: 0 additions & 45 deletions src/actions/index.spec.js

This file was deleted.

19 changes: 10 additions & 9 deletions src/components/App.cy-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
// compare to App.spec.js
import React from 'react'
import App from './App'
import {mount} from 'cypress-react-unit-test'
import { mount } from 'cypress-react-unit-test'
// we are making mini application - thus we need a store!
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import reducer from '../reducers'
import {addTodo, completeTodo} from '../actions'
const store = createStore(reducer)
import { store } from '../store'
import { addTodo, completeTodo } from '../slices/todos'

describe('components', () => {
const setup = () => {
Expand All @@ -35,14 +33,17 @@ describe('components', () => {

it('should render a couple todos', () => {
// use application code to interact with store
store.dispatch(addTodo('write app code'))
store.dispatch(addTodo('test components using Cypress'))
store.dispatch(completeTodo(1))
store.dispatch(addTodo({ text: 'write app code' }))
store.dispatch(addTodo({ text: 'test components using Cypress' }))
store.dispatch(completeTodo({ id: 1 }))
setup()

// make sure the list of items is correctly checked
cy.get('.todo').should('have.length', 2)
cy.contains('.todo', 'write app code').should('not.have.class', 'completed')
cy.contains('.todo', 'test components using Cypress').should('have.class', 'completed')
cy.contains('.todo', 'test components using Cypress').should(
'have.class',
'completed'
)
})
})
27 changes: 16 additions & 11 deletions src/components/Footer.cy-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ import { mount } from 'cypress-react-unit-test'

// we are making mini application - thus we need a store!
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import reducer from '../reducers'
const store = createStore(reducer)
import { store } from '../store'

const setup = propOverrides => {
const props = Object.assign({
completedCount: 0,
activeCount: 0,
onClearCompleted: cy.stub().as('clear'),
}, propOverrides)
const setup = (propOverrides) => {
const props = Object.assign(
{
completedCount: 0,
activeCount: 0,
onClearCompleted: cy.stub().as('clear'),
},
propOverrides
)

mount(
<Provider store={store}>
Expand All @@ -38,7 +39,8 @@ describe('components', () => {

it('should render filters', () => {
setup()
cy.get('footer li').should('have.length', 3)
cy.get('footer li')
.should('have.length', 3)
.should((li) => {
expect(li[0]).to.have.text('All')
expect(li[1]).to.have.text('Active')
Expand All @@ -53,7 +55,10 @@ describe('components', () => {

it('should render clear button when completed todos', () => {
setup({ completedCount: 1 })
cy.contains('button', 'Clear completed').should('have.class', 'clear-completed')
cy.contains('button', 'Clear completed').should(
'have.class',
'clear-completed'
)
})

it('should call onClearCompleted on clear button click', () => {
Expand Down
18 changes: 10 additions & 8 deletions src/components/Header.cy-spec.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
/// <reference types="cypress" />
import React from 'react'
import Header from './Header'
import {mount} from 'cypress-react-unit-test'
import { mount } from 'cypress-react-unit-test'

// we are making mini application - thus we need a store!
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import reducer from '../reducers'
const store = createStore(reducer)
import { store } from '../store'

describe('components', () => {
describe('Header', () => {
beforeEach(() => {
const props = {
addTodo: cy.stub().as('addTodo')
addTodo: cy.stub().as('addTodo'),
}
mount(
<Provider store={store}>
Expand All @@ -22,9 +21,12 @@ describe('components', () => {
})

it('should render correctly', () => {
cy.get('header').should('have.class', 'header')
.contains('h1', 'todos')
cy.get('header input').should('have.attr', 'placeholder', 'What needs to be done?')
cy.get('header').should('have.class', 'header').contains('h1', 'todos')
cy.get('header input').should(
'have.attr',
'placeholder',
'What needs to be done?'
)
})

it('should call addTodo if length of text is greater than 0', () => {
Expand Down
10 changes: 5 additions & 5 deletions src/components/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@ import React from 'react'
import TodoTextInput from './TodoTextInput'

const Header = ({ addTodo }) => (
<header className='header'>
<header className="header">
<h1>todos</h1>
<TodoTextInput
newTodo
onSave={text => {
onSave={(text) => {
if (text.length !== 0) {
// simulate delayed application logic
// setTimeout(addTodo, 1000, text)
addTodo(text)
addTodo({ text })
}
}}
placeholder='What needs to be done?'
placeholder="What needs to be done?"
/>
</header>
)

Header.propTypes = {
addTodo: PropTypes.func.isRequired
addTodo: PropTypes.func.isRequired,
}

export default Header
38 changes: 19 additions & 19 deletions src/components/MainSection.cy-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@ import { mount } from 'cypress-react-unit-test'

// we are making mini application - thus we need a store!
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import reducer from '../reducers'
const store = createStore(reducer)
import { store } from '../store'

const setup = propOverrides => {
const props = Object.assign({
todosCount: 2,
completedCount: 1,
actions: {
editTodo: cy.stub().as('edit'),
deleteTodo: cy.stub().as('delete'),
completeTodo: cy.stub().as('complete'),
completeAllTodos: cy.stub().as('completeAll'),
clearCompleted: cy.stub().as('clearCompleted')
}
}, propOverrides)
const setup = (propOverrides) => {
const props = Object.assign(
{
todosCount: 2,
completedCount: 1,
actions: {
editTodo: cy.stub().as('edit'),
deleteTodo: cy.stub().as('delete'),
completeTodo: cy.stub().as('complete'),
completeAllTodos: cy.stub().as('completeAll'),
clearCompleted: cy.stub().as('clearCompleted'),
},
},
propOverrides
)

mount(
<Provider store={store}>
Expand All @@ -47,10 +48,9 @@ describe('components', () => {

it('should be checked if all todos completed', () => {
setup({
completedCount: 2
completedCount: 2,
})
cy.get('input[type=checkbox]')
.should('be.checked')
cy.get('input[type=checkbox]').should('be.checked')
})

it('should call completeAllTodos on change', () => {
Expand Down Expand Up @@ -84,7 +84,7 @@ describe('components', () => {
it('should not render if there are no todos', () => {
setup({
todosCount: 0,
completedCount: 0
completedCount: 0,
})
cy.get('li').should('have.length', 0)
})
Expand Down
16 changes: 8 additions & 8 deletions src/components/MainSection.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@ import Footer from './Footer'
import VisibleTodoList from '../containers/VisibleTodoList'

const MainSection = ({ todosCount, completedCount, actions }) => (
<section className='main'>
<section className="main">
{!!todosCount && (
<span>
<input
className='toggle-all'
type='checkbox'
className="toggle-all"
type="checkbox"
checked={completedCount === todosCount}
onClick={actions.completeAllTodos}
onChange={actions.completeAllTodos}
onClick={() => actions.completeAllTodos()}
onChange={() => actions.completeAllTodos()}
/>
<label data-cy-toggle-all onClick={actions.completeAllTodos} />
<label data-cy-toggle-all onClick={() => actions.completeAllTodos()} />
</span>
)}
<VisibleTodoList />
{!!todosCount && (
<Footer
completedCount={completedCount}
activeCount={todosCount - completedCount}
onClearCompleted={actions.clearCompleted}
onClearCompleted={() => actions.clearCompleted()}
/>
)}
</section>
Expand All @@ -31,7 +31,7 @@ const MainSection = ({ todosCount, completedCount, actions }) => (
MainSection.propTypes = {
todosCount: PropTypes.number.isRequired,
completedCount: PropTypes.number.isRequired,
actions: PropTypes.object.isRequired
actions: PropTypes.object.isRequired,
}

export default MainSection
Loading