bloombase/plants/tests/test_pruning.py
Stephan Kerkman b88ba03884 feat: location FK, multi-photo gallery, hide pruning history
- Location model: plants now FK to Location instead of free-text CharField
- Data migration 0004 converts existing location strings to Location objects
- PlantForm uses ModelChoiceField dropdown + inline "add new location" text field
- PlantPhoto model: multiple photos per plant with is_thumbnail flag
- Plant.thumbnail_url property: picks marked thumbnail, falls back to first photo then legacy photo field
- Photo gallery partial: upload, set thumbnail (★), delete (✕) with HTMX swaps on #photo-gallery
- plant_detail: uses thumbnail_url for hero image, pruning history section removed
- plant_list search updated: location__name__icontains instead of location__icontains
- Three new URL routes: upload_photo, set_thumbnail, delete_photo
- All 53 tests updated and passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 18:27:45 +02:00

95 lines
3 KiB
Python

import pytest
from datetime import date
from plants.models import Plant, PruningLog, Location
from plants.utils.pruning import pruning_status, months_before
def make_location(name):
loc, _ = Location.objects.get_or_create(name=name)
return loc
def test_months_before_same_year():
d = date(2026, 5, 27)
assert months_before(d, 1) == date(2026, 4, 1)
assert months_before(d, 4) == date(2026, 1, 1)
def test_months_before_crosses_year():
d = date(2026, 5, 27)
assert months_before(d, 5) == date(2025, 12, 1)
assert months_before(d, 12) == date(2025, 5, 1)
def test_months_before_january():
d = date(2026, 1, 15)
assert months_before(d, 1) == date(2025, 12, 1)
assert months_before(d, 2) == date(2025, 11, 1)
@pytest.mark.django_db
def test_no_schedule():
plant = Plant.objects.create(name='Fern', pruning_months=[])
assert pruning_status(plant) == 'no_schedule'
@pytest.mark.django_db
def test_due_this_month():
today = date(2026, 5, 15)
plant = Plant.objects.create(name='Rose', pruning_months=[5])
assert pruning_status(plant, today) == 'due_this_month'
@pytest.mark.django_db
def test_due_this_month_already_logged():
today = date(2026, 5, 15)
plant = Plant.objects.create(name='Rose', pruning_months=[5])
PruningLog.objects.create(plant=plant, pruned_on=date(2026, 5, 1))
assert pruning_status(plant, today) == 'upcoming'
@pytest.mark.django_db
def test_overdue_when_past_month_not_logged():
today = date(2026, 5, 15)
plant = Plant.objects.create(name='Rose', pruning_months=[3])
assert pruning_status(plant, today) == 'overdue'
@pytest.mark.django_db
def test_not_overdue_when_past_month_logged():
today = date(2026, 5, 15)
plant = Plant.objects.create(name='Rose', pruning_months=[3])
PruningLog.objects.create(plant=plant, pruned_on=date(2026, 3, 10))
assert pruning_status(plant, today) == 'upcoming'
@pytest.mark.django_db
def test_not_overdue_when_logged_after_scheduled_month():
# Pruned in May clears a March schedule — the common real-world case
today = date(2026, 5, 28)
plant = Plant.objects.create(name='Rose', pruning_months=[3])
PruningLog.objects.create(plant=plant, pruned_on=date(2026, 5, 28))
assert pruning_status(plant, today) == 'upcoming'
@pytest.mark.django_db
def test_upcoming_future_month():
today = date(2026, 5, 15)
plant = Plant.objects.create(name='Rose', pruning_months=[8])
assert pruning_status(plant, today) == 'upcoming'
@pytest.mark.django_db
def test_overdue_crosses_year_boundary():
# Pruning month December, checked in January
today = date(2026, 1, 10)
plant = Plant.objects.create(name='Apple', pruning_months=[12])
assert pruning_status(plant, today) == 'overdue'
@pytest.mark.django_db
def test_overdue_several_months_before_year_boundary():
# Plant scheduled in August, checked in January — should be overdue
today = date(2026, 1, 10)
plant = Plant.objects.create(name='Oak', pruning_months=[8])
assert pruning_status(plant, today) == 'overdue'