Skip to content

Commit feef44e

Browse files
committed
cicd tests
1 parent 0601e32 commit feef44e

1 file changed

Lines changed: 143 additions & 0 deletions

File tree

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
"""Tests for the CICDInfrastructure model, form, and API.
2+
3+
Migration behaviour is tested separately in
4+
``test_cicd_infrastructure_migration.py``.
5+
"""
6+
7+
from django.db import IntegrityError, transaction
8+
from django.urls import reverse
9+
from rest_framework.authtoken.models import Token
10+
from rest_framework.test import APIClient, APITestCase
11+
12+
from dojo.forms import CICDInfrastructureForm
13+
from dojo.models import CICDInfrastructure
14+
15+
16+
# ---------------------------------------------------------------------------
17+
# Model
18+
# ---------------------------------------------------------------------------
19+
20+
class CICDInfrastructureModelTests(APITestCase):
21+
"""Model-level constraints and defaults."""
22+
23+
def test_unique_together_within_same_type_rejects_duplicate(self):
24+
CICDInfrastructure.objects.create(name="Jenkins", infrastructure_type="build_server")
25+
with self.assertRaises(IntegrityError):
26+
with transaction.atomic():
27+
CICDInfrastructure.objects.create(name="Jenkins", infrastructure_type="build_server")
28+
29+
def test_same_name_across_different_types_allowed(self):
30+
"""unique_together is (name, infrastructure_type), so the same name across
31+
different types coexists — supports the 'one Jenkins instance, multiple
32+
roles' case."""
33+
CICDInfrastructure.objects.create(name="Jenkins", infrastructure_type="build_server")
34+
CICDInfrastructure.objects.create(name="Jenkins", infrastructure_type="scm_server")
35+
CICDInfrastructure.objects.create(name="Jenkins", infrastructure_type="orchestration")
36+
self.assertEqual(CICDInfrastructure.objects.filter(name="Jenkins").count(), 3)
37+
38+
def test_description_and_url_default_to_empty_string(self):
39+
"""description and url are non-null with default='' (no None values)."""
40+
infra = CICDInfrastructure.objects.create(name="Bare", infrastructure_type="build_server")
41+
self.assertEqual(infra.description, "")
42+
self.assertEqual(infra.url, "")
43+
44+
45+
# ---------------------------------------------------------------------------
46+
# Form
47+
# ---------------------------------------------------------------------------
48+
49+
class CICDInfrastructureFormTests(APITestCase):
50+
"""Form-level behaviour — specifically the type-locked-on-edit rule."""
51+
52+
def test_infrastructure_type_editable_on_create(self):
53+
form = CICDInfrastructureForm()
54+
self.assertFalse(form.fields["infrastructure_type"].disabled)
55+
56+
def test_infrastructure_type_disabled_on_edit(self):
57+
existing = CICDInfrastructure.objects.create(
58+
name="LockedType", infrastructure_type="build_server",
59+
)
60+
form = CICDInfrastructureForm(instance=existing)
61+
self.assertTrue(form.fields["infrastructure_type"].disabled)
62+
63+
def test_disabled_field_ignores_posted_value(self):
64+
"""Django enforces ``disabled=True`` server-side — POSTed values
65+
for the type field on edit are silently ignored, so users cannot
66+
sneak around the UI lock."""
67+
existing = CICDInfrastructure.objects.create(
68+
name="LockedType2", infrastructure_type="build_server",
69+
)
70+
form = CICDInfrastructureForm(
71+
data={
72+
"name": "LockedType2",
73+
"description": "",
74+
"url": "",
75+
"infrastructure_type": "orchestration",
76+
},
77+
instance=existing,
78+
)
79+
self.assertTrue(form.is_valid(), form.errors)
80+
saved = form.save()
81+
self.assertEqual(saved.infrastructure_type, "build_server")
82+
83+
84+
# ---------------------------------------------------------------------------
85+
# API
86+
# ---------------------------------------------------------------------------
87+
88+
class CICDInfrastructureAPITests(APITestCase):
89+
"""The /cicd_infrastructure endpoint uses UserHasConfigurationPermissionSuperuser
90+
— superusers can do anything; non-superusers need the explicit Django permission."""
91+
92+
fixtures = ["dojo_testdata.json"]
93+
94+
def _client_for(self, username):
95+
token = Token.objects.get(user__username=username)
96+
c = APIClient()
97+
c.credentials(HTTP_AUTHORIZATION="Token " + token.key)
98+
return c
99+
100+
def test_superuser_can_list(self):
101+
c = self._client_for("admin")
102+
r = c.get(reverse("cicd_infrastructure-list"))
103+
self.assertEqual(r.status_code, 200, r.content[:1000])
104+
105+
def test_superuser_can_create(self):
106+
c = self._client_for("admin")
107+
r = c.post(
108+
reverse("cicd_infrastructure-list"),
109+
{"name": "Created via API", "infrastructure_type": "build_server"},
110+
format="json",
111+
)
112+
self.assertEqual(r.status_code, 201, r.content[:1000])
113+
self.assertTrue(CICDInfrastructure.objects.filter(name="Created via API").exists())
114+
115+
def test_create_rejects_duplicate_name_same_type(self):
116+
c = self._client_for("admin")
117+
CICDInfrastructure.objects.create(name="ApiDupe", infrastructure_type="scm_server")
118+
r = c.post(
119+
reverse("cicd_infrastructure-list"),
120+
{"name": "ApiDupe", "infrastructure_type": "scm_server"},
121+
format="json",
122+
)
123+
# DRF translates the unique_together violation to 400.
124+
self.assertEqual(r.status_code, 400, r.content[:1000])
125+
126+
def test_create_allows_same_name_different_type(self):
127+
c = self._client_for("admin")
128+
CICDInfrastructure.objects.create(name="Shared", infrastructure_type="build_server")
129+
r = c.post(
130+
reverse("cicd_infrastructure-list"),
131+
{"name": "Shared", "infrastructure_type": "orchestration"},
132+
format="json",
133+
)
134+
self.assertEqual(r.status_code, 201, r.content[:1000])
135+
136+
def test_non_superuser_is_rejected(self):
137+
# 'user1' (pk=2 in dojo_testdata.json) is a non-superuser with a token.
138+
try:
139+
c = self._client_for("user1")
140+
except Token.DoesNotExist:
141+
self.skipTest("user1 token not present in dojo_testdata fixture.")
142+
r = c.get(reverse("cicd_infrastructure-list"))
143+
self.assertIn(r.status_code, (401, 403), f"expected 401/403, got {r.status_code}")

0 commit comments

Comments
 (0)