from django.contrib.auth import get_user_model from django.test import TestCase from django.urls import reverse from django.utils import timezone from artifacts.models import Artifact, Label, TagColor User = get_user_model() class LabelPaletteTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username="alice", password="pw") self.client.force_login(self.user) def url(self): return reverse("settings-labels") def test_requires_login(self): self.client.logout() self.assertEqual(self.client.get(self.url()).status_code, 302) def test_create_label_sets_palette_and_tagcolor(self): self.client.post(self.url(), {"action": "create", "name": "follow-up", "color": "#112233"}) label = Label.objects.get(user=self.user, name="follow-up") self.assertEqual(label.color, "#112233") self.assertEqual(TagColor.objects.get(name="follow-up").color, "#112233") def test_create_rejects_bad_color(self): self.client.post(self.url(), {"action": "create", "name": "x", "color": "red"}) self.assertFalse(Label.objects.filter(user=self.user).exists()) def test_create_requires_name(self): self.client.post(self.url(), {"action": "create", "name": " ", "color": "#112233"}) self.assertFalse(Label.objects.filter(user=self.user).exists()) def test_duplicate_name_same_user_rejected(self): Label.objects.create(user=self.user, name="dup", color="#111111") self.client.post(self.url(), {"action": "create", "name": "dup", "color": "#222222"}) self.assertEqual(Label.objects.filter(user=self.user, name="dup").count(), 1) def test_same_name_different_user_allowed(self): other = User.objects.create_user(username="bob", password="pw") Label.objects.create(user=other, name="shared", color="#111111") self.client.post(self.url(), {"action": "create", "name": "shared", "color": "#222222"}) self.assertTrue(Label.objects.filter(user=self.user, name="shared").exists()) def test_recolor_updates_tagcolor(self): label = Label.objects.create(user=self.user, name="urgent", color="#111111") self.client.post(self.url(), {"action": "update", "label_id": label.pk, "color": "#ff0000"}) label.refresh_from_db() self.assertEqual(label.color, "#ff0000") self.assertEqual(TagColor.objects.get(name="urgent").color, "#ff0000") def test_delete_removes_from_palette_only(self): label = Label.objects.create(user=self.user, name="temp", color="#111111") art = Artifact.objects.create( id="lbl00001", owner=self.user, source="agent", title="T", kind=Artifact.MARKDOWN, day=timezone.localdate(), path="agent/lbl00001.html", original_kind=Artifact.MARKDOWN, tags=["temp"], ) self.client.post(self.url(), {"action": "delete", "label_id": label.pk}) self.assertFalse(Label.objects.filter(pk=label.pk).exists()) art.refresh_from_db() self.assertEqual(art.tags, ["temp"]) # chip stays on the message class ToggleLabelTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username="alice", password="pw") self.other = User.objects.create_user(username="bob", password="pw") self.client.force_login(self.user) self.label = Label.objects.create(user=self.user, name="star", color="#abcdef") self.art = Artifact.objects.create( id="tog00001", owner=self.user, source="agent", title="T", kind=Artifact.MARKDOWN, day=timezone.localdate(), path="agent/tog00001.html", original_kind=Artifact.MARKDOWN, ) def toggle(self, art_id, name): return self.client.post(reverse("artifact-toggle-label", args=[art_id]), {"name": name}) def test_toggle_on_then_off(self): r = self.toggle(self.art.id, "star") self.assertEqual(r.status_code, 200) self.assertTrue(r.json()["applied"]) self.art.refresh_from_db() self.assertIn("star", self.art.tags) r = self.toggle(self.art.id, "star") self.assertFalse(r.json()["applied"]) self.art.refresh_from_db() self.assertNotIn("star", self.art.tags) def test_toggle_syncs_tagcolor(self): self.toggle(self.art.id, "star") self.assertEqual(TagColor.objects.get(name="star").color, "#abcdef") def test_name_not_in_palette_rejected(self): r = self.toggle(self.art.id, "nope") self.assertEqual(r.status_code, 400) self.art.refresh_from_db() self.assertEqual(self.art.tags, []) def test_owner_scoped(self): theirs = Artifact.objects.create( id="tog00002", owner=self.other, source="agent", title="T", kind=Artifact.MARKDOWN, day=timezone.localdate(), path="agent/tog00002.html", original_kind=Artifact.MARKDOWN, ) self.assertEqual(self.toggle(theirs.id, "star").status_code, 404) def test_requires_login(self): self.client.logout() self.assertEqual(self.toggle(self.art.id, "star").status_code, 302)