> For the complete documentation index, see [llms.txt](https://hackerati.gitbook.io/react-tutorial/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hackerati.gitbook.io/react-tutorial/todomvc_app/delete_a_todo.md).

# Delete a Todo

## *Story: As a user, I want to delete a todo from my todos list.*

## TodoMVC actions

#### It should create an action to delete a todo

Write a test.

```javascript
diff --git a/tests/todomvc/actions.spec.js b/tests/todomvc/actions.spec.js
index 694dd04..fd31f8f 100644
--- a/tests/todomvc/actions.spec.js
+++ b/tests/todomvc/actions.spec.js
@@ -21,5 +21,13 @@ describe('TodoMVC actions', () => {
     };

     expect(todomvc.actions.editTodo('my_id', description)).to.deep.equal(expectedAction)
+  });
+
+  it('Should create an action to delete a todo', () => {
+    const expectedAction = {
+      type: todomvc.types.DELETE, id: 'my_id'
+    };
+
+    expect(todomvc.actions.deleteTodo('my_id')).to.deep.equal(expectedAction)
   })
 });
(END)
```

Run the test and watch it fail.

```bash
  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    1) Should create an action to delete a todo

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo


  25 passing (88ms)
  1 failing

  1) TodoMVC actions Should create an action to delete a todo:
     TypeError: _todomvc2.default.actions.deleteTodo is not a function
      at Context.<anonymous> (tests/todomvc/actions.spec.js:31:28)
```

Write the code to make the test pass. This time we will define the DELETE action type and use it in the same code change.

```javascript
diff --git a/src/todomvc/ActionTypes.js b/src/todomvc/ActionTypes.js
index 28b3b32..60f8aa8 100644
--- a/src/todomvc/ActionTypes.js
+++ b/src/todomvc/ActionTypes.js
@@ -2,3 +2,4 @@

 export const ADD = 'todomvc/ADD';
 export const EDIT = 'todomvc/EDIT';
+export const DELETE = 'todomvc/DELETE';
(END)
```

```javascript
diff --git a/src/todomvc/actions.js b/src/todomvc/actions.js
index dc30850..0f1e307 100644
--- a/src/todomvc/actions.js
+++ b/src/todomvc/actions.js
@@ -9,3 +9,7 @@ export function addTodo(text) {
 export function editTodo(id, text) {
   return {type: types.EDIT, id: id, description: text}
 }
+
+export function deleteTodo(id) {
+  return {type: types.DELETE, id: id}
+}
(END)
```

Run the test and watch it pass.

```bash
  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo


  26 passing (94ms)
```

Commit changes.

```bash
$ git add .
$ git commit -m 'created an action to delete a todo'
```

## TodoMVC reducer

#### It should handle DELETE todo

Write the test.

```javascript
diff --git a/tests/todomvc/reducer.spec.js b/tests/todomvc/reducer.spec.js
index 0c4fb5e..dd79807 100644
--- a/tests/todomvc/reducer.spec.js
+++ b/tests/todomvc/reducer.spec.js
@@ -41,5 +41,18 @@ describe('TodoMVC reducer', () => {
     expect(new_state.get(1).get('id')).to.equal(state.get(1).get('id'));
     expect(new_state.get(1).get('description')).to.equal('My updated todo');
     expect(new_state.get(1).get('completed')).to.equal(state.get(1).get('completed'))
+  });
+
+  it('Should handle DELETE todo', () => {
+    const state = List([
+      Map({id: uuid.v4(), description: 'My todo', completed: false}),
+      Map({id: uuid.v4(), description: 'My soon to be deleted todo', completed: false})
+    ]);
+    const new_state = todomvc.reducer(state, {
+      type: todomvc.types.DELETE, id: state.get(1).get('id')
+    });
+
+    expect(new_state.size).to.equal(1);
+    expect(new_state.get(0)).to.equal(state.get(0))
   })
 });
(END)
```

Run the test and watch it fail.

```bash
  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    1) Should handle DELETE todo


  26 passing (90ms)
  1 failing

  1) TodoMVC reducer Should handle DELETE todo:

      AssertionError: expected 2 to equal 1
      + expected - actual

      -2
      +1

      at Context.<anonymous> (tests/todomvc/reducer.spec.js:55:31)
```

Write the code to make the test pass.

```javascript
diff --git a/src/todomvc/reducer.js b/src/todomvc/reducer.js
index b79948a..5f9a53c 100644
--- a/src/todomvc/reducer.js
+++ b/src/todomvc/reducer.js
@@ -11,6 +11,8 @@ export default function reducer(state = List([]), action) {
       return (state.push(Map({id: uuid.v4(), description: action.description, completed: false})));
     case types.EDIT:
       return (state.map(todo => todo.get('id') === action.id ? todo.set('description', action.description) : todo));
+    case types.DELETE:
+      return state.filter(todo => todo.get('id') !== action.id);
     default:
       // just return the same state
       return (state)
(END)
```

Run the test and watch it pass.

```bash
  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo


  27 passing (83ms)
```

Commit changes.

```bash
$ git add .
$ git commit -m 'handle DELETE todo'
```

## TodoItem component

### It Should render correctly

#### It should have a delete button

Write the test.

```javascript
diff --git a/tests/todomvc/components/TodoItem.spec.js b/tests/todomvc/components/TodoItem.spec.js
index 50c527e..8c2611f 100644
--- a/tests/todomvc/components/TodoItem.spec.js
+++ b/tests/todomvc/components/TodoItem.spec.js
@@ -38,6 +38,14 @@ describe('TodoItem component', () => {

       expect(label).to.have.length(1);
       expect(label.children().text()).to.equal(props.todo.get('description'))
+    });
+
+    it('Should have a delete button', () => {
+      const {component} = setup();
+      const button = component.children('button');
+
+      expect(button).to.have.length(1);
+      expect(button.children().text()).to.equal('delete todo')
     })
   });

(END)
```

Run the test and watch it fail.

```bash
  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      1) Should have a delete button
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo


  27 passing (86ms)
  1 failing

  1) TodoItem component Should render correctly Should have a delete button:

      AssertionError: expected { Object (root, unrendered, ...) } to have a length of 1 but got 0
      + expected - actual

      -0
      +1

      at Context.<anonymous> (tests/todomvc/components/TodoItem.spec.js:47:30)
```

Write the code to make the test pass.

```javascript
diff --git a/src/todomvc/components/TodoItem.js b/src/todomvc/components/TodoItem.js
index ef548fa..de2de69 100644
--- a/src/todomvc/components/TodoItem.js
+++ b/src/todomvc/components/TodoItem.js
@@ -34,6 +34,7 @@ export default class TodoItem extends Component {
         <label onDoubleClick={this.handleDoubleClick.bind(this)}>
           {todo.get('description')}
         </label>
+        <button>delete todo</button>
       </li>
     )
   }
@@ -44,6 +45,7 @@ export default class TodoItem extends Component {
     return (
       <li>
         <TodoTextInput text={todo.get('description')} onSave={(text) => this.handleSave(todo.get('id'), text)}/>
+        <button>delete todo</button>
       </li>
     )
   }
(END)
```

Run the test and watch it pass.

```bash
  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo


  28 passing (97ms)
```

Commit changes.

```bash
$ git add .
$ git commit -m 'have a delete button'
```

### It Should behave correctly

#### Should call deleteTodo() when the delete button is clicked

Write the test

```javascript
diff --git a/tests/todomvc/components/TodoItem.spec.js b/tests/todomvc/components/TodoItem.spec.js
index 8c2611f..21c704d 100644
--- a/tests/todomvc/components/TodoItem.spec.js
+++ b/tests/todomvc/components/TodoItem.spec.js
@@ -12,7 +12,8 @@ import TodoItem from '../../../src/todomvc/components/TodoItem'
 function setup() {
   const props = {
     todo: Map({id: uuid.v4(), description: 'Use Redux', completed: false}),
-    editTodo: sinon.spy()
+    editTodo: sinon.spy(),
+    deleteTodo: sinon.spy()
   };
   const component = shallow(
     <TodoItem {...props} />
@@ -76,6 +77,14 @@ describe('TodoItem component', () => {
       component.find('TodoTextInput').props().onSave('Use Redux'); // update
       component.update(); // force component to re-render
       expect(component.children('label')).to.have.length(1) // switched back to label
+    });
+
+    it('Should call deleteTodo() when the delete button is clicked', () => {
+      const {component, props} = setup();
+      const button = component.find('button');
+
+      button.simulate('click');
+      expect(props.deleteTodo.called).to.be.true
     })
   })
 });
(END)
```

Run the test and watch it fail

```bash
  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      1) Should call deleteTodo() when the delete button is clicked

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo


  28 passing (90ms)
  1 failing

  1) TodoItem component Should behave correctly Should call deleteTodo() when the delete button is clicked:

      AssertionError: expected false to be true
      + expected - actual

      -false
      +true

      at Context.<anonymous> (tests/todomvc/components/TodoItem.spec.js:87:7)
```

Write the code to make the test pass.

```javascript
diff --git a/src/todomvc/components/TodoItem.js b/src/todomvc/components/TodoItem.js
index de2de69..f125dc5 100644
--- a/src/todomvc/components/TodoItem.js
+++ b/src/todomvc/components/TodoItem.js
@@ -7,7 +7,8 @@ import TodoTextInput from './TodoTextInput'
 export default class TodoItem extends Component {
   static propTypes = {
     todo: PropTypes.object.isRequired,
-    editTodo: PropTypes.func.isRequired
+    editTodo: PropTypes.func.isRequired,
+    deleteTodo: PropTypes.func.isRequired
   };

   constructor(props, context) {
@@ -27,25 +28,25 @@ export default class TodoItem extends Component {
   }

   renderTodoListItem() {
-    const {todo} = this.props;
+    const {todo, deleteTodo} = this.props;

     return (
       <li>
         <label onDoubleClick={this.handleDoubleClick.bind(this)}>
           {todo.get('description')}
         </label>
-        <button>delete todo</button>
+        <button onClick={ () => deleteTodo(todo.get('id')) }>delete todo</button>
       </li>
     )
   }

   renderTodoTextInput() {
-    const {todo} = this.props;
+    const {todo, deleteTodo} = this.props;

     return (
       <li>
         <TodoTextInput text={todo.get('description')} onSave={(text) => this.handleSave(todo.get('id'), text)}/>
-        <button>delete todo</button>
+        <button onClick={ () => deleteTodo(todo.get('id')) }>delete todo</button>
       </li>
     )
   }
(END)
```

Run the test and watch it pass.

```bash
  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
Warning: Failed prop type: The prop `deleteTodo` is marked as required in `TodoItem`, but its value is `undefined`.
    in TodoItem
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo


  29 passing (98ms)
```

Let's now fix the required prop warning regression in the same way we did it for editTodo action.

```javascript
diff --git a/tests/todomvc/components/MainSection.spec.js b/tests/todomvc/components/MainSection.spec.js
index ff09a7b..badf84c 100644
--- a/tests/todomvc/components/MainSection.spec.js
+++ b/tests/todomvc/components/MainSection.spec.js
@@ -17,7 +17,8 @@ function setup() {
       Map({id: uuid.v4(), description: 'Run the tests', completed: false})
     ]),
     actions: {
-      editTodo: sinon.spy ()
+      editTodo: sinon.spy(),
+      deleteTodo: sinon.spy()
     }
   };

(END)
```

Run the test and watch it pass, this time without the warning.

```bash
  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo


  29 passing (98ms)
```

Commit changes.

```bash
$ git add .
$ git commit -m 'call deleteTodo() when the delete button is clicked'
```

#### Should call deleteTodo() when TodoTextInput onSave is called with no text

Write the test

```javascript
diff --git a/tests/todomvc/components/TodoItem.spec.js b/tests/todomvc/components/TodoItem.spec.js
index 21c704d..9792ed2 100644
--- a/tests/todomvc/components/TodoItem.spec.js
+++ b/tests/todomvc/components/TodoItem.spec.js
@@ -85,6 +85,14 @@ describe('TodoItem component', () => {

       button.simulate('click');
       expect(props.deleteTodo.called).to.be.true
+    });
+
+    it('Should call deleteTodo() when TodoTextInput onSave is called with no text', () => {
+      const {component, props} = setup();
+
+      component.children('label').simulate('doubleclick'); // switch to edit mode
+      component.find('TodoTextInput').props().onSave('');
+      expect(props.deleteTodo.called).to.be.true
     })
   })
 });
(END)
```

Run the test and watch it fail

```bash
  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked
      1) Should call deleteTodo() when TodoTextInput onSave is called with no text

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo


  29 passing (99ms)
  1 failing

  1) TodoItem component Should behave correctly Should call deleteTodo() when TodoTextInput onSave is called with no text:

      AssertionError: expected false to be true
      + expected - actual

      -false
      +true

      at Context.<anonymous> (tests/todomvc/components/TodoItem.spec.js:95:7)
```

Write the code to make the test pass.

```javascript
diff --git a/src/todomvc/components/TodoItem.js b/src/todomvc/components/TodoItem.js
index eb68ddd..a3d8959 100644
--- a/src/todomvc/components/TodoItem.js
+++ b/src/todomvc/components/TodoItem.js
@@ -23,7 +23,7 @@ export default class TodoItem extends Component {
   }

   handleSave(id, text) {
-    this.props.editTodo(id, text);
+    text === '' ? this.props.deleteTodo(id) : this.props.editTodo(id, text);
     this.setState({editing: false})
   }

(END)
```

Run the test and watch it pass, this time without the warning.

```bash
  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked
      ✓ Should call deleteTodo() when TodoTextInput onSave is called with no text

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo


  30 passing (98ms)
```

Commit changes.

```bash
$ git add .
$ git commit -m 'call deleteTodo() when TodoTextInput onSave is called with no text'
```

## Run It!

Now let's see what this looks like.

Open <http://localhost:4000> in your web browser.

Type "Hello" into the text input box and see a new delete button appear. Then enter "World". Now click on the "delete todo" button next to the "World" todo.

![](/files/-LPqjEdayxomuaPuT_mQ)

Now doubleclick on "Hello", delete all of the text, hit "enter" button and see that todo being deleted too.
