Skip to content
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
5 changes: 0 additions & 5 deletions .env.example

This file was deleted.

15 changes: 15 additions & 0 deletions src/components/ShoppingList/ShoppingList.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { render, screen } from '@testing-library/react';
import ShoppingList from './ShoppingList';

describe('ShoppingList', () => {
it('renders the shopping list name', () => {
const testList = {
id: '1',
name: 'The Shoppingest List',
shoppingItems: [],
};
render(<ShoppingList shoppingList={testList} />);
expect(screen.queryByTestId('shopping-list-name-1').textContent)
.toBe('The Shoppingest List');
});
});
54 changes: 54 additions & 0 deletions src/components/ShoppingList/ShoppingListForm.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {
fireEvent,
render,
screen,
TestingLibraryElementError,
} from '@testing-library/react';
import ShoppingListForm from './ShoppingListForm';

describe('ShoppingListForm', () => {

it('renders a form', () => {
render(
<ShoppingListForm
id="test"
/>
);

const form = screen.getByTestId('shopping-list-form-test');

expect(form).toBeInTheDocument();
});

it('renders a submit button', () => {
render(
<ShoppingListForm
id="new"
/>
);

const button = screen.queryByTestId('shopping-list-form-submit-button-new');
expect(button).not.toBe(null);
expect(() => screen.getByTestId('shopping-list-form-submit-button-new'))
.not.toThrow(TestingLibraryElementError);
try {
screen.getByTestId('shopping-list-form-submit-button-new');
} catch (error) {
// eslint-disable-next-line no-undef
assert.fail();
}
});

it('text field is working', () => {
render(
<ShoppingListForm
id="new"
mode="create"
/>
);

const textarea = screen.getByTestId('shopping-list-form-name-new');
fireEvent.change(textarea, { target: { value: 'cats are alright' } });
expect(textarea.value).toBe('cats are alright');
});
});
26 changes: 24 additions & 2 deletions src/components/ShoppingList/ShoppingListItem.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
export default function ShoppingListItem() {
return <></>;
export default function ShoppingListItem({
shoppingItem,
onUpdateShoppingItem,
onDeleteShoppingItem,
}) {
return (
<div>
<span>
{shoppingItem.item_name}: {shoppingItem.quantity}
</span>
<br />
<button
data-testid={`update-shopping-item-${shoppingItem.id}`}
onClick={() => onUpdateShoppingItem(shoppingItem)}>
update
</button>
<br />
<button
data-testid={`delete-shopping-item-${shoppingItem.id}`}
onClick={() => onDeleteShoppingItem(shoppingItem)}>
delete
</button>
</div>
);
}
41 changes: 41 additions & 0 deletions src/components/ShoppingList/ShoppingListItem.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { fireEvent, render, screen } from '@testing-library/react';

import ShoppingListItem from './ShoppingListItem';

describe('Shopping List Item', () => {
const shoppingItem = {
id: 1,
item_name: 'test item',
quantity: 1,
};

it('update button updates shopping item', () => {
const onUpdateShoppingItem = jest.fn();
render(
<ShoppingListItem
shoppingItem={shoppingItem}
onUpdateShoppingItem={onUpdateShoppingItem}
/>
);
const updateButton = screen.getByTestId('update-shopping-item-1');
fireEvent.click(updateButton);
expect(onUpdateShoppingItem).toHaveBeenCalledWith(
shoppingItem
);
});

it('delete button deletes shopping item', () => {
const onDeleteShoppingItem = jest.fn();
render(
<ShoppingListItem
shoppingItem={shoppingItem}
onDeleteShoppingItem={onDeleteShoppingItem}
/>
);
const deleteButton = screen.getByTestId('delete-shopping-item-1');
fireEvent.click(deleteButton);
expect(onDeleteShoppingItem).toHaveBeenCalledWith(
shoppingItem
);
});
});
73 changes: 71 additions & 2 deletions src/components/ShoppingList/ShoppingListItemForm.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,72 @@
export default function ShoppingListItemForm() {
return <></>;
import { useState } from 'react';

const defaultShoppingItem = {
id: null,
item_name: '',
quantity: 0,
done: false,
};

export default function ShoppingListItemForm({
id,
shoppingItem,
onSubmit,
}) {
const [newShoppingItem, setNewShoppingItem] = useState(
shoppingItem || defaultShoppingItem
);

return (
<form
data-testid={`new-shopping-item-${id}`}
onSubmit={(e) => {
e.preventDefault();
onSubmit(newShoppingItem);
setNewShoppingItem(defaultShoppingItem);
}}
>
<label>
Item name:
<input
data-testid={`new-shopping-item-name-${id}`}
type="text"
name="name"
value={newShoppingItem.item_name}
onChange={(e) =>
setNewShoppingItem({
...newShoppingItem,
item_name: e.target.value,
})
}
/>
</label>
<br />
<label>
Quantity:
<input
data-testid={`new-shopping-item-quantity-${id}`}
type="number"
name="quantity"
value={newShoppingItem.quantity}
onChange={(e) =>
setNewShoppingItem({
...newShoppingItem,
quantity: e.target.value,
})
}
/>
</label>
<br />
<button
data-testid={`shopping-item-form-submit-button-${id}`}
onClick={(e) => {
e.preventDefault();
onSubmit(newShoppingItem);
}}
type="submit"
>
Add item
</button>
</form>
);
}
51 changes: 51 additions & 0 deletions src/components/ShoppingList/ShoppingListItemForm.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { fireEvent, render, screen } from '@testing-library/react';

import ShoppingListItemForm from './ShoppingListItemForm';

describe('Shopping List Item Form', () => {
it('renders a form', () => {
render(<ShoppingListItemForm id="test" />);
const form = screen.getByTestId('new-shopping-item-test');
expect(form).toBeInTheDocument();
});

it('renders a name input', () => {
render(<ShoppingListItemForm id="test" />);
const nameInput = screen.getByTestId(
'new-shopping-item-name-test'
);
expect(nameInput).toBeInTheDocument();

fireEvent.change(nameInput, { target: { value: 'test item' } });
expect(nameInput.value).toBe('test item');
});

it('submits form with shopping item on button click', () => {
const defaultShoppingItem = {
id: null,
item_name: 'test item',
quantity: 0,
done: false,
};

const onSubmit = jest.fn();
render(<ShoppingListItemForm id="test" onSubmit={onSubmit} />);
const nameInput = screen.getByTestId(
'new-shopping-item-name-test'
);
fireEvent.change(nameInput, { target: { value: 'test item' } });
const quantityInput = screen.getByTestId(
'new-shopping-item-quantity-test'
);
fireEvent.change(quantityInput, {
target: {
value: 0,
},
});
const button = screen.getByTestId(
'shopping-item-form-submit-button-test'
);
fireEvent.click(button);
expect(onSubmit).toHaveBeenCalledWith(defaultShoppingItem);
});
});
28 changes: 28 additions & 0 deletions src/components/ShoppingList/ShoppingLists.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//Write a test for creating new shopping lists.

import { render, screen } from '@testing-library/react';

import ShoppingLists from './ShoppingLists';

describe('Shopping Lists', () => {
it('renders a list of shopping lists', () => {
const time = new Date().getTime().toString();
const shoppingLists = [
{
id: 1,
name: 'test 1',
shoppingItems: [
{ id: 1, created_at: time, name: 'test item 1' },
{ id: 2, created_at: time, name: 'test item 2' },
{ id: 3, created_at: time, name: 'test item 3' },
],
},
];

render(<ShoppingLists shoppingLists={shoppingLists} />);

const shoppingListsList = screen.getByTestId('shopping-lists');
expect(shoppingListsList).toBeInTheDocument();
expect(shoppingListsList.children.length).toBe(1);
});
});
9 changes: 5 additions & 4 deletions src/hooks/useShoppingLists.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { createShoppingList } from '../services/shopping-lists.js';
import {
createShoppingListItem,
updateShoppingListItem,
deleteShoppingListItem
} from '../services/shopping-list-items.js';

export default function useShoppingLists() {
Expand Down Expand Up @@ -60,17 +61,17 @@ export default function useShoppingLists() {
};

const onDeleteShoppingItem = async (shoppingListItem) => {
await updateShoppingListItem(shoppingListItem);
await deleteShoppingListItem(shoppingListItem.id);
const newLists = [...shoppingLists];
const listIndex = newLists.findIndex(list => {
const listIndex = newLists.findIndex((list) => {
return list.id === shoppingListItem.shopping_list_id;
});
const newList = newLists[listIndex];
const itemIndex = newList.shoppingItems.findIndex(item => {
const itemIndex = newList.shoppingItems.findIndex((item) => {
return item.id === shoppingListItem.id;
});
const newItems = [...newList.shoppingItems];
delete newItems[itemIndex];
newItems.splice(itemIndex, 1);
newLists[listIndex] = {
...newList,
shoppingItems: newItems,
Expand Down