1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
from django.test import TestCase, Client
from django.urls import reverse
from kitchen.models import Ingredient, PantryItem, MetaRecipe, Slot, SlotOption
class PantryStateTests(TestCase):
def setUp(self):
self.client = Client()
self.eggs = Ingredient.objects.create(name="eggs", default_unit="items")
self.item = PantryItem.objects.create(
ingredient=self.eggs, location="fridge", state="in"
)
def test_state_defaults_to_in(self):
self.assertEqual(self.item.state, "in")
def test_quantity_is_optional(self):
self.assertIsNone(self.item.quantity)
def test_set_state_endpoint(self):
resp = self.client.post(
reverse("app-pantry-set-state", args=[self.item.id]), {"to": "low"}
)
self.assertEqual(resp.status_code, 200)
self.item.refresh_from_db()
self.assertEqual(self.item.state, "low")
def test_set_state_rejects_unknown_value(self):
self.client.post(
reverse("app-pantry-set-state", args=[self.item.id]), {"to": "bogus"}
)
self.item.refresh_from_db()
self.assertEqual(self.item.state, "in") # unchanged
def test_out_items_still_listed(self):
self.item.state = "out"
self.item.save()
resp = self.client.get(reverse("app-pantry"))
self.assertContains(resp, "eggs")
def test_add_creates_in_stock_item(self):
resp = self.client.post(
reverse("app-pantry-add"),
{"ingredient_name": "milk", "location": "fridge"},
)
self.assertEqual(resp.status_code, 200)
self.assertTrue(
PantryItem.objects.filter(ingredient__name="milk", state="in").exists()
)
def test_add_restocks_existing_to_in(self):
self.item.state = "out"
self.item.save()
self.client.post(
reverse("app-pantry-add"),
{"ingredient_name": "eggs", "location": "fridge"},
)
# No duplicate row, and the existing one is back in stock.
items = PantryItem.objects.filter(ingredient=self.eggs, location="fridge")
self.assertEqual(items.count(), 1)
self.assertEqual(items.first().state, "in")
def test_search_matches_by_name(self):
resp = self.client.get(
reverse("app-pantry-search"), {"ingredient_name": "egg"}
)
self.assertContains(resp, "eggs")
class RecipesPresenceTests(TestCase):
"""The recipes matcher is presence-based now: having an ingredient (not
'out') satisfies a slot regardless of quantity."""
def setUp(self):
self.client = Client()
self.noodles = Ingredient.objects.create(name="noodles", default_unit="nests")
self.mr = MetaRecipe.objects.create(name="Noodles", method="boil")
slot = Slot.objects.create(meta_recipe=self.mr, name="carb", required=True)
SlotOption.objects.create(
slot=slot, ingredient=self.noodles, quantity_per_serving=2, unit="nests"
)
def test_present_ingredient_no_quantity_is_available(self):
# 'in' with no quantity should still count as available.
PantryItem.objects.create(
ingredient=self.noodles, location="cupboard", state="in"
)
resp = self.client.get(reverse("app-recipes"))
self.assertEqual(resp.status_code, 200)
self.assertContains(resp, "Noodles")
def test_out_ingredient_renders_without_error(self):
PantryItem.objects.create(
ingredient=self.noodles, location="cupboard", state="out"
)
resp = self.client.get(reverse("app-recipes"))
self.assertEqual(resp.status_code, 200)
class PageSmokeTests(TestCase):
def test_pages_render(self):
for name in ("app-pantry", "app-recipes", "app-shopping", "app-log"):
with self.subTest(page=name):
self.assertEqual(self.client.get(reverse(name)).status_code, 200)
|