defined Meta ordering of the Item() model in apps.dashboard.models; Item() also now returns a __str__ result; in .forms, defined a specific use-case of is_valid() method; a pair of new UTs in .tests.test_models help confirm str representation and list order of items; .test_forms now ensures the .is-invalid bootstrap class is tested as a css class attr; migrations run; full UT & FT suite back to passing state (tho a refactor of flimsy form customizations is desperately needed)

This commit is contained in:
Disco DeDisco
2026-01-24 13:00:12 -05:00
parent 49491e2497
commit 0afc5ee8d7
6 changed files with 54 additions and 5 deletions

View File

@@ -19,6 +19,12 @@ class ItemForm(forms.models.ModelForm):
} }
error_messages = {"text": {"required": EMPTY_ITEM_ERROR}} error_messages = {"text": {"required": EMPTY_ITEM_ERROR}}
def is_valid(self):
result = super().is_valid()
if not result:
self.fields["text"].widget.attrs["class"] += " is-invalid"
return result
def save(self, for_list): def save(self, for_list):
self.instance.list = for_list self.instance.list = for_list
return super().save() return super().save()

View File

@@ -0,0 +1,17 @@
# Generated by Django 6.0 on 2026-01-24 17:54
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('dashboard', '0004_alter_item_unique_together'),
]
operations = [
migrations.AlterModelOptions(
name='item',
options={'ordering': ('id',)},
),
]

View File

@@ -5,10 +5,14 @@ class List(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return reverse("view_list", args=[self.id]) return reverse("view_list", args=[self.id])
class Item(models.Model): class Item(models.Model):
text = models.TextField(default="") text = models.TextField(default="")
list = models.ForeignKey(List, default=None, on_delete=models.CASCADE) list = models.ForeignKey(List, default=None, on_delete=models.CASCADE)
class Meta: class Meta:
ordering = ("id",)
unique_together = ("list", "text") unique_together = ("list", "text")
def __str__(self):
return self.text

View File

@@ -23,6 +23,15 @@ class ItemFormTest(TestCase):
self.assertFalse(form.is_valid()) self.assertFalse(form.is_valid())
self.assertEqual(form.errors["text"], [EMPTY_ITEM_ERROR]) self.assertEqual(form.errors["text"], [EMPTY_ITEM_ERROR])
def test_invalid_form_has_bootstrap_is_invalid_css_class(self):
form = ItemForm(data={"text": ""})
self.assertFalse(form.is_valid())
field = form.fields["text"]
self.assertEqual(
field.widget.attrs["class"],
"form-control form-control-lg is-invalid",
)
def test_form_save_handles_saving_to_a_list(self): def test_form_save_handles_saving_to_a_list(self):
mylist = List.objects.create() mylist = List.objects.create()
form = ItemForm(data={"text": "do re mi"}) form = ItemForm(data={"text": "do re mi"})

View File

@@ -41,7 +41,21 @@ class ItemModelTest(TestCase):
item = Item(list=list2, text="nojk") item = Item(list=list2, text="nojk")
item.full_clean() # should not raise item.full_clean() # should not raise
def test_string_representation(self):
item = Item(text="sample text")
self.assertEqual(str(item), "sample text")
class ListModelTest(TestCase): class ListModelTest(TestCase):
def test_get_absolute_url(self): def test_get_absolute_url(self):
mylist = List.objects.create() mylist = List.objects.create()
self.assertEqual(mylist.get_absolute_url(), f"/apps/dashboard/{mylist.id}/") self.assertEqual(mylist.get_absolute_url(), f"/apps/dashboard/{mylist.id}/")
def test_list_items_order(self):
list1 = List.objects.create()
item1 = Item.objects.create(list=list1, text="i1")
item2 = Item.objects.create(list=list1, text="item 2")
item3 = Item.objects.create(list=list1, text="3")
self.assertEqual(
list(list1.item_set.all()),
[item1, item2, item3],
)

View File

@@ -1,16 +1,15 @@
from django.core.exceptions import ValidationError
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from .forms import ExistingListItemForm, ItemForm from .forms import ExistingListItemForm, ItemForm
from .models import Item, List from .models import Item, List
def home_page(request): def home_page(request):
return render(request, 'apps/dashboard/home.html', {"form": ItemForm()}) return render(request, "apps/dashboard/home.html", {"form": ItemForm()})
def new_list(request): def new_list(request):
form = ItemForm(data=request.POST) form = ItemForm(data=request.POST)
if form.is_valid(): if form.is_valid():
nulist = List.objects.create() nulist = List.objects.create()
Item.objects.create(text=request.POST["text"], list=nulist) form.save(for_list=nulist)
return redirect(nulist) return redirect(nulist)
else: else:
return render(request, "apps/dashboard/home.html", {"form": form}) return render(request, "apps/dashboard/home.html", {"form": form})
@@ -24,5 +23,5 @@ def view_list(request, list_id):
if form.is_valid(): if form.is_valid():
form.save() form.save()
return redirect(our_list) return redirect(our_list)
return render(request, 'apps/dashboard/list.html', {'list': our_list, "form": form}) return render(request, "apps/dashboard/list.html", {"list": our_list, "form": form})