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}}
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):
self.instance.list = for_list
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):
return reverse("view_list", args=[self.id])
class Item(models.Model):
text = models.TextField(default="")
list = models.ForeignKey(List, default=None, on_delete=models.CASCADE)
class Meta:
ordering = ("id",)
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.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):
mylist = List.objects.create()
form = ItemForm(data={"text": "do re mi"})

View File

@@ -41,7 +41,21 @@ class ItemModelTest(TestCase):
item = Item(list=list2, text="nojk")
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):
def test_get_absolute_url(self):
mylist = List.objects.create()
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 .forms import ExistingListItemForm, ItemForm
from .models import Item, List
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):
form = ItemForm(data=request.POST)
if form.is_valid():
nulist = List.objects.create()
Item.objects.create(text=request.POST["text"], list=nulist)
form.save(for_list=nulist)
return redirect(nulist)
else:
return render(request, "apps/dashboard/home.html", {"form": form})
@@ -24,5 +23,5 @@ def view_list(request, list_id):
if form.is_valid():
form.save()
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})